diff --git a/src/components/Faq/Faq.tsx b/src/components/Faq/Faq.tsx index 18b4a00..b3ffe43 100644 --- a/src/components/Faq/Faq.tsx +++ b/src/components/Faq/Faq.tsx @@ -1,5 +1,5 @@ -'use client'; -import React, {ReactNode, useState} from "react"; +"use client"; +import React, { ReactNode, useState } from "react"; import { FaBus, FaCompass, @@ -9,17 +9,17 @@ import { FaStar, FaTicketAlt, FaUser, - FaTshirt -} from "react-icons/fa" + FaTshirt, +} from "react-icons/fa"; import Typography from "@/components/Typography/Typography"; import { IoIosArrowDown } from "react-icons/io"; const Faq = ({ - display = 'list', - limit + display = "list", + limit, }: { - display: 'list' | 'grid', - limit?: number, + display: "list" | "grid"; + limit?: number; }) => { const [openIndex, setOpenIndex] = useState(null); @@ -30,53 +30,65 @@ const Faq = ({ }[] = [ { question: "Quelle est la date et le lieu de Meet Magento France 2025 ?", - icon: , - answer: "Meet Magento France 2025 se déroulera le 25 mars 2025, à L’Étoile Business Center à Paris.", + icon: , + answer: + "Meet Magento France 2025 se déroulera le 25 mars 2025, à L’Étoile Business Center à Paris.", }, { - question: "Quels types de conférences seront proposés lors de l'événement ?", - icon: , - answer: "Des conférences business et techniques animées par des experts du digital, e-ommerçants, éditeurs et agences sont attendues au programme de Meet Magento France 2025 ! Découvrez dès à présent l’agenda des conférences et la liste des intervenants.", + question: + "Quels types de conférences seront proposés lors de l'événement ?", + icon: , + answer: + "Des conférences business et techniques animées par des experts du digital, e-ommerçants, éditeurs et agences sont attendues au programme de Meet Magento France 2025 ! Découvrez dès à présent l’agenda des conférences et la liste des intervenants.", }, { question: "Qui peut participer à Meet Magento France 2025 ?", - icon: , - answer: "Meet Magento France 2025 accueillera les acteurs de l’écosystème Magento et Adobe Commerce. E-commerçants, éditeurs, agences digitales se rencontreront lors de cet événement communautaire et tous avec les mêmes objectifs : l’échange et le partage.", + icon: , + answer: + "Meet Magento France 2025 accueillera les acteurs de l’écosystème Magento et Adobe Commerce. E-commerçants, éditeurs, agences digitales se rencontreront lors de cet événement communautaire et tous avec les mêmes objectifs : l’échange et le partage.", }, { question: "Comment puis-je acheter des billets pour l'événement ?", - icon: , - answer: "Les billets pour Meet Magento France 2025 sont disponibles ! Rendez-vous sur la billeterie à partir du menu.", + icon: , + answer: + "Les billets pour Meet Magento France 2025 sont disponibles ! Rendez-vous sur la billeterie à partir du menu.", }, { - question: "Puis-je proposer un sujet de conférence pour Meet Magento France 2025 ?", - icon: , - answer: "L’appel à speakers pour Meet Magento France 2025 est maintenant terminé. Les candidatures ont été clôturées le 31 janvier 2025 !", + question: + "Puis-je proposer un sujet de conférence pour Meet Magento France 2025 ?", + icon: , + answer: + "L’appel à speakers pour Meet Magento France 2025 est maintenant terminé. Les candidatures ont été clôturées le 31 janvier 2025 !", }, { question: "Que contient un billet pour Meet Magento France 2025 ?", - icon: , - answer: "Lorsque vous achetez un billet pour Meet Magento France 2025 vous accédez à la totalité des conférences de l’événement, du petit-déjeuner d’accueil à cocktail dinatoire de clôture, en passant par le déjeuner networking.", + icon: , + answer: + "Lorsque vous achetez un billet pour Meet Magento France 2025 vous accédez à la totalité des conférences de l’événement, du petit-déjeuner d’accueil à cocktail dinatoire de clôture, en passant par le déjeuner networking.", }, { question: "What if I don't speak French?", - icon: , - answer: "You are still welcomed! Although the main track will be Business and in French, we will have a secondary track for English Speakers and Tech talks.", + icon: , + answer: + "You are still welcomed! Although the main track will be Business and in French, we will have a secondary track for English Speakers and Tech talks.", }, { - question: "Quels sont les transports à proximité de l'Étoile Business Center ?", - icon: , - answer: "L'Étoile Business Center est idéalement situé à deux pas de l'Arc de Triomphe. Accès direct par les lignes de métro 1, 2 et 6 (station Charles de Gaulle - Étoile) et le RER A. De nombreuses lignes de bus desservent également le quartier.", + question: + "Quels sont les transports à proximité de l'Étoile Business Center ?", + icon: , + answer: + "L'Étoile Business Center est idéalement situé à deux pas de l'Arc de Triomphe. Accès direct par les lignes de métro 1, 2 et 6 (station Charles de Gaulle - Étoile) et le RER A. De nombreuses lignes de bus desservent également le quartier.", }, { question: "Est-ce qu’il y aura un vestiaire sur place ?", - icon: , - answer: "Oui, un vestiaire gratuit sera à votre disposition pendant toute la durée de l'événement." + icon: , + answer: + "Oui, un vestiaire gratuit sera à votre disposition pendant toute la durée de l'événement.", }, ]; const renderFaqItem = ( - faq: { question: string, icon: ReactNode, answer: string }, + faq: { question: string; icon: ReactNode; answer: string }, index: number ) => (
+ }`} + />
{openIndex === index && (
@@ -107,18 +120,29 @@ const Faq = ({ limit = !limit || limit > faqList.length ? faqList.length : limit; const faqWrap = []; - if (display === 'grid') { - faqWrap.push(faqList.slice(0, Math.ceil((limit) / 2))); - faqWrap.push(faqList.slice(Math.ceil((limit) / 2), limit)); + if (display === "grid") { + faqWrap.push(faqList.slice(0, Math.ceil(limit / 2))); + faqWrap.push(faqList.slice(Math.ceil(limit / 2), limit)); } else { faqWrap.push(faqList.slice(0, limit)); } let faqId = 0; return ( -
+
{faqWrap.map((faqItems, wrapIndex) => ( -
+
{faqItems.map((faq) => (
{renderFaqItem(faq, faqId++)} @@ -128,6 +152,6 @@ const Faq = ({ ))}
); -} +}; export default Faq; diff --git a/src/components/Program/ProgramList.tsx b/src/components/Program/ProgramList.tsx index 2f5921f..3243628 100644 --- a/src/components/Program/ProgramList.tsx +++ b/src/components/Program/ProgramList.tsx @@ -8,10 +8,14 @@ import "swiper/css/navigation"; import useDataProvider from "@/hooks/useDataProvider"; import ClientOnly from "@/helpers/ClientOnly"; import ProgramTile from "./ProgramTile"; +import SessionPopIn from "../Speakers/Session/SessionPopIn"; +import { SessionProps } from "../Speakers/Session/SessionProps"; const ProgramList = () => { const swiperRef = React.useRef(null); const sessions = useDataProvider().useSessions(); + const [selectedSession, setSelectedSession] = + React.useState(null); const handlePrev = () => { if (swiperRef.current) { @@ -69,11 +73,21 @@ const ProgramList = () => { > {sessions.map((session) => ( - + setSelectedSession(session)} + /> ))} + {selectedSession && ( + setSelectedSession(null)} + /> + )} ); }; diff --git a/src/components/Program/ProgramTile.tsx b/src/components/Program/ProgramTile.tsx index 3dbb044..403d3fb 100644 --- a/src/components/Program/ProgramTile.tsx +++ b/src/components/Program/ProgramTile.tsx @@ -6,7 +6,13 @@ import Session from "@/components/Speakers/Session/Session"; import Person from "@/components/Person/Person"; import ButtonLink from "@/components/ButtonLink/ButtonLink"; -const ProgramTile = ({ session }: { session: SessionProps }) => { +const ProgramTile = ({ + session, + onPopInClick, +}: { + session: SessionProps; + onPopInClick: () => void; +}) => { const dataProvider = useDataProvider(); const speakers = dataProvider .usePersonList("speakers", "data.speakers") @@ -15,7 +21,7 @@ const ProgramTile = ({ session }: { session: SessionProps }) => { return (
- +
{speakers.map((speaker) => ( diff --git a/src/components/Speakers/Session/Session.tsx b/src/components/Speakers/Session/Session.tsx index 3b20fb1..a99bd4d 100644 --- a/src/components/Speakers/Session/Session.tsx +++ b/src/components/Speakers/Session/Session.tsx @@ -7,15 +7,15 @@ import Image from "next/image"; import { PiCalendarPlus } from "react-icons/pi"; import ButtonLink from "@/components/ButtonLink/ButtonLink"; import { useTranslation } from "react-i18next"; +import { BsFillInfoCircleFill } from "react-icons/bs"; interface Session { session: SessionProps; - showAddToCalendar?: boolean; + onPopInClick?: () => void; } -const Session = ({ session, showAddToCalendar = true }: Session) => { +const Session = ({ session, onPopInClick }: Session) => { const { t } = useTranslation(["speakers"]); - return (
@@ -36,6 +36,12 @@ const Session = ({ session, showAddToCalendar = true }: Session) => { {session.start} {session.end} + {onPopInClick && ( + + )}
@@ -52,7 +58,7 @@ const Session = ({ session, showAddToCalendar = true }: Session) => { ))}
- {showAddToCalendar && !!session.eventUrl && ( + {!!session.eventUrl && (
void; +}) => { + return ( + + + + ); +}; + +export default SessionPopIn; diff --git a/src/components/Speakers/Session/SessionPopInContent.tsx b/src/components/Speakers/Session/SessionPopInContent.tsx new file mode 100644 index 0000000..22ed2fd --- /dev/null +++ b/src/components/Speakers/Session/SessionPopInContent.tsx @@ -0,0 +1,37 @@ +import React from "react"; +import { SessionProps } from "./SessionProps"; +import Session from "./Session"; +import Person from "@/components/Person/Person"; +import useDataProvider from "@/hooks/useDataProvider"; +import Typography from "@/components/Typography/Typography"; +import { PiCalendarPlus } from "react-icons/pi"; + +const SessionPopInContent = ({ session }: { session: SessionProps }) => { + const dataProvider = useDataProvider(); + const speakers = dataProvider + .usePersonList("speakers", "data.speakers") + .filter((speaker) => session.speakers.includes(speaker.id)); + return ( +
+ +
+
+ {speakers.map((speaker) => ( + + ))} +
+ {session.description} +
+
+
+ + + Ajouter cette conférence à mon agenda + +
+
+
+ ); +}; + +export default SessionPopInContent; diff --git a/tailwind.config.ts b/tailwind.config.ts index 0d3d093..46aa5f8 100644 --- a/tailwind.config.ts +++ b/tailwind.config.ts @@ -7,7 +7,7 @@ export default { "./src/layouts/**/*.{js,ts,jsx,tsx,mdx}", "./src/app/**/*.{js,ts,jsx,tsx,mdx}", ], - darkMode: 'class', + darkMode: "class", theme: { extend: { fontFamily: { @@ -18,7 +18,7 @@ export default { background: "var(--background)", foreground: "var(--foreground)", royalBlue: "#19009E", - royalPink: "#FF7DD1", + pink: "#FF7DD1", orange: "#EE6524", camel: "rgba(255, 212, 181, 0.15)", purple: {