Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import Header from "@/components/Header.tsx";
import React from "react";
import PrivacyPolicy from "@/pages/PrivacyPolicy.tsx";
import Footer from "@/components/Footer.tsx";
import SpeakerInfo from "@/components/SpeakerInfo.tsx";
import SpeakerInfo from "@/components/speakers/SpeakerInfo.tsx";
import {AppProvider, useAppContext} from "@/context/AppContext.tsx";
import TicketsPage from "@/pages/TicketsPage.tsx";
import CodeOfConductSpeakers from "@/pages/CodeOfConductSpeakers.tsx";
Expand Down
38 changes: 14 additions & 24 deletions src/components/agenda/CardCharla.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
import React, { useEffect, useState } from "react";
import { IRoomAgenda } from "@/types/agenda.ts";
import { useAppContext } from "@/context/AppContext.tsx";
import {ISession} from "@/types/speakers.ts";
import {Star} from "lucide-react";
import {Button} from "@/components/ui/button.tsx";
import {useNavigate} from "react-router-dom";
import {ISession} from "@/types/sessions.ts";

interface CardEventProps {
room: IRoomAgenda;
room?: IRoomAgenda;
session: ISession;
className?: string;
}

const CardEvent: React.FC<CardEventProps> = ({ room }) => {
const CardEvent: React.FC<CardEventProps> = ({ room, session, className }) => {
const { savedSessions, setSavedSessions, displayAll } = useAppContext();
const session = room.session;
const navigate = useNavigate();
const [isSaved, setIsSaved] = useState(false);

Expand All @@ -39,16 +40,15 @@ const CardEvent: React.FC<CardEventProps> = ({ room }) => {

if (!displayAll && !savedSessions.has(session.id)) return null;
return (
<div id={`session-${session.id}`} className="flex flex-col gap-4 mt-6">
<h3 className={`font-bold text-2xl`}>Sala: {room.name}</h3>
<WrappedCardEvent className={`relative
<div id={`session-${session.id}`} className={`flex flex-col gap-4 ${className}`}>
{ room && <h3 className={`font-bold text-2xl`}>Sala: {room.name}</h3>}
<article className={`relative
bg-white shadow-sm shadow-gray-600 border-2 border-primary-600
flex flex-col gap-2 rounded-lg min-h-52 h-full p-4
transition-all duration-300
`}
session={session}
>
<aside className="flex w-full items-center">
<aside className={`flex w-full items-center`}>
{isSaved && (
<span className="bg-primary-500 text-white text-xs font-bold px-2 py-1 rounded-full shadow w-20 text-center justify-self-start">Guardado</span>
)}
Expand All @@ -61,7 +61,7 @@ const CardEvent: React.FC<CardEventProps> = ({ room }) => {
}}
className={`bg-white justify-self-end group flex justify-center items-center gap-2 border border-primary-500 font-bold px-2 py-1 rounded-lg transition-colors duration-300`}
>
<Star className={`h-4 w-4 text-primary-500 ${isSaved ? "fill-primary-500" : "fill-white group-hover:fill-primary-500"}`}/>
<Star className={`h-4 w-4 text-primary-500 ${isSaved ? "fill-primary-500" : "fill-white md:group-hover:fill-primary-500"}`}/>
</button>
</aside>

Expand All @@ -75,27 +75,17 @@ const CardEvent: React.FC<CardEventProps> = ({ room }) => {
</div>
<p hidden={session.speakers.length > 0} className={`h-full ${isSaved ? "text-gray-600" : "text-gray-500"} font-bold text-2xl`}>{session.description}</p>
{ session.speakers.length > 0 && (
<Button variant="ghost" onClick={() => navigate(`/session/${session.id}`)}>
<Button variant="ghost" role="link" aria-label="Ir a ver mas detalles de la charla" onClick={() => {
navigate(`/session/${session.id}`);
}}>
Ver detalles
</Button>
)}
</WrappedCardEvent>
</article>
</div>
);
};

interface WrappedCardEventProps {
session: ISession;
children: React.ReactNode;
className: string;
}

const WrappedCardEvent: React.FC<WrappedCardEventProps> = ({session, children, className}) => {
if (session.speakers.length === 0) return (<div className={className}>{children}</div>)
return <div
className={className}
>{children}
</div>
}

export default CardEvent;
9 changes: 7 additions & 2 deletions src/components/agenda/Rooms.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
import React from "react";
import CardCharla from "@/components/agenda/CardCharla.tsx";
import {IRoomAgenda} from "@/types/agenda.ts";

const Rooms = ({rooms}) => {
interface RoomsProps {
rooms: IRoomAgenda[]
}

const Rooms: React.FC<RoomsProps> = ({rooms}) => {
return (
<div className="grid grid-cols-[repeat(auto-fit,minmax(280px,1fr))] gap-6 px-4 w-full">
{rooms.map((room) => {
return <CardCharla key={room.id} room={room} />
return <CardCharla key={room.id} className="mt-6" room={room} session={room.session} />
})}
</div>
)
Expand Down
26 changes: 0 additions & 26 deletions src/components/agenda/RoomsExpandable.tsx

This file was deleted.

12 changes: 11 additions & 1 deletion src/components/session/SessionCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,16 @@ import {Card, CardFooter} from "@/components/ui/card.tsx";
import {Badge} from "@/components/ui/badge.tsx";
import {Speech} from "lucide-react";
import React from "react";
import {ISessionInfo} from "@/types/sessions.ts";

const SessionCard = ({session}) => {
interface SessionCardProps {
session: ISessionInfo
}

const SessionCard: React.FC<SessionCardProps> = ({session}) => {
const category = session.category
const startTime = new Date(session.startsAt).toLocaleTimeString(["en-US"], {hour: '2-digit', minute:'2-digit'})
const endTime = new Date(session.endsAt).toLocaleTimeString(["en-US"], {hour: '2-digit', minute:'2-digit'})
return (
<Card className="py-8 px-6 flex flex-col gap-4">
<h2 className="text-3xl font-bold text-alternative-700">
Expand All @@ -13,6 +20,9 @@ const SessionCard = ({session}) => {
<h3 className="text-2xl text-gray-700 font-semibold">
{session.title}
</h3>
{ startTime && endTime &&
<h1 className="text-lg font-bold text-alternative-700"><time dateTime={startTime}>{startTime}</time> <span aria-label="a">-</span> <time dateTime={endTime}>{endTime}</time></h1>
}
<span className="text-lg text-primary-600 font-semibold">Descripción</span>
<p className="text-lg text-gray-700">{session.description}</p>
<CardFooter className="p-0">
Expand Down
38 changes: 38 additions & 0 deletions src/components/session/SessionTracks.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import React from "react";
import {Card} from "@/components/ui/card.tsx";
import CardCharla from "@/components/agenda/CardCharla.tsx";
import {Speech} from "lucide-react";
import {Badge} from "@/components/ui/badge.tsx";
import {formatTiemstamp} from "@/lib/utils.ts";
import {ISessionInfo} from "@/types/sessions.ts";

interface SessionTracksProps {
currentSession?: ISessionInfo
sessions: ISessionInfo[]
category: string
}

const SessionTracks: React.FC<SessionTracksProps> = ({sessions, category, currentSession}) => {
const tracks = sessions.filter(session => session.category === category && session.id !== currentSession.id);
return (
<Card className="py-8 px-6 flex flex-col gap-8">
<Badge variant="alternative" className="flex gap-2"><Speech/> Charlas de {category}</Badge>
<div className="grid grid-cols-[repeat(auto-fit,minmax(300px,1fr))] gap-6 w-full h-full">
{
tracks.map(session => (
<article className="flex flex-col gap-y-2 h-full" key={`track-${session.id}`}>
<h3 className="text-xl font-bold text-alternative-700 px-2 flex gap-2">
<time>{formatTiemstamp(session.startsAt)}</time>
<span aria-label="a">-</span>
<time>{formatTiemstamp(session.endsAt)}</time>
</h3>
<CardCharla className="m-0 min-h-[318px]" session={session} room={null} />
</article>
))
}
</div>
</Card>
)
}

export default SessionTracks
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
import {ISpeaker} from "@/types/speakers.ts";
import {Card, CardFooter} from "@/components/ui/card.tsx";
import {Card} from "@/components/ui/card.tsx";
import React, {useEffect, useState} from "react";
import {useLocation, useNavigate, useParams} from "react-router-dom";
import SocialMedia from "@/components/SocialMedia.tsx";
import {Badge} from "@/components/ui/badge.tsx";
import { ChevronLeft, Speech} from "lucide-react";
import Gradient from "@/components/Gradient.tsx";
import {useAppContext} from "@/context/AppContext.tsx";
import {findSpeaker, scrollToTop} from "@/lib/utils.ts";
import Shared from "@/components/Shared.tsx";
import Loading from "@/pages/Loading.tsx";
import SessionCard from "@/components/session/SessionCard.tsx";
import SessionTracks from "@/components/session/SessionTracks.tsx";

const SpeakerInfo = () => {
const navigate = useNavigate()
const location = useLocation();
const { speakerId } = useParams();
const { speakers } = useAppContext();
const { speakers, sessions } = useAppContext();
const speaker = location.state?.speaker as ISpeaker;
const [currentSpeaker, setCurrentSpeaker] = useState<ISpeaker>()
const fullUrl = `${window.location.origin}${location.pathname}${location.search}${location.hash}`;
Expand All @@ -32,7 +33,7 @@ const SpeakerInfo = () => {
}
}, [speaker, speakers]);

if (!currentSpeaker) {
if (!currentSpeaker || speakers.length == 0) {
return (
<div className="flex items-center justify-center min-h-screen">
<Loading size={60} count={5} />
Expand Down Expand Up @@ -75,20 +76,15 @@ const SpeakerInfo = () => {
</div>
</Card>

<Card className="py-8 px-6 flex flex-col gap-4">
<h2 className="text-3xl font-bold text-alternative-700">
Charla
</h2>
<h3 className="text-2xl text-gray-700 font-semibold">
{currentSpeaker.sessions.title}
</h3>
<span className="text-lg text-primary-600 font-semibold">Descripción</span>
<p className="text-lg text-gray-700">{currentSpeaker.sessions.description}</p>
<CardFooter className="p-0">
<Badge variant="default" className="flex gap-2"><Speech/> Track: {currentSpeaker.category}</Badge>
</CardFooter>
</Card>
{
currentSpeaker.sessions.map(session => (
<SessionCard key={session.id} session={session}/>
))
}
</article>
{ currentSpeaker.sessions.length == 1 &&
<SessionTracks currentSession={currentSpeaker.sessions[0]} sessions={sessions} category={currentSpeaker.sessions[0].category} />
}
</Gradient>
)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import Speaker from "@/components/Speaker.tsx";
import Speaker from "@/components/speakers/Speaker.tsx";
import Carousel, {GridConfig} from "@/components/Carousel.tsx";
import {useAppContext} from "@/context/AppContext.tsx";
import {ISpeaker} from "@/types/speakers.ts";
Expand Down
2 changes: 2 additions & 0 deletions src/components/ui/badge.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ const badgeVariants = cva(
"border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80",
outline: "text-foreground",
ghost: "border border-primary-600 bg-white text-primary-600 transition-colors duration-300",
border: "border border-alternative-600 bg-white text-alternative-600 transition-colors duration-300",
alternative: "border-transparent bg-alternative-600 text-white transition-colors duration-300",
},
},
defaultVariants: {
Expand Down
26 changes: 16 additions & 10 deletions src/context/AppContext.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
import { createContext, useContext, useState, useEffect } from "react";
import {ISession, ISessionInfo, ISpeaker} from "@/types/speakers.ts";
import { ISpeaker} from "@/types/speakers.ts";
import {getAll} from "@/https/fetch.ts";
import {AppStatus} from "@/types/types.ts";
import {addSessionSpeakers, getCategoryNameSessions} from "@/lib/utils.ts";
import {addInformationToSession, addSessionSpeakers} from "@/lib/utils.ts";
import {ITimeSlot} from "@/types/agenda.ts";
import ErrorPage from "@/pages/ErrorPage.tsx";
import Loading from "@/pages/Loading.tsx";
import {ISessionInfo} from "@/types/sessions.ts";


interface AppContextType {
speakers: ISpeaker[];
sessions: ISessionInfo[];
agenda: ITimeSlot[];
appStatus: AppStatus;
setAppStatus: (status: AppStatus) => void
setAgenda: (agenda: ITimeSlot[]) => void;
savedSessions: Set<number>;
setSavedSessions: (sessions: Set<number>) => void;
Expand All @@ -28,6 +30,7 @@ export const AppProvider = ({ children }) => {
const [appStatus, setAppStatus] = useState(AppStatus.Loading);
const [displayAll, setDisplayAll] = useState<boolean>(true);
const [sessions, setSessions] = useState<ISessionInfo[]>([]);
const [error, setError] = useState<Error>(null)
const [savedSessions, setSavedSessions] = useState<Set<number>>(() => {
const raw = localStorage.getItem("savedSessions");
return raw ? new Set<number>(JSON.parse(raw)) : new Set<number>();
Expand All @@ -39,18 +42,20 @@ export const AppProvider = ({ children }) => {

useEffect(() => {
getAll()
.then((data) => {
const categories = data.categories[0].items
.then(({categories, sessions, speakers, rooms}) => {
const categoriesItems = categories[0].items
const sessionsInfo = sessions.map(session => addInformationToSession(session, speakers, categoriesItems))
const getSpeakersWithSessions = addSessionSpeakers(
data.sessions,
data.speakers,
categories
sessionsInfo,
speakers
);
console.log(getSpeakersWithSessions[0]);
setSpeakers(getSpeakersWithSessions);
setSessions(getCategoryNameSessions(categories, data.sessions));
setSessions(sessionsInfo);
setAppStatus(AppStatus.Success);
})
.catch(() => {
.catch(e => {
setError(e);
setAppStatus(AppStatus.Error);
});
}, []);
Expand All @@ -65,6 +70,7 @@ export const AppProvider = ({ children }) => {
speakers,
agenda,
appStatus,
setAppStatus
};

return (
Expand All @@ -75,7 +81,7 @@ export const AppProvider = ({ children }) => {
</div>
)}

{appStatus === AppStatus.Error && <ErrorPage />}
{appStatus === AppStatus.Error && <ErrorPage error={error} />}

{appStatus === AppStatus.Success && children}
</AppContext.Provider>
Expand Down
3 changes: 2 additions & 1 deletion src/https/fetch.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {IAgenda, IConferenceData, ISpeaker} from "@/types/speakers.ts";
import {IConferenceData, ISpeaker} from "@/types/speakers.ts";
import {IAgenda} from "@/types/agenda.ts";

export const getSpeakers = async () => {
const response = await fetch('https://sessionize.com/api/v2/n25df8kw/view/Speakers');
Expand Down
Loading