Management UI
CI / ci (push) Canceled after 0s

This commit is contained in:
Stefan Lazic committed 2026-09-05 09:11:24 +01:00
1 parent cd6abeca6e
commit f11404c574
29 files changed
+876 -89

No files matched your search

@@ -0,0 +1,22 @@
<x-layouts.manager>
<main class="mx-auto max-w-4xl px-5 py-10 sm:px-8 lg:px-12 lg:py-14">
<a href="{{ route('manager.dashboard') }}" class="text-xs font-bold uppercase tracking-widest text-muted">← Businesses</a>
<div class="mt-10"><p class="text-[10px] font-bold uppercase tracking-[0.3em] text-accent-foreground">New tenant</p><h1 class="mt-3 text-4xl font-black tracking-tight">Create a business</h1><p class="mt-3 max-w-2xl text-sm leading-6 text-muted">Provision the tenant, its defaults, and the owner’s secure setup invitation together.</p></div>
@if ($errors->any())<div class="mt-8 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('manager.businesses.store') }}" class="mt-8 space-y-8">
@csrf
<section class="rounded-jumbo border border-line bg-white p-6 sm:p-8"><h2 class="text-lg font-black">Business details</h2><div class="mt-6 grid gap-5 sm:grid-cols-2">
<label class="block text-sm font-bold sm:col-span-2">Business name<input name="name" value="{{ old('name') }}" required class="mt-2 w-full rounded-tile border border-line px-4 py-3"></label>
<label class="block text-sm font-bold">Short name <span class="font-normal text-muted">(optional)</span><input name="shortName" value="{{ old('shortName') }}" class="mt-2 w-full rounded-tile border border-line px-4 py-3"></label>
<label class="block text-sm font-bold">Slug<input name="slug" value="{{ old('slug') }}" placeholder="blake-heritage" required class="mt-2 w-full rounded-tile border border-line px-4 py-3"></label>
<label class="block text-sm font-bold sm:col-span-2">Primary domain<input name="domain" value="{{ old('domain') }}" placeholder="book.example.com" required class="mt-2 w-full rounded-tile border border-line px-4 py-3"><span class="mt-2 block text-xs font-normal text-muted">This hostname routes public and owner requests to this tenant.</span></label>
<label class="block text-sm font-bold">Business email<input name="email" value="{{ old('email') }}" type="email" class="mt-2 w-full rounded-tile border border-line px-4 py-3"></label>
<label class="block text-sm font-bold">Phone<input name="phone" value="{{ old('phone') }}" class="mt-2 w-full rounded-tile border border-line px-4 py-3"></label>
<label class="block text-sm font-bold">Timezone<select name="timezone" class="mt-2 w-full rounded-tile border border-line bg-white px-4 py-3">@foreach (DateTimeZone::listIdentifiers() as $timezone)<option value="{{ $timezone }}" @selected(old('timezone', 'Europe/London') === $timezone)>{{ $timezone }}</option>@endforeach</select></label>
<label class="block text-sm font-bold">Currency<input name="currency" value="{{ old('currency', 'GBP') }}" maxlength="3" required class="mt-2 w-full rounded-tile border border-line px-4 py-3"></label>
</div></section>
<section class="rounded-jumbo border border-line bg-white p-6 sm:p-8"><h2 class="text-lg font-black">Business owner</h2><p class="mt-2 text-sm text-muted">The owner receives a one-time link to choose their password.</p><div class="mt-6 grid gap-5 sm:grid-cols-2"><label class="block text-sm font-bold">Owner name<input name="ownerName" value="{{ old('ownerName') }}" required class="mt-2 w-full rounded-tile border border-line px-4 py-3"></label><label class="block text-sm font-bold">Owner email<input name="ownerEmail" value="{{ old('ownerEmail') }}" type="email" required class="mt-2 w-full rounded-tile border border-line px-4 py-3"></label></div></section>
<div class="flex justify-end"><x-ui.button type="submit">Provision business</x-ui.button></div>
</form>
</main>
</x-layouts.manager>
@@ -0,0 +1,8 @@
<x-layouts.manager>
<main class="mx-auto max-w-4xl px-5 py-10 sm:px-8 lg:px-12 lg:py-14">
<a href="{{ route('manager.businesses.show', $business) }}" class="text-xs font-bold uppercase tracking-widest text-muted">← {{ $business->name }}</a>
<div class="mt-10"><p class="text-[10px] font-bold uppercase tracking-[0.3em] text-accent-foreground">Tenant settings</p><h1 class="mt-3 text-4xl font-black tracking-tight">Edit business</h1></div>
@if ($errors->any())<div class="mt-8 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('manager.businesses.update', $business) }}" class="mt-8 rounded-jumbo border border-line bg-white p-6 sm:p-8">@csrf @method('PUT')<div class="grid gap-5 sm:grid-cols-2"><label class="block text-sm font-bold sm:col-span-2">Business name<input name="name" value="{{ old('name', $business->name) }}" required class="mt-2 w-full rounded-tile border border-line px-4 py-3"></label><label class="block text-sm font-bold">Short name<input name="shortName" value="{{ old('shortName', $business->shortName) }}" class="mt-2 w-full rounded-tile border border-line px-4 py-3"></label><label class="block text-sm font-bold">Slug<input name="slug" value="{{ old('slug', $business->slug) }}" required class="mt-2 w-full rounded-tile border border-line px-4 py-3"></label><label class="block text-sm font-bold sm:col-span-2">Primary domain<input name="domain" value="{{ old('domain', $business->primaryDomain?->hostname) }}" required class="mt-2 w-full rounded-tile border border-line px-4 py-3"></label><label class="block text-sm font-bold">Business email<input name="email" value="{{ old('email', $business->email) }}" type="email" class="mt-2 w-full rounded-tile border border-line px-4 py-3"></label><label class="block text-sm font-bold">Phone<input name="phone" value="{{ old('phone', $business->phone) }}" class="mt-2 w-full rounded-tile border border-line px-4 py-3"></label><label class="block text-sm font-bold">Timezone<select name="timezone" class="mt-2 w-full rounded-tile border border-line bg-white px-4 py-3">@foreach (DateTimeZone::listIdentifiers() as $timezone)<option value="{{ $timezone }}" @selected(old('timezone', $business->timezone) === $timezone)>{{ $timezone }}</option>@endforeach</select></label><label class="block text-sm font-bold">Currency<input name="currency" value="{{ old('currency', $business->currency) }}" maxlength="3" required class="mt-2 w-full rounded-tile border border-line px-4 py-3"></label></div><div class="mt-8 flex justify-end"><x-ui.button type="submit">Save changes</x-ui.button></div></form>
</main>
</x-layouts.manager>
@@ -0,0 +1,10 @@
<x-layouts.manager>
<main class="mx-auto max-w-6xl px-5 py-10 sm:px-8 lg:px-12 lg:py-14">
<a href="{{ route('manager.dashboard') }}" class="text-xs font-bold uppercase tracking-widest text-muted">← Businesses</a>
<div class="mt-10 flex flex-col justify-between gap-5 sm:flex-row sm:items-end"><div><p class="text-[10px] font-bold uppercase tracking-[0.3em] text-accent-foreground">Business tenant</p><h1 class="mt-3 text-4xl font-black tracking-tight">{{ $business->name }}</h1><p class="mt-3 text-sm text-muted">{{ $business->slug }}</p></div><x-ui.button variant="secondary" href="{{ route('manager.businesses.edit', $business) }}">Edit business</x-ui.button></div>
@if (session('status'))<div class="mt-8 rounded-tile bg-accent p-4 text-sm font-bold text-ink">{{ session('status') }}</div>@endif
@if (session('owner_invitation_url'))<div class="mt-4 rounded-jumbo border border-amber-200 bg-amber-50 p-6"><p class="text-xs font-bold uppercase tracking-widest text-amber-900">Owner setup link</p><p class="mt-2 text-sm text-amber-900">Share this link securely with the business owner. It expires after seven days and can only be used once.</p><code class="mt-4 block break-all rounded-tile bg-white p-3 text-xs text-ink">{{ session('owner_invitation_url') }}</code></div>@endif
<section class="mt-10 grid gap-4 sm:grid-cols-3"><x-ui.card class="p-5"><p class="text-[10px] font-bold uppercase tracking-widest text-muted">Primary domain</p><p class="mt-3 font-black">{{ $business->primaryDomain?->hostname ?: 'Not configured' }}</p></x-ui.card><x-ui.card class="p-5"><p class="text-[10px] font-bold uppercase tracking-widest text-muted">Timezone</p><p class="mt-3 font-black">{{ $business->timezone }}</p></x-ui.card><x-ui.card class="p-5"><p class="text-[10px] font-bold uppercase tracking-widest text-muted">Defaults</p><p class="mt-3 font-black">{{ $business->hours->count() }} days · {{ $business->staff->count() }} staff</p></x-ui.card></section>
<div class="mt-10 grid gap-8 lg:grid-cols-2"><section><h2 class="text-lg font-black">Domains</h2><div class="mt-4 space-y-3">@foreach ($business->domains as $domain)<div class="flex items-center justify-between rounded-tile border border-line bg-white p-4"><div><p class="font-bold">{{ $domain->hostname }}</p><p class="mt-1 text-xs text-muted">{{ $domain->isPrimary ? 'Primary' : 'Additional' }}</p></div><x-ui.badge tone="{{ $domain->isActive ? 'accent' : 'default' }}">{{ $domain->isActive ? 'Active' : 'Inactive' }}</x-ui.badge></div>@endforeach</div></section><section><h2 class="text-lg font-black">Staff and owners</h2><div class="mt-4 space-y-3">@foreach ($business->staff as $member)<div class="rounded-tile border border-line bg-white p-4"><p class="font-bold">{{ $member->user?->name ?: $member->user?->email }}</p><p class="mt-1 text-xs text-muted">{{ $member->role?->name }} · {{ $member->user?->email }}</p></div>@endforeach</div></section></div>
</main>
</x-layouts.manager>