From 780f74222e8350c81b00a0935e86f0e20f6900e1 Mon Sep 17 00:00:00 2001 From: Noe Terrier Date: Wed, 19 Nov 2025 21:35:39 +0100 Subject: [PATCH] feat: add registration progress bar for events --- src/components/RegistrationProgressBar.tsx | 29 ++++++++ src/pages/index.tsx | 49 ++++++++++++- .../RegistrationProgressBar.module.scss | 71 +++++++++++++++++++ 3 files changed, 147 insertions(+), 2 deletions(-) create mode 100644 src/components/RegistrationProgressBar.tsx create mode 100644 src/styles/RegistrationProgressBar.module.scss diff --git a/src/components/RegistrationProgressBar.tsx b/src/components/RegistrationProgressBar.tsx new file mode 100644 index 0000000..d824a23 --- /dev/null +++ b/src/components/RegistrationProgressBar.tsx @@ -0,0 +1,29 @@ +import style from "@/styles/RegistrationProgressBar.module.scss"; + +export default function RegistrationProgressBar(props: { + registration_count: number; + max_registrations: number; + event_name: string; +}) { + var inner_bar_width = + (props.registration_count / props.max_registrations) * 100; + return ( +
+
+

{props.event_name}

+

+ ยท {props.registration_count}/{props.max_registrations} inscriptions +

+
+
+
+
+
+
+ ); +} diff --git a/src/pages/index.tsx b/src/pages/index.tsx index fabd441..241a6f6 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -8,12 +8,13 @@ import Gallery from "@/components/Gallery"; import MembersList from "@/components/MembersList"; import NewsCard from "@/components/NewsCard"; import PartnersList from "@/components/PartnersList"; +import RegistrationProgressBar from "@/components/RegistrationProgressBar"; import SocialsList from "@/components/SocialsList"; import TabTitle from "@/components/TabTitle"; import { - LayoutProps, directus, getDirectusImageUrl, + LayoutProps, populateLayoutProps, } from "@/directus"; import { @@ -25,13 +26,21 @@ import styles from "@/styles/Homepage.module.scss"; import { Association, AssociationMembership, + Event, Member, News, Partner, PublicFiles, SocialLink, } from "@/types/aliases"; -import { readFiles, readItems, readSingleton } from "@directus/sdk"; +import { Schema } from "@/types/schema"; +import { + aggregate, + AggregationOutput, + readFiles, + readItems, + readSingleton, +} from "@directus/sdk"; import { GetServerSideProps, InferGetServerSidePropsType } from "next"; import { useRouter } from "next/router"; @@ -66,6 +75,17 @@ export default function Home(
+ {props.events.map((event) => ( + b.event == event.id) + ?.count || "" + )} + /> + ))}

News

{props.news.map((n) => ( @@ -114,6 +134,12 @@ export const getServerSideProps: GetServerSideProps< committee: (AssociationMembership & { member: Member })[]; publicFiles: PublicFiles[]; gallery: any[]; + events: Event[]; + registrations_count: AggregationOutput< + Schema, + "registrations", + { aggregate: { count: "*" }; groupBy: "event"[] } + >; } & LayoutProps > = populateLayoutProps(async (_) => { return { @@ -202,6 +228,25 @@ export const getServerSideProps: GetServerSideProps< }, }) ), + events: await directus().request( + readItems("events", { + fields: ["id", "name", "max_registrations"], + filter: { + opened: { + _eq: true, + }, + max_registrations: { + _nnull: true, + }, + }, + }) + ), + registrations_count: await directus().request( + aggregate("registrations", { + aggregate: { count: "*" }, + groupBy: ["event"], + }) + ), }, }; }); diff --git a/src/styles/RegistrationProgressBar.module.scss b/src/styles/RegistrationProgressBar.module.scss new file mode 100644 index 0000000..162743f --- /dev/null +++ b/src/styles/RegistrationProgressBar.module.scss @@ -0,0 +1,71 @@ +@use "utilities/variables"; + +.main { + background-color: transparent; + border-radius: variables.$small-border-radius; + width: 40%; + padding: 2rem; + + display: flex; + flex-direction: column; + + .info { + display: flex; + gap: 1rem; + } + + .eventName { + font-weight: 500; + font-size: 2rem; + margin: 0; + color: variables.$dark-text-color; + } + + .count { + color: white; + font-size: 2rem; + margin: 0; + } + + .progressBar { + position: relative; + width: 100%; + height: 2rem; + + .outerBar { + width: calc(100% + 0.2rem); + left: -0.4rem; + bottom: 0; + top: 0; + margin: auto; + height: 1rem; + padding: 0.1rem; + border-radius: 25px; + border: solid 0.2rem white; + position: absolute; + background-color: rgba(255, 255, 255, 0.147); + } + + .innerBar { + height: 0.8rem; + left: 0; + bottom: 0; + top: 0; + margin: auto; + background: green; + position: absolute; + border-radius: 25px; + background: #2a7b9b; + background: linear-gradient( + 90deg, + rgba(42, 123, 155, 1) 0%, + rgba(87, 199, 133, 1) 50%, + rgba(237, 221, 83, 1) 100% + ); + } + } + + @media (max-width: 1000px) { + width: 65%; + } +}