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:
@@ -14,6 +14,21 @@
|
||||
let uploadStatus = $state<Record<string, string>>({});
|
||||
let uploadResults = $state<{ name: string; url?: string; error?: string }[]>([]);
|
||||
|
||||
const MAX_FILE_SIZE = 20 * 1024 * 1024; // 20MB
|
||||
|
||||
function formatFileSize(bytes: number): string {
|
||||
if (bytes >= 1024 * 1024) {
|
||||
return (bytes / (1024 * 1024)).toFixed(1) + ' MB';
|
||||
}
|
||||
return (bytes / 1024).toFixed(1) + ' KB';
|
||||
}
|
||||
|
||||
function isFileTooBig(file: File): boolean {
|
||||
return file.size > MAX_FILE_SIZE;
|
||||
}
|
||||
|
||||
let hasOversizedFiles = $derived(uploadFiles.some(isFileTooBig));
|
||||
|
||||
function handleFilesDropped(files: File[]) {
|
||||
uploadFiles = files;
|
||||
generatePreviews(files);
|
||||
@@ -505,7 +520,7 @@
|
||||
<div class="flex flex-col items-start justify-between gap-2 sm:flex-row sm:items-center">
|
||||
<div>
|
||||
<Card.Title>Drop or Select Files</Card.Title>
|
||||
<Card.Description>Supported: JPEG, PNG, WebP, and other image formats</Card.Description>
|
||||
<Card.Description>HEIC, AVIF, WebP, PNG, JPEG and more. Maximum 20MB per file</Card.Description>
|
||||
</div>
|
||||
</div>
|
||||
</Card.Header>
|
||||
@@ -529,7 +544,7 @@
|
||||
<line x1="12" y1="3" x2="12" y2="15" />
|
||||
</svg>
|
||||
<p class="text-sm font-medium text-gray-700">Drop images here or click to browse</p>
|
||||
<p class="mt-1 text-xs text-gray-500">Supports AVIF, PNG, JPG, WebP and other formats</p>
|
||||
<p class="mt-1 text-xs text-gray-500">HEIC, AVIF, WebP, PNG, JPEG, GIF & more — max 20MB per file</p>
|
||||
</div>
|
||||
</FileDropZone>
|
||||
|
||||
@@ -555,8 +570,11 @@
|
||||
<div class="space-y-2">
|
||||
{#each uploadFiles as f (f.name)}
|
||||
{@const preview = filePreviews.find((p) => p.file === f)?.preview}
|
||||
{@const oversized = isFileTooBig(f)}
|
||||
<div
|
||||
class="flex items-center justify-between rounded-lg border border-gray-200 bg-white p-3 sm:p-4"
|
||||
class="flex items-center justify-between rounded-lg border bg-white p-3 sm:p-4"
|
||||
class:border-red-300={oversized}
|
||||
class:border-gray-200={!oversized}
|
||||
>
|
||||
<div class="flex min-w-0 flex-1 items-center gap-3">
|
||||
<div class="flex-shrink-0">
|
||||
@@ -580,9 +598,16 @@
|
||||
{/if}
|
||||
</div>
|
||||
<div class="min-w-0 flex-1">
|
||||
<p class="truncate text-sm font-medium text-gray-900">{f.name}</p>
|
||||
<p class="truncate text-sm font-medium" class:text-gray-900={!oversized} class:text-red-900={oversized}>
|
||||
{f.name}
|
||||
</p>
|
||||
<div class="flex items-center gap-2">
|
||||
<p class="text-xs text-gray-500">{(f.size / 1024).toFixed(1)} KB</p>
|
||||
<p class="text-xs" class:text-gray-500={!oversized} class:text-red-600={oversized}>
|
||||
{formatFileSize(f.size)}
|
||||
{#if oversized}
|
||||
— exceeds 20MB limit
|
||||
{/if}
|
||||
</p>
|
||||
{#if uploading && uploadStatus[f.name]}
|
||||
<span
|
||||
class="inline-flex items-center gap-1.5 text-xs font-medium text-blue-600"
|
||||
@@ -625,10 +650,10 @@
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<!-- Upload Results Section -->
|
||||
<!-- Upload Results Section -->
|
||||
{#if uploadResults.length > 0}
|
||||
<div class="border-t pt-6">
|
||||
<h3 class="mb-4 font-semibold text-gray-900">Upload Results</h3>
|
||||
@@ -780,7 +805,7 @@
|
||||
<!-- Action Buttons -->
|
||||
<div class="border-t pt-6">
|
||||
<div class="flex justify-end">
|
||||
<Button onclick={uploadOneOrMany} disabled={!uploadFiles.length || uploading}>
|
||||
<Button onclick={uploadOneOrMany} disabled={!uploadFiles.length || uploading || hasOversizedFiles}>
|
||||
{#if uploading}
|
||||
<svg
|
||||
class="mr-2 h-4 w-4 animate-spin"
|
||||
|
||||
Reference in New Issue
Block a user