Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 34 additions & 14 deletions src/components/layout/NavBar.svelte
Original file line number Diff line number Diff line change
@@ -1,19 +1,40 @@
<script>
import NavButton from './NavButton.svelte';
import NavExpansion from './NavExpansion.svelte';
import NavMobileExpansion from './NavMobileExpansion.svelte';
import ECSESS from 'assets/ECSESS.png';
import { Menu } from '@lucide/svelte';
import { slide } from 'svelte/transition';

let menuHidden = $state(true);

const teamItems = [
{ href: '/socialcom', label: 'Social Committee' },
{ href: '/externalcom', label: 'External Committee' },
{ href: '/devteam', label: 'Dev Team' },
{ href: '/bits', label: 'ECSESS Bits' }
];

const sponsorItems = [
{ href: '/sponsor', label: 'Package' },
{ href: '/sponsorCal', label: 'Sponsor Calculator' }
];

const resourcesItems = [
{ href: '/information', label: 'ECSESS Information' },
{ href: '/academic', label: 'Academic' },
{ href: '/resources', label: 'Extra Resources' }
];

const announcementIntro = 'ECSESS Election: Voting period is happening! Vote now: ';
const announcementLinkUrl = 'https://ssmu.simplyvoting.com';
const announcementLinkText = 'ssmu.simplyvoting.com';
</script>

<div class="sticky top-0 z-40 w-full">
<nav class="bg-ecsess-black text-ecsess-100 w-full py-1">
<nav class="bg-ecsess-black text-ecsess-100 relative w-full py-1">
<!-- Small screens -->
<div class="block md:hidden">
<div class="block lg:hidden">
<div class="mx-4 flex items-center-safe justify-between">
<a href="/">
<img src={ECSESS} alt="ECSESS Logo" class="w-20 p-2" />
Expand All @@ -22,9 +43,7 @@
<button
type="button"
class="bg-ecsess-black-hover hover:bg-ecsess-800 active:bg-ecsess-900 grid size-10 place-items-center rounded-md transition-colors ease-in-out"
onclick={() => {
menuHidden = !menuHidden;
}}
onclick={() => { menuHidden = !menuHidden; }}
>
<Menu class="size-6 transition-transform duration-300 ease-in-out" />
</button>
Expand All @@ -35,31 +54,32 @@
class="bg-ecsess-900 border-ecsess-700 mx-2 mb-2 flex w-auto flex-col gap-1 rounded-lg border-2 px-2 py-2 shadow-lg"
transition:slide
>
<NavButton href="/">Home</NavButton>
<NavButton href="/council">Meet the council</NavButton>
<NavButton href="/events">Events</NavButton>
<NavButton href="/resources">Resources</NavButton>
<NavButton href="/devteam">Dev Team</NavButton>
<NavButton href="/council">Meet the Council</NavButton>
<NavButton href="/join">Join ECSESS</NavButton>
<NavMobileExpansion label="SubTeam" items={teamItems} />
<NavMobileExpansion label="Sponsor" items={sponsorItems} />
<NavMobileExpansion label="Resources" items={resourcesItems} />
</div>
{/if}
</div>

<!-- Medium and larger screens -->
<div class="hidden md:block">
<div class="hidden lg: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="/devteam">Dev Team</NavButton>
<NavButton href="/council">Meet the Council</NavButton>
<NavExpansion label="SubTeam" items={teamItems} />
<NavButton href="/join">Join ECSESS</NavButton>
<NavExpansion label="Sponsor" items={sponsorItems} />
<NavExpansion label="Resources" items={resourcesItems} />
</div>
</div>
</nav>

<!-- Small announcement underneath navbar -->
<div class="border-ecsess-black bg-ecsess-800 border-b px-4 py-2 shadow-sm" role="alert">
<p class="text-ecsess-100 text-center text-sm font-medium md:text-base">
Expand Down
59 changes: 59 additions & 0 deletions src/components/layout/NavExpansion.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<script lang="ts">
import { page } from '$app/state';
import { ChevronDown } from '@lucide/svelte';
import { fly } from 'svelte/transition';

interface NavItem {
href: string;
label: string;
}

let { label, items }: { label: string; items: NavItem[] } = $props();

let open = $state(false);
let containerEl = $state<HTMLDivElement | null>(null);

const isActive = $derived(items.some((item: NavItem) => page.url.pathname === item.href));

function handleOutsideClick(e: MouseEvent) {
if (containerEl && !containerEl.contains(e.target as Node)) {
open = false;
}
}
</script>

<svelte:document onclick={handleOutsideClick} />

<div class="mx-1" bind:this={containerEl}>
<button
type="button"
onclick={() => (open = !open)}
class="hover:text-ecsess-100 hover:border-ecsess-100 text-ecsess-200 active:text-ecsess-500 active:border-ecsess-500
mx-0.5 flex items-center gap-1 rounded-none border-b-4 px-6 py-2 font-semibold
transition-all hover:cursor-pointer active:scale-99
{isActive ? 'border-ecsess-300' : 'border-transparent'}"
>
{label}
<ChevronDown
class="size-4 transition-transform duration-200 ease-in-out {open ? 'rotate-180' : ''}"
/>
</button>

{#if open}
<div
class="bg-ecsess-900 border-ecsess-700 absolute top-full left-0 right-0 z-50 flex w-full justify-center gap-2 border-y-2 px-8 py-3 shadow-lg"
transition:fly={{ y: -6, duration: 150 }}
>
{#each items as item}
<a
href={item.href}
onclick={() => (open = false)}
class="hover:bg-ecsess-800 text-ecsess-200 hover:text-ecsess-100 rounded-md px-6 py-2.5 text-sm font-semibold transition-colors
{page.url.pathname === item.href ? 'text-ecsess-100 bg-ecsess-800' : ''}"
>
{item.label}
</a>
{/each}
</div>
{/if}
</div>
33 changes: 33 additions & 0 deletions src/components/layout/NavMobileExpansion.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<script lang="ts">
import NavButton from './NavButton.svelte';
import { ChevronDown } from '@lucide/svelte';
import { slide } from 'svelte/transition';

interface NavItem {
href: string;
label: string;
}

let { label, items }: { label: string; items: NavItem[] } = $props();

let open = $state(false);
</script>

<button
type="button"
class="hover:text-ecsess-100 hover:bg-ecsess-800 text-ecsess-200 flex w-full items-center justify-center rounded-md px-6 py-2 font-semibold transition-colors hover:cursor-pointer"
onclick={() => (open = !open)}
>
{label}
<ChevronDown
class="size-4 transition-transform duration-200 ease-in-out {open ? 'rotate-180' : ''}"
/>
</button>

{#if open}
<div class="border-ecsess-700 ml-3 flex flex-col gap-1 border-l-2 pl-2" transition:slide>
{#each items as item}
<NavButton href={item.href}>{item.label}</NavButton>
{/each}
</div>
{/if}
Loading