Initial PHP rebuild of the app
This commit is contained in:
690 files changed
+33944
-12046
No files matched your search
@@ -0,0 +1,10 @@
|
||||
<x-layouts.public :business="$business">
|
||||
<main class="mx-auto flex min-h-screen max-w-xl flex-col justify-center px-5 py-16 text-center lg:px-10">
|
||||
<div class="mx-auto flex h-16 w-16 items-center justify-center rounded-full bg-accent text-3xl font-black text-white">✓</div>
|
||||
<p class="mt-8 text-[10px] font-bold uppercase tracking-[0.3em] text-accent-foreground">{{ $appointment->status->value === 'PENDING' ? 'Request received' : 'Booking confirmed' }}</p>
|
||||
<h1 class="mt-3 text-4xl font-black tracking-tight">You’re all set</h1>
|
||||
<p class="mt-4 text-sm leading-6 text-muted">{{ $appointment->customer->firstName }}, your appointment at {{ $business->name }} is booked for {{ $appointment->startAt->setTimezone($business->timezone)->format('l, j F · g:i A') }}.</p>
|
||||
<x-ui.card class="mt-8 p-6 text-left"><p class="text-sm font-bold">{{ $appointment->services->pluck('service.name')->join(', ') }}</p><p class="mt-2 text-sm text-muted">with {{ $appointment->staff->user?->name ?: 'your barber' }}</p><p class="mt-5 border-t border-line pt-4 text-xs text-muted">A confirmation link has been created for this booking.</p></x-ui.card>
|
||||
<x-ui.button class="mt-6 w-full" href="{{ route('public.home') }}">Done</x-ui.button>
|
||||
</main>
|
||||
</x-layouts.public>
|
||||
@@ -0,0 +1,14 @@
|
||||
<x-layouts.public :business="$business">
|
||||
<main class="mx-auto min-h-screen max-w-xl px-5 pb-16 pt-8 lg:px-10">
|
||||
<a href="{{ route('booking.time') }}" class="text-xs font-bold uppercase tracking-widest text-muted">← Time</a>
|
||||
<div class="mt-10"><p class="text-[10px] font-bold uppercase tracking-widest text-muted">Step 3 of 4</p><h1 class="mt-2 text-3xl font-black tracking-tight">Your details</h1><p class="mt-3 text-sm text-muted">We’ll use these details to send your booking confirmation.</p></div>
|
||||
<form method="POST" action="{{ route('booking.details.store') }}" class="mt-8 space-y-4 rounded-md border border-line bg-white p-6 shadow-sm">
|
||||
@csrf
|
||||
@foreach ([['firstName', 'First name', 'text'], ['lastName', 'Last name', 'text'], ['email', 'Email address', 'email'], ['phone', 'Phone number (optional)', 'tel']] as [$name, $label, $type])
|
||||
<label class="block"><span class="mb-2 ml-1 block text-[10px] font-bold uppercase tracking-widest text-muted">{{ $label }}</span><input name="{{ $name }}" type="{{ $type }}" value="{{ old($name) }}" class="w-full rounded-md border border-line px-4 py-3 text-sm outline-none focus:border-ink" @required(in_array($name, ['firstName', 'lastName', 'email']))>@error($name)<span class="mt-1 block text-xs text-danger">{{ $message }}</span>@enderror</label>
|
||||
@endforeach
|
||||
<label class="block"><span class="mb-2 ml-1 block text-[10px] font-bold uppercase tracking-widest text-muted">Notes (optional)</span><textarea name="notes" rows="4" class="w-full rounded-md border border-line px-4 py-3 text-sm outline-none focus:border-ink">{{ old('notes') }}</textarea></label>
|
||||
<x-ui.button class="mt-3 w-full" type="submit">Review booking</x-ui.button>
|
||||
</form>
|
||||
</main>
|
||||
</x-layouts.public>
|
||||
@@ -0,0 +1,7 @@
|
||||
<x-layouts.public :business="app(\App\Services\Tenant\TenantContext::class)->business()">
|
||||
<main class="mx-auto flex min-h-screen max-w-xl flex-col justify-center px-6 py-16">
|
||||
<a href="{{ route('public.home') }}" class="text-xs font-bold uppercase tracking-widest text-muted">← Back</a>
|
||||
<h1 class="mt-8 text-4xl font-black tracking-tight">Choose your service</h1>
|
||||
<p class="mt-4 text-sm leading-6 text-muted">The booking journey is the next migration slice. The legacy flow remains available in <code>legacy-nextjs</code> while it is being rebuilt with Blade and Alpine.</p>
|
||||
</main>
|
||||
</x-layouts.public>
|
||||
@@ -0,0 +1,13 @@
|
||||
<x-layouts.public :business="$business">
|
||||
<main class="mx-auto min-h-screen max-w-xl px-5 pb-16 pt-8 lg:px-10">
|
||||
<a href="{{ route('booking.details') }}" class="text-xs font-bold uppercase tracking-widest text-muted">← Your details</a>
|
||||
<div class="mt-10"><p class="text-[10px] font-bold uppercase tracking-widest text-muted">Step 4 of 4</p><h1 class="mt-2 text-3xl font-black tracking-tight">Review booking</h1></div>
|
||||
<div class="mt-8 space-y-3">
|
||||
<x-ui.card class="p-6"><p class="text-[10px] font-bold uppercase tracking-widest text-muted">Services</p>@foreach ($services as $service)<div class="mt-3 flex justify-between gap-3 text-sm"><span>{{ $service->name }} <span class="text-muted">· {{ $service->durationMinutes }}m</span></span><strong>£{{ number_format((float) $service->price, 2) }}</strong></div>@endforeach</x-ui.card>
|
||||
<x-ui.card class="p-6"><p class="text-[10px] font-bold uppercase tracking-widest text-muted">When & who</p><p class="mt-3 text-sm font-bold">{{ \Carbon\CarbonImmutable::parse($draft['time']['startAt'])->setTimezone($business->timezone)->format('l, j F · g:i A') }}</p><p class="mt-1 text-sm text-muted">with {{ $staff->user?->name ?: 'your barber' }}</p><p class="mt-4 border-t border-line pt-4 text-sm">{{ $draft['customer']['firstName'] }} {{ $draft['customer']['lastName'] }}<br><span class="text-muted">{{ $draft['customer']['email'] }}</span></p></x-ui.card>
|
||||
<div class="flex items-center justify-between px-1 pt-3"><span class="text-sm font-bold">Total</span><span class="text-2xl font-black">£{{ number_format((float) $total, 2) }}</span></div>
|
||||
</div>
|
||||
@if ($errors->any()) <div class="mt-5 rounded-md border border-danger/20 bg-red-50 p-4 text-sm text-red-800">{{ $errors->first() }}</div> @endif
|
||||
<form method="POST" action="{{ route('booking.confirm') }}" class="mt-6"><button class="inline-flex h-12 w-full items-center justify-center rounded-md bg-ink px-6 text-xs font-bold uppercase tracking-widest text-white shadow-lg shadow-ink/10 hover:bg-black" type="submit">Confirm booking</button>@csrf</form>
|
||||
</main>
|
||||
</x-layouts.public>
|
||||
@@ -0,0 +1,29 @@
|
||||
<x-layouts.public :business="$business">
|
||||
<main class="mx-auto min-h-screen max-w-3xl px-5 pb-16 pt-8 lg:px-10">
|
||||
<a href="{{ route('public.home') }}" class="text-xs font-bold uppercase tracking-widest text-muted">← {{ $business->shortName ?: $business->name }}</a>
|
||||
<div class="mt-10 flex items-end justify-between gap-4">
|
||||
<div><p class="text-[10px] font-bold uppercase tracking-widest text-muted">Step 1 of 4</p><h1 class="mt-2 text-3xl font-black tracking-tight">Choose your service</h1></div>
|
||||
<span class="text-xs text-muted">{{ $categories->sum(fn ($category) => $category->services->count()) }} available</span>
|
||||
</div>
|
||||
@if ($errors->any()) <div class="mt-5 rounded-md border border-danger/20 bg-red-50 p-4 text-sm text-red-800">{{ $errors->first() }}</div> @endif
|
||||
<form method="POST" action="{{ route('booking.services.store') }}" class="mt-8 space-y-6">
|
||||
@csrf
|
||||
@forelse ($categories as $category)
|
||||
<section>
|
||||
<h2 class="mb-3 text-[10px] font-bold uppercase tracking-widest text-muted">{{ $category->name }}</h2>
|
||||
<div class="space-y-3">
|
||||
@foreach ($category->services as $service)
|
||||
<label class="flex cursor-pointer items-center justify-between gap-4 rounded-md border border-line bg-white p-5 shadow-sm transition has-checked:border-ink has-checked:ring-1 has-checked:ring-ink">
|
||||
<span class="flex items-center gap-4"><input type="checkbox" name="serviceIds[]" value="{{ $service->id }}" class="h-5 w-5 accent-ink"><span><strong class="block text-sm">{{ $service->name }}</strong><span class="mt-1 block text-xs text-muted">{{ $service->durationMinutes }} minutes</span></span></span>
|
||||
<span class="text-sm font-bold">{{ $business->currency === 'GBP' ? '£' : $business->currency }}{{ number_format((float) $service->price, 2) }}</span>
|
||||
</label>
|
||||
@endforeach
|
||||
</div>
|
||||
</section>
|
||||
@empty
|
||||
<div class="rounded-md border border-line bg-white p-6 text-sm text-muted">No services are currently available to book.</div>
|
||||
@endforelse
|
||||
<div class="sticky bottom-4 pt-3"><x-ui.button class="w-full" type="submit">Continue to barber & time</x-ui.button></div>
|
||||
</form>
|
||||
</main>
|
||||
</x-layouts.public>
|
||||
@@ -0,0 +1,19 @@
|
||||
<x-layouts.public :business="$business">
|
||||
<main class="mx-auto min-h-screen max-w-3xl px-5 pb-16 pt-8 lg:px-10">
|
||||
<a href="{{ route('booking.services') }}" class="text-xs font-bold uppercase tracking-widest text-muted">← Services</a>
|
||||
<div class="mt-10"><p class="text-[10px] font-bold uppercase tracking-widest text-muted">Step 2 of 4</p><h1 class="mt-2 text-3xl font-black tracking-tight">Pick a time</h1><p class="mt-3 text-sm text-muted">{{ $services->pluck('name')->join(', ') }}</p></div>
|
||||
@if ($errors->any()) <div class="mt-5 rounded-md border border-danger/20 bg-red-50 p-4 text-sm text-red-800">{{ $errors->first() }}</div> @endif
|
||||
<div class="mt-8 flex items-center justify-between rounded-md border border-line bg-white p-4"><a class="text-xl" href="{{ route('booking.time', ['date' => $date->subDay()->toDateString()]) }}" aria-label="Previous day">←</a><span class="text-sm font-bold">{{ $date->format('l, j F Y') }}</span><a class="text-xl" href="{{ route('booking.time', ['date' => $date->addDay()->toDateString()]) }}" aria-label="Next day">→</a></div>
|
||||
<div class="mt-5 grid gap-3 sm:grid-cols-2">
|
||||
@forelse ($slots as $slot)
|
||||
<form method="POST" action="{{ route('booking.time.store') }}">
|
||||
@csrf
|
||||
<input type="hidden" name="staffId" value="{{ $slot['staffId'] }}">
|
||||
<button type="submit" name="startAt" value="{{ $slot['startAt'] }}" class="w-full rounded-md border border-line bg-white p-4 text-left shadow-sm transition hover:-translate-y-0.5 hover:border-ink"><span class="block text-sm font-bold">{{ $slot['label'] }}</span><span class="mt-1 block text-xs text-muted">{{ $slot['staffName'] }}</span></button>
|
||||
</form>
|
||||
@empty
|
||||
<div class="rounded-md border border-line bg-white p-6 text-sm text-muted sm:col-span-2">There are no available times on this date. Try another day.</div>
|
||||
@endforelse
|
||||
</div>
|
||||
</main>
|
||||
</x-layouts.public>
|
||||
Reference in new issue
Block a user