Align Branches and Team settings UI with Care layout.
Deploy Ladill Frontdesk / deploy (push) Successful in 1m5s
Deploy Ladill Frontdesk / deploy (push) Successful in 1m5s
Use the shared settings page and card pattern for branch, team, buildings, and desks screens, with Settings breadcrumbs and a Branches & team hub card on the organization settings page.
This commit is contained in:
@@ -1,14 +1,37 @@
|
||||
<x-app-layout title="Add branch">
|
||||
<div class="mx-auto max-w-lg">
|
||||
<a href="{{ route('frontdesk.branches.index') }}" class="text-sm text-slate-500 hover:text-slate-800">← Branches</a>
|
||||
<h1 class="mt-2 text-xl font-semibold text-slate-900">Add branch</h1>
|
||||
<form method="POST" action="{{ route('frontdesk.branches.store') }}" class="mt-6 space-y-4 rounded-2xl border border-slate-200 bg-white p-6">
|
||||
@csrf
|
||||
<div><label class="block text-sm font-medium">Name</label><input type="text" name="name" required class="mt-1 w-full rounded-lg border-slate-300 text-sm"></div>
|
||||
<div><label class="block text-sm font-medium">Code</label><input type="text" name="code" class="mt-1 w-full rounded-lg border-slate-300 text-sm"></div>
|
||||
<div><label class="block text-sm font-medium">Address</label><input type="text" name="address" class="mt-1 w-full rounded-lg border-slate-300 text-sm"></div>
|
||||
<div><label class="block text-sm font-medium">Phone</label><input type="tel" name="phone" class="mt-1 w-full rounded-lg border-slate-300 text-sm"></div>
|
||||
<button type="submit" class="btn-primary w-full">Save</button>
|
||||
</form>
|
||||
<x-settings.page title="Add branch" description="Create a new location for visitors, devices, and staff.">
|
||||
<div class="mb-4 flex flex-wrap items-center gap-2 text-sm">
|
||||
<a href="{{ route('frontdesk.settings') }}" class="text-slate-500 hover:text-slate-800">Settings</a>
|
||||
<span class="text-slate-300">/</span>
|
||||
<a href="{{ route('frontdesk.branches.index') }}" class="text-slate-500 hover:text-slate-800">Branches</a>
|
||||
<span class="text-slate-300">/</span>
|
||||
<span class="font-medium text-slate-900">Add</span>
|
||||
</div>
|
||||
|
||||
<x-settings.card title="Branch details">
|
||||
<form method="POST" action="{{ route('frontdesk.branches.store') }}" class="space-y-4">
|
||||
@csrf
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-slate-700">Name</label>
|
||||
<input type="text" name="name" value="{{ old('name') }}" required class="mt-1 w-full rounded-lg border-slate-300 text-sm">
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-slate-700">Code</label>
|
||||
<input type="text" name="code" value="{{ old('code') }}" class="mt-1 w-full rounded-lg border-slate-300 text-sm">
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-slate-700">Address</label>
|
||||
<input type="text" name="address" value="{{ old('address') }}" class="mt-1 w-full rounded-lg border-slate-300 text-sm">
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-slate-700">Phone</label>
|
||||
<input type="tel" name="phone" value="{{ old('phone') }}" class="mt-1 w-full rounded-lg border-slate-300 text-sm">
|
||||
</div>
|
||||
<div class="flex justify-end gap-3">
|
||||
<a href="{{ route('frontdesk.branches.index') }}" class="rounded-xl border border-slate-200 px-4 py-2 text-sm font-medium text-slate-700 hover:bg-slate-50">Cancel</a>
|
||||
<button type="submit" class="btn-primary">Save</button>
|
||||
</div>
|
||||
</form>
|
||||
</x-settings.card>
|
||||
</x-settings.page>
|
||||
</x-app-layout>
|
||||
|
||||
@@ -1,15 +1,41 @@
|
||||
<x-app-layout title="Edit branch">
|
||||
<div class="mx-auto max-w-lg">
|
||||
<a href="{{ route('frontdesk.branches.index') }}" class="text-sm text-slate-500 hover:text-slate-800">← Branches</a>
|
||||
<h1 class="mt-2 text-xl font-semibold text-slate-900">Edit branch</h1>
|
||||
<form method="POST" action="{{ route('frontdesk.branches.update', $branch) }}" class="mt-6 space-y-4 rounded-2xl border border-slate-200 bg-white p-6">
|
||||
@csrf @method('PUT')
|
||||
<div><label class="block text-sm font-medium">Name</label><input type="text" name="name" value="{{ old('name', $branch->name) }}" required class="mt-1 w-full rounded-lg border-slate-300 text-sm"></div>
|
||||
<div><label class="block text-sm font-medium">Code</label><input type="text" name="code" value="{{ old('code', $branch->code) }}" class="mt-1 w-full rounded-lg border-slate-300 text-sm"></div>
|
||||
<div><label class="block text-sm font-medium">Address</label><input type="text" name="address" value="{{ old('address', $branch->address) }}" class="mt-1 w-full rounded-lg border-slate-300 text-sm"></div>
|
||||
<div><label class="block text-sm font-medium">Phone</label><input type="tel" name="phone" value="{{ old('phone', $branch->phone) }}" class="mt-1 w-full rounded-lg border-slate-300 text-sm"></div>
|
||||
<label class="flex items-center gap-2 text-sm"><input type="checkbox" name="is_active" value="1" @checked(old('is_active', $branch->is_active))> Active</label>
|
||||
<button type="submit" class="btn-primary w-full">Update</button>
|
||||
</form>
|
||||
<x-settings.page title="Edit branch" description="Update location details for {{ $branch->name }}.">
|
||||
<div class="mb-4 flex flex-wrap items-center gap-2 text-sm">
|
||||
<a href="{{ route('frontdesk.settings') }}" class="text-slate-500 hover:text-slate-800">Settings</a>
|
||||
<span class="text-slate-300">/</span>
|
||||
<a href="{{ route('frontdesk.branches.index') }}" class="text-slate-500 hover:text-slate-800">Branches</a>
|
||||
<span class="text-slate-300">/</span>
|
||||
<span class="font-medium text-slate-900">{{ $branch->name }}</span>
|
||||
</div>
|
||||
|
||||
<x-settings.card title="Branch details">
|
||||
<form method="POST" action="{{ route('frontdesk.branches.update', $branch) }}" class="space-y-4">
|
||||
@csrf @method('PUT')
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-slate-700">Name</label>
|
||||
<input type="text" name="name" value="{{ old('name', $branch->name) }}" required class="mt-1 w-full rounded-lg border-slate-300 text-sm">
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-slate-700">Code</label>
|
||||
<input type="text" name="code" value="{{ old('code', $branch->code) }}" class="mt-1 w-full rounded-lg border-slate-300 text-sm">
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-slate-700">Address</label>
|
||||
<input type="text" name="address" value="{{ old('address', $branch->address) }}" class="mt-1 w-full rounded-lg border-slate-300 text-sm">
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-slate-700">Phone</label>
|
||||
<input type="tel" name="phone" value="{{ old('phone', $branch->phone) }}" class="mt-1 w-full rounded-lg border-slate-300 text-sm">
|
||||
</div>
|
||||
<label class="flex items-center gap-2 text-sm text-slate-700">
|
||||
<input type="checkbox" name="is_active" value="1" @checked(old('is_active', $branch->is_active))>
|
||||
Active
|
||||
</label>
|
||||
<div class="flex justify-end gap-3">
|
||||
<a href="{{ route('frontdesk.branches.index') }}" class="rounded-xl border border-slate-200 px-4 py-2 text-sm font-medium text-slate-700 hover:bg-slate-50">Cancel</a>
|
||||
<button type="submit" class="btn-primary">Save changes</button>
|
||||
</div>
|
||||
</form>
|
||||
</x-settings.card>
|
||||
</x-settings.page>
|
||||
</x-app-layout>
|
||||
|
||||
@@ -6,45 +6,41 @@
|
||||
@endphp
|
||||
|
||||
<x-app-layout title="Branches">
|
||||
<div class="space-y-6">
|
||||
<a href="{{ route('frontdesk.settings') }}" class="inline-flex items-center gap-1 text-sm text-slate-500 hover:text-slate-800">← Settings</a>
|
||||
<x-frontdesk.page-hero
|
||||
badge="Settings · Locations · Buildings"
|
||||
title="Branches"
|
||||
description="Organize your sites, buildings, and reception desks so visits and devices stay scoped to the right location."
|
||||
:stats="[
|
||||
['value' => number_format($heroStats['total']), 'label' => 'Branches'],
|
||||
['value' => number_format($heroStats['active']), 'label' => 'Active'],
|
||||
['value' => number_format($heroStats['buildings']), 'label' => 'Buildings'],
|
||||
]">
|
||||
@if ($canManageBranches)
|
||||
<x-slot name="actions">
|
||||
<a href="{{ route('frontdesk.branches.create') }}" class="btn-primary">
|
||||
<svg class="h-4 w-4" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M12 4.5v15m7.5-7.5h-15"/></svg>
|
||||
Add branch
|
||||
</a>
|
||||
</x-slot>
|
||||
<x-settings.page title="Branches" description="Organize locations and sites so visits, devices, and staff stay scoped to the right branch.">
|
||||
<div class="mb-4 flex flex-wrap items-center justify-between gap-3">
|
||||
<div class="flex flex-wrap items-center gap-2 text-sm">
|
||||
<a href="{{ route('frontdesk.settings') }}" class="text-slate-500 hover:text-slate-800">Settings</a>
|
||||
<span class="text-slate-300">/</span>
|
||||
<span class="font-medium text-slate-900">Branches</span>
|
||||
@if (app(\App\Services\Frontdesk\FrontdeskPermissions::class)->can(
|
||||
auth()->user() ? app(\App\Services\Frontdesk\OrganizationResolver::class)->memberFor(auth()->user(), $organization) : null,
|
||||
'admin.members.view'
|
||||
))
|
||||
<a href="{{ route('frontdesk.members.index') }}" class="ml-3 text-indigo-600 hover:text-indigo-800">Team</a>
|
||||
@endif
|
||||
</x-frontdesk.page-hero>
|
||||
|
||||
<div class="overflow-hidden rounded-2xl border border-slate-200 bg-white">
|
||||
<div class="border-b border-slate-100 px-6 py-4">
|
||||
<h2 class="text-sm font-semibold text-slate-900">All branches</h2>
|
||||
</div>
|
||||
@if ($canManageBranches)
|
||||
<a href="{{ route('frontdesk.branches.create') }}" class="btn-primary">Add branch</a>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
<x-settings.card title="All branches" description="{{ number_format($heroStats['total']) }} total · {{ number_format($heroStats['active']) }} active · {{ number_format($heroStats['buildings']) }} building(s)">
|
||||
@forelse ($branches as $branch)
|
||||
<div class="flex items-center justify-between border-b border-slate-50 px-6 py-4 last:border-b-0">
|
||||
<div class="flex items-center justify-between gap-4 border-b border-slate-50 py-3 last:border-b-0">
|
||||
<div>
|
||||
<p class="font-medium text-slate-900">{{ $branch->name }}</p>
|
||||
<p class="text-sm text-slate-500">{{ $branch->address ?? 'No address' }} · {{ $branch->buildings_count }} building(s)</p>
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<x-btn href="{{ route('frontdesk.buildings.index', $branch) }}" variant="link" size="sm" plain>Buildings</x-btn>
|
||||
<a href="{{ route('frontdesk.branches.edit', $branch) }}" class="text-sm text-slate-600 hover:text-slate-800">Edit</a>
|
||||
<div class="flex items-center gap-3">
|
||||
<a href="{{ route('frontdesk.buildings.index', $branch) }}" class="text-sm font-medium text-indigo-600 hover:text-indigo-800">Buildings</a>
|
||||
@if ($canManageBranches)
|
||||
<a href="{{ route('frontdesk.branches.edit', $branch) }}" class="text-sm font-medium text-slate-600 hover:text-slate-900">Edit</a>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
@empty
|
||||
<p class="px-6 py-10 text-center text-sm text-slate-500">No branches yet.</p>
|
||||
<p class="text-sm text-slate-500">No branches yet.</p>
|
||||
@endforelse
|
||||
</div>
|
||||
</div>
|
||||
</x-settings.card>
|
||||
</x-settings.page>
|
||||
</x-app-layout>
|
||||
|
||||
@@ -1,27 +1,31 @@
|
||||
<x-app-layout :title="$branch->name.' buildings'">
|
||||
<div class="flex items-center justify-between">
|
||||
<div>
|
||||
<x-btn href="{{ route('frontdesk.branches.index') }}" variant="link" size="sm" plain>← Branches</x-btn>
|
||||
<h1 class="mt-1 text-xl font-semibold text-slate-900">{{ $branch->name }}</h1>
|
||||
</div>
|
||||
<x-settings.page title="{{ $branch->name }}" description="Buildings and reception desks for this branch.">
|
||||
<div class="mb-4 flex flex-wrap items-center gap-2 text-sm">
|
||||
<a href="{{ route('frontdesk.settings') }}" class="text-slate-500 hover:text-slate-800">Settings</a>
|
||||
<span class="text-slate-300">/</span>
|
||||
<a href="{{ route('frontdesk.branches.index') }}" class="text-slate-500 hover:text-slate-800">Branches</a>
|
||||
<span class="text-slate-300">/</span>
|
||||
<span class="font-medium text-slate-900">Buildings</span>
|
||||
</div>
|
||||
|
||||
<form method="POST" action="{{ route('frontdesk.buildings.store', $branch) }}" class="mt-6 flex gap-2 rounded-2xl border border-slate-200 bg-white p-4">
|
||||
<x-settings.card title="Add building">
|
||||
<form method="POST" action="{{ route('frontdesk.buildings.store', $branch) }}" class="flex flex-col gap-3 sm:flex-row">
|
||||
@csrf
|
||||
<input type="text" name="name" placeholder="Building name" required class="flex-1 rounded-lg border-slate-300 text-sm">
|
||||
<input type="text" name="floor_count" placeholder="Floors" class="w-24 rounded-lg border-slate-300 text-sm">
|
||||
<button type="submit" class="btn-primary">Add</button>
|
||||
<input type="text" name="floor_count" placeholder="Floors" class="w-full rounded-lg border-slate-300 text-sm sm:w-24">
|
||||
<button type="submit" class="btn-primary shrink-0">Add</button>
|
||||
</form>
|
||||
</x-settings.card>
|
||||
|
||||
<div class="mt-4 space-y-2">
|
||||
<x-settings.card title="Buildings">
|
||||
@forelse ($buildings as $building)
|
||||
<div class="flex items-center justify-between rounded-xl border border-slate-200 bg-white px-4 py-3">
|
||||
<div class="flex items-center justify-between gap-4 border-b border-slate-50 py-3 last:border-b-0">
|
||||
<div>
|
||||
<p class="font-medium">{{ $building->name }}</p>
|
||||
<p class="font-medium text-slate-900">{{ $building->name }}</p>
|
||||
<p class="text-xs text-slate-500">{{ $building->reception_desks_count }} desk(s)</p>
|
||||
</div>
|
||||
<div class="btn-group">
|
||||
<x-btn href="{{ route('frontdesk.desks.index', $building) }}" variant="link" size="sm" plain>Desks</x-btn>
|
||||
<div class="flex items-center gap-3">
|
||||
<a href="{{ route('frontdesk.desks.index', $building) }}" class="text-sm font-medium text-indigo-600 hover:text-indigo-800">Desks</a>
|
||||
<x-confirm-dialog
|
||||
:name="'remove-building-'.$building->id"
|
||||
title="Remove this building?"
|
||||
@@ -31,7 +35,7 @@
|
||||
confirm-label="Remove building"
|
||||
>
|
||||
<x-slot:trigger>
|
||||
<x-btn type="button" variant="danger" size="sm">Remove</x-btn>
|
||||
<button type="button" class="text-sm font-medium text-red-600 hover:text-red-800">Remove</button>
|
||||
</x-slot:trigger>
|
||||
</x-confirm-dialog>
|
||||
</div>
|
||||
@@ -39,5 +43,6 @@
|
||||
@empty
|
||||
<p class="text-sm text-slate-500">No buildings yet.</p>
|
||||
@endforelse
|
||||
</div>
|
||||
</x-settings.card>
|
||||
</x-settings.page>
|
||||
</x-app-layout>
|
||||
|
||||
@@ -1,19 +1,29 @@
|
||||
<x-app-layout :title="$building->name.' desks'">
|
||||
<x-btn href="{{ route('frontdesk.buildings.index', $building->branch) }}" variant="link" size="sm" plain class="mb-1">← Buildings</x-btn>
|
||||
<h1 class="mt-1 text-xl font-semibold text-slate-900">{{ $building->name }}</h1>
|
||||
<x-settings.page title="{{ $building->name }}" description="Reception desks in this building.">
|
||||
<div class="mb-4 flex flex-wrap items-center gap-2 text-sm">
|
||||
<a href="{{ route('frontdesk.settings') }}" class="text-slate-500 hover:text-slate-800">Settings</a>
|
||||
<span class="text-slate-300">/</span>
|
||||
<a href="{{ route('frontdesk.branches.index') }}" class="text-slate-500 hover:text-slate-800">Branches</a>
|
||||
<span class="text-slate-300">/</span>
|
||||
<a href="{{ route('frontdesk.buildings.index', $building->branch) }}" class="text-slate-500 hover:text-slate-800">Buildings</a>
|
||||
<span class="text-slate-300">/</span>
|
||||
<span class="font-medium text-slate-900">Desks</span>
|
||||
</div>
|
||||
|
||||
<form method="POST" action="{{ route('frontdesk.desks.store', $building) }}" class="mt-6 flex gap-2 rounded-2xl border border-slate-200 bg-white p-4">
|
||||
<x-settings.card title="Add desk">
|
||||
<form method="POST" action="{{ route('frontdesk.desks.store', $building) }}" class="flex flex-col gap-3 sm:flex-row">
|
||||
@csrf
|
||||
<input type="text" name="name" placeholder="Desk name" required class="flex-1 rounded-lg border-slate-300 text-sm">
|
||||
<input type="text" name="location" placeholder="Location" class="flex-1 rounded-lg border-slate-300 text-sm">
|
||||
<button type="submit" class="btn-primary">Add</button>
|
||||
<button type="submit" class="btn-primary shrink-0">Add</button>
|
||||
</form>
|
||||
</x-settings.card>
|
||||
|
||||
<div class="mt-4 space-y-2">
|
||||
<x-settings.card title="Reception desks">
|
||||
@forelse ($desks as $desk)
|
||||
<div class="flex items-center justify-between rounded-xl border border-slate-200 bg-white px-4 py-3">
|
||||
<div class="flex items-center justify-between gap-4 border-b border-slate-50 py-3 last:border-b-0">
|
||||
<div>
|
||||
<p class="font-medium">{{ $desk->name }}</p>
|
||||
<p class="font-medium text-slate-900">{{ $desk->name }}</p>
|
||||
<p class="text-xs text-slate-500">{{ $desk->location ?? '—' }}</p>
|
||||
</div>
|
||||
<x-confirm-dialog
|
||||
@@ -24,12 +34,13 @@
|
||||
confirm-label="Remove desk"
|
||||
>
|
||||
<x-slot:trigger>
|
||||
<x-btn type="button" variant="danger" size="sm">Remove</x-btn>
|
||||
<button type="button" class="text-sm font-medium text-red-600 hover:text-red-800">Remove</button>
|
||||
</x-slot:trigger>
|
||||
</x-confirm-dialog>
|
||||
</div>
|
||||
@empty
|
||||
<p class="text-sm text-slate-500">No reception desks yet.</p>
|
||||
@endforelse
|
||||
</div>
|
||||
</x-settings.card>
|
||||
</x-settings.page>
|
||||
</x-app-layout>
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
<x-app-layout title="Add member">
|
||||
<div class="mx-auto max-w-lg">
|
||||
<a href="{{ route('frontdesk.members.index') }}" class="text-sm text-slate-500 hover:text-slate-800">← Team</a>
|
||||
<h1 class="mt-2 text-xl font-semibold text-slate-900">Invite team member</h1>
|
||||
<x-settings.page title="Invite team member" description="They get access only to Ladill Frontdesk (plus Mail if they already have a Ladill mailbox).">
|
||||
<div class="mb-4 flex flex-wrap items-center gap-2 text-sm">
|
||||
<a href="{{ route('frontdesk.settings') }}" class="text-slate-500 hover:text-slate-800">Settings</a>
|
||||
<span class="text-slate-300">/</span>
|
||||
<a href="{{ route('frontdesk.members.index') }}" class="text-slate-500 hover:text-slate-800">Team</a>
|
||||
<span class="text-slate-300">/</span>
|
||||
<span class="font-medium text-slate-900">Invite</span>
|
||||
</div>
|
||||
|
||||
<form method="POST" x-data action="{{ route('frontdesk.members.store') }}" class="mt-6 space-y-4 rounded-2xl border border-slate-200 bg-white p-6">
|
||||
<x-settings.card title="Invitation">
|
||||
<form method="POST" action="{{ route('frontdesk.members.store') }}" class="space-y-4" x-data>
|
||||
@csrf
|
||||
|
||||
@if (! empty($mailboxOptions))
|
||||
@@ -26,6 +32,9 @@
|
||||
class="mt-1 w-full rounded-lg border-slate-300 text-sm"
|
||||
placeholder="colleague@company.com">
|
||||
<p class="mt-1 text-xs text-slate-500">They will receive an email to accept and join your Frontdesk organization.</p>
|
||||
@error('email')
|
||||
<p class="mt-1 text-sm text-red-600">{{ $message }}</p>
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<div>
|
||||
@@ -47,7 +56,11 @@
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end gap-3">
|
||||
<a href="{{ route('frontdesk.members.index') }}" class="rounded-xl border border-slate-200 px-4 py-2 text-sm font-medium text-slate-700 hover:bg-slate-50">Cancel</a>
|
||||
<button type="submit" class="btn-primary">Send invitation</button>
|
||||
</form>
|
||||
</div>
|
||||
</form>
|
||||
</x-settings.card>
|
||||
</x-settings.page>
|
||||
</x-app-layout>
|
||||
|
||||
@@ -1,32 +1,44 @@
|
||||
<x-app-layout title="Team">
|
||||
<div class="space-y-6">
|
||||
<a href="{{ route('frontdesk.settings') }}" class="inline-flex items-center gap-1 text-sm text-slate-500 hover:text-slate-800">← Settings</a>
|
||||
<x-frontdesk.page-hero
|
||||
badge="Settings · Roles · Access"
|
||||
title="Team"
|
||||
description="Invite colleagues, assign Frontdesk roles, and limit branch access for reception and security staff."
|
||||
:stats="[
|
||||
['value' => number_format($heroStats['total']), 'label' => 'Members'],
|
||||
['value' => number_format($heroStats['admins']), 'label' => 'Administrators'],
|
||||
['value' => number_format($heroStats['branch_scoped']), 'label' => 'Branch-scoped'],
|
||||
]">
|
||||
<x-slot name="actions">
|
||||
<a href="{{ route('frontdesk.members.create') }}" class="btn-primary">
|
||||
<svg class="h-4 w-4" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M12 4.5v15m7.5-7.5h-15"/></svg>
|
||||
Add member
|
||||
</a>
|
||||
</x-slot>
|
||||
</x-frontdesk.page-hero>
|
||||
@php
|
||||
$canManageMembers = app(\App\Services\Frontdesk\FrontdeskPermissions::class)->can(
|
||||
auth()->user() ? app(\App\Services\Frontdesk\OrganizationResolver::class)->memberFor(auth()->user(), $organization) : null,
|
||||
'admin.members.manage'
|
||||
);
|
||||
@endphp
|
||||
|
||||
<div class="overflow-hidden rounded-2xl border border-slate-200 bg-white">
|
||||
<div class="border-b border-slate-100 px-6 py-4">
|
||||
<h2 class="text-sm font-semibold text-slate-900">Team members</h2>
|
||||
<x-app-layout title="Team">
|
||||
<x-settings.page title="Team" description="Manage who can access Frontdesk, their roles, and which branch each member belongs to.">
|
||||
<div class="mb-4 flex flex-wrap items-center justify-between gap-3">
|
||||
<div class="flex flex-wrap items-center gap-2 text-sm">
|
||||
<a href="{{ route('frontdesk.settings') }}" class="text-slate-500 hover:text-slate-800">Settings</a>
|
||||
<span class="text-slate-300">/</span>
|
||||
<span class="font-medium text-slate-900">Team</span>
|
||||
@if (app(\App\Services\Frontdesk\FrontdeskPermissions::class)->can(
|
||||
auth()->user() ? app(\App\Services\Frontdesk\OrganizationResolver::class)->memberFor(auth()->user(), $organization) : null,
|
||||
'admin.branches.view'
|
||||
))
|
||||
<a href="{{ route('frontdesk.branches.index') }}" class="ml-3 text-indigo-600 hover:text-indigo-800">Branches</a>
|
||||
@endif
|
||||
</div>
|
||||
@if ($canManageMembers)
|
||||
<a href="{{ route('frontdesk.members.create') }}" class="btn-primary">Add member</a>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
<x-settings.card title="Team members" description="{{ number_format($heroStats['total']) }} members · {{ number_format($heroStats['admins']) }} administrators · {{ number_format($heroStats['branch_scoped']) }} branch-scoped">
|
||||
@if ($members->isEmpty())
|
||||
<p class="text-sm text-slate-500">No team members yet.</p>
|
||||
@else
|
||||
<div class="overflow-x-auto">
|
||||
<table class="min-w-full text-sm">
|
||||
<thead class="bg-slate-50 text-left text-xs uppercase text-slate-500">
|
||||
<tr><th class="px-4 py-3">Member</th><th class="px-4 py-3">Role</th><th class="px-4 py-3">Branch</th><th class="px-4 py-3"></th></tr>
|
||||
<thead class="text-left text-xs uppercase text-slate-500">
|
||||
<tr>
|
||||
<th class="pb-2 pr-4">Member</th>
|
||||
<th class="pb-2 pr-4">Role</th>
|
||||
<th class="pb-2 pr-4">Branch</th>
|
||||
<th class="pb-2"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-slate-50">
|
||||
<tbody class="divide-y divide-slate-100">
|
||||
@foreach ($members as $member)
|
||||
@php
|
||||
$display = str_contains($member->user_ref, '@')
|
||||
@@ -34,11 +46,11 @@
|
||||
: (\App\Models\User::where('public_id', $member->user_ref)->value('email') ?? $member->user_ref);
|
||||
@endphp
|
||||
<tr>
|
||||
<td class="px-4 py-3 text-sm">{{ $display }}</td>
|
||||
<td class="px-4 py-3">{{ $roles[$member->role] ?? $member->role }}</td>
|
||||
<td class="px-4 py-3">{{ $member->branch?->name ?? 'All branches' }}</td>
|
||||
<td class="px-4 py-3 text-right">
|
||||
@if ($member->user_ref !== auth()->user()->public_id)
|
||||
<td class="py-3 pr-4">{{ $display }}</td>
|
||||
<td class="py-3 pr-4">{{ $roles[$member->role] ?? $member->role }}</td>
|
||||
<td class="py-3 pr-4">{{ $member->branch?->name ?? 'All branches' }}</td>
|
||||
<td class="py-3 text-right">
|
||||
@if ($canManageMembers && $member->user_ref !== auth()->user()->public_id)
|
||||
<x-confirm-dialog
|
||||
:name="'remove-member-'.$member->id"
|
||||
title="Remove this member?"
|
||||
@@ -48,7 +60,7 @@
|
||||
confirm-label="Remove member"
|
||||
>
|
||||
<x-slot:trigger>
|
||||
<x-btn type="button" variant="danger" size="sm">Remove</x-btn>
|
||||
<button type="button" class="text-sm font-medium text-red-600 hover:text-red-800">Remove</button>
|
||||
</x-slot:trigger>
|
||||
</x-confirm-dialog>
|
||||
@endif
|
||||
@@ -58,5 +70,7 @@
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
</x-settings.card>
|
||||
</x-settings.page>
|
||||
</x-app-layout>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
$settings = $organization->settings ?? [];
|
||||
@endphp
|
||||
|
||||
<x-settings.page description="Configure branding, reception workflows, host alerts, and integrations for {{ $organization->name }}.">
|
||||
<x-settings.page title="Organization settings" description="Configure branding, reception workflows, host alerts, and access for {{ $organization->name }}.">
|
||||
@if ($canManage)
|
||||
<x-settings.card title="Plan & usage" description="Subscription limits and notification billing for {{ $organization->name }}.">
|
||||
<div class="flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between">
|
||||
@@ -48,42 +48,40 @@
|
||||
@endif
|
||||
|
||||
@if ($canViewBranches || $canViewTeam)
|
||||
<div class="grid gap-4 sm:grid-cols-2">
|
||||
<x-settings.card title="Branches & team" description="Locations and staff access for this organization. Multi-branch and team require Frontdesk Pro.">
|
||||
<ul class="space-y-3">
|
||||
@if ($canViewBranches)
|
||||
<li>
|
||||
<a href="{{ route('frontdesk.branches.index') }}"
|
||||
class="group rounded-2xl border border-slate-200 bg-white p-5 shadow-sm transition hover:border-indigo-200 hover:shadow-md">
|
||||
<div class="flex items-start justify-between gap-3">
|
||||
<div>
|
||||
<p class="text-sm font-semibold text-slate-900 group-hover:text-indigo-700">Branches</p>
|
||||
<p class="mt-1 text-sm text-slate-500">Locations, buildings, and reception desks.</p>
|
||||
</div>
|
||||
class="flex items-center justify-between rounded-xl border border-slate-100 bg-slate-50 px-4 py-3 text-sm text-slate-700 hover:text-indigo-700">
|
||||
<span>
|
||||
Branches
|
||||
@if (! $hasBranchesFeature)
|
||||
<span class="shrink-0 rounded-full bg-amber-50 px-2 py-0.5 text-[10px] font-semibold uppercase tracking-wide text-amber-700">Pro</span>
|
||||
<span class="ml-2 rounded-full bg-amber-50 px-2 py-0.5 text-[10px] font-semibold uppercase tracking-wide text-amber-700">Pro</span>
|
||||
@endif
|
||||
</div>
|
||||
<p class="mt-4 text-xs font-medium text-indigo-600">
|
||||
{{ $hasBranchesFeature ? 'Manage branches →' : 'Upgrade to unlock →' }}
|
||||
</p>
|
||||
<span class="mt-0.5 block text-xs text-slate-500">Locations, buildings, and reception desks</span>
|
||||
</span>
|
||||
<span class="text-slate-400">→</span>
|
||||
</a>
|
||||
</li>
|
||||
@endif
|
||||
@if ($canViewTeam)
|
||||
<li>
|
||||
<a href="{{ route('frontdesk.members.index') }}"
|
||||
class="group rounded-2xl border border-slate-200 bg-white p-5 shadow-sm transition hover:border-indigo-200 hover:shadow-md">
|
||||
<div class="flex items-start justify-between gap-3">
|
||||
<div>
|
||||
<p class="text-sm font-semibold text-slate-900 group-hover:text-indigo-700">Team</p>
|
||||
<p class="mt-1 text-sm text-slate-500">Invite colleagues and assign Frontdesk roles.</p>
|
||||
</div>
|
||||
class="flex items-center justify-between rounded-xl border border-slate-100 bg-slate-50 px-4 py-3 text-sm text-slate-700 hover:text-indigo-700">
|
||||
<span>
|
||||
Team
|
||||
@if (! $hasTeamFeature)
|
||||
<span class="shrink-0 rounded-full bg-amber-50 px-2 py-0.5 text-[10px] font-semibold uppercase tracking-wide text-amber-700">Pro</span>
|
||||
<span class="ml-2 rounded-full bg-amber-50 px-2 py-0.5 text-[10px] font-semibold uppercase tracking-wide text-amber-700">Pro</span>
|
||||
@endif
|
||||
</div>
|
||||
<p class="mt-4 text-xs font-medium text-indigo-600">
|
||||
{{ $hasTeamFeature ? 'Manage team →' : 'Upgrade to unlock →' }}
|
||||
</p>
|
||||
<span class="mt-0.5 block text-xs text-slate-500">Invite colleagues and assign Frontdesk roles</span>
|
||||
</span>
|
||||
<span class="text-slate-400">→</span>
|
||||
</a>
|
||||
</li>
|
||||
@endif
|
||||
</div>
|
||||
</ul>
|
||||
</x-settings.card>
|
||||
@endif
|
||||
|
||||
<form method="POST" action="{{ route('frontdesk.settings.update') }}" enctype="multipart/form-data" class="space-y-6">
|
||||
|
||||
@@ -1,21 +1,20 @@
|
||||
<x-app-layout :title="$title">
|
||||
<div class="mx-auto max-w-lg">
|
||||
<p class="text-xs font-semibold uppercase tracking-wide text-slate-400">Settings</p>
|
||||
<h1 class="mt-1 text-xl font-semibold text-slate-900">{{ $title }}</h1>
|
||||
<p class="mt-2 text-sm text-slate-600">{{ $description }}</p>
|
||||
<x-settings.page :title="$title" :description="$description">
|
||||
<div class="mb-4 flex flex-wrap items-center gap-2 text-sm">
|
||||
<a href="{{ route('frontdesk.settings') }}" class="text-slate-500 hover:text-slate-800">Settings</a>
|
||||
<span class="text-slate-300">/</span>
|
||||
<span class="font-medium text-slate-900">{{ $title }}</span>
|
||||
</div>
|
||||
|
||||
<div class="mt-6 rounded-2xl border border-indigo-200 bg-indigo-50 p-6">
|
||||
<h2 class="font-semibold text-indigo-900">Upgrade to Pro</h2>
|
||||
<p class="mt-2 text-sm text-indigo-800">
|
||||
<x-settings.card title="Upgrade to Pro">
|
||||
<p class="text-sm text-slate-600">
|
||||
GHS {{ number_format($proPriceMinor / 100, 0) }} / branch / month from your Ladill wallet —
|
||||
provided visitor kiosks, multi-branch locations, team roles, integrations, and more.
|
||||
</p>
|
||||
<a href="{{ route('frontdesk.pro.index') }}" class="btn-primary mt-4 inline-flex">View Pro plans</a>
|
||||
<p class="mt-3 text-xs text-indigo-700">
|
||||
<a href="{{ route('frontdesk.wallet') }}" class="underline">Top up your wallet</a> if you need more balance.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<a href="{{ route('frontdesk.settings') }}" class="mt-6 inline-block text-sm text-slate-600 hover:text-slate-900">← Back to settings</a>
|
||||
<div class="mt-4 flex flex-wrap items-center gap-3">
|
||||
<a href="{{ route('frontdesk.pro.index') }}" class="btn-primary">View Pro plans</a>
|
||||
<a href="{{ route('frontdesk.wallet') }}" class="text-sm font-medium text-indigo-600 hover:text-indigo-800">Top up wallet</a>
|
||||
</div>
|
||||
</x-settings.card>
|
||||
</x-settings.page>
|
||||
</x-app-layout>
|
||||
|
||||
Reference in New Issue
Block a user