diff --git a/pwa/app/(common)/events/components/EventsPage.tsx b/pwa/app/(common)/events/components/EventsPage.tsx index 6999f0b10..a6eb04d2f 100644 --- a/pwa/app/(common)/events/components/EventsPage.tsx +++ b/pwa/app/(common)/events/components/EventsPage.tsx @@ -36,13 +36,13 @@ export default function EventsPage({ events }: EventsPageProps) { city: "Lille", }, startDate: { - date: "2024-09-19", + date: "2025-09-18", }, endDate: { - date: "2024-09-20", + date: "2025-09-19", }, picture: `/images/con/og-2021.png`, - title: "API Platform Conference 2024", + title: "API Platform Conference 2025", slug: "api-con", }; diff --git a/pwa/app/(con)/[locale]/con/2023/review/components/Review/en.tsx b/pwa/app/(con)/[locale]/con/2023/review/components/Review/en.tsx index 1c66be78e..2178bddb3 100644 --- a/pwa/app/(con)/[locale]/con/2023/review/components/Review/en.tsx +++ b/pwa/app/(con)/[locale]/con/2023/review/components/Review/en.tsx @@ -16,7 +16,7 @@ export default function ReviewList() { 2 @@ -53,7 +53,7 @@ export default function ReviewList() { 25 @@ -94,7 +94,7 @@ export default function ReviewList() { 14 diff --git a/pwa/app/(con)/[locale]/con/2023/review/components/Review/fr.tsx b/pwa/app/(con)/[locale]/con/2023/review/components/Review/fr.tsx index e20c4b294..e75c64a66 100644 --- a/pwa/app/(con)/[locale]/con/2023/review/components/Review/fr.tsx +++ b/pwa/app/(con)/[locale]/con/2023/review/components/Review/fr.tsx @@ -16,7 +16,7 @@ export default function ReviewList() { 2 @@ -55,7 +55,7 @@ export default function ReviewList() { 25 @@ -102,7 +102,7 @@ export default function ReviewList() { 14 diff --git a/pwa/app/(con)/[locale]/con/2024/components/AfterMovie.tsx b/pwa/app/(con)/[locale]/con/2024/components/AfterMovie.tsx new file mode 100644 index 000000000..042f56de5 --- /dev/null +++ b/pwa/app/(con)/[locale]/con/2024/components/AfterMovie.tsx @@ -0,0 +1,29 @@ +"use client"; +import SectionTitle from "components/con/common/typography/SectionTitle"; +import Section from "components/con/home/Section"; +import { useContext } from "react"; +import { LanguageContext } from "contexts/con/LanguageContext"; +import SectionSubTitle from "components/con/common/typography/SectionSubtitle"; + +export default function AfterMovie() { + const { t, Translate } = useContext(LanguageContext); + return ( +
+
+ + + + {t("2024.aftermovie.subtitle")} + +
+
+ ); +} diff --git a/pwa/app/(con)/[locale]/con/2024/components/HomePage.tsx b/pwa/app/(con)/[locale]/con/2024/components/HomePage.tsx index b49254a72..c41f50fc6 100644 --- a/pwa/app/(con)/[locale]/con/2024/components/HomePage.tsx +++ b/pwa/app/(con)/[locale]/con/2024/components/HomePage.tsx @@ -246,6 +246,9 @@ const HomePage = ({ speakers, partners, images }: HomePageProps) => { {t("last_places")} )} + @@ -284,7 +287,7 @@ const HomePage = ({ speakers, partners, images }: HomePageProps) => { ) : null} - { + {currentEdition === "2024" && (
{
- } + )}
diff --git a/pwa/app/(con)/[locale]/con/2024/review/components/Review/ReviewCover.tsx b/pwa/app/(con)/[locale]/con/2024/review/components/Review/ReviewCover.tsx new file mode 100644 index 000000000..bc5aeaaf9 --- /dev/null +++ b/pwa/app/(con)/[locale]/con/2024/review/components/Review/ReviewCover.tsx @@ -0,0 +1,35 @@ +"use client"; +import ReviewCoverBase from "components/con/review/ReviewCover"; +import { useContext } from "react"; +import { LanguageContext } from "contexts/con/LanguageContext"; + +export default function ReviewCover() { + const { t, Translate } = useContext(LanguageContext); + return ( + +

{t("2024.review.subtitle_1")}

+ + {t("2024.review.link")} + + ), + }} + /> + + } + /> + ); +} diff --git a/pwa/app/(con)/[locale]/con/2024/review/components/Review/en.tsx b/pwa/app/(con)/[locale]/con/2024/review/components/Review/en.tsx new file mode 100644 index 000000000..86e3565b7 --- /dev/null +++ b/pwa/app/(con)/[locale]/con/2024/review/components/Review/en.tsx @@ -0,0 +1,378 @@ +/* eslint-disable react/no-unescaped-entities */ +"use client"; +import React from "react"; +import Button from "components/con/common/Button"; +import useDynamicRefs from "hooks/con/useDynamicRefs"; +import ReviewItem from "components/con/review/ReviewItem"; +import LinedTitle from "components/con/common/typography/LinedTitle"; + +export default function ReviewList() { + const [, setRef] = useDynamicRefs(); + const reviewRef = setRef("review-list"); + + return ( +
+
+ + 1 + major announcement + + } + > + + Game-Changing Announcement for the PHP Ecosystem! + +

+ The API Platform Conference kicked off with a major announcement: + Laravel support is now available with API Platform 4. +

+

+ On the agenda: quick exposure of a REST or GraphQL API from Eloquent + models, addition of advanced API features (pagination, filters, + authentication, data validation), compatibility with Octane and + + FrankenPHP + {" "} + for optimal performance, and automatic generation of OpenAPI + documentation. +

+

+ API Platform offers, more than ever, an elegant and optimized + experience tailored to all development needs. +

+ +
+ + 25 + High-Level Talks + + } + > + + Exclusive content sharing, tailored to all levels. + +

+ International figures from the PHP, JavaScript, and Cloud ecosystems + were present in Lille on September 19 and 20. +

+

+ Talks on AI, best practices, performance, and experience sharing... + The latest innovations, trends, and best development practices were + at the heart of this event. +

+ +
+ + 25 + partners + + } + > + + A strong support that greatly contributed to the conference's + success + +

