Responsive navbar, council card and popup update for accessibility, remove analytics from Vercel

This commit is contained in:
Antoine Phan
2025-08-25 02:26:48 -04:00
parent 15fe42d046
commit 32c2970574
10 changed files with 105 additions and 65 deletions

View File

@@ -5,24 +5,23 @@
"name": "ecsess-website", "name": "ecsess-website",
"dependencies": { "dependencies": {
"@lucide/svelte": "^0.539.0", "@lucide/svelte": "^0.539.0",
"@sanity/client": "^7.5.0", "@sanity/client": "^7.8.2",
"@vercel/analytics": "^1.5.0",
}, },
"devDependencies": { "devDependencies": {
"@portabletext/svelte": "^3.0.0", "@portabletext/svelte": "^3.0.0",
"@skeletonlabs/skeleton": "^3.1.3", "@skeletonlabs/skeleton": "^3.1.7",
"@skeletonlabs/skeleton-svelte": "^1.2.3", "@skeletonlabs/skeleton-svelte": "^1.3.1",
"@sveltejs/adapter-auto": "^6.0.1", "@sveltejs/adapter-auto": "^6.0.2",
"@sveltejs/kit": "^2.21.3", "@sveltejs/kit": "^2.27.3",
"@sveltejs/vite-plugin-svelte": "^5.1.0", "@sveltejs/vite-plugin-svelte": "^5.1.1",
"@tailwindcss/vite": "^4.1.8", "@tailwindcss/vite": "^4.1.11",
"prettier": "^3.5.3", "prettier": "^3.6.2",
"prettier-plugin-svelte": "^3.4.0", "prettier-plugin-svelte": "^3.4.0",
"prettier-plugin-tailwindcss": "^0.6.12", "prettier-plugin-tailwindcss": "^0.6.14",
"svelte": "^5.33.18", "svelte": "^5.38.1",
"svelte-check": "^4.2.1", "svelte-check": "^4.3.1",
"tailwindcss": "^4.1.8", "tailwindcss": "^4.1.11",
"typescript": "^5.8.3", "typescript": "^5.9.2",
"vite": "^6.3.5", "vite": "^6.3.5",
}, },
}, },
@@ -212,8 +211,6 @@
"@types/node": ["@types/node@24.0.15", "", { "dependencies": { "undici-types": "~7.8.0" } }, "sha512-oaeTSbCef7U/z7rDeJA138xpG3NuKc64/rZ2qmUFkFJmnMsAPaluIifqyWd8hSSMxyP9oie3dLAqYPblag9KgA=="], "@types/node": ["@types/node@24.0.15", "", { "dependencies": { "undici-types": "~7.8.0" } }, "sha512-oaeTSbCef7U/z7rDeJA138xpG3NuKc64/rZ2qmUFkFJmnMsAPaluIifqyWd8hSSMxyP9oie3dLAqYPblag9KgA=="],
"@vercel/analytics": ["@vercel/analytics@1.5.0", "", { "peerDependencies": { "@remix-run/react": "^2", "@sveltejs/kit": "^1 || ^2", "next": ">= 13", "react": "^18 || ^19 || ^19.0.0-rc", "svelte": ">= 4", "vue": "^3", "vue-router": "^4" }, "optionalPeers": ["@remix-run/react", "@sveltejs/kit", "next", "react", "svelte", "vue", "vue-router"] }, "sha512-MYsBzfPki4gthY5HnYN7jgInhAZ7Ac1cYDoRWFomwGHWEX7odTEzbtg9kf/QSo7XEsEAqlQugA6gJ2WS2DEa3g=="],
"@zag-js/accordion": ["@zag-js/accordion@1.18.4", "", { "dependencies": { "@zag-js/anatomy": "1.18.4", "@zag-js/core": "1.18.4", "@zag-js/dom-query": "1.18.4", "@zag-js/types": "1.18.4", "@zag-js/utils": "1.18.4" } }, "sha512-lwLq38eSJs6zC9HfmvPxK3LbWSjJJm8Lg+yu8jYHOQlMwWymJAXM2yaLGVqz2HBDwv4jJCqUQ+sYFPEpuITfTw=="], "@zag-js/accordion": ["@zag-js/accordion@1.18.4", "", { "dependencies": { "@zag-js/anatomy": "1.18.4", "@zag-js/core": "1.18.4", "@zag-js/dom-query": "1.18.4", "@zag-js/types": "1.18.4", "@zag-js/utils": "1.18.4" } }, "sha512-lwLq38eSJs6zC9HfmvPxK3LbWSjJJm8Lg+yu8jYHOQlMwWymJAXM2yaLGVqz2HBDwv4jJCqUQ+sYFPEpuITfTw=="],
"@zag-js/anatomy": ["@zag-js/anatomy@1.18.4", "", {}, "sha512-t1vWjWOnjmslHCpDx7wQTHTuT7DRs4H3rqvL2Mq+uLKMzbkLfjBMBVU70L23WdRKkdhCML5lzoH+EXcEn2PQ1g=="], "@zag-js/anatomy": ["@zag-js/anatomy@1.18.4", "", {}, "sha512-t1vWjWOnjmslHCpDx7wQTHTuT7DRs4H3rqvL2Mq+uLKMzbkLfjBMBVU70L23WdRKkdhCML5lzoH+EXcEn2PQ1g=="],

