-
-
Notifications
You must be signed in to change notification settings - Fork 68
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
392 additions
and
61 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,19 +3,19 @@ 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 { currentEdition } from "data/con/editions"; | ||
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 from "components/con/home/Section"; | ||
import PictureGallery from "components/con/common/PictureGallery"; | ||
import prices from "data/con/2024/prices"; | ||
import Logo from "./Logo"; | ||
import AfterMovie from "app/con/2024/components/AfterMovie"; | ||
import PricingCard from "components/con/home/Pricing/PricingCard"; | ||
import BuyButton from "components/con/common/BuyButton"; | ||
|
||
type HomePageProps = { | ||
speakers: Speaker[]; | ||
|
@@ -43,61 +43,28 @@ const HomePage = ({ speakers, partners, images }: HomePageProps) => { | |
{t("2025.subbaseline")} | ||
</p> | ||
<div className="flex gap-2"> | ||
<Button className="pink" to={`/${locale}/con/2024/review`}> | ||
{currentEdition === "2025" && ( | ||
<BuyButton className="mr-2" id="cover"> | ||
{t("buy_tickets")} | ||
</BuyButton> | ||
)} | ||
<Button empty to={`/${locale}/con/2024/review`}> | ||
{t("2025.previous_edition")} | ||
</Button> | ||
</div> | ||
</div> | ||
</div> | ||
<Wave className="absolute opacity-30 z-0 bottom-0 h-[60vh] right-[7%] top-[63%] -translate-y-1/2" /> | ||
</Section> | ||
<Section | ||
section="lastYear" | ||
className="bg-white z-10 relative pb-10 overflow-y-clip" | ||
> | ||
<div className="container text-center"> | ||
<SectionTitle> | ||
<Translate translationKey="last_edition.title" /> | ||
</SectionTitle> | ||
<SectionSubTitle> | ||
<Translate | ||
translationKey="2025.see_review.subtitle" | ||
translationParams={{ | ||
edition: "2024", | ||
link: ( | ||
<a href={`/${locale}/con/2024/review`} className="link"> | ||
{t("2025.see_review.link")} | ||
</a> | ||
), | ||
}} | ||
/> | ||
</SectionSubTitle> | ||
<PictureGallery | ||
className="py-4" | ||
link="https://www.flickr.com/photos/194052559@N02/albums/72177720320499314/" | ||
> | ||
{images.map((image: string) => ( | ||
<Image | ||
className="object-cover" | ||
key={image} | ||
fill | ||
src={image} | ||
alt="" | ||
sizes="(max-width: 640px) 200px, (max-width: 768px) 240px, (max-width: 1536px) 300px, 400px" | ||
/> | ||
))} | ||
</PictureGallery> | ||
</div> | ||
</Section> | ||
<Section | ||
section="speakers" | ||
className="z-10 relative py-4 overflow-x-hidden text-white" | ||
className="bg-white z-10 relative py-4 overflow-x-hidden" | ||
> | ||
<div className="container text-center"> | ||
<SectionTitle dark h1> | ||
<SectionTitle h1> | ||
<Translate translationKey="2025.our_speakers.title" /> | ||
</SectionTitle> | ||
<SectionSubTitle dark> | ||
<SectionSubTitle> | ||
<Translate | ||
translationKey="2025.our_speakers.subtitle" | ||
translationParams={{ | ||
|
@@ -130,15 +97,86 @@ const HomePage = ({ speakers, partners, images }: HomePageProps) => { | |
</Button> | ||
</div> | ||
</Section> | ||
{currentEdition === "2025" && ( | ||
<Section | ||
className="relative py-10 before:bg-grey before:h-[calc(100%-500px)] before:absolute before:left-0 before:bottom-0 before:w-full after:bg-wave2 after:w-[1300px] after:h-[800px] after:absolute after:top-24 after:left-1/2 after:bg-top after:bg-contain after:opacity-50 after:bg-no-repeat after:-translate-x-1/2 after:rotate-6" | ||
section="pricing" | ||
> | ||
<div className="container relative z-10"> | ||
<SectionTitle dark> | ||
<Translate translationKey="pricing.title" /> | ||
</SectionTitle> | ||
<div className="max-w-4xl mx-auto flex flex-row flex-wrap justify-center"> | ||
{prices.map((price) => ( | ||
<PricingCard key={price.id} price={price} /> | ||
))} | ||
<div className="w-full self-center max-w-md mt-10 | lg:pl-10 lg:mt-0 lg:w-1/3"> | ||
<div className="p-5 dotted-corner flex flex-col items-center text-center bg-blue bg-blue-gradient shadow-md border-blue-dark border-4"> | ||
<span className="font-bold text-white leading-tight font-title uppercase lined-center lined-white relative"> | ||
{t("pricing.student")} | ||
</span> | ||
<div className="mt-2 text-blue-black/80 font-semibold"> | ||
<Translate translationKey="pricing.free_ticket" /> | ||
</div> | ||
<Button | ||
size="small" | ||
square | ||
className="white mt-2 mb-5" | ||
to="mailto:[email protected]" | ||
> | ||
{t("contact_us")} | ||
</Button> | ||
<small className="text-xs text-blue-black/50 font-bold"> | ||
*{t("pricing.certificate_needed")} | ||
</small> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
</Section> | ||
)} | ||
<Venue subtitle={t("2025.venue.subtitle")} /> | ||
<Section | ||
section="lastYear" | ||
className=" z-10 relative pb-10 overflow-y-clip" | ||
> | ||
<div className="container text-center flex flex-col items-center pt-12"> | ||
<SectionTitle dark> | ||
<Translate translationKey="last_edition.title" /> | ||
</SectionTitle> | ||
<SectionSubTitle dark> | ||
<Translate | ||
translationKey="2025.see_review.subtitle" | ||
translationParams={{ | ||
edition: "2024", | ||
link: ( | ||
<a href={`/${locale}/con/2024/review`} className="link"> | ||
{t("2025.see_review.link")} | ||
</a> | ||
), | ||
}} | ||
/> | ||
</SectionSubTitle> | ||
<iframe | ||
className="aspect-video w-full max-w-2xl border-white border-8 shadow-2xl" | ||
src="https://www.youtube.com/embed/XXj8NCvLuis?si=hWGWKS81UriUkJ3R&controls=0" | ||
title="YouTube video player" | ||
frameBorder="0" | ||
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" | ||
referrerPolicy="strict-origin-when-cross-origin" | ||
allowFullScreen | ||
></iframe> | ||
</div> | ||
</Section> | ||
<Section | ||
section="missing" | ||
className="relative z-10 text-center overflow-y-clip bg-white" | ||
className="relative bg-grey z-10 text-center overflow-y-clip" | ||
> | ||
<div className="container text-center"> | ||
<SectionTitle> | ||
<Translate | ||
translationKey="missing_conferences.title" | ||
translationParams={{ edition: "2024" }} | ||
translationParams={{ edition: "2025" }} | ||
/> | ||
</SectionTitle> | ||
<SectionSubTitle>{t("missing_conferences.subtitle")}</SectionSubTitle> | ||
|
@@ -151,10 +189,6 @@ const HomePage = ({ speakers, partners, images }: HomePageProps) => { | |
</Button> | ||
</div> | ||
</Section> | ||
<div className="pb-12"> | ||
<AfterMovie /> | ||
</div> | ||
<Venue subtitle={t("2025.venue.subtitle")} /> | ||
<Section section="sponsorship" className="py-8"> | ||
<div className="container text-center"> | ||
<SectionTitle dark> | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
157 changes: 157 additions & 0 deletions
157
pwa/app/(con)/[locale]/con/2025/register/RegisterPage.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,157 @@ | ||
"use client"; | ||
import { useContext } from "react"; | ||
import { LanguageContext } from "contexts/con/LanguageContext"; | ||
import SectionTitle from "components/con/common/typography/SectionTitle"; | ||
import SectionSubTitle from "components/con/common/typography/SectionSubtitle"; | ||
import Script from "next/script"; | ||
import prices from "data/con/2025/prices"; | ||
import { Offer } from "types/con"; | ||
import dayjs from "dayjs"; | ||
import classNames from "classnames"; | ||
import { toLocaleDate } from "utils/con"; | ||
|
||
export default function RegisterPage() { | ||
const { t, Translate, locale, getLocaleDictionary } = | ||
useContext(LanguageContext); | ||
const timelinePrices = prices | ||
.find((p) => p.id === 1) | ||
?.offers.filter((o) => o.type); | ||
|
||
const isActiveOffer = (offer: Offer) => { | ||
if (offer.limitDate && dayjs(offer.limitDate).isBefore(dayjs(), "day")) | ||
return false; | ||
if (offer.startDate && dayjs(offer.startDate).isAfter(dayjs(), "day")) | ||
return false; | ||
return true; | ||
}; | ||
|
||
const isPastOffer = (offer: Offer) => { | ||
if (isActiveOffer(offer)) return false; | ||
if (offer.startDate && dayjs(offer.startDate).isBefore(dayjs(), "day")) | ||
return true; | ||
return false; | ||
}; | ||
|
||
const expectations = | ||
getLocaleDictionary?.()[2025].tickets.expect.points || []; | ||
|
||
const onIframeLoaded = () => { | ||
const iframe = document.getElementById("yurplan-widget-141690") as HTMLIFrameElement | null; | ||
if (!iframe) return; | ||
const contenu = iframe.contentWindow?.document.body.scrollHeight; | ||
iframe.style.height = contenu + "px"; | ||
} | ||
|
||
return ( | ||
<> | ||
<div className="container max-w-5xl flex flex-col items-center py-12 relative z-10"> | ||
<SectionTitle small h1 dark lined> | ||
<Translate translationKey="2025.tickets.title" /> | ||
</SectionTitle> | ||
<SectionSubTitle dark>{t("2025.tickets.subtitle")}</SectionSubTitle> | ||
</div> | ||
<div className="after:h-1/3 after:absolute after:w-full after:bg-grey after:bottom-0 after:left-0 relative"> | ||
<div className="container max-w-6xl relative z-10"> | ||
<div className="flex flex-col lg:flex-row w-full max-w-6xl items-center lg:items-start"> | ||
<div className="translate-y-12 relative z-10 w-4/5 lg:w-2/5 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"> | ||
<img | ||
className="relative" | ||
src="/images/con/2024/review/pic-06.jpg" | ||
/> | ||
</div> | ||
<div className="flex-1 relative bg-white shadow-floating dotted-corner p-12 pt-24 lg:pt-12 lg:pl-24 lg:-translate-x-12 leading-relaxed font-light"> | ||
<Translate translationKey="2025.tickets.description" /> | ||
<p className="mt-4 text-lg font-bold"> | ||
{t("2025.tickets.description2")} | ||
</p> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
<div className="bg-grey py-12"> | ||
<div className="container max-w-6xl"> | ||
<SectionTitle small lined> | ||
<Translate translationKey="2025.tickets.expect.title" /> | ||
</SectionTitle> | ||
<div className="mx-auto max-w-64 sm:max-w-xl grid grid-cols-1 sm:grid-cols-2 xl:max-w-none xl:grid-cols-4 gap-8 text-white"> | ||
{expectations.map((e, i) => ( | ||
<div | ||
key={i} | ||
className={classNames( | ||
"p-8 aspect-square flex flex-col justify-center", | ||
i === 0 && "bg-blue-dark", | ||
i === 1 && "bg-blue-black/80", | ||
i === 2 && "bg-blue-darkest", | ||
i === 3 && "bg-blue-dark" | ||
)} | ||
> | ||
<p className="uppercase font-bold text-xl">{e.title}</p> | ||
<p>{e.text}</p> | ||
</div> | ||
))} | ||
</div> | ||
</div> | ||
</div> | ||
<div className="bg-white"> | ||
<div className="container max-w-4xl py-12"> | ||
<SectionTitle small lined> | ||
<strong>{t("2025.tickets.buy")}</strong> | ||
</SectionTitle> | ||
<div className="hidden relative w-full gap-0 md:grid grid-cols-3 py-12 overflow-hidden"> | ||
<div className="absolute w-1.5 h-full left-4 -translate-x-1/2 md:-translate-x-0 top-0 md:h-1.5 md:w-full md:top-1/2 md:left-0 md:-translate-y-1/2 bg-blue-black/30"></div> | ||
{timelinePrices?.map((p) => ( | ||
<div | ||
key={p.type} | ||
className="relative flex flex-col items-center gap-2" | ||
> | ||
<div className="ml-8 md:ml-0 whitespace-nowrap absolute left-full md:left-1/2 top-1/2 -translate-y-1/2 -translate-x-1/2"> | ||
<div | ||
className={classNames( | ||
"font-bold uppercase md:mb-12 text-left md:text-center", | ||
isActiveOffer(p) ? "text-blue" : isPastOffer(p) ? "text-blue-black/30" : "text-blue-black" | ||
)} | ||
> | ||
{p.type} | ||
</div> | ||
<p className={classNames(isPastOffer(p) ? "text-blue-black/30" : "text-blue-black/70")}> | ||
{t("2025.tickets.until_date", { | ||
date: toLocaleDate(p.limitDate as string), | ||
})} | ||
</p> | ||
</div> | ||
<div | ||
className={classNames( | ||
"relative rounded-full border-4 size-8", | ||
isActiveOffer(p) | ||
? "border-blue bg-blue before:h-screen before:w-1.5 before:md:w-screen before:absolute before:md:h-1.5 before:bottom-full before:-translate-x-1/2 before:md:-translate-x-0 before:md:right-full before:bg-blue before:left-1/2 before:md:left-auto before:md:top-1/2 before:md:-translate-y-1/2" | ||
: isPastOffer(p) ? "border-blue bg-white z-10" : "border-blue-black/30 bg-white" | ||
)} | ||
/> | ||
</div> | ||
))} | ||
</div> | ||
<div className="yurplan-widget-container max-w-5xl container pb-40 md:pt-12 -mb-[180px]"> | ||
<iframe | ||
onLoad={() => onIframeLoaded()} | ||
title="yurplan" | ||
src={`https://yurplan.com/events/API-Platform-Conference-2025/138927/tickets/widget?widget=dGlja2V0aW5nV2lkZ2V0WXBfMTM2ODk5XzE0MTY5MA%3D%3D&from=widget_141690&wversion=1&culture=${locale}`} | ||
width="100%" | ||
height="100%" | ||
frameBorder="0" | ||
scrolling="no" | ||
className="yurplan-widget" | ||
style={{ height: "auto", clipPath: "inset(0px 0px 180px 0px);" }} | ||
id="yurplan-widget-141690" | ||
data-id="141690" | ||
></iframe> | ||
</div> | ||
<Script | ||
type="text/javascript" | ||
src="https://assets.yurplan.com/yurplan-v1/dist/widget.js" | ||
/> | ||
</div> | ||
</div> | ||
</> | ||
); | ||
} | ||
|
Oops, something went wrong.