feat(frontend): add custom services management UI components

Add CustomServicesManagement component for CRUD operations on custom services. Update BookingCreateModal, WalkInCreateModal, and BookingsCard to support custom service selection. Minor improvements to ServicesManagement and ImageUpload.

Ultraworked with Sisyphus (https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
2026-06-15 16:58:28 +01:00
co-authored by Sisyphus
parent c62e8322b5
commit 8f8bf83b64
6 changed files with 1036 additions and 19 deletions
@@ -23,6 +23,8 @@
created_by?: string;
};
const durationOptions = Array.from({ length: 32 }, (_, i) => (i + 1) * 15);
let services = $state<Service[]>([]);
let newService = $state<
Omit<Service, 'id' | 'created_at' | 'created_by' | 'patch_test_duration_hours'>
@@ -563,18 +565,18 @@
</div>
<div class="space-y-2">
<label for="service-duration" class="text-sm font-medium">Duration (minutes) *</label>
<Input
<label for="service-duration" class="text-sm font-medium">Duration *</label>
<select
id="service-duration"
type="number"
inputmode="numeric"
min="1"
step="1"
placeholder="60"
bind:value={newService.duration_minutes}
onblur={validateDurationField}
class="w-full {serviceErrors.duration_minutes ? 'border-red-500' : ''}"
/>
class="flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 {serviceErrors.duration_minutes ? 'border-red-500' : ''}"
>
<option value={0}>Select...</option>
{#each durationOptions as mins (mins)}
<option value={mins}>{mins} min{mins >= 60 ? ` (${Math.floor(mins / 60)}h${mins % 60 > 0 ? ` ${mins % 60}m` : ''})` : ''}</option>
{/each}
</select>
{#if serviceErrors.duration_minutes}
<p class="text-sm text-red-600">{serviceErrors.duration_minutes}</p>
{/if}