+ Thank you to our Gold sponsors:{" "} + + Sensiolabs + + ,{" "} + + React-admin + + ,{" "} + + France Télévisions + + ,{" "} + + Sylius + {" "} + and{" "} + + la CGT. + + . +

+

+ Thanks also to our Silver sponsors:{" "} + + EMAGMA + + ,{" "} + + Akawaka + + ,{" "} + + Clever Cloud + + ,{" "} + + WeLoveDevs.com + + ,{" "} + + Codéin + + ,{" "} + + Sweeek + {" "} + and{" "} + + Fairness + + . +

+

+ Thank you to our Bronze sponsors:{" "} + + Darkwood + + ,{" "} + + Orbitale.io + {" "} + et{" "} + + Lior Chamla + + . +

+

+ A special thanks to our sponsors{" "} + + baksla.sh + {" "} + for the lanyards and{" "} + + JL Recrutement + {" "} + for the community evening. +

+

+ Finally, thanks to our community and media partners:{" "} + + Laravel France + + ,{" "} + + Motiv'Her + + ,{" "} + + Archimag + + ,{" "} + + Programmez! + + ,{" "} + + Symfony + + ,{" "} + + Euratechnologies + {" "} + ,{" "} + + BitExpert + {" "} + and{" "} + + Hôtels de Lille + + . +

+ +
+ + 1 + community party + + } + > + Celebrating the tech reunion +

+ This year again, the community evening was sponsored by{" "} + + JL Recrutement + + . +

+

+ To top it off, the beautiful weather was on our side, allowing us to + enjoy most of the evening on the terrace, under the setting sun. +

+
+
+
+ ); +} diff --git a/pwa/app/(con)/[locale]/con/2024/review/components/Review/fr.tsx b/pwa/app/(con)/[locale]/con/2024/review/components/Review/fr.tsx new file mode 100644 index 000000000..476e82da4 --- /dev/null +++ b/pwa/app/(con)/[locale]/con/2024/review/components/Review/fr.tsx @@ -0,0 +1,383 @@ +/* eslint-disable react/no-unescaped-entities */ +"use client"; +import React from "react"; +import Button from "components/con/common/Button"; +import useDynamicRefs from "hooks/con/useDynamicRefs"; +import ReviewItem from "components/con/review/ReviewItem"; +import LinedTitle from "components/con/common/typography/LinedTitle"; + +export default function ReviewList() { + const [, setRef] = useDynamicRefs(); + const reviewRef = setRef("review-list"); + + return ( +
+
+ + 1 + annonce majeure + + } + > + + Séisme dans l'écosystème PHP ! + +

+ L’API Platform Conference a démarré avec une annonce de taille : le + support de Laravel est désormais disponible avec API Platform 4. +

+

+ Au programme : exposition rapide d'une API REST ou GraphQL à partir + des modèles Eloquent, ajout de fonctionnalités natives et avancées + (pagination, filtres, authentification, validation des données), + compatibilité avec Octane et{" "} + + FrankenPHP + {" "} + pour des performances optimales, ainsi que génération automatique de + documentation OpenAPI. +

+

+ API Platform offre, plus que jamais, une expérience de développement + simple, élégante et adaptée à tous les besoins. +

+ +
+ + 25 + conférences + + } + > + + Un partage de contenu inédit, adapté à chaque niveau. + +

