fix: replace {__} workaround with clean range() helper in Svelte templates
This commit is contained in:
@@ -5,6 +5,7 @@
|
|||||||
import { CalendarDate, getLocalTimeZone, type DateValue } from '@internationalized/date';
|
import { CalendarDate, getLocalTimeZone, type DateValue } from '@internationalized/date';
|
||||||
import { isValidUKPhone, toE164UK } from '$lib/utils/phone';
|
import { isValidUKPhone, toE164UK } from '$lib/utils/phone';
|
||||||
import { formatUserName } from '$lib/utils/nameDisplay';
|
import { formatUserName } from '$lib/utils/nameDisplay';
|
||||||
|
import { range } from '$lib/utils/format';
|
||||||
|
|
||||||
// UI Components
|
// UI Components
|
||||||
import * as Modal from '$lib/components/ui/dialog';
|
import * as Modal from '$lib/components/ui/dialog';
|
||||||
@@ -1145,10 +1146,8 @@
|
|||||||
<div class="max-h-[300px] overflow-y-auto rounded-md border border-gray-200">
|
<div class="max-h-[300px] overflow-y-auto rounded-md border border-gray-200">
|
||||||
{#if loadingUsers}
|
{#if loadingUsers}
|
||||||
<div class="space-y-2 p-2">
|
<div class="space-y-2 p-2">
|
||||||
{#each Array(3) as __, i (i)}
|
{#each range(3) as i (i)}
|
||||||
{__}
|
|
||||||
<Skeleton class="h-10 w-full" />
|
<Skeleton class="h-10 w-full" />
|
||||||
{__}
|
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
{:else if users.length === 0}
|
{:else if users.length === 0}
|
||||||
@@ -1259,10 +1258,8 @@
|
|||||||
<Card.Content class="space-y-4">
|
<Card.Content class="space-y-4">
|
||||||
{#if loadingServices}
|
{#if loadingServices}
|
||||||
<div class="grid grid-cols-1 gap-4 md:grid-cols-2">
|
<div class="grid grid-cols-1 gap-4 md:grid-cols-2">
|
||||||
{#each Array(4) as __, i (i)}
|
{#each range(4) as i (i)}
|
||||||
{__}
|
|
||||||
<Skeleton class="h-28 w-full" />
|
<Skeleton class="h-28 w-full" />
|
||||||
{__}
|
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
{:else if services.length === 0}
|
{:else if services.length === 0}
|
||||||
@@ -1294,10 +1291,8 @@
|
|||||||
</div>
|
</div>
|
||||||
{#if loadingCustomServices}
|
{#if loadingCustomServices}
|
||||||
<div class="space-y-2">
|
<div class="space-y-2">
|
||||||
{#each Array(3) as __, i (i)}
|
{#each range(3) as i (i)}
|
||||||
{__}
|
|
||||||
<Skeleton class="h-10 w-full" />
|
<Skeleton class="h-10 w-full" />
|
||||||
{__}
|
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
{:else if customServices.length > 0}
|
{:else if customServices.length > 0}
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
import type { BusinessSettings } from '$lib/types/settings';
|
import type { BusinessSettings } from '$lib/types/settings';
|
||||||
import { isValidUKPhone, toE164UK, normalisePhoneInput } from '$lib/utils/phone';
|
import { isValidUKPhone, toE164UK, normalisePhoneInput } from '$lib/utils/phone';
|
||||||
import { isValidEmail, normalizeEmail } from '$lib/utils/email';
|
import { isValidEmail, normalizeEmail } from '$lib/utils/email';
|
||||||
|
import { range } from '$lib/utils/format';
|
||||||
|
|
||||||
let settings = $state<BusinessSettings | null>(null);
|
let settings = $state<BusinessSettings | null>(null);
|
||||||
let loading = $state(true);
|
let loading = $state(true);
|
||||||
@@ -286,8 +287,7 @@
|
|||||||
<Card.Content>
|
<Card.Content>
|
||||||
{#if loading}
|
{#if loading}
|
||||||
<div class="space-y-4">
|
<div class="space-y-4">
|
||||||
{#each Array(3) as __, i (i)}
|
{#each range(3) as i (i)}
|
||||||
{__}
|
|
||||||
<div class="space-y-2">
|
<div class="space-y-2">
|
||||||
<Skeleton class="h-4 w-32" />
|
<Skeleton class="h-4 w-32" />
|
||||||
<Skeleton class="h-5 w-full" />
|
<Skeleton class="h-5 w-full" />
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
import { apiFetch } from '$lib/utils/api';
|
import { apiFetch } from '$lib/utils/api';
|
||||||
import { toast } from 'svelte-sonner';
|
import { toast } from 'svelte-sonner';
|
||||||
import { sanitizeText } from '$lib/utils/toast-safe';
|
import { sanitizeText } from '$lib/utils/toast-safe';
|
||||||
|
import { range } from '$lib/utils/format';
|
||||||
import { Button } from '$lib/components/ui/button';
|
import { Button } from '$lib/components/ui/button';
|
||||||
import * as Card from '$lib/components/ui/card';
|
import * as Card from '$lib/components/ui/card';
|
||||||
import { Input } from '$lib/components/ui/input';
|
import { Input } from '$lib/components/ui/input';
|
||||||
@@ -283,8 +284,7 @@
|
|||||||
|
|
||||||
{#if loading}
|
{#if loading}
|
||||||
<div class="space-y-3">
|
<div class="space-y-3">
|
||||||
{#each Array(3) as __, i (i)}
|
{#each range(3) as i (i)}
|
||||||
{__}
|
|
||||||
<Skeleton class="h-12 w-full" />
|
<Skeleton class="h-12 w-full" />
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { SvelteDate } from 'svelte/reactivity';
|
import { SvelteDate } from 'svelte/reactivity';
|
||||||
import { apiFetch } from '$lib/utils/api';
|
import { apiFetch } from '$lib/utils/api';
|
||||||
|
import { range } from '$lib/utils/format';
|
||||||
import { toast } from 'svelte-sonner';
|
import { toast } from 'svelte-sonner';
|
||||||
import { Button } from '$lib/components/ui/button';
|
import { Button } from '$lib/components/ui/button';
|
||||||
import * as Card from '$lib/components/ui/card';
|
import * as Card from '$lib/components/ui/card';
|
||||||
@@ -275,8 +276,7 @@
|
|||||||
<Card.Content>
|
<Card.Content>
|
||||||
{#if loading}
|
{#if loading}
|
||||||
<div class="space-y-3">
|
<div class="space-y-3">
|
||||||
{#each Array(3) as __, i (i)}
|
{#each range(3) as i (i)}
|
||||||
{__}
|
|
||||||
<Skeleton class="h-16 w-full" />
|
<Skeleton class="h-16 w-full" />
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
import { EmailInput } from '$lib/components/ui/email-input';
|
import { EmailInput } from '$lib/components/ui/email-input';
|
||||||
import * as Modal from '$lib/components/ui/dialog';
|
import * as Modal from '$lib/components/ui/dialog';
|
||||||
import { Skeleton } from '$lib/components/ui/skeleton';
|
import { Skeleton } from '$lib/components/ui/skeleton';
|
||||||
|
import { range } from '$lib/utils/format';
|
||||||
import { formatUserName } from '$lib/utils/nameDisplay';
|
import { formatUserName } from '$lib/utils/nameDisplay';
|
||||||
import { SvelteDate, SvelteURLSearchParams } from 'svelte/reactivity';
|
import { SvelteDate, SvelteURLSearchParams } from 'svelte/reactivity';
|
||||||
|
|
||||||
@@ -1284,8 +1285,7 @@
|
|||||||
<!-- Mobile view - Balances -->
|
<!-- Mobile view - Balances -->
|
||||||
<div class="grid gap-4 md:hidden">
|
<div class="grid gap-4 md:hidden">
|
||||||
{#if loading}
|
{#if loading}
|
||||||
{#each Array(2) as __, i (i)}
|
{#each range(2) as i (i)}
|
||||||
{__}
|
|
||||||
<div class="space-y-3 rounded-lg border p-4">
|
<div class="space-y-3 rounded-lg border p-4">
|
||||||
<Skeleton class="h-4 w-36" />
|
<Skeleton class="h-4 w-36" />
|
||||||
<Skeleton class="h-4 w-full" />
|
<Skeleton class="h-4 w-full" />
|
||||||
@@ -1412,8 +1412,7 @@
|
|||||||
<!-- Mobile view - Expired Balances -->
|
<!-- Mobile view - Expired Balances -->
|
||||||
<div class="grid gap-4 md:hidden">
|
<div class="grid gap-4 md:hidden">
|
||||||
{#if loadingExpired}
|
{#if loadingExpired}
|
||||||
{#each Array(2) as __, i (i)}
|
{#each range(2) as i (i)}
|
||||||
{__}
|
|
||||||
<div class="space-y-3 rounded-lg border p-4">
|
<div class="space-y-3 rounded-lg border p-4">
|
||||||
<Skeleton class="h-4 w-36" />
|
<Skeleton class="h-4 w-36" />
|
||||||
<Skeleton class="h-4 w-full" />
|
<Skeleton class="h-4 w-full" />
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
import { toast } from 'svelte-sonner';
|
import { toast } from 'svelte-sonner';
|
||||||
import { sanitizeText } from '$lib/utils/toast-safe';
|
import { sanitizeText } from '$lib/utils/toast-safe';
|
||||||
import { apiFetch } from '$lib/utils/api';
|
import { apiFetch } from '$lib/utils/api';
|
||||||
|
import { range } from '$lib/utils/format';
|
||||||
|
|
||||||
// shadcn-svelte components
|
// shadcn-svelte components
|
||||||
import { Button } from '$lib/components/ui/button';
|
import { Button } from '$lib/components/ui/button';
|
||||||
@@ -342,8 +343,7 @@
|
|||||||
<Card.Content class="space-y-4">
|
<Card.Content class="space-y-4">
|
||||||
{#if exceptionGroupsLoading}
|
{#if exceptionGroupsLoading}
|
||||||
<div class="grid grid-cols-1 gap-4 md:grid-cols-2">
|
<div class="grid grid-cols-1 gap-4 md:grid-cols-2">
|
||||||
{#each Array(2) as __, i (i)}
|
{#each range(2) as i (i)}
|
||||||
{__}
|
|
||||||
<Skeleton class="h-32 w-full" />
|
<Skeleton class="h-32 w-full" />
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
import { Input } from '$lib/components/ui/input';
|
import { Input } from '$lib/components/ui/input';
|
||||||
import { Checkbox } from '$lib/components/ui/checkbox';
|
import { Checkbox } from '$lib/components/ui/checkbox';
|
||||||
import { Skeleton } from '$lib/components/ui/skeleton';
|
import { Skeleton } from '$lib/components/ui/skeleton';
|
||||||
|
import { range } from '$lib/utils/format';
|
||||||
import * as Modal from '$lib/components/ui/dialog';
|
import * as Modal from '$lib/components/ui/dialog';
|
||||||
import { SvelteMap } from 'svelte/reactivity';
|
import { SvelteMap } from 'svelte/reactivity';
|
||||||
|
|
||||||
@@ -356,8 +357,7 @@
|
|||||||
|
|
||||||
<div class="space-y-4 md:hidden">
|
<div class="space-y-4 md:hidden">
|
||||||
{#if loading}
|
{#if loading}
|
||||||
{#each Array(2) as __, i (i)}
|
{#each range(2) as i (i)}
|
||||||
{__}
|
|
||||||
<div class="space-y-3 rounded-lg border p-4">
|
<div class="space-y-3 rounded-lg border p-4">
|
||||||
<Skeleton class="h-5 w-32" />
|
<Skeleton class="h-5 w-32" />
|
||||||
<Skeleton class="h-4 w-48" />
|
<Skeleton class="h-4 w-48" />
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { toast } from 'svelte-sonner';
|
import { toast } from 'svelte-sonner';
|
||||||
import { apiFetch } from '$lib/utils/api';
|
import { apiFetch } from '$lib/utils/api';
|
||||||
|
import { range } from '$lib/utils/format';
|
||||||
|
|
||||||
// shadcn-svelte components
|
// shadcn-svelte components
|
||||||
import { Button } from '$lib/components/ui/button';
|
import { Button } from '$lib/components/ui/button';
|
||||||
@@ -462,8 +463,7 @@
|
|||||||
|
|
||||||
<div class="space-y-4 md:hidden">
|
<div class="space-y-4 md:hidden">
|
||||||
{#if servicesLoading}
|
{#if servicesLoading}
|
||||||
{#each Array(3) as __, i (i)}
|
{#each range(3) as i (i)}
|
||||||
{__}
|
|
||||||
<div class="rounded-lg border p-4">
|
<div class="rounded-lg border p-4">
|
||||||
<div class="space-y-3">
|
<div class="space-y-3">
|
||||||
<Skeleton class="h-5 w-32" />
|
<Skeleton class="h-5 w-32" />
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
import { CalendarDate } from '@internationalized/date';
|
import { CalendarDate } from '@internationalized/date';
|
||||||
import { toast } from 'svelte-sonner';
|
import { toast } from 'svelte-sonner';
|
||||||
import { sanitizeText } from '$lib/utils/toast-safe';
|
import { sanitizeText } from '$lib/utils/toast-safe';
|
||||||
import { formatDuration } from '$lib/utils/format';
|
import { formatDuration, range } from '$lib/utils/format';
|
||||||
import { formatUserName } from '$lib/utils/nameDisplay';
|
import { formatUserName } from '$lib/utils/nameDisplay';
|
||||||
import { formatLocalDateTime, parseWallClockDate } from '$lib/utils/timeSlots';
|
import { formatLocalDateTime, parseWallClockDate } from '$lib/utils/timeSlots';
|
||||||
|
|
||||||
@@ -552,8 +552,7 @@
|
|||||||
<Card.Content class="space-y-4">
|
<Card.Content class="space-y-4">
|
||||||
{#if loading}
|
{#if loading}
|
||||||
<div class="space-y-3">
|
<div class="space-y-3">
|
||||||
{#each Array(3) as __, i (i)}
|
{#each range(3) as i (i)}
|
||||||
{__}
|
|
||||||
<Skeleton class="h-16 w-full" />
|
<Skeleton class="h-16 w-full" />
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
@@ -666,8 +665,7 @@
|
|||||||
>
|
>
|
||||||
Prev
|
Prev
|
||||||
</Button>
|
</Button>
|
||||||
{#each Array(totalPages) as __, i (i)}
|
{#each range(totalPages) as i (i)}
|
||||||
{__}
|
|
||||||
<Button
|
<Button
|
||||||
variant={currentPage === i + 1 ? 'default' : 'outline'}
|
variant={currentPage === i + 1 ? 'default' : 'outline'}
|
||||||
size="sm"
|
size="sm"
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
import PatchTestModal from './PatchTestModal.svelte';
|
import PatchTestModal from './PatchTestModal.svelte';
|
||||||
import { formatUserName } from '$lib/utils/nameDisplay';
|
import { formatUserName } from '$lib/utils/nameDisplay';
|
||||||
import { parseWallClockDate } from '$lib/utils/timeSlots';
|
import { parseWallClockDate } from '$lib/utils/timeSlots';
|
||||||
|
import { range } from '$lib/utils/format';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
open: boolean;
|
open: boolean;
|
||||||
@@ -507,8 +508,7 @@
|
|||||||
Customer Relationship
|
Customer Relationship
|
||||||
</h3>
|
</h3>
|
||||||
<div class="space-y-2">
|
<div class="space-y-2">
|
||||||
{#each Array(5) as __, i (i)}
|
{#each range(5) as i (i)}
|
||||||
{__}
|
|
||||||
<div class="h-10 animate-pulse rounded-md bg-gray-200"></div>
|
<div class="h-10 animate-pulse rounded-md bg-gray-200"></div>
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { toast } from 'svelte-sonner';
|
import { toast } from 'svelte-sonner';
|
||||||
import { apiFetch } from '$lib/utils/api';
|
import { apiFetch } from '$lib/utils/api';
|
||||||
|
import { range } from '$lib/utils/format';
|
||||||
import * as Card from '$lib/components/ui/card';
|
import * as Card from '$lib/components/ui/card';
|
||||||
import { Input } from '$lib/components/ui/input';
|
import { Input } from '$lib/components/ui/input';
|
||||||
import { Button } from '$lib/components/ui/button';
|
import { Button } from '$lib/components/ui/button';
|
||||||
@@ -176,8 +177,7 @@
|
|||||||
|
|
||||||
<div class="mt-3 max-h-60 space-y-2 overflow-y-auto">
|
<div class="mt-3 max-h-60 space-y-2 overflow-y-auto">
|
||||||
{#if initialLoad}
|
{#if initialLoad}
|
||||||
{#each Array(3) as __, i (i)}
|
{#each range(3) as i (i)}
|
||||||
{__}
|
|
||||||
<div class="rounded bg-gray-50 p-2">
|
<div class="rounded bg-gray-50 p-2">
|
||||||
<Skeleton class="mb-1 h-4 w-32" />
|
<Skeleton class="mb-1 h-4 w-32" />
|
||||||
<Skeleton class="h-3 w-48" />
|
<Skeleton class="h-3 w-48" />
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
import { isValidUKPhone, toE164UK } from '$lib/utils/phone';
|
import { isValidUKPhone, toE164UK } from '$lib/utils/phone';
|
||||||
import { formatUserName } from '$lib/utils/nameDisplay';
|
import { formatUserName } from '$lib/utils/nameDisplay';
|
||||||
import { formatLocalDateTime } from '$lib/utils/timeSlots';
|
import { formatLocalDateTime } from '$lib/utils/timeSlots';
|
||||||
|
import { range } from '$lib/utils/format';
|
||||||
|
|
||||||
// UI Components
|
// UI Components
|
||||||
import * as Modal from '$lib/components/ui/dialog';
|
import * as Modal from '$lib/components/ui/dialog';
|
||||||
@@ -723,8 +724,7 @@
|
|||||||
<div class="max-h-[300px] overflow-y-auto rounded-md border border-gray-200">
|
<div class="max-h-[300px] overflow-y-auto rounded-md border border-gray-200">
|
||||||
{#if loadingUsers}
|
{#if loadingUsers}
|
||||||
<div class="space-y-2 p-2">
|
<div class="space-y-2 p-2">
|
||||||
{#each Array(3) as __, i (i)}
|
{#each range(3) as i (i)}
|
||||||
{__}
|
|
||||||
<Skeleton class="h-10 w-full" />
|
<Skeleton class="h-10 w-full" />
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
@@ -836,8 +836,7 @@
|
|||||||
<Card.Content class="space-y-4">
|
<Card.Content class="space-y-4">
|
||||||
{#if loadingServices}
|
{#if loadingServices}
|
||||||
<div class="grid grid-cols-1 gap-4 md:grid-cols-2">
|
<div class="grid grid-cols-1 gap-4 md:grid-cols-2">
|
||||||
{#each Array(4) as __, i (i)}
|
{#each range(4) as i (i)}
|
||||||
{__}
|
|
||||||
<Skeleton class="h-28 w-full" />
|
<Skeleton class="h-28 w-full" />
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
@@ -870,8 +869,7 @@
|
|||||||
</div>
|
</div>
|
||||||
{#if loadingCustomServices}
|
{#if loadingCustomServices}
|
||||||
<div class="space-y-2">
|
<div class="space-y-2">
|
||||||
{#each Array(3) as __, i (i)}
|
{#each range(3) as i (i)}
|
||||||
{__}
|
|
||||||
<Skeleton class="h-10 w-full" />
|
<Skeleton class="h-10 w-full" />
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
import { toast } from 'svelte-sonner';
|
import { toast } from 'svelte-sonner';
|
||||||
import { browser } from '$app/environment';
|
import { browser } from '$app/environment';
|
||||||
import { apiFetch } from '$lib/utils/api';
|
import { apiFetch } from '$lib/utils/api';
|
||||||
|
import { range } from '$lib/utils/format';
|
||||||
|
|
||||||
// shadcn-svelte components
|
// shadcn-svelte components
|
||||||
import { Button } from '$lib/components/ui/button';
|
import { Button } from '$lib/components/ui/button';
|
||||||
@@ -569,8 +570,7 @@
|
|||||||
|
|
||||||
<!-- Mobile Skeleton -->
|
<!-- Mobile Skeleton -->
|
||||||
<div class="space-y-3 md:hidden">
|
<div class="space-y-3 md:hidden">
|
||||||
{#each Array(7) as __, i (i)}
|
{#each range(7) as i (i)}
|
||||||
{__}
|
|
||||||
<div class="rounded-lg border p-4">
|
<div class="rounded-lg border p-4">
|
||||||
<div class="mb-3 flex items-center justify-between">
|
<div class="mb-3 flex items-center justify-between">
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
import { Skeleton } from '$lib/components/ui/skeleton';
|
import { Skeleton } from '$lib/components/ui/skeleton';
|
||||||
import ApprovalModal from '$lib/components/admin/ApprovalModal.svelte';
|
import ApprovalModal from '$lib/components/admin/ApprovalModal.svelte';
|
||||||
import EditRequestModal from '$lib/components/admin/EditRequestModal.svelte';
|
import EditRequestModal from '$lib/components/admin/EditRequestModal.svelte';
|
||||||
|
import { range } from '$lib/utils/format';
|
||||||
import { formatUserName } from '$lib/utils/nameDisplay';
|
import { formatUserName } from '$lib/utils/nameDisplay';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
@@ -312,8 +313,7 @@
|
|||||||
<Card.Content>
|
<Card.Content>
|
||||||
{#if loading}
|
{#if loading}
|
||||||
<div class="space-y-3">
|
<div class="space-y-3">
|
||||||
{#each Array(3) as __, i (i)}
|
{#each range(3) as i (i)}
|
||||||
{__}
|
|
||||||
<div class="rounded-lg border p-3">
|
<div class="rounded-lg border p-3">
|
||||||
<div class="flex items-start justify-between">
|
<div class="flex items-start justify-between">
|
||||||
<div class="flex-1 space-y-2">
|
<div class="flex-1 space-y-2">
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
import { toast } from 'svelte-sonner';
|
import { toast } from 'svelte-sonner';
|
||||||
import { sanitizeText } from '$lib/utils/toast-safe';
|
import { sanitizeText } from '$lib/utils/toast-safe';
|
||||||
import { formatUserName } from '$lib/utils/nameDisplay';
|
import { formatUserName } from '$lib/utils/nameDisplay';
|
||||||
|
import { range } from '$lib/utils/format';
|
||||||
import * as Card from '$lib/components/ui/card';
|
import * as Card from '$lib/components/ui/card';
|
||||||
import { Button } from '$lib/components/ui/button';
|
import { Button } from '$lib/components/ui/button';
|
||||||
import { Badge } from '$lib/components/ui/badge';
|
import { Badge } from '$lib/components/ui/badge';
|
||||||
@@ -687,8 +688,7 @@
|
|||||||
<Card.Content>
|
<Card.Content>
|
||||||
{#if loading}
|
{#if loading}
|
||||||
<div class="space-y-3">
|
<div class="space-y-3">
|
||||||
{#each Array(5) as __, i (i)}
|
{#each range(5) as i (i)}
|
||||||
{__}
|
|
||||||
<div class="flex items-center gap-3 rounded-lg border p-3 sm:gap-4">
|
<div class="flex items-center gap-3 rounded-lg border p-3 sm:gap-4">
|
||||||
<Skeleton class="h-4 w-[45px] sm:w-[60px] lg:w-[80px]" />
|
<Skeleton class="h-4 w-[45px] sm:w-[60px] lg:w-[80px]" />
|
||||||
<Skeleton class="h-10 w-1 shrink-0" />
|
<Skeleton class="h-10 w-1 shrink-0" />
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
import { Skeleton } from '$lib/components/ui/skeleton';
|
import { Skeleton } from '$lib/components/ui/skeleton';
|
||||||
import * as Card from '$lib/components/ui/card';
|
import * as Card from '$lib/components/ui/card';
|
||||||
import { formatLocalDateTime } from '$lib/utils/timeSlots';
|
import { formatLocalDateTime } from '$lib/utils/timeSlots';
|
||||||
|
import { range } from '$lib/utils/format';
|
||||||
|
|
||||||
type TodayAppointment = {
|
type TodayAppointment = {
|
||||||
id: string;
|
id: string;
|
||||||
@@ -210,8 +211,7 @@
|
|||||||
<Card.Content>
|
<Card.Content>
|
||||||
{#if loading && !stats}
|
{#if loading && !stats}
|
||||||
<div class="space-y-3">
|
<div class="space-y-3">
|
||||||
{#each Array(6) as __, i (i)}
|
{#each range(6) as i (i)}
|
||||||
{__}
|
|
||||||
<Skeleton class="h-5 w-full" />
|
<Skeleton class="h-5 w-full" />
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -80,3 +80,19 @@ export function calculateAge(dateOfBirth: string | undefined | null): number | n
|
|||||||
}
|
}
|
||||||
return age;
|
return age;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an array of numbers from 0 to n-1.
|
||||||
|
*
|
||||||
|
* Useful for iterating a fixed number of times in Svelte templates:
|
||||||
|
*
|
||||||
|
* {#each range(3) as i}
|
||||||
|
* <div>{i}</div>
|
||||||
|
* {/each}
|
||||||
|
*
|
||||||
|
* Replaces the `{#each Array(3) as _, i (i)}{__}{/each}` workaround pattern
|
||||||
|
* that was needed to suppress eslint unused-variable warnings.
|
||||||
|
*/
|
||||||
|
export function range(n: number): number[] {
|
||||||
|
return Array.from({ length: n }, (_, i) => i);
|
||||||
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
import { apiFetch } from '$lib/utils/api';
|
import { apiFetch } from '$lib/utils/api';
|
||||||
import UserBookingModal from '$lib/components/account/UserBookingModal.svelte';
|
import UserBookingModal from '$lib/components/account/UserBookingModal.svelte';
|
||||||
import { isValidUKPhone, formatPhoneDisplay, toE164UK } from '$lib/utils/phone';
|
import { isValidUKPhone, formatPhoneDisplay, toE164UK } from '$lib/utils/phone';
|
||||||
|
import { range } from '$lib/utils/format';
|
||||||
import { savedCardsStore, type SavedCard } from '$lib/stores/savedCards.svelte';
|
import { savedCardsStore, type SavedCard } from '$lib/stores/savedCards.svelte';
|
||||||
|
|
||||||
// zxcvbn-ts imports
|
// zxcvbn-ts imports
|
||||||
@@ -1284,8 +1285,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<Card.Root>
|
<Card.Root>
|
||||||
<Card.Content class="space-y-4 pt-6">
|
<Card.Content class="space-y-4 pt-6">
|
||||||
{#each Array(5) as __, i (i)}
|
{#each range(5) as i (i)}
|
||||||
{__}
|
|
||||||
<Skeleton class="h-12 w-full" />
|
<Skeleton class="h-12 w-full" />
|
||||||
{/each}
|
{/each}
|
||||||
</Card.Content>
|
</Card.Content>
|
||||||
@@ -1523,9 +1523,8 @@
|
|||||||
</Dialog.Root>
|
</Dialog.Root>
|
||||||
|
|
||||||
{#if loadingUser}
|
{#if loadingUser}
|
||||||
{#each Array(6) as __, i (i)}
|
{#each range(6) as i (i)}
|
||||||
{__}
|
<Skeleton class="h-12 w-full" />
|
||||||
<Skeleton class="h-12 w-full" />
|
|
||||||
{/each}
|
{/each}
|
||||||
{:else if userData}
|
{:else if userData}
|
||||||
<div class="grid gap-4 md:grid-cols-2">
|
<div class="grid gap-4 md:grid-cols-2">
|
||||||
@@ -1723,9 +1722,8 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="grid grid-cols-5 gap-3 sm:grid-cols-10">
|
<div class="grid grid-cols-5 gap-3 sm:grid-cols-10">
|
||||||
{#each Array(10) as __, i (i)}
|
{#each range(10) as i (i)}
|
||||||
{__}
|
{@const slotNum = i + 1}
|
||||||
{@const slotNum = i + 1}
|
|
||||||
{@const rot = ((slotNum * 37 + 13) % 7) - 3}
|
{@const rot = ((slotNum * 37 + 13) % 7) - 3}
|
||||||
{#if slotNum <= (stamps > 0 ? stamps % 10 || 10 : 0)}
|
{#if slotNum <= (stamps > 0 ? stamps % 10 || 10 : 0)}
|
||||||
<div
|
<div
|
||||||
@@ -1797,9 +1795,8 @@
|
|||||||
</Card.Header>
|
</Card.Header>
|
||||||
<Card.Content class="space-y-2">
|
<Card.Content class="space-y-2">
|
||||||
{#if loadingUpcoming}
|
{#if loadingUpcoming}
|
||||||
{#each Array(3) as __, i (i)}
|
{#each range(3) as i (i)}
|
||||||
{__}
|
<Skeleton class="h-16 w-full" />
|
||||||
<Skeleton class="h-16 w-full" />
|
|
||||||
{/each}
|
{/each}
|
||||||
{:else}
|
{:else}
|
||||||
{#each upcomingBookings as b (b.id)}
|
{#each upcomingBookings as b (b.id)}
|
||||||
@@ -1852,9 +1849,8 @@
|
|||||||
</Card.Header>
|
</Card.Header>
|
||||||
<Card.Content class="space-y-2">
|
<Card.Content class="space-y-2">
|
||||||
{#if loadingPast}
|
{#if loadingPast}
|
||||||
{#each Array(5) as __, i (i)}
|
{#each range(5) as i (i)}
|
||||||
{__}
|
<Skeleton class="h-16 w-full" />
|
||||||
<Skeleton class="h-16 w-full" />
|
|
||||||
{/each}
|
{/each}
|
||||||
{:else if pastBookings.length === 0}
|
{:else if pastBookings.length === 0}
|
||||||
<div class="py-4 text-center text-gray-500">No past bookings</div>
|
<div class="py-4 text-center text-gray-500">No past bookings</div>
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
import { apiFetch } from '$lib/utils/api';
|
import { apiFetch } from '$lib/utils/api';
|
||||||
import { Skeleton } from '$lib/components/ui/skeleton';
|
import { Skeleton } from '$lib/components/ui/skeleton';
|
||||||
import { Button } from '$lib/components/ui/button';
|
import { Button } from '$lib/components/ui/button';
|
||||||
|
import { range } from '$lib/utils/format';
|
||||||
import { Checkbox } from '$lib/components/ui/checkbox';
|
import { Checkbox } from '$lib/components/ui/checkbox';
|
||||||
import ApprovalModal from '$lib/components/admin/ApprovalModal.svelte';
|
import ApprovalModal from '$lib/components/admin/ApprovalModal.svelte';
|
||||||
import BookingModal from '$lib/components/admin/BookingModal.svelte';
|
import BookingModal from '$lib/components/admin/BookingModal.svelte';
|
||||||
@@ -367,8 +368,7 @@
|
|||||||
{#if pageState === 'loading'}
|
{#if pageState === 'loading'}
|
||||||
<div class="mx-auto max-w-3xl space-y-4 p-6 pt-24">
|
<div class="mx-auto max-w-3xl space-y-4 p-6 pt-24">
|
||||||
<Skeleton class="h-8 w-48" />
|
<Skeleton class="h-8 w-48" />
|
||||||
{#each Array(5) as __, i (i)}
|
{#each range(5) as i (i)}
|
||||||
{__}
|
|
||||||
<Skeleton class="h-24 w-full" />
|
<Skeleton class="h-24 w-full" />
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
import { Skeleton } from '$lib/components/ui/skeleton/index.js';
|
import { Skeleton } from '$lib/components/ui/skeleton/index.js';
|
||||||
import { toast } from 'svelte-sonner';
|
import { toast } from 'svelte-sonner';
|
||||||
import { apiFetch } from '$lib/utils/api';
|
import { apiFetch } from '$lib/utils/api';
|
||||||
import { formatDuration } from '$lib/utils/format';
|
import { formatDuration, range } from '$lib/utils/format';
|
||||||
|
|
||||||
type Service = {
|
type Service = {
|
||||||
id: string;
|
id: string;
|
||||||
@@ -62,8 +62,7 @@
|
|||||||
|
|
||||||
{#if servicesLoading}
|
{#if servicesLoading}
|
||||||
<div class="space-y-4">
|
<div class="space-y-4">
|
||||||
{#each Array(5) as __, i (i)}
|
{#each range(5) as i (i)}
|
||||||
{__}
|
|
||||||
<Card.Root class="shadow-sm">
|
<Card.Root class="shadow-sm">
|
||||||
<Card.Content>
|
<Card.Content>
|
||||||
<div class="flex items-start justify-between">
|
<div class="flex items-start justify-between">
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
import { toast } from 'svelte-sonner';
|
import { toast } from 'svelte-sonner';
|
||||||
import { SvelteDate } from 'svelte/reactivity';
|
import { SvelteDate } from 'svelte/reactivity';
|
||||||
import { fly } from 'svelte/transition';
|
import { fly } from 'svelte/transition';
|
||||||
|
import { range } from '$lib/utils/format';
|
||||||
import UserBookingModal from '$lib/components/account/UserBookingModal.svelte';
|
import UserBookingModal from '$lib/components/account/UserBookingModal.svelte';
|
||||||
import type { Booking, BookingService } from '$lib/types/booking';
|
import type { Booking, BookingService } from '$lib/types/booking';
|
||||||
import { Button } from '$lib/components/ui/button';
|
import { Button } from '$lib/components/ui/button';
|
||||||
@@ -208,8 +209,7 @@
|
|||||||
<div class="h-8 w-44 rounded-lg bg-gray-200"></div>
|
<div class="h-8 w-44 rounded-lg bg-gray-200"></div>
|
||||||
<div class="h-4 w-64 rounded bg-gray-200"></div>
|
<div class="h-4 w-64 rounded bg-gray-200"></div>
|
||||||
<div class="space-y-4 pt-2">
|
<div class="space-y-4 pt-2">
|
||||||
{#each Array(3) as __, i (i)}
|
{#each range(3) as i (i)}
|
||||||
{__}
|
|
||||||
<div class="rounded-xl border bg-white p-5 shadow-sm">
|
<div class="rounded-xl border bg-white p-5 shadow-sm">
|
||||||
<div class="mb-3 flex items-center gap-3">
|
<div class="mb-3 flex items-center gap-3">
|
||||||
<div class="h-4 w-24 rounded bg-gray-200"></div>
|
<div class="h-4 w-24 rounded bg-gray-200"></div>
|
||||||
@@ -242,8 +242,7 @@
|
|||||||
|
|
||||||
{#if loading}
|
{#if loading}
|
||||||
<div class="space-y-6">
|
<div class="space-y-6">
|
||||||
{#each Array(3) as __, i (i)}
|
{#each range(3) as i (i)}
|
||||||
{__}
|
|
||||||
<div class="animate-pulse rounded-xl border bg-white p-5 shadow-sm">
|
<div class="animate-pulse rounded-xl border bg-white p-5 shadow-sm">
|
||||||
<div class="mb-3 flex items-center gap-3">
|
<div class="mb-3 flex items-center gap-3">
|
||||||
<div class="h-4 w-24 rounded bg-gray-200"></div>
|
<div class="h-4 w-24 rounded bg-gray-200"></div>
|
||||||
|
|||||||
Reference in New Issue
Block a user