From ae398b3d37a7f99a17afe773e5b09bc0f146d80e Mon Sep 17 00:00:00 2001 From: Antoine Phan Date: Tue, 3 Feb 2026 11:26:11 -0500 Subject: [PATCH] Redesign the Council cards and popups --- src/components/council/CouncilAvatar.svelte | 19 +- src/components/council/CouncilCard.svelte | 59 ++++-- .../council/CouncilCardPopUp.svelte | 101 +++++----- src/components/layout/Section.svelte | 3 +- src/lib/format.ts | 13 ++ src/routes/council/+page.server.ts | 4 +- src/routes/council/+page.svelte | 174 +++++++++++------- 7 files changed, 239 insertions(+), 134 deletions(-) create mode 100644 src/lib/format.ts diff --git a/src/components/council/CouncilAvatar.svelte b/src/components/council/CouncilAvatar.svelte index a1ed1f5..bcf7f4c 100644 --- a/src/components/council/CouncilAvatar.svelte +++ b/src/components/council/CouncilAvatar.svelte @@ -16,17 +16,16 @@ } -
+
{#if src && !imageError} - {name} - {:else if !src || imageError} -
- {getInitials(name)} + {name} + {:else} +
+ {getInitials(name)}
{/if}
diff --git a/src/components/council/CouncilCard.svelte b/src/components/council/CouncilCard.svelte index 0e17e5b..190fb15 100644 --- a/src/components/council/CouncilCard.svelte +++ b/src/components/council/CouncilCard.svelte @@ -1,20 +1,53 @@ -
-
- +
+ {#if tag} + + {tag} + + {/if} + {#if image && !imageError} + {name} + {:else} + + {/if}
-
-

{name}

-

{position}

-
- -
+
+

+ {name} +

+

{position}

+
diff --git a/src/components/council/CouncilCardPopUp.svelte b/src/components/council/CouncilCardPopUp.svelte index a3b53fc..c7ac114 100644 --- a/src/components/council/CouncilCardPopUp.svelte +++ b/src/components/council/CouncilCardPopUp.svelte @@ -1,4 +1,4 @@ -
- -
- + +
-
+ {#if image && !imageError} {name} -
- {yearProgram} + {:else} + + {/if}
+ {#if yearProgram} +

+ {yearProgram} +

+ {/if} +
- -
-
-

{name}

-

{position}

+ +
+

{name}

+

{position}

+ + {#if positionDescription} +
+

+ {positionDescription} +

+ {/if} -
- -
- {#if positionDescription} -
-

- {positionDescription} -

-
- {/if} - {#if email} - - {/if} + {#if email} + -
+ {/if}
diff --git a/src/components/layout/Section.svelte b/src/components/layout/Section.svelte index e18c128..89b37f2 100644 --- a/src/components/layout/Section.svelte +++ b/src/components/layout/Section.svelte @@ -17,12 +17,11 @@ const base = 'mx-auto flex min-h-[90vh] flex-col items-center gap-4 p-4 text-center text-ecsess-100'; - const justifyClass = contentStart ? 'justify-start' : 'justify-center'; - // Compute classes: prefer gradient when from/to provided; otherwise fallback to previous behavior let tailwindClasses = $state(base); $effect(() => { + const justifyClass = contentStart ? 'justify-start' : 'justify-center'; const withJustify = `${base} ${justifyClass}`; if (from && to) { tailwindClasses = `${withJustify} bg-gradient-${direction} ${from} ${to} ${via}`; diff --git a/src/lib/format.ts b/src/lib/format.ts new file mode 100644 index 0000000..78139bb --- /dev/null +++ b/src/lib/format.ts @@ -0,0 +1,13 @@ +/** + * Get initials from a name (e.g. "Jane Doe" → "JD", "Mary Jane Watson" → "MJW"). + * Uses first letter of up to 3 words. Safe for null/undefined/empty. + */ +export function getInitials(name: string | null | undefined): string { + if (name == null || typeof name !== 'string') return ''; + const words = name.trim().split(/\s+/).filter(Boolean); + if (words.length === 0) return ''; + return words + .slice(0, 3) + .map((w) => w.charAt(0).toUpperCase()) + .join(''); +} diff --git a/src/routes/council/+page.server.ts b/src/routes/council/+page.server.ts index fa562b4..7530333 100644 --- a/src/routes/council/+page.server.ts +++ b/src/routes/council/+page.server.ts @@ -10,7 +10,7 @@ const councilQuery = `{ email, position, positionDescription, - "image": image.asset->url+"?h=300&fm=webp", + "image": image.asset->url+"?h=360&fm=webp", yearProgram }, "councilGoofyPic": *[_type == "homepage"]{ @@ -18,7 +18,7 @@ const councilQuery = `{ }[0] }`; -export const load = async ({ url }) => { +export const load = async ({ url }: { url: URL }) => { const { members, councilGoofyPic diff --git a/src/routes/council/+page.svelte b/src/routes/council/+page.svelte index 9755582..6f20632 100644 --- a/src/routes/council/+page.svelte +++ b/src/routes/council/+page.svelte @@ -2,8 +2,8 @@ import CouncilCardPopUp from 'components/council/CouncilCardPopUp.svelte'; import Section from 'components/layout/Section.svelte'; import CardCouncil from 'components/council/CouncilCard.svelte'; + import Link from 'components/Link.svelte'; import type { CouncilMember } from '$lib/schemas'; - import { fly } from 'svelte/transition'; import SeoMetaTags from 'components/layout/SeoMetaTags.svelte'; import { onMount } from 'svelte'; import { tick } from 'svelte'; @@ -12,7 +12,6 @@ const years = ['U4', 'U3', 'U2', 'U1', 'U0']; - // Get members by 3 main categories (reactive from data) let president = $derived( data.members.filter((member: CouncilMember) => member.position.includes('President'))[0] ); @@ -48,6 +47,11 @@ if (e.key === 'Escape') closeModal(); } + function getYearFromPosition(position: string): string | undefined { + const match = position.match(/\b(U[0-4])\b/); + return match?.[1]; + } + onMount(() => { function onKeyDown(e: KeyboardEvent) { if (e.key === 'Escape') closeModal(); @@ -75,82 +79,126 @@ canonical={data.canonical} /> -
-
-

Meet the council!

- ECSESS Council, but we are goofy -
+
+
+ +

Meet the ECSESS Council

-

- Our Student Council -

- - {#if president} -
- handleViewProfile(president)} +
+ ECSESS Council having fun -
- {/if} + -
-

- Vice Presidents -

-
- {#each vps as vp} - handleViewProfile(vp)} - /> - {/each} -
-

- Year Representatives -

-
- {#each ureps as urep} - handleViewProfile(urep)} - /> - {/each} -
+ + {#if president} +
+
+ +

+ President +

+ +
+
+ handleViewProfile(president)} + featured + /> +
+
+ {/if} + + +
+
+ +

+ Vice Presidents +

+ +
+
+ {#each vps as vp} +
+ handleViewProfile(vp)} + /> +
+ {/each} +
+
+ + +
+
+ +

+ Year Representatives +

+ +
+
+ {#each ureps as urep} +
+ handleViewProfile(urep)} + tag={getYearFromPosition(urep.position)} + /> +
+ {/each} +
+
+ + +
+

+ Like what you see? + + Join ECSESS and be part of the fun → + +

+
{#if selectedMember} -