feat(scheduling,admin,today): week-range queries, file size limits, mobile nav UX

- Expand exceptional application query to Monday of start week
- Add 20MB file size limit with visual feedback in ImageUpload
- Reorder admin nav links, add burger badge, slide transition + backdrop
- Fetch week-range working/available hours, add closing time indicator
- Skip lunch protection for days <= 5h via shouldApplyLunchProtection
- Extract formatDateISO to shared utils
This commit is contained in:
2026-06-03 10:22:16 +01:00
parent b1847b4cfc
commit 169d7dc6e3
6 changed files with 150 additions and 27 deletions
@@ -1,5 +1,6 @@
<script lang="ts">
import { onMount, onDestroy } from 'svelte';
import { slide } from 'svelte/transition';
import { navigating, page } from '$app/stores';
import { goto } from '$app/navigation';
import { authStore } from '$lib/stores/auth.svelte';
@@ -9,13 +10,13 @@
// Centralized link definition
const links = [
{ href: '/', label: 'Home', showWhen: 'non-admin', width: 'w-12' },
{ href: '/today', label: 'Today', showWhen: 'admin', width: 'w-28' },
{ href: '/admin/schedule', label: 'Schedule', showWhen: 'admin', width: 'w-20' },
{ href: '/prices', label: 'Price List', showWhen: 'guest', width: 'w-20' },
{ href: '/schedule', label: 'My Schedule', showWhen: 'auth-not-admin', width: 'w-24' },
{ href: '/book', label: 'Book an appointment', showWhen: 'non-admin', width: 'w-36' },
{ href: '/portfolio', label: 'Portfolio', showWhen: 'always', width: 'w-20' },
{ href: '/admin', label: 'Admin Dashboard', showWhen: 'admin', width: 'w-28' },
{ href: '/today', label: 'Today', showWhen: 'admin', width: 'w-28' },
{ href: '/admin/schedule', label: 'Schedule', showWhen: 'admin', width: 'w-20' },
{ href: '/contact', label: 'Contact', showWhen: 'non-admin', width: 'w-16' },
{ href: '/account', label: 'My Account', showWhen: 'auth', width: 'w-24' }
];
@@ -178,7 +179,7 @@
<!-- Mobile: Burger -->
<div class="flex items-center md:hidden">
<button onclick={toggleMenu} class="focus:outline-none" aria-label="Toggle menu">
<button onclick={toggleMenu} class="relative focus:outline-none" aria-label="Toggle menu">
<svg class="h-6 w-6 text-gray-700" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path
stroke-linecap="round"
@@ -187,14 +188,31 @@
d="M4 6h16M4 12h16M4 18h16"
/>
</svg>
{#if unreadCount > 0 && !mobileMenuOpen}
<span
class="absolute -top-1 -right-1.5 flex h-4 w-4 items-center justify-center rounded-full bg-red-500 text-[10px] font-bold text-white"
>
{unreadCount > 9 ? '9+' : unreadCount}
</span>
{/if}
</button>
</div>
</div>
</div>
{#if mobileMenuOpen}
<div
class="fixed inset-0 top-16 bg-black/30 backdrop-blur-[1px] md:hidden"
onclick={toggleMenu}
></div>
{/if}
<!-- Mobile Menu -->
{#if mobileMenuOpen}
<div class="border-b border-gray-200 bg-background md:hidden">
<div
transition:slide={{ duration: 100 }}
class="relative z-50 border-b border-gray-200 bg-background md:hidden"
>
<div class="space-y-1 px-2 pt-2 pb-3">
{#each links as link}
{#if canShow(link)}