+ Des figures internationales des écosystèmes PHP, JavaScript et Cloud + étaient présentes à Lille les 19 et 20 septembre derniers. +

+

+ Conférences sur l’IA, bonnes pratiques, performances et retours + d’expérience… Les dernières innovations, les tendances et meilleures + pratiques de développement étaient au cœur de cet événement. +

+ +
+ + 25 + partenaires + + } + > + + Un soutien de taille qui contribue grandement au succès de la + conférence + +

+ Merci à nos sponsors Gold :{" "} + + Sensiolabs + + ,{" "} + + React-admin + + ,{" "} + + France Télévisions + + ,{" "} + + Sylius + {" "} + et{" "} + + la CGT. + + . +

+

+ Merci également à nos sponsors Silver :{" "} + + EMAGMA + + ,{" "} + + Akawaka + + ,{" "} + + Clever Cloud + + ,{" "} + + WeLoveDevs.com + + ,{" "} + + Codéin + + ,{" "} + + Sweeek + {" "} + et{" "} + + Fairness + + . +

+

+ Merci à nos sponsors Bronze :{" "} + + Darkwood + + ,{" "} + + Orbitale.io + {" "} + et{" "} + + Lior Chamla + + . +

+

+ Merci aussi à nos sponsors{" "} + + baksla.sh + {" "} + pour les tours de cou et{" "} + + JL Recrutement + {" "} + pour la soirée communautaire. +

+

+ Enfin, saluons nos partenaires communautaires et média{" "} + + Laravel France + + ,{" "} + + Motiv'Her + + ,{" "} + + Archimag + + ,{" "} + + Programmez! + + ,{" "} + + Symfony + + ,{" "} + + Euratechnologies + {" "} + ,{" "} + + BitExpert + {" "} + et{" "} + + Hôtels de Lille + + . +

+ +
+ + 1 + apéro ensoleillé + + } + > + + Arroser les retrouvailles de la communauté + +

+ Cette année encore, la soirée communautaire était sponsorisée par le + cabinet{" "} + + JL Recrutement + + . +

+

+ Cerise sur le gâteau, le beau temps était au rendez-vous, nous + permettant de profiter de la majeure partie de la soirée en + terrasse, sous le soleil couchant. +

