Nest Care branches under settings with Frontdesk-style UI.
Deploy Ladill Care / deploy (push) Successful in 1m25s
Deploy Ladill Care / deploy (push) Successful in 1m25s
Move branch routes to /settings/branches, restyle list/create/edit with settings layout and breadcrumbs, and keep legacy /branches redirects.
This commit is contained in:
@@ -1,13 +1,37 @@
|
||||
<x-app-layout title="Add branch">
|
||||
<div class="mx-auto max-w-lg">
|
||||
<h1 class="text-xl font-semibold text-slate-900">Add branch</h1>
|
||||
<form method="POST" action="{{ route('care.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>
|
||||
</div>
|
||||
<x-settings.page title="Add branch" description="Create a new clinic location for patients, departments, and staff.">
|
||||
<div class="mb-4 flex flex-wrap items-center gap-2 text-sm">
|
||||
<a href="{{ route('care.settings') }}" class="text-slate-500 hover:text-slate-800">Settings</a>
|
||||
<span class="text-slate-300">/</span>
|
||||
<a href="{{ route('care.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('care.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('care.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,14 +1,41 @@
|
||||
<x-app-layout title="Edit branch">
|
||||
<div class="mx-auto max-w-lg">
|
||||
<h1 class="text-xl font-semibold text-slate-900">Edit branch</h1>
|
||||
<form method="POST" action="{{ route('care.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">Save changes</button>
|
||||
</form>
|
||||
</div>
|
||||
<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('care.settings') }}" class="text-slate-500 hover:text-slate-800">Settings</a>
|
||||
<span class="text-slate-300">/</span>
|
||||
<a href="{{ route('care.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('care.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('care.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>
|
||||
|
||||
@@ -1,43 +1,44 @@
|
||||
@php
|
||||
$canManageBranches = app(\App\Services\Care\CarePermissions::class)->can(
|
||||
auth()->user() ? app(\App\Services\Care\OrganizationResolver::class)->memberFor(auth()->user(), $organization) : null,
|
||||
'admin.branches.manage'
|
||||
);
|
||||
$member = auth()->user()
|
||||
? app(\App\Services\Care\OrganizationResolver::class)->memberFor(auth()->user())
|
||||
: null;
|
||||
$permissions = app(\App\Services\Care\CarePermissions::class);
|
||||
$canManageBranches = $permissions->can($member, 'admin.branches.manage');
|
||||
$canViewTeam = $permissions->can($member, 'admin.members.view');
|
||||
@endphp
|
||||
|
||||
<x-app-layout title="Branches">
|
||||
<div class="space-y-6">
|
||||
<x-care.page-hero
|
||||
badge="Locations · Sites · Coverage"
|
||||
title="Branches"
|
||||
description="Organize clinic locations and sites so patients, departments, and staff stay scoped to the right branch."
|
||||
:stats="[
|
||||
['value' => number_format($heroStats['total']), 'label' => 'Branches'],
|
||||
['value' => number_format($heroStats['active']), 'label' => 'Active'],
|
||||
['value' => number_format($heroStats['departments']), 'label' => 'Departments'],
|
||||
]">
|
||||
@if ($canManageBranches)
|
||||
<x-slot name="actions">
|
||||
<a href="{{ route('care.branches.create') }}" class="btn-primary">Add branch</a>
|
||||
</x-slot>
|
||||
@endif
|
||||
</x-care.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>
|
||||
<x-settings.page title="Branches" description="Organize clinic locations and sites so patients, departments, 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('care.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 ($canViewTeam)
|
||||
<a href="{{ route('care.members.index') }}" class="ml-3 text-indigo-600 hover:text-indigo-800">Team</a>
|
||||
@endif
|
||||
</div>
|
||||
@if ($canManageBranches)
|
||||
<a href="{{ route('care.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['departments']) }} department(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->departments_count }} department(s)</p>
|
||||
</div>
|
||||
<a href="{{ route('care.branches.edit', $branch) }}" class="text-sm text-slate-600 hover:text-slate-800">Edit</a>
|
||||
<div class="flex items-center gap-3">
|
||||
@if ($canManageBranches)
|
||||
<a href="{{ route('care.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-8 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>
|
||||
|
||||
+8
-5
@@ -158,11 +158,14 @@ Route::middleware(['auth', 'platform.session'])->group(function () {
|
||||
Route::get('/report-issue', [IssueReportController::class, 'create'])->name('care.issues.create');
|
||||
Route::post('/report-issue', [IssueReportController::class, 'store'])->name('care.issues.store');
|
||||
|
||||
Route::get('/branches', [BranchController::class, 'index'])->name('care.branches.index');
|
||||
Route::get('/branches/create', [BranchController::class, 'create'])->name('care.branches.create');
|
||||
Route::post('/branches', [BranchController::class, 'store'])->name('care.branches.store');
|
||||
Route::get('/branches/{branch}/edit', [BranchController::class, 'edit'])->name('care.branches.edit');
|
||||
Route::put('/branches/{branch}', [BranchController::class, 'update'])->name('care.branches.update');
|
||||
Route::get('/settings/branches', [BranchController::class, 'index'])->name('care.branches.index');
|
||||
Route::get('/settings/branches/create', [BranchController::class, 'create'])->name('care.branches.create');
|
||||
Route::post('/settings/branches', [BranchController::class, 'store'])->name('care.branches.store');
|
||||
Route::get('/settings/branches/{branch}/edit', [BranchController::class, 'edit'])->name('care.branches.edit');
|
||||
Route::put('/settings/branches/{branch}', [BranchController::class, 'update'])->name('care.branches.update');
|
||||
|
||||
Route::redirect('/branches', '/settings/branches');
|
||||
Route::redirect('/branches/create', '/settings/branches/create');
|
||||
|
||||
Route::get('/departments', [DepartmentController::class, 'index'])->name('care.departments.index');
|
||||
Route::get('/departments/create', [DepartmentController::class, 'create'])->name('care.departments.create');
|
||||
|
||||
@@ -131,7 +131,9 @@ class CareWebTest extends TestCase
|
||||
$this->actingAs($this->user)
|
||||
->get(route('care.branches.index'))
|
||||
->assertOk()
|
||||
->assertSee('Main Branch');
|
||||
->assertSee('All branches')
|
||||
->assertSee('Main Branch')
|
||||
->assertSee('Settings');
|
||||
}
|
||||
|
||||
public function test_members_index_loads(): void
|
||||
|
||||
Reference in New Issue
Block a user