View File

@@ -32,7 +32,6 @@
"type": "module", "type": "module",
"dependencies": { "dependencies": {
"@lucide/svelte": "^0.539.0", "@lucide/svelte": "^0.539.0",
"@sanity/client": "^7.8.2", "@sanity/client": "^7.8.2"
"@vercel/analytics": "^1.5.0"
} }
} }

View File

@@ -26,7 +26,7 @@ h2 {
} }
.page-title { .page-title {
@apply py-4 text-3xl font-bold md:text-4xl lg:text-6xl; @apply my-6 text-3xl font-bold md:text-4xl lg:text-6xl;
} }
.typography { .typography {

View File

@@ -1,11 +1,10 @@
<script> <script>
let { onViewProfile, name, position, image } = $props(); let { onViewProfile, name, position, image } = $props();
import placeholder from 'assets/placeholderAvatar.png';
import Button from 'components/Button.svelte'; import Button from 'components/Button.svelte';
import Avatar from 'components/Avatar.svelte'; import Avatar from 'components/Avatar.svelte';
</script> </script>
<div class="text-ecsess-200 flex max-w-md items-center gap-6 justify-between p-3"> <div class="text-ecsess-200 flex max-w-md items-center gap-6 p-3">
<!-- Profile picture --> <!-- Profile picture -->
<div> <div>
<Avatar {name} size={"size-26 md:size-32"} src={image}/> <Avatar {name} size={"size-26 md:size-32"} src={image}/>

View File

@@ -1,5 +1,6 @@
<script> <script>
let { name, position, email, positionDescription, yearProgram, image } = $props(); let { name, position, email, positionDescription, yearProgram, image } = $props();
import { Mail, NotepadText } from '@lucide/svelte';
import placeholder from 'assets/placeholderAvatar.png'; import placeholder from 'assets/placeholderAvatar.png';
import { slide } from 'svelte/transition'; import { slide } from 'svelte/transition';
</script> </script>
@@ -12,22 +13,30 @@
> >
<!-- AVATAR --> <!-- AVATAR -->
<div class="avatar"> <div class="avatar">
<div class="size-42 justify-center place-self-center-safe overflow-hidden rounded-lg shadow-md"> <div class="size-36 justify-center place-self-center-safe overflow-hidden rounded-lg shadow-md">
<img src={image || placeholder} alt={name} class="h-full w-full object-cover" /> <img src={image || placeholder} alt={name} class="h-full w-full object-cover" />
</div> </div>
<span class="yearProgram justify-center text-sm"> Major: {yearProgram} </span> <span class="yearProgram justify-center text-sm"> Major: {yearProgram} </span>
</div> </div>
<!-- CONTENT --> <!-- CONTENT -->
<div class="content"> <div class="content">
<p class="my-2 text-3xl font-bold">{name}</p>
<hr class="hr border-ecsess-600 border-1 border-dashed" />
<div class="my-2"> <div class="my-2">
<p>{position}</p> <p class="text-2xl font-bold lg:text-3xl">{name}</p>
<p class="text-base italic">{position}</p>
</div>
<hr class="hr border-ecsess-600 border-1 border-dashed" />
<div class="my-2 text-left">
<ul>
<li>
<p class="py-2 text-base">{positionDescription}</p>
</li>
<li class="flex flex-row place-items-center gap-2">
<Mail class="size-4" />
<p> <p>
Email: <a href="mailto:{email}" class="py-2 text-base underline">{email}</a> Email: <a href="mailto:{email}" class="py-2 text-base underline">{email}</a>
</p> </p>
</li>
</ul>
</div> </div>
<hr class="hr border-ecsess-600 border-1 border-dashed" />
<p class="py-2 text-base">{positionDescription}</p>
</div> </div>
</div> </div>

View File

@@ -1,15 +1,51 @@
<script> <script>
import Button from './Button.svelte';
import NavButton from './NavButton.svelte'; import NavButton from './NavButton.svelte';
import ECSESS from 'assets/ECSESS.png'; import ECSESS from 'assets/ECSESS.png';
import { Menu } from '@lucide/svelte';
import { slide } from 'svelte/transition';
let menuHidden = $state(true);
</script> </script>
<nav <nav class="bg-ecsess-black text-ecsess-200 sticky w-screen py-1">
class="bg-ecsess-black text-ecsess-200 mx-auto flex min-w-fit flex-wrap items-center justify-center px-4 pt-2" <div class="block md:hidden">
> <div class="mx-4 flex items-center-safe justify-between">
<a href="/">
<img src={ECSESS} alt="ECSESS Logo" class="w-20 p-2" /> <img src={ECSESS} alt="ECSESS Logo" class="w-20 p-2" />
</a>
<button
type="button"
class="bg-ecsess-black-hover hover:bg-ecsess-800 grid size-10 place-items-center rounded-lg transition-colors ease-in-out active:bg-green-900"
onclick={() => {
menuHidden = !menuHidden;
}}
>
<Menu class="size-6 transition-transform duration-300 ease-in-out" />
</button>
</div>
{#if !menuHidden}
<div class="flex flex-col place-items-center gap-1" transition:slide>
<NavButton href="/">Home</NavButton> <NavButton href="/">Home</NavButton>
<NavButton href="/council">Meet the council</NavButton> <NavButton href="/council">Meet the council</NavButton>
<NavButton href="/events">Events</NavButton> <NavButton href="/events">Events</NavButton>
<NavButton href="/resources">Resources</NavButton> <NavButton href="/resources">Resources</NavButton>
<NavButton href="/join">Join ECSESS</NavButton> <NavButton href="/join">Join ECSESS</NavButton>
</div>
{/if}
</div>
<div class="hidden md:block">
<div class="flex place-content-center items-end">
<a href="/">
<img src={ECSESS} alt="ECSESS Logo" class="h-12 p-2" />
</a>
<NavButton href="/">Home</NavButton>
<NavButton href="/council">Meet the council</NavButton>
<NavButton href="/events">Events</NavButton>
<NavButton href="/resources">Resources</NavButton>
<NavButton href="/join">Join ECSESS</NavButton>
</div>
</div>
</nav> </nav>

View File

@@ -20,21 +20,20 @@
}); });
</script> </script>
<div class="grid grid-cols-1 md:grid-cols-3 lg:grid-cols-5 gap-2 place-self-center place-content-center"> <div class="grid grid-cols-1 md:grid-cols-3 lg:grid-cols-5 gap-2">
{#each ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'] as day} {#each ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'] as day}
<div> <div class="items-stretch justify-self-center min-w-[80%] max-w-[16rem] md:min-w-[90%] md:max-w-[20rem]">
<p class="text-center text-xl">{day}</p> <p class="text-center text-xl">{day}</p>
{#each sortedOHs.filter((OH) => OH.day == day) as OH} {#each sortedOHs.filter((OH) => OH.day == day) as OH}
<div <div
class="bg-ecsess-200 text-ecsess-black m-2 grid h-28 lg:h-36 max-w-md class="bg-ecsess-200 text-ecsess-black m-2 grid h-28 lg:h-36 grid-cols-1 grid-rows-[2fr_4fr_3fr]
min-w-50 grid-cols-1 grid-rows-[2fr_4fr_3fr]
place-content-center rounded-xl p-3 text-center" place-content-center rounded-xl p-3 text-center"
> >
<p class="border-b-ecsess-600 md:text-md border-b-2 text-base lg:text-lg"> <p class="border-b-ecsess-600 md:text-md border-b-2 text-base lg:text-lg">
{OH.startTime} - {OH.endTime} {OH.startTime} - {OH.endTime}
</p> </p>
<p class="text-ecsess-800 place-self-center font-extrabold text-lg md:text-xl lg:text-2xl"> <p class="text-ecsess-800 place-self-center font-extrabold text-lg md:text-xl lg:text-xl">
{OH.member.name.split(' ')[0]} {OH.member.name.split(' ')[0]}
</p> </p>
<p class="text-sm italic lg:text-base">{OH.member.position}</p> <p class="text-sm italic lg:text-base">{OH.member.position}</p>

View File

@@ -2,9 +2,7 @@
import '../app.css'; import '../app.css';
import Navbar from 'components/NavBar.svelte'; import Navbar from 'components/NavBar.svelte';
import Footer from 'components/Footer.svelte'; import Footer from 'components/Footer.svelte';
import { injectAnalytics } from '@vercel/analytics/sveltekit';
injectAnalytics({ mode: 'auto' });
let { children } = $props(); let { children } = $props();
</script> </script>

View File

@@ -4,6 +4,7 @@
import RichText from 'components/RichText.svelte'; import RichText from 'components/RichText.svelte';
import OhSchedule from 'components/OHSchedule.svelte'; import OhSchedule from 'components/OHSchedule.svelte';
import Link from 'components/Link.svelte'; import Link from 'components/Link.svelte';
import { fade } from 'svelte/transition';
/** loading things from the server side */ /** loading things from the server side */
let { data } = $props(); let { data } = $props();
@@ -17,10 +18,14 @@
<!-- ECSESS Introduction --> <!-- ECSESS Introduction -->
<Section> <Section>
<div class="place-self-center-safe md:grid md:gap-6 lg:grid-cols-3"> <div class="place-self-center md:grid md:grid-cols-1 md:gap-6 lg:grid-cols-3">
<div class="m-8 w-full place-self-center md:place-content-around lg:col-span-1"> <div class="place-self-center md:place-content-around lg:col-span-1 lg:m-8">
<div class="flex h-1/2 flex-col items-center justify-center text-center"> <div class="flex h-1/2 flex-col place-content-center text-center">
<p class="page-title">What is ECSESS?</p> <p>
{#each 'We are ECSESS!' as char, i}
<span class="page-title" in:fade|global={{ delay: 200 + i * 100, duration: 800 }}>{char}</span>
{/each}
</p>
<div class="p-4"> <div class="p-4">
<RichText value={data.description} /> <RichText value={data.description} />
</div> </div>
@@ -35,7 +40,7 @@
</div> </div>
</div> </div>
</div> </div>
<div class="m-4 place-content-around lg:col-span-2 lg:mx-12 lg:my-0"> <div class="m-2 place-content-around lg:col-span-2 lg:mx-12 lg:my-0">
<img <img
src={data.councilPhoto} src={data.councilPhoto}
alt="ECSESS Council" alt="ECSESS Council"

View File

@@ -3,7 +3,8 @@
import Section from 'components/Section.svelte'; import Section from 'components/Section.svelte';
import CardCouncil from 'components/CouncilCard.svelte'; import CardCouncil from 'components/CouncilCard.svelte';
import type { CouncilMember } from '$lib/schemas'; import type { CouncilMember } from '$lib/schemas';
import { fly, slide } from 'svelte/transition'; import { fly } from 'svelte/transition';
import Button from 'components/Button.svelte';
let { data } = $props(); let { data } = $props();
@@ -32,7 +33,6 @@
}); });
let selectedMember = $state<CouncilMember | null>(null); let selectedMember = $state<CouncilMember | null>(null);
function handleViewProfile(member: CouncilMember) { function handleViewProfile(member: CouncilMember) {
selectedMember = member; selectedMember = member;
} }
@@ -40,12 +40,13 @@
<title> ECSESS council </title> <title> ECSESS council </title>
<Section> <Section>
<div class="flex flex-col place-items-center">
<p class="page-title">Meet the council!</p> <p class="page-title">Meet the council!</p>
<div>
<img <img
src={data.councilGoofyPic.url} src={data.councilGoofyPic.url}
alt="ECSESS Council, but we are goofy" alt="ECSESS Council, but we are goofy"
class="ring-ecsess-400 shadow-ecsess-black mb-8 place-self-center rounded-lg shadow-2xl ring-4 lg:w-[90%]" class="ring-ecsess-400 shadow-ecsess-black mb-8 rounded-lg shadow-2xl ring-4 lg:w-[90%]"
transition:fly transition:fly
/> />
</div> </div>
@@ -61,13 +62,13 @@
/> />
</div> </div>
<div class="flex flex-col justify-center"> <div class="grid place-items-center">
<h2 <h2
class="border-b-ecsess-200 w-full place-self-center-safe border-b-2 border-dashed md:w-1/2 lg:w-1/3" class="border-b-ecsess-200 w-full place-self-center-safe border-b-2 border-dashed md:w-1/2 lg:w-1/3"
> >
Vice Presidents Vice Presidents
</h2> </h2>
<div class="flex flex-row flex-wrap justify-baseline gap-10 p-4 align-middle md:justify-center"> <div class="grid gap-2 py-8 md:grid-cols-2 lg:grid-cols-3">
{#each vps as vp} {#each vps as vp}
<CardCouncil <CardCouncil
name={vp.name} name={vp.name}
@@ -77,13 +78,12 @@
/> />
{/each} {/each}
</div> </div>
<h2 <h2
class="border-b-ecsess-200 w-full place-self-center-safe border-b-2 border-dashed md:w-1/2 lg:w-1/3" class="border-b-ecsess-200 w-full place-self-center-safe border-b-2 border-dashed md:w-1/2 lg:w-1/3"
> >
Year Representative Year Representative
</h2> </h2>
<div class="flex flex-row flex-wrap justify-baseline gap-10 p-4 align-middle md:justify-center"> <div class="grid gap-2 py-8 md:grid-cols-2 lg:grid-cols-3">
{#each ureps as urep} {#each ureps as urep}
<CardCouncil <CardCouncil
name={urep.name} name={urep.name}
@@ -94,13 +94,8 @@
{/each} {/each}
</div> </div>
</div> </div>
<!-- svelte-ignore a11y_no_static_element_interactions -->
{#if selectedMember} {#if selectedMember}
<!-- svelte-ignore a11y_click_events_have_key_events --> <div class="fixed inset-0 z-10 flex flex-col items-center justify-center bg-black/70">
<div
class="fixed inset-0 z-50 flex items-center justify-center bg-black/60"
onclick={() => (selectedMember = null)}
>
<CouncilCardPopUp <CouncilCardPopUp
name={selectedMember.name} name={selectedMember.name}
position={selectedMember.position} position={selectedMember.position}
@@ -109,6 +104,9 @@
yearProgram={selectedMember.yearProgram} yearProgram={selectedMember.yearProgram}
image={selectedMember.image} image={selectedMember.image}
/> />
<div transition:fly>
<Button onclick={() => (selectedMember = null)}>Close</Button>
</div>
</div> </div>
{/if} {/if}
</Section> </Section>