+
+
+
+ ); +} diff --git a/pwa/app/(con)/[locale]/con/2024/review/page.tsx b/pwa/app/(con)/[locale]/con/2024/review/page.tsx new file mode 100644 index 000000000..465424a6e --- /dev/null +++ b/pwa/app/(con)/[locale]/con/2024/review/page.tsx @@ -0,0 +1,73 @@ +import { getAllEditionPictures } from "api/con/editions"; +import Cover from "./components/Review/ReviewCover"; +import ReviewListFr from "./components/Review/fr"; +import ReviewListEn from "./components/Review/en"; +import Image from "next/image"; +import PictureGallery from "components/con/common/PictureGallery"; +import { Locale, i18n } from "i18n/i18n-config"; +import { Metadata } from "next"; +import AfterMovie from "../components/AfterMovie"; + +type Props = { + params: { locale: Locale }; +}; +export async function generateMetadata({ params }: Props): Promise { + const locale = params.locale || i18n.defaultLocale; + const dictionary = await import(`i18n/meta/${locale}.json`); + + return { + title: dictionary.review.title, + description: dictionary.review.description.replace("%edition%", "2024"), + openGraph: { + title: `${dictionary.review.title} - API Platform Conference 2024`, + description: dictionary.review.description.replace("%edition%", "2024"), + }, + twitter: { + title: `${dictionary.review.title} - API Platform Conference 2024`, + description: dictionary.review.description.replace("%edition%", "2024"), + }, + alternates: { + languages: { + en: locale === "en" ? undefined : "/con/2024/review", + fr: locale === "fr" ? undefined : "/fr/con/2024/review", + }, + }, + }; +} + +export default async function Page({ params }: { params: { locale: Locale } }) { + const images = await getAllEditionPictures("2024"); + return ( + <> + + { + params.locale === "fr" ? ( + + ) : null /*FIXME: find an other way to translate this page*/ + } + { + params.locale === "en" ? ( + + ) : null /*FIXME: find an other way to translate this page*/ + } +
+ +
+ + {images.map((image: string) => ( + + ))} + + + ); +} diff --git a/pwa/app/(con)/[locale]/con/2025/components/HomePage.tsx b/pwa/app/(con)/[locale]/con/2025/components/HomePage.tsx new file mode 100644 index 000000000..918648d28 --- /dev/null +++ b/pwa/app/(con)/[locale]/con/2025/components/HomePage.tsx @@ -0,0 +1,176 @@ +"use client"; +import Button from "components/con/common/Button"; +import SpeakerList from "components/con/speakers/SpeakerList"; +import SectionTitle from "components/con/common/typography/SectionTitle"; +import SectionSubTitle from "components/con/common/typography/SectionSubtitle"; +import Web from "components/con/common/Web"; +import Wave from "components/con/common/Wave"; +import Venue from "components/con/home/Venue"; +import Image from "next/image"; +import Partners from "components/con/home/Partners"; +import LookingSponsorCard from "components/con/home/LookingSponsorCard"; +import { Partner, Speaker } from "types/con"; +import { useContext } from "react"; +import { LanguageContext } from "contexts/con/LanguageContext"; +import Section, { SectionsContext } from "components/con/home/Section"; +import PictureGallery from "components/con/common/PictureGallery"; +import Logo from "./Logo"; +import AfterMovie from "app/con/2024/components/AfterMovie"; + +type HomePageProps = { + speakers: Speaker[]; + partners: Partner[]; + images: string[]; +}; + +const HomePage = ({ speakers, partners, images }: HomePageProps) => { + const { t, Translate, locale } = useContext(LanguageContext); + const { isVisible } = useContext(SectionsContext); + return ( + <> +
+
+
+ +
+
+ + {t("2024.baseline")} + +
+ +
+
+ +
+ +
+
+
+ + + + + + {t("last_edition.subtitle_link")} + + ), + }} + /> + + + {images.map((image: string) => ( + + ))} + +
+
+
+ +
+
+
+ + + + {t("missing_conferences.subtitle")} + +
+
+
+
+ + + + + + {t("2025.our_speakers.subtitle_link")} + + ), + }} + /> + + + {speakers.length > 6 ? ( + + ) : null} +
+
+ +
+
+ + + + +
+
+
+
+ {t("sponsorship.they_trust_us", { year: "2024" })} +
+ +
+
+
+ + ); +}; + +export const revalidate = 43200; + +export default HomePage; diff --git a/pwa/app/(con)/[locale]/con/2025/components/Logo.tsx b/pwa/app/(con)/[locale]/con/2025/components/Logo.tsx new file mode 100644 index 000000000..de6c05463 --- /dev/null +++ b/pwa/app/(con)/[locale]/con/2025/components/Logo.tsx @@ -0,0 +1,560 @@ +export default function Logo() { + return ( +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SE + + + P + + + {" "} + 18 + + + - + + + 19, 2025 | LILLE + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ ); +} diff --git a/pwa/app/(con)/[locale]/con/2025/layout.tsx b/pwa/app/(con)/[locale]/con/2025/layout.tsx new file mode 100644 index 000000000..ea3574699 --- /dev/null +++ b/pwa/app/(con)/[locale]/con/2025/layout.tsx @@ -0,0 +1,60 @@ +import React from "react"; +import LayoutBase from "components/con/layout/LayoutBase"; +import ContactCard from "components/con/layout/ContactCard"; +import nav from "data/con/2025/nav"; +import footer from "data/con/2025/footer"; +import { Metadata } from "next"; +import { getEditionEventData } from "utils/con"; +import { i18n } from "i18n/i18n-config"; +import { getRootUrl } from "utils"; + +type Props = { + params: { edition: string; locale: string }; +}; + +export async function generateMetadata({ params }: Props): Promise { + // read route params + const locale = params.locale || i18n.defaultLocale; + + const dictionary = await import(`i18n/meta/${locale}.json`); + + const URL = `${getRootUrl()}/con/2025`; + + return { + title: { + default: dictionary[2025].title, + template: `%s - API Platform Conference 2025`, + }, + description: dictionary[2025].description, + openGraph: { + url: URL, + title: dictionary[2025].title, + description: dictionary[2025].description, + }, + twitter: { + title: dictionary[2025].title, + description: dictionary[2025].description, + }, + }; +} + +function EditionLayout({ children }: { children: React.ReactNode }) { + const eventData = getEditionEventData("2025"); + return ( + +