Fix admin
This commit is contained in:
@@ -961,6 +961,28 @@
|
||||
showServiceModal = true;
|
||||
}
|
||||
|
||||
/** Calculate hours between start and end time */
|
||||
function calculateHours(startTime: string, endTime: string): string {
|
||||
// Convert formatted times to 24-hour format for calculation
|
||||
const start = timeToInputValue(startTime);
|
||||
const end = timeToInputValue(endTime);
|
||||
|
||||
const [startHours, startMinutes] = start.split(':').map(Number);
|
||||
const [endHours, endMinutes] = end.split(':').map(Number);
|
||||
|
||||
const startTotalMinutes = startHours * 60 + startMinutes;
|
||||
const endTotalMinutes = endHours * 60 + endMinutes;
|
||||
|
||||
const diffMinutes = endTotalMinutes - startTotalMinutes;
|
||||
const hours = Math.floor(diffMinutes / 60);
|
||||
const minutes = diffMinutes % 60;
|
||||
|
||||
if (minutes === 0) {
|
||||
return `${hours}`;
|
||||
}
|
||||
return `${hours}.${minutes === 30 ? '5' : Math.round((minutes / 60) * 10)}`;
|
||||
}
|
||||
|
||||
// Fetch services on component mount
|
||||
$effect(() => {
|
||||
if (pageState === 'authorized') {
|
||||
@@ -1151,8 +1173,26 @@
|
||||
|
||||
<Card.Root>
|
||||
<Card.Header>
|
||||
<Card.Title>Image Upload</Card.Title>
|
||||
<Card.Description>Upload images for the portfolio or other uses.</Card.Description>
|
||||
<div class="flex items-center justify-between">
|
||||
<div>
|
||||
<Card.Title>Image Upload</Card.Title>
|
||||
<Card.Description>Upload images for the portfolio or other uses.</Card.Description>
|
||||
</div>
|
||||
<div class="hidden rounded-lg p-2 md:block">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="h-6 w-6"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
>
|
||||
<rect x="3" y="3" width="18" height="18" rx="2" ry="2" />
|
||||
<circle cx="8.5" cy="8.5" r="1.5" />
|
||||
<polyline points="21 15 16 10 5 21" />
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</Card.Header>
|
||||
<Card.Content class="space-y-4">
|
||||
<FileDropZone onfiles={handleFilesDropped} accept="image/*" multiple>
|
||||
@@ -1205,8 +1245,31 @@
|
||||
<div class="grid grid-cols-1 gap-4 md:grid-cols-2">
|
||||
<Card.Root class="h-full">
|
||||
<Card.Header>
|
||||
<Card.Title>Users</Card.Title>
|
||||
<Card.Description>Search and manage user details.</Card.Description>
|
||||
<div class="flex items-start justify-between">
|
||||
<div>
|
||||
<Card.Title class="flex items-center gap-2">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="h-5 w-5"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
>
|
||||
<path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2" />
|
||||
<circle cx="9" cy="7" r="4" />
|
||||
<path d="M23 21v-2a4 4 0 0 0-3-3.87" />
|
||||
<path d="M16 3.13a4 4 0 0 1 0 7.75" />
|
||||
</svg>
|
||||
Users
|
||||
</Card.Title>
|
||||
<Card.Description>Search and manage user details.</Card.Description>
|
||||
</div>
|
||||
|
||||
<div class="rounded-full bg-gray-100 px-2 py-0.5 text-xs font-medium">
|
||||
<span class="text-xs font-semibold">{users.length}</span>
|
||||
</div>
|
||||
</div>
|
||||
</Card.Header>
|
||||
<Card.Content class="space-y-4">
|
||||
<div>
|
||||
@@ -1238,8 +1301,30 @@
|
||||
|
||||
<Card.Root class="h-full">
|
||||
<Card.Header>
|
||||
<Card.Title>Bookings</Card.Title>
|
||||
<Card.Description>Search and manage booking history.</Card.Description>
|
||||
<div class="flex items-start justify-between">
|
||||
<div>
|
||||
<Card.Title class="flex items-center gap-2">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="h-5 w-5"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
>
|
||||
<rect x="3" y="4" width="18" height="18" rx="2" ry="2" />
|
||||
<line x1="16" y1="2" x2="16" y2="6" />
|
||||
<line x1="8" y1="2" x2="8" y2="6" />
|
||||
<line x1="3" y1="10" x2="21" y2="10" />
|
||||
</svg>
|
||||
Bookings
|
||||
</Card.Title>
|
||||
<Card.Description>Search and manage booking history.</Card.Description>
|
||||
</div>
|
||||
<div class="rounded-full bg-gray-100 px-2 py-0.5 text-xs font-medium">
|
||||
<span class="text-xs font-semibold">{bookings.length}</span>
|
||||
</div>
|
||||
</div>
|
||||
</Card.Header>
|
||||
<Card.Content class="space-y-4">
|
||||
<div>
|
||||
@@ -1274,17 +1359,31 @@
|
||||
|
||||
<Card.Root>
|
||||
<Card.Header>
|
||||
<Card.Title>Holiday Hours</Card.Title>
|
||||
<Card.Description>
|
||||
Manage temporary schedules for holidays, closures, and special events.
|
||||
</Card.Description>
|
||||
<div class="flex items-center justify-between">
|
||||
<div>
|
||||
<Card.Title>Holiday Hours</Card.Title>
|
||||
<Card.Description>
|
||||
Manage temporary schedules for holidays, closures, and special events.
|
||||
</Card.Description>
|
||||
</div>
|
||||
<Button variant="default" onclick={createNewException}>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="mr-2 h-4 w-4"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
>
|
||||
<line x1="12" y1="5" x2="12" y2="19" />
|
||||
<line x1="5" y1="12" x2="19" y2="12" />
|
||||
</svg>
|
||||
New Schedule
|
||||
</Button>
|
||||
</div>
|
||||
</Card.Header>
|
||||
|
||||
<Card.Content class="space-y-4">
|
||||
<div class="flex items-center justify-between">
|
||||
<Button variant="default" onclick={createNewException}>New schedule</Button>
|
||||
</div>
|
||||
|
||||
{#if exceptionGroupsLoading}
|
||||
<div class="grid grid-cols-1 gap-4 md:grid-cols-2">
|
||||
{#each Array(2) as _, i}
|
||||
@@ -1298,22 +1397,75 @@
|
||||
{/if}
|
||||
|
||||
{#each exceptionGroups as g}
|
||||
<div class="relative h-full rounded border p-3 pb-12">
|
||||
<div class="group relative h-full rounded-lg border p-4 transition-all">
|
||||
<div class="flex h-full flex-col gap-3">
|
||||
<div class="flex-1">
|
||||
<div class="font-semibold">{g.name}</div>
|
||||
<div class="text-sm text-gray-600">{g.description}</div>
|
||||
<div class="mt-1 text-xs text-gray-500">
|
||||
Applies to weeks: {g.weekStarts?.slice(0, 5).join(', ')}
|
||||
{#if (g.weekStarts?.length ?? 0) > 5}
|
||||
(+{(g.weekStarts?.length ?? 0) - 5} more)
|
||||
{/if}
|
||||
<div class="mb-2 flex items-start justify-between">
|
||||
<div class="flex items-center gap-2">
|
||||
<div class="rounded-lg bg-gray-50 p-2">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="h-4 w-4"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
>
|
||||
<rect x="3" y="4" width="18" height="18" rx="2" ry="2" />
|
||||
<line x1="16" y1="2" x2="16" y2="6" />
|
||||
<line x1="8" y1="2" x2="8" y2="6" />
|
||||
<line x1="3" y1="10" x2="21" y2="10" />
|
||||
</svg>
|
||||
</div>
|
||||
<h3 class="font-semibold text-gray-900">{g.name}</h3>
|
||||
</div>
|
||||
<span class="rounded-full bg-gray-100 px-2 py-0.5 text-xs font-medium">
|
||||
{g.weekStarts?.length || 0} weeks
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<p class="mb-3 text-sm text-gray-600">{g.description}</p>
|
||||
|
||||
<div class="rounded-lg bg-gray-50 p-2">
|
||||
<div class="mb-1 text-xs font-medium text-gray-500">Applies to weeks:</div>
|
||||
<div class="text-xs text-gray-700">
|
||||
{g.weekStarts
|
||||
?.slice(0, 3)
|
||||
.map((w) =>
|
||||
new Date(w).toLocaleDateString('en-GB', {
|
||||
day: 'numeric',
|
||||
month: 'short'
|
||||
})
|
||||
)
|
||||
.join(', ')}
|
||||
{#if (g.weekStarts?.length ?? 0) > 3}
|
||||
<span class="text-gray-500">
|
||||
(+{(g.weekStarts?.length ?? 0) - 3} more)</span
|
||||
>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="absolute bottom-3 right-3 flex gap-2">
|
||||
<Button variant="default" size="sm" onclick={() => openViewExceptionModal(g)}>
|
||||
View
|
||||
<div class="flex gap-2 border-t pt-2">
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onclick={() => openViewExceptionModal(g)}
|
||||
class="flex-1"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="mr-1 h-3 w-3"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
>
|
||||
<path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z" />
|
||||
<circle cx="12" cy="12" r="3" />
|
||||
</svg>
|
||||
View Details
|
||||
</Button>
|
||||
<Button
|
||||
variant="destructive"
|
||||
@@ -1323,7 +1475,19 @@
|
||||
showDeleteExceptionAlert = true;
|
||||
}}
|
||||
>
|
||||
Delete
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="h-3 w-3"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
>
|
||||
<polyline points="3 6 5 6 21 6" />
|
||||
<path
|
||||
d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"
|
||||
/>
|
||||
</svg>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1336,94 +1500,288 @@
|
||||
|
||||
<!-- Default Hours Card -->
|
||||
<Card.Root>
|
||||
<Card.Header>
|
||||
<Card.Title>Working Hours</Card.Title>
|
||||
<Card.Description>View and manage your standard weekly schedule.</Card.Description>
|
||||
</Card.Header>
|
||||
{#if !defaultHoursIsLoading}
|
||||
<Card.Content class="space-y-4">
|
||||
<div class="flex items-center justify-between">
|
||||
<h3 class="font-semibold">Weekly Schedule</h3>
|
||||
<div>
|
||||
<h3 class="text-lg font-semibold">Weekly Schedule</h3>
|
||||
<p class="text-sm text-gray-500">
|
||||
Your standard operating hours for each day of the week
|
||||
</p>
|
||||
</div>
|
||||
<Button onclick={prepareDefaultHoursEdit} disabled={loadingHours || savingHours}>
|
||||
Edit Defaults
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="mr-2 h-4 w-4"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
>
|
||||
<path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7" />
|
||||
<path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z" />
|
||||
</svg>
|
||||
Edit Schedule
|
||||
</Button>
|
||||
</div>
|
||||
<div class="w-full overflow-x-auto">
|
||||
<table class="w-full table-auto">
|
||||
<!-- Desktop Table -->
|
||||
<div class="hidden w-full overflow-x-auto sm:block">
|
||||
<table class="w-full table-auto border-collapse">
|
||||
<thead>
|
||||
<tr class="text-left text-xs text-gray-500">
|
||||
<th class="py-2">Day</th>
|
||||
<th class="py-2">Status</th>
|
||||
<th class="py-2">Start</th>
|
||||
<th class="py-2">End</th>
|
||||
<tr class="border-b text-left text-xs text-gray-500">
|
||||
<th class="px-4 py-3">Day</th>
|
||||
<th class="px-4 py-3 text-center">Status</th>
|
||||
<th class="px-4 py-3">Opening Time</th>
|
||||
<th class="px-4 py-3">Closing Time</th>
|
||||
<th class="px-4 py-3 text-right">Total Hours</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tbody class="divide-y divide-gray-200">
|
||||
{#each defaultHours as row}
|
||||
<tr class="border-t">
|
||||
<td class="py-2 text-sm">{weekdayLabel(row.weekday)}</td>
|
||||
<td class="py-2">
|
||||
<tr class="transition-colors hover:bg-gray-50">
|
||||
<td class="p-3">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="font-medium"
|
||||
>{weekdayLabel(row.weekday) === 'Mon'
|
||||
? 'Monday'
|
||||
: weekdayLabel(row.weekday) === 'Tue'
|
||||
? 'Tuesday'
|
||||
: weekdayLabel(row.weekday) === 'Wed'
|
||||
? 'Wednesday'
|
||||
: weekdayLabel(row.weekday) === 'Thu'
|
||||
? 'Thursday'
|
||||
: weekdayLabel(row.weekday) === 'Fri'
|
||||
? 'Friday'
|
||||
: weekdayLabel(row.weekday) === 'Sat'
|
||||
? 'Saturday'
|
||||
: 'Sunday'}</span
|
||||
>
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-4 py-4 text-center">
|
||||
<span
|
||||
class="text-sm font-medium {row.is_open
|
||||
? 'text-emerald-600'
|
||||
: 'text-red-600'}"
|
||||
class="inline-flex items-center rounded-full px-3 py-1 text-xs font-medium {row.is_open
|
||||
? 'bg-emerald-100 text-emerald-800'
|
||||
: 'bg-gray-100 text-gray-800'}"
|
||||
>
|
||||
<span
|
||||
class="mr-1.5 h-1.5 w-1.5 rounded-full {row.is_open
|
||||
? 'bg-emerald-600'
|
||||
: 'bg-gray-600'}"
|
||||
></span>
|
||||
{row.is_open ? 'Open' : 'Closed'}
|
||||
</span>
|
||||
</td>
|
||||
<td class="py-2 text-sm">
|
||||
{row.is_open ? row.start_time : '—'}
|
||||
<td class="px-4 py-4">
|
||||
{#if row.is_open}
|
||||
<div class="flex items-center gap-2">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="h-4 w-4 text-gray-400"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
>
|
||||
<circle cx="12" cy="12" r="10" />
|
||||
<polyline points="12 6 12 12 16 14" />
|
||||
</svg>
|
||||
<span class="font-medium text-gray-900">{row.start_time}</span>
|
||||
</div>
|
||||
{:else}
|
||||
<span class="text-gray-400">—</span>
|
||||
{/if}
|
||||
</td>
|
||||
<td class="py-2 text-sm">
|
||||
{row.is_open ? row.end_time : '—'}
|
||||
<td class="px-4 py-4">
|
||||
{#if row.is_open}
|
||||
<div class="flex items-center gap-2">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="h-4 w-4 text-gray-400"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
>
|
||||
<circle cx="12" cy="12" r="10" />
|
||||
<polyline points="12 6 12 12 16 14" />
|
||||
</svg>
|
||||
<span class="font-medium text-gray-900">{row.end_time}</span>
|
||||
</div>
|
||||
{:else}
|
||||
<span class="text-gray-400">—</span>
|
||||
{/if}
|
||||
</td>
|
||||
<td class="px-4 py-4 text-right">
|
||||
{#if row.is_open}
|
||||
<span
|
||||
class="inline-flex items-center gap-1 text-sm font-medium text-gray-700"
|
||||
>
|
||||
{calculateHours(row.start_time, row.end_time)}
|
||||
<span class="text-xs text-gray-500">hrs</span>
|
||||
</span>
|
||||
{:else}
|
||||
<span class="text-gray-400">—</span>
|
||||
{/if}
|
||||
</td>
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<!-- Mobile Cards -->
|
||||
<div class="space-y-3 sm:hidden">
|
||||
{#each defaultHours as row}
|
||||
<div class="rounded-lg border p-4 transition-colors hover:bg-gray-50">
|
||||
<div class="mb-3 flex items-center justify-between">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="font-semibold text-gray-900">
|
||||
{weekdayLabel(row.weekday) === 'Mon'
|
||||
? 'Monday'
|
||||
: weekdayLabel(row.weekday) === 'Tue'
|
||||
? 'Tuesday'
|
||||
: weekdayLabel(row.weekday) === 'Wed'
|
||||
? 'Wednesday'
|
||||
: weekdayLabel(row.weekday) === 'Thu'
|
||||
? 'Thursday'
|
||||
: weekdayLabel(row.weekday) === 'Fri'
|
||||
? 'Friday'
|
||||
: weekdayLabel(row.weekday) === 'Sat'
|
||||
? 'Saturday'
|
||||
: 'Sunday'}
|
||||
</span>
|
||||
</div>
|
||||
<span
|
||||
class="inline-flex items-center rounded-full px-2.5 py-1 text-xs font-medium {row.is_open
|
||||
? 'bg-emerald-100 text-emerald-800'
|
||||
: 'bg-gray-100 text-gray-800'}"
|
||||
>
|
||||
<span
|
||||
class="mr-1.5 h-1.5 w-1.5 rounded-full {row.is_open
|
||||
? 'bg-emerald-600'
|
||||
: 'bg-gray-600'}"
|
||||
></span>
|
||||
{row.is_open ? 'Open' : 'Closed'}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{#if row.is_open}
|
||||
<div class="grid grid-cols-2 gap-3 text-sm">
|
||||
<div>
|
||||
<div class="mb-1 text-xs text-gray-500">Opening</div>
|
||||
<div class="font-medium text-gray-900">{row.start_time}</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="mb-1 text-xs text-gray-500">Closing</div>
|
||||
<div class="font-medium text-gray-900">{row.end_time}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-3 border-t pt-3 text-xs text-gray-600">
|
||||
Total: <span class="font-medium text-gray-900"
|
||||
>{calculateHours(row.start_time, row.end_time)} hours</span
|
||||
>
|
||||
</div>
|
||||
{:else}
|
||||
<div class="text-sm text-gray-500">No hours scheduled for this day</div>
|
||||
{/if}
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
</Card.Content>
|
||||
{:else}
|
||||
<!-- Skeleton loading -->
|
||||
<Card.Content class="space-y-4">
|
||||
<div class="w-full overflow-x-auto">
|
||||
<table class="w-full table-auto">
|
||||
<!-- Desktop Skeleton -->
|
||||
<div class="hidden w-full overflow-x-auto md:block">
|
||||
<table class="w-full table-auto border-collapse">
|
||||
<thead>
|
||||
<tr class="text-left text-xs text-gray-500">
|
||||
<th class="py-2">Day</th>
|
||||
<th class="py-2">Status</th>
|
||||
<th class="py-2">Start</th>
|
||||
<th class="py-2">End</th>
|
||||
<tr
|
||||
class="border-b bg-gray-50 text-left text-xs font-medium uppercase tracking-wider text-gray-600"
|
||||
>
|
||||
<th class="px-4 py-3">Day</th>
|
||||
<th class="px-4 py-3 text-center">Status</th>
|
||||
<th class="px-4 py-3">Opening Time</th>
|
||||
<th class="px-4 py-3">Closing Time</th>
|
||||
<th class="px-4 py-3 text-right">Total Hours</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tbody class="divide-y divide-gray-200">
|
||||
{#each Array(7) as _, i}
|
||||
<tr class="border-t">
|
||||
<td class="py-2"><Skeleton class="h-4 w-20" /></td>
|
||||
<td class="py-2"><Skeleton class="h-4 w-12" /></td>
|
||||
<td class="py-2"><Skeleton class="h-4 w-12" /></td>
|
||||
<td class="py-2"><Skeleton class="h-4 w-12" /></td>
|
||||
<tr>
|
||||
<td class="px-4 py-4">
|
||||
<div class="flex items-center gap-2">
|
||||
<Skeleton class="h-8 w-8 rounded-full" />
|
||||
<Skeleton class="h-4 w-20" />
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-4 py-4 text-center">
|
||||
<Skeleton class="mx-auto h-6 w-16 rounded-full" />
|
||||
</td>
|
||||
<td class="px-4 py-4">
|
||||
<Skeleton class="h-4 w-20" />
|
||||
</td>
|
||||
<td class="px-4 py-4">
|
||||
<Skeleton class="h-4 w-20" />
|
||||
</td>
|
||||
<td class="px-4 py-4 text-right">
|
||||
<Skeleton class="ml-auto h-4 w-12" />
|
||||
</td>
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<!-- Mobile Skeleton -->
|
||||
<div class="space-y-3 md:hidden">
|
||||
{#each Array(7) as _, i}
|
||||
<div class="rounded-lg border p-4">
|
||||
<div class="mb-3 flex items-center justify-between">
|
||||
<div class="flex items-center gap-2">
|
||||
<Skeleton class="h-10 w-10 rounded-full" />
|
||||
<Skeleton class="h-5 w-24" />
|
||||
</div>
|
||||
<Skeleton class="h-6 w-16 rounded-full" />
|
||||
</div>
|
||||
<div class="grid grid-cols-2 gap-3">
|
||||
<Skeleton class="h-12 w-full" />
|
||||
<Skeleton class="h-12 w-full" />
|
||||
</div>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
</Card.Content>
|
||||
{/if}
|
||||
</Card.Root>
|
||||
<!-- Services Management Card -->
|
||||
<Card.Root>
|
||||
<Card.Header>
|
||||
<Card.Title>Services Management</Card.Title>
|
||||
<Card.Description
|
||||
>Manage your services - add, edit, toggle availability, or delete services.</Card.Description
|
||||
>
|
||||
</Card.Header>
|
||||
<Card.Content class="space-y-4">
|
||||
<div class="flex items-center justify-between">
|
||||
<Button onclick={openServiceModal}>Add Service</Button>
|
||||
<div>
|
||||
<Card.Title>Services Management</Card.Title>
|
||||
<Card.Description>
|
||||
Manage your services - add, edit, toggle availability, or delete services.
|
||||
</Card.Description>
|
||||
</div>
|
||||
<Button onclick={openServiceModal}>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="mr-2 h-4 w-4"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
>
|
||||
<line x1="12" y1="5" x2="12" y2="19" />
|
||||
<line x1="5" y1="12" x2="19" y2="12" />
|
||||
</svg>
|
||||
Add Service
|
||||
</Button>
|
||||
</div>
|
||||
</Card.Header>
|
||||
|
||||
<Card.Content class="space-y-4">
|
||||
<!-- Desktop Table -->
|
||||
<div class="hidden w-full overflow-x-auto md:block">
|
||||
<table class="w-full table-auto border-collapse text-sm">
|
||||
@@ -1610,7 +1968,7 @@
|
||||
<div class="w-full overflow-x-auto">
|
||||
<table class="w-full table-auto">
|
||||
<thead>
|
||||
<tr class="text-left text-xs text-gray-500">
|
||||
<tr class="border-b text-left text-xs text-gray-500">
|
||||
<th class="py-2">Day</th>
|
||||
<th class="py-2">Open</th>
|
||||
<th class="py-2">Start</th>
|
||||
|
||||
Reference in New Issue
Block a user