Skip to content

Commit

Permalink
feat: add register page
Browse files Browse the repository at this point in the history
  • Loading branch information
ginifizz committed Dec 23, 2024
1 parent e825fd4 commit 124e548
Show file tree
Hide file tree
Showing 10 changed files with 392 additions and 61 deletions.
2 changes: 1 addition & 1 deletion pwa/app/(con)/[locale]/con/2025/call-for-papers/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export async function generateMetadata({ params }: Props): Promise<Metadata> {
alternates: {
languages: {
en: locale === "en" ? undefined : "/con/2025",
fr: locale === "fr" ? undefined : "/fr/con/2024",
fr: locale === "fr" ? undefined : "/fr/con/2025",
},
},
};
Expand Down
138 changes: 86 additions & 52 deletions pwa/app/(con)/[locale]/con/2025/components/HomePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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[];
Expand Down Expand Up @@ -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={{
Expand Down Expand Up @@ -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:events@les-tilleuls.coop"
>
{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&amp;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>
Expand All @@ -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>
Expand Down
7 changes: 1 addition & 6 deletions pwa/app/(con)/[locale]/con/2025/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,7 @@ export async function generateMetadata({ params }: Props): Promise<Metadata> {
function EditionLayout({ children }: { children: React.ReactNode }) {
const eventData = getEditionEventData("2025");
return (
<LayoutBase
edition="2025"
nav={nav}
footer={footer}
isTicketingOpen={false}
>
<LayoutBase edition="2025" nav={nav} footer={footer} isTicketingOpen>
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(eventData) }}
Expand Down
157 changes: 157 additions & 0 deletions pwa/app/(con)/[locale]/con/2025/register/RegisterPage.tsx
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>
</>
);
}

Loading

0 comments on commit 124e548

Please sign in to comment.