+
{speaker.links.map((link, index) => (
))}
-
-
)
diff --git a/src/components/SpeakerInfo.tsx b/src/components/SpeakerInfo.tsx
index 87b14dc..9cabfcc 100644
--- a/src/components/SpeakerInfo.tsx
+++ b/src/components/SpeakerInfo.tsx
@@ -1,8 +1,52 @@
+import {ISpeaker} from "@/types/speakers.ts";
+import {Card, CardFooter} from "@/components/ui/card.tsx";
+import React, {useEffect} from "react";
+import {useLocation} from "react-router-dom";
+import SocialMedia from "@/components/SocialMedia.tsx";
+import {Badge} from "@/components/ui/badge.tsx";
+import {Share2, Speech} from "lucide-react";
+import Gradient from "@/components/Gradient.tsx";
+
const SpeakerInfo = () => {
+ const location = useLocation();
+ const speaker = location.state?.speaker as ISpeaker;
+ const {fullName, sessions, profilePicture, tagLine, bio, links} = speaker;
+
return (
-
+
+
+
+
+
+
{fullName}
+
{tagLine}
+
{bio}
+
+ {links.map((link, index) => (
+
+ ))}
+
+ Compartir
+
+
+
+
-
+
+
+ Charla
+
+
+ {sessions.title}
+
+ Descripción
+ {sessions.description}
+
+ Track: {speaker.category}
+
+
+
+
)
}
export default SpeakerInfo
\ No newline at end of file
diff --git a/src/components/Speakers.tsx b/src/components/Speakers.tsx
index 1b47343..2e5e180 100644
--- a/src/components/Speakers.tsx
+++ b/src/components/Speakers.tsx
@@ -1,26 +1,15 @@
-import React, {useEffect, useState} from 'react';
-import {ISpeaker} from "@/types/speakers.ts";
-import {getSpeakers} from "@/https/fetch.ts";
+import React from 'react';
import Speaker from "@/components/Speaker.tsx";
import Carousel, {GridConfig} from "@/components/Carousel.tsx";
-import Loading from "@/components/Loading.tsx";
+import {useAppContext} from "@/context/AppContext.tsx";
const Speakers = () => {
- const [speakers, setSpeakers] = useState
([]);
- const [loading, setLoading] = useState(true);
+ const {speakers} = useAppContext();
const gridLg: GridConfig = {cols: 3, rows: 2, itemsPerSlide: 5};
const gridMd: GridConfig = {cols: 2, rows: 2, itemsPerSlide: 3};
const gridSm: GridConfig = {cols: 1, rows: 1, itemsPerSlide: 1};
- useEffect(() => {
- getSpeakers().then((data) => {
- setSpeakers(data);
- setLoading(false);
- });
- }, []);
- if (loading) return ();
-
if (speakers.length === 0) return null
return (
@@ -31,7 +20,7 @@ const Speakers = () => {
aria-labelledby="hero-title"
>
Speakers
-
+
diff --git a/src/components/ui/badge.tsx b/src/components/ui/badge.tsx
index f000e3e..9df3ac6 100644
--- a/src/components/ui/badge.tsx
+++ b/src/components/ui/badge.tsx
@@ -9,7 +9,7 @@ const badgeVariants = cva(
variants: {
variant: {
default:
- "border-transparent bg-primary text-primary-foreground hover:bg-primary/80",
+ "border-transparent bg-primary text-primary-foreground",
secondary:
"border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",
destructive:
diff --git a/src/context/AppContext.tsx b/src/context/AppContext.tsx
new file mode 100644
index 0000000..49e9140
--- /dev/null
+++ b/src/context/AppContext.tsx
@@ -0,0 +1,62 @@
+import { createContext, useContext, useState, useEffect } from "react";
+import {ISession, ISpeaker} from "@/types/speakers.ts";
+import {getAll} from "@/https/fetch.ts";
+import {AppStatus} from "@/types/types.ts";
+import Loading from "@/components/Loading.tsx";
+import {addSessionSpeakers} from "@/lib/utils.ts";
+
+
+interface AppContextType {
+ speakers: ISpeaker[];
+ sessions: ISession[];
+ agenda: any[]; // o tipa tu modelo de agenda si lo tienes
+ appStatus: AppStatus;
+}
+
+const AppContext = createContext(null);
+
+export const AppProvider = ({ children }) => {
+ const [speakers, setSpeakers] = useState([]);
+ const [agenda, setAgenda] = useState([]);
+ const [appStatus, setAppStatus] = useState(AppStatus.Loading);
+
+ useEffect(() => {
+ getAll().then((data) => {
+ const getSpeakersWithSessions = addSessionSpeakers(data.sessions, data.speakers, data.categories[0].items);
+ setSpeakers(getSpeakersWithSessions);
+ });
+ setAppStatus(AppStatus.Success)
+ }, []);
+
+ const value = {
+ speakers,
+ agenda,
+ appStatus
+ };
+
+ if (appStatus === AppStatus.Loading) {
+ return (
+
+
+
+ );
+ }
+
+ if (appStatus === AppStatus.Error) {
+ return (
+
+ Error al cargar los datos iniciales 😞
+
+ );
+ }
+
+ return {children};
+};
+
+export const useAppContext = (): AppContextType => {
+ const context = useContext(AppContext);
+ if (!context) {
+ throw new Error("");
+ }
+ return context;
+};
\ No newline at end of file
diff --git a/src/https/fetch.ts b/src/https/fetch.ts
index 364501e..d7ca34f 100644
--- a/src/https/fetch.ts
+++ b/src/https/fetch.ts
@@ -1,4 +1,4 @@
-import {ISpeaker} from "@/types/speakers.ts";
+import {IConferenceData, ISpeaker} from "@/types/speakers.ts";
export const getSpeakers = async () => {
const response = await fetch('https://sessionize.com/api/v2/n25df8kw/view/Speakers');
@@ -7,4 +7,12 @@ export const getSpeakers = async () => {
}
const data: ISpeaker[] = await response.json();
return data;
+}
+
+export const getAll = async (): Promise => {
+ const response = await fetch('https://sessionize.com/api/v2/n25df8kw/view/All');
+ if (!response.ok) {
+ throw new Error('Failed to fetch data');
+ }
+ return await response.json()
}
\ No newline at end of file
diff --git a/src/index.css b/src/index.css
index 7aff0e0..f74257f 100644
--- a/src/index.css
+++ b/src/index.css
@@ -131,7 +131,6 @@ All colors MUST be HSL.
}
}
-/* Estilos personalizados para Posadev */
.gradient-bg {
background: linear-gradient(
125deg,
@@ -149,6 +148,7 @@ All colors MUST be HSL.
}
}
+
.gradient-text {
background: linear-gradient(135deg, #CF0F47, #FF0B55);
-webkit-background-clip: text;
@@ -181,4 +181,14 @@ All colors MUST be HSL.
30% { transform: translateY(-8px) rotate(-18deg); }
60% { transform: translateY(0) rotate(-22deg); }
100% { transform: translateY(0) rotate(-20deg); }
+}
+
+@layer utilities {
+ .bg-candy-stripes {
+ background-image: repeating-linear-gradient(
+ 45deg,
+ #FF0B55 0 10px,
+ white 10px 20px
+ );
+ }
}
\ No newline at end of file
diff --git a/src/lib/utils.ts b/src/lib/utils.ts
index 2eac70c..6efe90a 100644
--- a/src/lib/utils.ts
+++ b/src/lib/utils.ts
@@ -1,5 +1,6 @@
import { clsx, type ClassValue } from "clsx"
import { twMerge } from "tailwind-merge"
+import {ICategory, ISession, ISpeaker} from "@/types/speakers.ts";
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs))
@@ -16,4 +17,17 @@ export const handleCopy = async (toast, dismiss) => {
} finally {
setTimeout(() => dismiss(), 3000);
}
-};
\ No newline at end of file
+};
+
+export const addSessionSpeakers = (sessions: ISession[], speakers: ISpeaker[], categories: ICategory[]): ISpeaker[] => {
+ return speakers.map((speaker) => {
+ const session = sessions.find((session) => session.speakers.includes(speaker.id));
+ const category = categories.find((category) => session.categoryItems.includes(category.id))
+ console.log(category.name)
+ return {
+ ...speaker,
+ sessions: session,
+ category: category.name
+ };
+ });
+}
\ No newline at end of file
diff --git a/src/pages/Index.tsx b/src/pages/Index.tsx
index f261a13..9a1d663 100644
--- a/src/pages/Index.tsx
+++ b/src/pages/Index.tsx
@@ -1,9 +1,7 @@
import React, {useEffect} from 'react';
import Hero from '@/components/Hero';
import Gallery from '@/components/Gallery';
-import Sponsors from '@/components/Sponsors';
import {useLocation} from "react-router-dom";
-import Communities from "@/components/Communities.tsx";
import BecomeSponsor from "@/components/BecomeSponsor.tsx";
import Organizers from "@/components/Organizers.tsx";
import Speakers from "@/components/Speakers.tsx";
diff --git a/src/types/speakers.ts b/src/types/speakers.ts
index 9f4abe7..ac1ee35 100644
--- a/src/types/speakers.ts
+++ b/src/types/speakers.ts
@@ -6,16 +6,20 @@ export interface ISpeaker {
bio: string
tagLine: string
profilePicture: string
- sessions: ISession[]
+ sessions: ISession
isTopSpeaker: boolean
links: ILink[]
- questionAnswers: IQuestionAnswer[]
- categories: any[]
+ category: string
}
export interface ISession {
id: number
- name: string
+ title: string
+ description: string
+ startAt: string
+ endAt: string
+ speakers: string[]
+ categoryItems: number[]
}
export interface ILink {
@@ -31,11 +35,15 @@ export enum LinkType {
Instagram = "Instagram"
}
-export interface IQuestionAnswer {
+export interface ICategory {
id: number
- question: string
- questionType: string
- answer: any
- sort: number
- answerExtra: any
+ name: string
}
+
+export interface IConferenceData {
+ sessions: ISession[];
+ speakers: ISpeaker[];
+ categories: [{
+ items: ICategory[]
+ }]
+}
\ No newline at end of file
diff --git a/src/types/types.ts b/src/types/types.ts
index 36b7a0c..67e8846 100644
--- a/src/types/types.ts
+++ b/src/types/types.ts
@@ -26,4 +26,10 @@ export interface ISponsor {
image: string;
isPaid: boolean;
type?: 'gold' | 'silver' | 'bronze';
+}
+
+export enum AppStatus {
+ Loading,
+ Success,
+ Error
}
\ No newline at end of file