feat(frontend): integrate custom services across booking flow and routes
Update BookingFlow to support custom service selection, add custom_services to booking types, and link CustomServicesManagement into admin pages. Minor updates to schedules, prices, and today routes. Ultraworked with Sisyphus (https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
@@ -1514,10 +1514,19 @@
|
||||
{services}
|
||||
selected={selectedServices}
|
||||
loading={servicesLoading}
|
||||
ontoggle={toggleService}
|
||||
/>
|
||||
ontoggle={toggleService}
|
||||
/>
|
||||
|
||||
{#if selectedServices.length > 0}
|
||||
<div class="mt-4 rounded-lg border border-dashed border-gray-300 bg-gray-50 p-4 text-center">
|
||||
<p class="text-sm text-gray-600">
|
||||
Need something different? Select the closest service and add a note, or contact us for a bespoke treatment.
|
||||
</p>
|
||||
<a href="/contact" class="mt-1 inline-block text-sm font-medium text-blue-600 hover:underline">
|
||||
Arrange a custom booking →
|
||||
</a>
|
||||
</div>
|
||||
|
||||
{#if selectedServices.length > 0}
|
||||
<div class="rounded-lg bg-gray-50 p-4">
|
||||
<h4 class="mb-2 font-semibold">Selected Services</h4>
|
||||
<div class="space-y-2">
|
||||
|
||||
@@ -744,7 +744,7 @@
|
||||
{item.data.user_name}
|
||||
</button>
|
||||
<div class="flex flex-wrap items-center gap-x-1 text-sm text-gray-600">
|
||||
<span class="truncate">{item.data.services.join(', ')}</span>
|
||||
<span class="truncate">{(item.data.services ?? []).join(', ')}</span>
|
||||
<span
|
||||
class="shrink-0 rounded-full bg-gray-100 px-1.5 py-0.5 text-xs font-medium"
|
||||
>
|
||||
|
||||
@@ -6,10 +6,17 @@ export interface Service {
|
||||
duration_minutes: number;
|
||||
patch_test_duration_hours: number;
|
||||
minimum_age_required: number;
|
||||
// Patch test status (present when user is authenticated, not admin)
|
||||
patch_test_status?: 'ok' | 'required' | 'expired';
|
||||
}
|
||||
|
||||
export interface CustomService extends Service {
|
||||
usage_count: number;
|
||||
last_used_at: string | null;
|
||||
notes: string | null;
|
||||
created_at: string;
|
||||
created_by?: string;
|
||||
}
|
||||
|
||||
export interface CustomerInfo {
|
||||
firstName: string;
|
||||
lastName: string;
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
import TimeBlockers from '$lib/components/admin/TimeBlockers.svelte';
|
||||
import WeeklySchedule from '$lib/components/admin/WeeklySchedule.svelte';
|
||||
import ServicesManagement from '$lib/components/admin/ServicesManagement.svelte';
|
||||
import CustomServicesManagement from '$lib/components/admin/CustomServicesManagement.svelte';
|
||||
import PatchTestsManagement from '$lib/components/admin/PatchTestsManagement.svelte';
|
||||
import DiscountsManagement from '$lib/components/admin/DiscountsManagement.svelte';
|
||||
import GiftCardsManagement from '$lib/components/admin/GiftCardsManagement.svelte';
|
||||
@@ -300,6 +301,7 @@
|
||||
<HolidayHours />
|
||||
<WeeklySchedule />
|
||||
<ServicesManagement />
|
||||
<CustomServicesManagement />
|
||||
<PatchTestsManagement />
|
||||
<DiscountsManagement />
|
||||
<GiftCardsManagement />
|
||||
|
||||
@@ -131,7 +131,7 @@
|
||||
}
|
||||
|
||||
function getServiceNames(b: ScheduleBooking): string {
|
||||
return b.services
|
||||
return (b.services ?? [])
|
||||
.map((s) => s.service_name)
|
||||
.filter(Boolean)
|
||||
.join(', ');
|
||||
|
||||
@@ -156,6 +156,17 @@
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
<Card.Root class="border-dashed border-gray-300 bg-gray-50">
|
||||
<Card.Content class="p-6 text-center">
|
||||
<p class="text-sm text-gray-600">
|
||||
Need something different? Select the closest service and add a note, or contact us for a bespoke treatment.
|
||||
</p>
|
||||
<a href={resolve('/contact')} class="mt-1 inline-block text-sm font-medium text-blue-600 hover:underline">
|
||||
Arrange a custom booking →
|
||||
</a>
|
||||
</Card.Content>
|
||||
</Card.Root>
|
||||
|
||||
<Card.Root class="border-amber-200 bg-amber-50">
|
||||
<Card.Header>
|
||||
<Card.Title class="flex items-center gap-2 text-amber-800">
|
||||
|
||||
@@ -135,8 +135,8 @@
|
||||
<!-- Quick Booking + Till Purchases Grid -->
|
||||
<div class="grid grid-cols-1 gap-4 lg:grid-cols-2 lg:gap-6">
|
||||
<div class="space-y-4">
|
||||
<WalkInBooking />
|
||||
<CallInBooking />
|
||||
<WalkInBooking />
|
||||
</div>
|
||||
<div>
|
||||
<TillPurchases />
|
||||
|
||||
Reference in New Issue
Block a user