Skip to content

Commit 24ecf8d

Browse files
committed
feat: add cfp page for 2026
1 parent a30edbb commit 24ecf8d

File tree

26 files changed

+412
-0
lines changed

26 files changed

+412
-0
lines changed
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
"use client";
2+
import { useContext } from "react";
3+
import { LanguageContext } from "contexts/con/LanguageContext";
4+
import SectionTitle from "components/con/common/typography/SectionTitle";
5+
import Button from "components/con/common/Button";
6+
import SectionSubTitle from "components/con/common/typography/SectionSubtitle";
7+
8+
const Arrow = () => (
9+
<svg
10+
xmlns="http://www.w3.org/2000/svg"
11+
fill="none"
12+
viewBox="0 0 24 24"
13+
strokeWidth={1.5}
14+
className="stroke-blue size-8"
15+
>
16+
<path
17+
strokeLinecap="round"
18+
strokeLinejoin="round"
19+
d="m12.75 15 3-3m0 0-3-3m3 3h-7.5M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z"
20+
/>
21+
</svg>
22+
);
23+
24+
export default function Informations() {
25+
const { t } = useContext(LanguageContext);
26+
return (
27+
<div className="after:h-1/3 after:absolute after:w-full after:bg-grey after:bottom-0 after:left-0 relative">
28+
<div className="container flex flex-col items-center py-12 relative z-10">
29+
<SectionTitle h1 dark lined>
30+
<strong>{t("2026.cfp.title")}</strong>
31+
</SectionTitle>
32+
<SectionSubTitle dark>{t("2026.cfp.subtitle")}</SectionSubTitle>
33+
<div className="bg-white border-t-8 border-t-blue shadow-xl text-center p-8 dotted-corner corner-bottom mx-auto w-full max-w-4xl flex flex-col gap-8 items-center">
34+
<span className="font-bold text-blue leading-tight font-title text-xl uppercase lined-center lined-blue relative">
35+
{t("2026.cfp.informations")}
36+
</span>
37+
<ul className="flex flex-col gap-8 text-left text-lg">
38+
{[1, 2, 3, 4, 5, 6].map((index) => (
39+
<li key={index} className="flex flex-row gap-2">
40+
<Arrow />
41+
<p className="flex-1">{t(`2026.cfp.point_${index}`)}</p>
42+
</li>
43+
))}
44+
</ul>
45+
<Button
46+
size="large"
47+
external
48+
to="https://conference-hall.io/api-platform-conference-2026-lille-and-online"
49+
>
50+
{t("2026.cfp.button_subscribe")}
51+
</Button>
52+
</div>
53+
</div>
54+
</div>
55+
);
56+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
"use client";
2+
import { useContext } from "react";
3+
import { LanguageContext } from "contexts/con/LanguageContext";
4+
import SectionTitle from "components/con/common/typography/SectionTitle";
5+
6+
export default function Package() {
7+
const { t } = useContext(LanguageContext);
8+
return (
9+
<div className="container max-w-6xl text-center">
10+
<SectionTitle small dark lined>
11+
<strong>{t("2026.cfp.package.title")}</strong>
12+
</SectionTitle>
13+
<div className="flex flex-col lg:flex-row items-center lg:items-start gap-12 lg:gap-0 text-left">
14+
<div className="translate-y-12 relative z-10 w-4/5 lg:w-1/2 max-w-md before:absolute before:w-full before:h-full before:bg-blue before:-translate-x-3 before:-translate-y-3 before:left-0 before:top-0">
15+
<img
16+
src="/images/con/2026/cfp/speaker-gift.jpg"
17+
className="relative w-full"
18+
alt=""
19+
/>
20+
</div>
21+
<div className="bg-white max-w-xl p-8 flex-1 pt-20 lg:pt-8 lg:pl-20 -translate-y-12 lg:-translate-y-0 lg:-translate-x-12">
22+
<div className="font-bold text-blue leading-tight font-title text-xl uppercase lined-left lined-blue relative">
23+
{t("2026.cfp.package.subtitle")}
24+
</div>
25+
<ul className="mb-30 text-left flex flex-col gap-3 mt-8">
26+
{[1, 2, 3, 4, 5, 6].map((index) => (
27+
<li key={index} className="flex items-baseline">
28+
<span className="text-blue icon-circle-chevron-right mr-2" />
29+
{t(`2026.cfp.package.point_${index}`)}
30+
</li>
31+
))}
32+
</ul>
33+
</div>
34+
</div>
35+
</div>
36+
);
37+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
"use client";
2+
import { useContext } from "react";
3+
import { LanguageContext } from "contexts/con/LanguageContext";
4+
import SectionTitle from "components/con/common/typography/SectionTitle";
5+
import Button from "components/con/common/Button";
6+
import SectionSubTitle from "components/con/common/typography/SectionSubtitle";
7+
8+
export default function Informations() {
9+
const { t, getLocaleDictionary } = useContext(LanguageContext);
10+
const categories = getLocaleDictionary?.()[2026].cfp.subject.categories || [];
11+
return (
12+
<div className="bg-grey pb-12 relative z-20">
13+
<div className="container flex flex-col items-center">
14+
<SectionTitle small lined>
15+
<strong>{t("2026.cfp.subject.title")}</strong>
16+
</SectionTitle>
17+
<SectionSubTitle>{t("2026.cfp.subject.subtitle")}</SectionSubTitle>
18+
<div className="flex flex-wrap justify-center gap-8 md:gap-3">
19+
{categories.map((c) => {
20+
return (
21+
<div
22+
key={c.icon}
23+
className="flex flex-col md:flex-row text-center md:text-left md:odd:translate-x-4 md:even:-translate-x-4 md:odd:rotate-2 md:even:-rotate-1 md:even:flex-row-reverse gap-4 md:gap-12 items-center bg-white w-full max-w-3xl p-8 shadow-floating"
24+
>
25+
<div className="rounded-full bg-white size-28 md:size-40 relative flex items-center justify-center">
26+
<img
27+
src={`/images/con/2026/cfp/${c.icon}.png`}
28+
className="rounded-full"
29+
alt=""
30+
/>
31+
<div className="size-[110%] absolute max-w-none bg-circle bg-no-repeat left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2" />
32+
</div>
33+
<div className="flex-1">
34+
<p className="font-title text-lg text-blue font-extrabold mb-4 uppercase">
35+
{c.title}
36+
</p>
37+
<div className="text-left flex flex-col gap-2">
38+
{c.points.map((p, i) => (
39+
<div key={i} className="flex flex-row items-baseline">
40+
<span className="text-blue icon-circle-chevron-right mr-2" />
41+
<p
42+
dangerouslySetInnerHTML={{
43+
__html: p,
44+
}}
45+
/>
46+
</div>
47+
))}
48+
</div>
49+
</div>
50+
</div>
51+
);
52+
})}
53+
</div>
54+
<Button
55+
className="mt-12"
56+
size="large"
57+
external
58+
to="https://conference-hall.io/api-platform-conference-2026-lille-and-online"
59+
>
60+
{t("2026.cfp.subject.button_subscribe")}
61+
</Button>
62+
</div>
63+
</div>
64+
);
65+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
"use client";
2+
import { useContext } from "react";
3+
import { LanguageContext } from "contexts/con/LanguageContext";
4+
import SectionTitle from "components/con/common/typography/SectionTitle";
5+
import { Logos } from "./logos";
6+
7+
export default function Technos() {
8+
const { t } = useContext(LanguageContext);
9+
return (
10+
<div className="container pt-12 flex flex-col items-center pb-44">
11+
<SectionTitle small dark lined>
12+
<strong>{t("2026.cfp.techno.title")}</strong>
13+
</SectionTitle>
14+
<div className="relative w-full h-16 my-4">
15+
<div className="absolute max-w-none w-max left-0 top-0 flex gap-4 flex-row h-20 animate-defile">
16+
<Logos />
17+
<Logos />
18+
<Logos />
19+
</div>
20+
</div>
21+
</div>
22+
);
23+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
export function Logos() {
2+
return (
3+
<>
4+
<img src="/images/con/2025/cfp/api-platform.png" alt="" />
5+
<img src="/images/con/2025/cfp/caddy.png" alt="" />
6+
<img src="/images/con/2025/cfp/elastic.png" alt="" />
7+
<img src="/images/con/2025/cfp/frankenphp.png" alt="" />
8+
<img src="/images/con/2025/cfp/JS.png" alt="" />
9+
<img src="/images/con/2025/cfp/laravel.png" alt="" />
10+
<img src="/images/con/2025/cfp/php.png" alt="" />
11+
<img src="/images/con/2025/cfp/rabbitmq.png" alt="" />
12+
<img src="/images/con/2025/cfp/react-admin.png" alt="" />
13+
<img src="/images/con/2025/cfp/xdebug.png" alt="" />
14+
</>
15+
);
16+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import { Locale, i18n } from "i18n/i18n-config";
2+
import { Metadata } from "next";
3+
import Package from "./components/Package";
4+
import Informations from "./components/Informations";
5+
import Subject from "./components/Subject";
6+
import Technos from "./components/Techno";
7+
8+
type Props = {
9+
params: { locale: Locale };
10+
};
11+
export async function generateMetadata({ params }: Props): Promise<Metadata> {
12+
const locale = params.locale || i18n.defaultLocale;
13+
const dictionary = await import(`i18n/meta/${locale}.json`);
14+
15+
return {
16+
title: {
17+
absolute: dictionary["call-for-papers"].title,
18+
template: `%s - API Platform Conference 2026`,
19+
},
20+
description: dictionary["call-for-papers"].description,
21+
openGraph: {
22+
title: `${dictionary["call-for-papers"].title} - API Platform Conference`,
23+
description: dictionary["call-for-papers"].description,
24+
},
25+
twitter: {
26+
title: `${dictionary["call-for-papers"].title} - API Platform Conference`,
27+
description: dictionary["call-for-papers"].description,
28+
},
29+
alternates: {
30+
languages: {
31+
en: locale === "en" ? undefined : "/con/2026/call-for-papers",
32+
fr: locale === "fr" ? undefined : "/fr/con/2026/call-for-papers",
33+
},
34+
},
35+
};
36+
}
37+
38+
export default async function Page({ params }: { params: { locale: Locale } }) {
39+
return (
40+
<div>
41+
<Informations />
42+
<Subject />
43+
<Package />
44+
<Technos />
45+
</div>
46+
);
47+
}

pwa/i18n/dictionaries/en.json

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,90 @@
268268
"tip_title": "Important",
269269
"tip": "Hotel demand is very high in Lille at this time of year, so to make your travel easier, we have negotiated special prices. Take a look at the available rooms on {{tip_link}}, get a 10% discount on your stay, and book them as soon as possible with this code: <strong>TILLEULS25</strong><br/><br/>This code is valid for the following hotels: Arbre Voyageur BW Premier Collection 4*, Best Western Why Premier 4*, Boa BW Signature Collection 4*, La Valiz 3*, Kanai 3*, and Le Rosa 3* for stays between 17th and 21st September.<br/><br/>This discount is available until 7th September 2025.",
270270
"tip_link": "this website"
271+
},
272+
"cfp": {
273+
"title": "Call for papers",
274+
"subtitle": "The call for papers for API Platform Conference 2026 is open until March 22. Final speakers will be announced starting May 12. Submit your pitch, and with a bit of luck, you could join us in September!",
275+
"package": {
276+
"title": "Speaker package",
277+
"subtitle": "Speaker package includes:",
278+
"point_1": "Travel to Lille covered (A maximum amount may apply depending on your country of residence)",
279+
"point_2": "Speakers' dinner on Wednesday, September 16",
280+
"point_3": "Entrance to the conference and to the community party on Thursday 17th",
281+
"point_4": "Two hotel nights for speakers based in France, or three nights for speakers coming from outside France",
282+
"point_5": "If your employer can cover your travel and hotel, we’re happy to list them as a sponsor. Employer sponsorship allows us to invite more international speakers to the conference.",
283+
"point_6": "A gift box with some customized surprises."
284+
},
285+
"techno": {
286+
"title": "Talk us about your favorite techno!"
287+
},
288+
"subject": {
289+
"title": "Talk categories",
290+
"subtitle": "We are looking forward to talks on (but not limited to) these topics:",
291+
"button_subscribe": "Submit your pitch",
292+
"categories": [
293+
{
294+
"icon": "api-platform-ecosystem",
295+
"title": "API Platform and its ecosystem",
296+
"points": [
297+
"You have discovered new features, a use case, a migration story or a contribution to share with the API Platform framework.",
298+
"You have built applications for real-world enterprise scenarios and your talk will showcase your development’s journey – from initial adoption to implementation.",
299+
"You have used API Platform as a key tool in your API design."
300+
]
301+
},
302+
{
303+
"icon": "going-further-api-p",
304+
"title": "Going further with API Platform",
305+
"points": [
306+
"<strong>JavaScript</strong> - API Platform is not only about PHP: in addition to its powerful admin generator, API Platform also features a client generator capable of scaffolding fully functional applications with Next.js, Nuxt.js, React/Redux, Vue.js, Quasar, and Vuetify for both PWAs and SPAs. Share your insights, contributions, and discoveries about it!",
307+
"<strong>Devops</strong> - you host or you have deployed a project with API Platform: tell us about it!",
308+
"Share your experiments on using <strong>AI</strong> on your web project."
309+
]
310+
},
311+
{
312+
"icon": "franken-php",
313+
"title": "High-Performance PHP with FrankenPHP",
314+
"points": [
315+
"You’ve optimized your application’s performance or migrated it with FrankenPHP.",
316+
"You’ve deployed FrankenPHP natively or using a cloud hosting solution. Share your feedback with us!",
317+
"You are leveraging FrankenPHP’s latest features to improve developer experience, extensibility, and background processing.",
318+
"We also welcome talks on FrankenPHP’s runtime model, production usage, observability, deployment strategies, migrations to worker mode, ecosystem integrations, and lessons learned from real-world projects."
319+
]
320+
},
321+
{
322+
"icon": "real-time",
323+
"title": "Mercure & Real-Time Web",
324+
"points": [
325+
"We are interested in talks around Mercure and real-time web architectures, including real-world use cases, architectural choices, security considerations, and production feedback."
326+
]
327+
},
328+
{
329+
"icon": "frameworks",
330+
"title": "Frameworks and tools",
331+
"points": [
332+
"Share with us your findings or best practices regarding tools from the PHP ecosystem.",
333+
"Tell us about the tools and good practices you use to build your software’s architecture. "
334+
]
335+
},
336+
{
337+
"icon": "society",
338+
"title": "Society",
339+
"points": [
340+
"Different management, corporate culture, mental health, agility, or the struggle for greater diversity and inclusion in tech... We always open the floor to more cross-cutting topics during our event."
341+
]
342+
}
343+
]
344+
},
345+
"informations": "Informations",
346+
"point_1": "The API Platform Conference is an international event held in France, featuring two parallel tracks over two days in both English and French.",
347+
"point_2": "The talks are 20 or 40 min (Q&A included).",
348+
"point_3": "Talks are limited to a maximum of two speakers for organizational reasons.",
349+
"point_4": "AI can be a great help on a daily basis, but we encourage you to submit a talk that truly reflects your own voice and experience. We tend to recognize AI-generated content quite easily",
350+
"point_5": "The event is hybrid: your talk will be streamed live online and recorded. Unless you advise otherwise, it will be published on our YouTube channel after the event.",
351+
"point_6": "Submitting multiple proposals is encouraged, but it does not necessarily increase your chances of selection.",
352+
"point_7": "While we prefer original content, submitting a previously presented conference topic is not grounds for elimination. Each talk is unique and never delivered in the same way.",
353+
"point_8": "Speakers are expected to uphold the same Code of Conduct as attendees and staff.",
354+
"button_subscribe": "Submit your pitch"
271355
}
272356
},
273357
"an_event_by": "an event by",

0 commit comments

Comments
 (0)