Initial PHP rebuild of the app
This commit is contained in:
690 files changed
+33944
-12046
No files matched your search
@@ -0,0 +1 @@
|
||||
<x-layouts.staff :business="$business"><main class="mx-auto max-w-3xl px-5 py-8 sm:px-8 lg:px-12 lg:py-12"><a href="{{ route('owner.services') }}" class="text-xs font-bold uppercase tracking-widest text-white/60">← Services</a><p class="mt-12 text-[10px] font-bold uppercase tracking-[0.3em] text-accent">Scheduling policy</p><h1 class="mt-3 text-4xl font-black tracking-tight">Booking rules</h1>@if (session('status'))<div class="mt-6 rounded-tile bg-accent p-4 text-sm font-bold text-ink">{{ session('status') }}</div>@endif<form method="POST" action="{{ route('owner.booking-rules.update') }}" class="mt-8 space-y-5 rounded-jumbo bg-white p-6 text-ink">@csrf @method('PUT')<div class="grid gap-5 sm:grid-cols-2"><label class="text-sm font-bold">Minimum notice (minutes)<input name="minNoticeMinutes" type="number" value="{{ $rules->minNoticeMinutes }}" class="mt-2 w-full rounded-tile border border-line px-4 py-3"></label><label class="text-sm font-bold">Max advance (days)<input name="maxAdvanceDays" type="number" value="{{ $rules->maxAdvanceDays }}" class="mt-2 w-full rounded-tile border border-line px-4 py-3"></label><label class="text-sm font-bold">Slot interval<select name="slotIntervalMinutes" class="mt-2 w-full rounded-tile border border-line px-4 py-3"><option value="15">15 minutes</option><option value="30" @selected($rules->slotIntervalMinutes == 30)>30 minutes</option><option value="60" @selected($rules->slotIntervalMinutes == 60)>60 minutes</option></select></label><label class="text-sm font-bold">Cancellation window (hours)<input name="cancellationWindowHours" type="number" value="{{ $rules->cancellationWindowHours ?? 24 }}" class="mt-2 w-full rounded-tile border border-line px-4 py-3"></label><label class="text-sm font-bold">Reschedule window (hours)<input name="rescheduleWindowHours" type="number" value="{{ $rules->rescheduleWindowHours ?? 24 }}" class="mt-2 w-full rounded-tile border border-line px-4 py-3"></label><label class="text-sm font-bold">Buffer after (minutes)<input name="bufferAfterMinutes" type="number" value="{{ $rules->bufferAfterMinutes ?? 5 }}" class="mt-2 w-full rounded-tile border border-line px-4 py-3"></label></div><input type="hidden" name="bufferBeforeMinutes" value="{{ $rules->bufferBeforeMinutes ?? 0 }}"><label class="flex items-center gap-3 text-sm font-bold"><input type="checkbox" name="allowGuestBooking" value="1" @checked($rules->allowGuestBooking) class="rounded border-line text-accent"> Allow guest booking</label><label class="flex items-center gap-3 text-sm font-bold"><input type="checkbox" name="requireApproval" value="1" @checked($rules->requireApproval) class="rounded border-line text-accent"> Require approval</label><label class="flex items-center gap-3 text-sm font-bold"><input type="checkbox" name="customerCanChooseStaff" value="1" @checked($rules->customerCanChooseStaff) class="rounded border-line text-accent"> Let customers choose staff</label><x-ui.button type="submit">Save rules</x-ui.button></form></main></x-layouts.staff>
|
||||
@@ -0,0 +1 @@
|
||||
<x-layouts.staff :business="$business"><main class="mx-auto max-w-3xl px-5 py-8 sm:px-8 lg:px-12 lg:py-12"><a href="{{ route('owner.dashboard') }}" class="text-xs font-bold uppercase tracking-widest text-white/60">← Owner workspace</a><p class="mt-12 text-[10px] font-bold uppercase tracking-[0.3em] text-accent">Business profile</p><h1 class="mt-3 text-4xl font-black tracking-tight">Business details</h1>@if (session('status'))<div class="mt-6 rounded-tile bg-accent p-4 text-sm font-bold text-ink">{{ session('status') }}</div>@endif<form method="POST" action="{{ route('owner.business.update') }}" class="mt-8 space-y-5 rounded-jumbo bg-white p-6 text-ink">@csrf @method('PUT')<div class="grid gap-5 sm:grid-cols-2"><label class="text-sm font-bold">Name<input name="name" value="{{ $business->name }}" required class="mt-2 w-full rounded-tile border border-line px-4 py-3"></label><label class="text-sm font-bold">Short name<input name="shortName" value="{{ $business->shortName }}" class="mt-2 w-full rounded-tile border border-line px-4 py-3"></label></div><label class="block text-sm font-bold">Description<textarea name="description" rows="4" class="mt-2 w-full rounded-tile border border-line px-4 py-3">{{ $business->description }}</textarea></label><div class="grid gap-5 sm:grid-cols-2"><label class="text-sm font-bold">Phone<input name="phone" value="{{ $business->phone }}" class="mt-2 w-full rounded-tile border border-line px-4 py-3"></label><label class="text-sm font-bold">Email<input name="email" type="email" value="{{ $business->email }}" class="mt-2 w-full rounded-tile border border-line px-4 py-3"></label></div><label class="block text-sm font-bold">Website<input name="website" type="url" value="{{ $business->website }}" class="mt-2 w-full rounded-tile border border-line px-4 py-3"></label><div class="grid gap-5 sm:grid-cols-2"><label class="text-sm font-bold">Timezone<input name="timezone" value="{{ $business->timezone }}" required class="mt-2 w-full rounded-tile border border-line px-4 py-3"></label><label class="text-sm font-bold">Currency<input name="currency" value="{{ $business->currency }}" maxlength="3" required class="mt-2 w-full rounded-tile border border-line px-4 py-3"></label></div><x-ui.button type="submit">Save details</x-ui.button></form></main></x-layouts.staff>
|
||||
@@ -0,0 +1 @@
|
||||
<x-layouts.staff :business="$business"><main class="mx-auto max-w-3xl px-5 py-8 sm:px-8 lg:px-12 lg:py-12"><a href="{{ route('owner.dashboard') }}" class="text-xs font-bold uppercase tracking-widest text-white/60">← Owner workspace</a><p class="mt-12 text-[10px] font-bold uppercase tracking-[0.3em] text-accent">Opening hours</p><h1 class="mt-3 text-4xl font-black tracking-tight">Business hours</h1>@if (session('status'))<div class="mt-6 rounded-tile bg-accent p-4 text-sm font-bold text-ink">{{ session('status') }}</div>@endif @if ($errors->any())<div class="mt-6 rounded-tile border border-red-200 bg-red-50 p-4 text-sm text-red-700">{{ $errors->first() }}</div>@endif<form method="POST" action="{{ route('owner.hours.update') }}" class="mt-8 space-y-3">@csrf @method('PUT')@foreach ($days as $day)@php($item = $hours->get($day))<div class="grid items-center gap-3 rounded-jumbo bg-white p-4 text-ink sm:grid-cols-[120px_1fr_1fr_auto]"><p class="text-sm font-bold">{{ ucfirst(strtolower($day)) }}</p><input name="{{ strtolower($day) }}_open" type="time" value="{{ $item && $item->opensAtMinutes !== null ? sprintf('%02d:%02d', intdiv($item->opensAtMinutes, 60), $item->opensAtMinutes % 60) : '10:00' }}" class="rounded-tile border border-line px-3 py-2 text-sm"><input name="{{ strtolower($day) }}_close" type="time" value="{{ $item && $item->closesAtMinutes !== null ? sprintf('%02d:%02d', intdiv($item->closesAtMinutes, 60), $item->closesAtMinutes % 60) : '19:00' }}" class="rounded-tile border border-line px-3 py-2 text-sm"><label class="flex items-center gap-2 text-xs font-bold"><input name="{{ strtolower($day) }}_closed" type="checkbox" value="1" @checked($item?->isClosed) class="rounded border-line text-accent"> Closed</label></div>@endforeach<x-ui.button type="submit">Save hours</x-ui.button></form></main></x-layouts.staff>
|
||||
@@ -0,0 +1,5 @@
|
||||
<x-layouts.staff :business="$business">
|
||||
<main class="mx-auto max-w-3xl px-5 py-8 sm:px-8 lg:px-12 lg:py-12"><a href="{{ route('owner.dashboard') }}" class="text-xs font-bold uppercase tracking-widest text-white/60">← Owner workspace</a><p class="mt-12 text-[10px] font-bold uppercase tracking-[0.3em] text-accent">Programme settings</p><h1 class="mt-3 text-4xl font-black tracking-tight">Loyalty</h1>@if (session('status'))<div class="mt-6 rounded-tile bg-accent p-4 text-sm font-bold text-ink">{{ session('status') }}</div>@endif
|
||||
<form method="POST" action="{{ route('owner.loyalty.update') }}" class="mt-8 space-y-6">@csrf<input type="hidden" name="rewardPosition" value="AFTER_ALL_STAMPS"><input type="hidden" name="cardFont" value="SANS"><input type="hidden" name="cardTitleTextSize" value="MD">@if ($errors->any())<div class="rounded-tile border border-red-200 bg-red-50 p-4 text-sm text-red-700">{{ $errors->first() }}</div>@endif<div class="rounded-jumbo bg-white p-6 text-ink"><label class="flex items-center justify-between gap-4 text-sm font-bold">Enable loyalty<input type="checkbox" name="isEnabled" value="1" @checked(old('isEnabled', $programme->isEnabled)) class="h-5 w-5 rounded border-line text-accent"></label><div class="mt-6 grid gap-5 sm:grid-cols-2"><label class="text-sm font-bold">Stamps required<input name="stampsRequired" type="number" min="1" max="10" value="{{ old('stampsRequired', $programme->stampsRequired) }}" class="mt-2 w-full rounded-tile border border-line px-4 py-3"></label><label class="text-sm font-bold">Reward label<input name="rewardLabel" value="{{ old('rewardLabel', $programme->rewardLabel) }}" placeholder="Free service" class="mt-2 w-full rounded-tile border border-line px-4 py-3"></label></div><div class="mt-5 grid gap-5 sm:grid-cols-2"><label class="text-sm font-bold">Reward type<select name="rewardType" class="mt-2 w-full rounded-tile border border-line px-4 py-3"><option value="PERCENTAGE">Percentage off</option><option value="FIXED_AMOUNT">Fixed amount</option><option value="FREE_SERVICE">Free service</option></select></label><label class="text-sm font-bold">Reward value<input name="rewardValue" type="number" step="0.01" value="{{ old('rewardValue', $programme->rewardValue) }}" class="mt-2 w-full rounded-tile border border-line px-4 py-3"></label></div><label class="mt-5 block text-sm font-bold">Free service<select name="freeServiceId" class="mt-2 w-full rounded-tile border border-line px-4 py-3"><option value="">Choose a service</option>@foreach ($services as $service)<option value="{{ $service->id }}" @selected(old('freeServiceId', $programme->freeServiceId) === $service->id)>{{ $service->name }}</option>@endforeach</select></label></div><div class="rounded-jumbo bg-white p-6 text-ink"><div class="grid gap-5 sm:grid-cols-2"><label class="text-sm font-bold">Card title<input name="cardTitleText" value="{{ old('cardTitleText', $programme->cardTitleText) }}" class="mt-2 w-full rounded-tile border border-line px-4 py-3"></label><label class="text-sm font-bold">Terms line<input name="termsLine" value="{{ old('termsLine', $programme->termsLine) }}" class="mt-2 w-full rounded-tile border border-line px-4 py-3"></label></div></div><x-ui.button type="submit">Save loyalty settings</x-ui.button></form>
|
||||
</main>
|
||||
</x-layouts.staff>
|
||||
@@ -0,0 +1 @@
|
||||
<x-layouts.staff :business="$business"><main class="mx-auto max-w-6xl px-5 py-8 sm:px-8 lg:px-12 lg:py-12"><a href="{{ route('owner.dashboard') }}" class="text-xs font-bold uppercase tracking-widest text-white/60">← Owner workspace</a><p class="mt-12 text-[10px] font-bold uppercase tracking-[0.3em] text-accent">Business health</p><h1 class="mt-3 text-4xl font-black tracking-tight">Reports</h1><p class="mt-3 text-sm text-white/60">{{ now($business->timezone)->format('F Y') }} to date</p><div class="mt-10 grid gap-3 sm:grid-cols-3"><div class="rounded-jumbo bg-white/10 p-6"><p class="text-xs text-white/50">Appointments</p><p class="mt-3 text-4xl font-black">{{ $appointments->count() }}</p></div><div class="rounded-jumbo bg-white/10 p-6"><p class="text-xs text-white/50">Completed</p><p class="mt-3 text-4xl font-black">{{ $completed->count() }}</p></div><div class="rounded-jumbo bg-accent p-6 text-ink"><p class="text-xs text-ink/60">Recorded revenue</p><p class="mt-3 text-4xl font-black">£{{ number_format($revenue, 2) }}</p></div></div><div class="mt-6 rounded-jumbo bg-white/10 p-6"><p class="text-sm text-white/60">Active team members</p><p class="mt-2 text-3xl font-black">{{ $staffCount }}</p></div></main></x-layouts.staff>
|
||||
@@ -0,0 +1 @@
|
||||
<x-layouts.staff :business="$business"><main class="mx-auto max-w-4xl px-5 py-8 sm:px-8 lg:px-12 lg:py-12"><a href="{{ route('owner.dashboard') }}" class="text-xs font-bold uppercase tracking-widest text-white/60">← Owner workspace</a><p class="mt-12 text-[10px] font-bold uppercase tracking-[0.3em] text-accent">Customer voice</p><h1 class="mt-3 text-4xl font-black tracking-tight">Reviews</h1>@if (session('status'))<div class="mt-6 rounded-tile bg-accent p-4 text-sm font-bold text-ink">{{ session('status') }}</div>@endif<div class="mt-8 space-y-3">@forelse ($reviews as $review)<article class="rounded-jumbo bg-white p-6 text-ink"><div class="flex items-center justify-between gap-4"><p class="font-bold">{{ $review->authorName }} · {{ str_repeat('★', $review->rating) }}</p><form method="POST" action="{{ route('owner.reviews.toggle', $review->id) }}">@csrf<button class="text-[10px] font-bold uppercase tracking-widest text-accent-foreground">{{ $review->isHidden ? 'Show' : 'Hide' }}</button></form></div><p class="mt-4 text-sm leading-6 text-muted">{{ $review->text ?: 'Rating only' }}</p></article>@empty<x-ui.card class="p-6"><p class="text-sm text-white/60">Reviews will appear after a Google Places sync is configured.</p></x-ui.card>@endforelse</div></main></x-layouts.staff>
|
||||
@@ -0,0 +1,5 @@
|
||||
<x-layouts.staff :business="$business">
|
||||
<main class="mx-auto max-w-6xl px-5 py-8 sm:px-8 lg:px-12 lg:py-12"><a href="{{ route('owner.dashboard') }}" class="text-xs font-bold uppercase tracking-widest text-white/60">← Owner workspace</a><div class="mt-12 flex flex-wrap items-end justify-between gap-4"><div><p class="text-[10px] font-bold uppercase tracking-[0.3em] text-accent">Catalogue</p><h1 class="mt-3 text-4xl font-black tracking-tight">Services</h1></div><a href="{{ route('owner.booking-rules') }}" class="text-xs font-bold uppercase tracking-widest text-accent">Booking rules →</a></div>@if (session('status'))<div class="mt-6 rounded-tile bg-accent p-4 text-sm font-bold text-ink">{{ session('status') }}</div>@endif
|
||||
<div class="mt-8 grid gap-8 lg:grid-cols-[1fr_340px]"><div class="space-y-4">@foreach ($categories as $category)<section><h2 class="mb-3 text-sm font-bold uppercase tracking-widest text-white/50">{{ $category->name }}</h2>@foreach ($category->services as $service)<article class="mb-3 rounded-jumbo bg-white p-5 text-ink"><form method="POST" action="{{ route('owner.services.update', $service->id) }}" class="grid gap-4 sm:grid-cols-[1fr_110px_100px_auto] sm:items-end">@csrf @method('PUT')<label class="text-xs font-bold">Service<input name="name" value="{{ $service->name }}" class="mt-2 w-full rounded-tile border border-line px-3 py-2 text-sm"></label><label class="text-xs font-bold">Minutes<input name="durationMinutes" type="number" value="{{ $service->durationMinutes }}" class="mt-2 w-full rounded-tile border border-line px-3 py-2 text-sm"></label><label class="text-xs font-bold">Price<input name="price" type="number" step="0.01" value="{{ $service->price }}" class="mt-2 w-full rounded-tile border border-line px-3 py-2 text-sm"></label><div class="flex gap-2"><input type="hidden" name="isActive" value="{{ $service->isActive ? 1 : 0 }}"><input type="hidden" name="allowOnlineBooking" value="{{ $service->allowOnlineBooking ? 1 : 0 }}"><button class="rounded-md bg-ink px-3 py-2 text-[10px] font-bold uppercase tracking-widest text-white">Save</button></div></form></article>@endforeach</section>@endforeach</div><aside class="rounded-jumbo bg-white p-6 text-ink"><h2 class="text-lg font-bold">Add service</h2><form method="POST" action="{{ route('owner.services.store') }}" class="mt-5 space-y-4">@csrf<label class="block text-xs font-bold">Category<select name="categoryId" class="mt-2 w-full rounded-tile border border-line px-3 py-2 text-sm"><option value="">New category</option>@foreach ($categories as $category)<option value="{{ $category->id }}">{{ $category->name }}</option>@endforeach</select></label><label class="block text-xs font-bold">New category name<input name="categoryName" class="mt-2 w-full rounded-tile border border-line px-3 py-2 text-sm"></label><label class="block text-xs font-bold">Name<input name="name" required class="mt-2 w-full rounded-tile border border-line px-3 py-2 text-sm"></label><label class="block text-xs font-bold">Duration<input name="durationMinutes" type="number" value="30" required class="mt-2 w-full rounded-tile border border-line px-3 py-2 text-sm"></label><label class="block text-xs font-bold">Price<input name="price" type="number" step="0.01" required class="mt-2 w-full rounded-tile border border-line px-3 py-2 text-sm"></label><x-ui.button type="submit" class="w-full">Add service</x-ui.button></form></aside></div>
|
||||
</main>
|
||||
</x-layouts.staff>
|
||||
@@ -0,0 +1 @@
|
||||
<x-layouts.staff :business="$business"><main class="mx-auto max-w-6xl px-5 py-8 sm:px-8 lg:px-12 lg:py-12"><a href="{{ route('owner.dashboard') }}" class="text-xs font-bold uppercase tracking-widest text-white/60">← Owner workspace</a><div class="mt-12"><p class="text-[10px] font-bold uppercase tracking-[0.3em] text-accent">People</p><h1 class="mt-3 text-4xl font-black tracking-tight">Team</h1></div>@if (session('status'))<div class="mt-6 rounded-tile bg-accent p-4 text-sm font-bold text-ink">{{ session('status') }}</div>@endif<div class="mt-8 grid gap-8 lg:grid-cols-[1fr_340px]"><div class="space-y-3">@foreach ($staff as $member)<article class="flex items-center justify-between rounded-jumbo bg-white p-5 text-ink"><div><p class="text-sm font-bold">{{ $member->user->name ?: $member->user->email }}</p><p class="mt-1 text-xs text-muted">{{ $member->role->name }} · {{ ucfirst(strtolower($member->status->value)) }}</p></div><span class="text-[10px] font-bold uppercase tracking-widest text-muted">{{ $member->invitation?->acceptedAt ? 'Accepted' : 'Invite pending' }}</span></article>@endforeach</div><aside class="rounded-jumbo bg-white p-6 text-ink"><h2 class="text-lg font-bold">Add team member</h2><form method="POST" action="{{ route('owner.team.store') }}" class="mt-5 space-y-4">@csrf<div class="grid gap-4 sm:grid-cols-2 lg:grid-cols-1"><label class="block text-xs font-bold">First name<input name="firstName" required class="mt-2 w-full rounded-tile border border-line px-3 py-2 text-sm"></label><label class="block text-xs font-bold">Last name<input name="lastName" required class="mt-2 w-full rounded-tile border border-line px-3 py-2 text-sm"></label></div><label class="block text-xs font-bold">Email<input name="email" type="email" required class="mt-2 w-full rounded-tile border border-line px-3 py-2 text-sm"></label><x-ui.button type="submit" class="w-full">Add member</x-ui.button></form></aside></div></main></x-layouts.staff>
|
||||
Reference in new issue
Block a user