updates for admin area

This commit is contained in:
Mark Gregory
2026-09-12 21:18:19 +01:00
parent ab3134de13
commit 5e2f4a1fa7
42 changed files with 894 additions and 210 deletions
+55
View File
@@ -0,0 +1,55 @@
@extends('layouts.admin')
@section('title', ($record ? 'Edit ' : 'Add ').$definition['singular'])
@section('page-title', $definition['title'])
@section('content')
<div class="page-heading admin-heading crud-heading">
<div><div class="eyebrow">{{ $record ? 'Edit record' : 'New record' }}</div><h1>{{ $record ? 'Edit '.$definition['singular'] : 'Add '.$definition['singular'] }}</h1><p>Complete the fields below and save your changes.</p></div>
<a class="toggle-button" href="{{ route('admin.resources.index', $resource) }}">← Back to {{ strtolower($definition['title']) }}</a>
</div>
@if($errors->any())
<div class="admin-error"><strong>Please correct the following:</strong><ul>@foreach($errors->all() as $error)<li>{{ $error }}</li>@endforeach</ul></div>
@endif
<div class="admin-card crud-form-card">
<form method="post" action="{{ $record ? route('admin.resources.update', [$resource, $record->getKey()]) : route('admin.resources.store', $resource) }}" class="crud-form">
@csrf
@if($record) @method('PUT') @endif
<div class="crud-form-grid">
@foreach($definition['fields'] as $name => $field)
@php
$raw = old($name);
if ($raw === null && $record) {
if ($name === 'role' && method_exists($record, 'getRoleNames')) $raw = $record->getRoleNames()->first();
elseif ($name === 'filters' && is_array($record->filters ?? null)) $raw = json_encode($record->filters, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
else $raw = data_get($record, $name);
}
if ($raw instanceof \Carbon\CarbonInterface && ($field['type'] ?? '') === 'datetime-local') $raw = $raw->format('Y-m-d\TH:i');
if ($raw instanceof \Carbon\CarbonInterface && ($field['type'] ?? '') === 'date') $raw = $raw->format('Y-m-d');
@endphp
@if(($field['type'] ?? 'text') === 'checkbox')
<label class="crud-check full-field"><input type="hidden" name="{{ $name }}" value="0"><input type="checkbox" name="{{ $name }}" value="1" @checked((bool)$raw)><span><strong>{{ $field['label'] }}</strong></span></label>
@else
<label class="crud-field {{ !empty($field['large']) || ($field['type'] ?? '') === 'textarea' ? 'full-field' : '' }}">
<span>{{ $field['label'] }}</span>
@if(($field['type'] ?? '') === 'select')
<select name="{{ $name }}">
@if(!empty($field['nullable']))<option value="">— None —</option>@endif
@php $selectOptions = isset($field['options']) ? ($options[$field['options']] ?? []) : ($field['values'] ?? []); @endphp
@foreach($selectOptions as $value => $label)<option value="{{ $value }}" @selected((string)$raw === (string)$value)>{{ $label }}</option>@endforeach
</select>
@elseif(($field['type'] ?? '') === 'textarea')
<textarea name="{{ $name }}" rows="{{ !empty($field['large']) ? 14 : 5 }}">{{ $raw }}</textarea>
@else
<input type="{{ $field['type'] ?? 'text' }}" name="{{ $name }}" value="{{ ($field['type'] ?? '') === 'password' ? '' : $raw }}" @if(isset($field['step'])) step="{{ $field['step'] }}" @endif @if(isset($field['min'])) min="{{ $field['min'] }}" @endif @if(isset($field['max'])) max="{{ $field['max'] }}" @endif>
@endif
@if(!empty($field['help']))<small>{{ $field['help'] }}</small>@endif
@error($name)<small class="field-error">{{ $message }}</small>@enderror
</label>
@endif
@endforeach
</div>
<div class="crud-form-actions"><button class="admin-button primary" type="submit">{{ $record ? 'Save changes' : 'Create '.$definition['singular'] }}</button><a class="toggle-button" href="{{ route('admin.resources.index', $resource) }}">Cancel</a></div>
</form>
</div>
@endsection
@@ -0,0 +1,62 @@
@extends('layouts.admin')
@section('title', $definition['title'])
@section('page-title', $definition['title'])
@section('content')
<div class="page-heading admin-heading crud-heading">
<div>
<div class="eyebrow">Management</div>
<h1>{{ $definition['title'] }}</h1>
<p>Create, edit and remove {{ strtolower($definition['title']) }} records.</p>
</div>
<div class="crud-heading-actions">
@if($resource === 'roles')<a class="toggle-button" href="{{ route('admin.resources.index', 'permissions') }}">Manage permissions</a>@endif
@if($resource === 'permissions')<a class="toggle-button" href="{{ route('admin.resources.index', 'roles') }}">Manage roles</a>@endif
@if($resource === 'settings')<form method="post" action="{{ route('admin.settings.clear-cache') }}">@csrf<button class="toggle-button" type="submit">Clear application cache</button></form>@endif
<a class="admin-button primary" href="{{ route('admin.resources.create', $resource) }}">+ Add {{ strtolower($definition['singular']) }}</a>
</div>
</div>
<div class="admin-card crud-toolbar">
<form method="get" action="{{ route('admin.resources.index', $resource) }}" class="crud-search">
<input type="search" name="q" value="{{ request('q') }}" placeholder="Search {{ strtolower($definition['title']) }}…">
<button class="admin-button" type="submit">Search</button>
@if(request('q'))<a class="toggle-button" href="{{ route('admin.resources.index', $resource) }}">Clear</a>@endif
</form>
<span class="record-count">{{ number_format($records->total()) }} records</span>
</div>
<div class="admin-card table-card">
<div class="responsive-table">
<table class="crud-table">
<thead><tr>@foreach($definition['columns'] as $label)<th>{{ $label }}</th>@endforeach<th class="actions-col">Actions</th></tr></thead>
<tbody>
@forelse($records as $record)
<tr>
@foreach($definition['columns'] as $path => $label)
@php
$value = $path === 'roles_text' ? $record->getRoleNames()->join(', ') : data_get($record, $path);
if ($value instanceof \Carbon\CarbonInterface) $value = $value->format('j M Y H:i');
elseif (is_bool($value)) $value = $value ? 'Yes' : 'No';
elseif (in_array($path, ['amount','total','deposit','price_from'], true) && $value !== null) $value = '£'.number_format((float)$value, 2);
@endphp
<td data-label="{{ $label }}">{{ filled($value) ? $value : '—' }}</td>
@endforeach
<td data-label="Actions">
<div class="row-actions">
<a class="toggle-button" href="{{ route('admin.resources.edit', [$resource, $record->getKey()]) }}">Edit</a>
<form method="post" action="{{ route('admin.resources.destroy', [$resource, $record->getKey()]) }}" onsubmit="return confirm('Delete this {{ strtolower($definition['singular']) }}? This cannot be undone.')">
@csrf @method('DELETE')
<button class="danger-button" type="submit">Delete</button>
</form>
</div>
</td>
</tr>
@empty
<tr><td colspan="{{ count($definition['columns']) + 1 }}"><div class="feature-empty"><div class="feature-icon">+</div><h2>No {{ strtolower($definition['title']) }} yet</h2><p>Create the first record to start managing this area.</p><a class="admin-button primary" href="{{ route('admin.resources.create', $resource) }}">Add {{ strtolower($definition['singular']) }}</a></div></td></tr>
@endforelse
</tbody>
</table>
</div>
</div>
<div class="crud-pagination">{{ $records->links() }}</div>
@endsection
+4 -4
View File
@@ -3,10 +3,10 @@
@section('page-title','Dashboard')
@section('content')
<div class="page-heading admin-heading"><div><div class="eyebrow">Marketplace control centre</div><h1>Dashboard</h1><p>Live overview of users, DJs, bookings and moderation.</p></div></div>
<div class="admin-stats">@foreach($stats as $key=>$value)<a class="admin-stat" href="{{ $key === 'pending reviews' ? route('admin.section','reviews') : ($key === 'djs' ? route('admin.section','djs') : ($key === 'bookings' ? route('admin.section','bookings') : route('admin.section','users'))) }}"><span>{{ ucfirst($key) }}</span><strong>{{ number_format($value) }}</strong><small>Open section →</small></a>@endforeach</div>
<div class="admin-stats">@foreach($stats as $key=>$value)<a class="admin-stat" href="{{ $key === 'pending reviews' ? route('admin.resources.index','reviews') : ($key === 'djs' ? route('admin.resources.index','djs') : ($key === 'bookings' ? route('admin.resources.index','bookings') : route('admin.resources.index','users'))) }}"><span>{{ ucfirst($key) }}</span><strong>{{ number_format($value) }}</strong><small>Open section →</small></a>@endforeach</div>
<div class="admin-grid">
<section class="admin-card"><div class="panel-head"><h2>Newest users</h2><a href="{{ route('admin.section','users') }}">Manage</a></div>@forelse($recentUsers as $user)<div class="admin-list-row"><div><strong>{{ $user->name }}</strong><span>{{ $user->email }}</span></div><span>{{ $user->created_at?->diffForHumans() }}</span></div>@empty<div class="empty-state">No users yet.</div>@endforelse</section>
<section class="admin-card"><div class="panel-head"><h2>Latest enquiries</h2><a href="{{ route('admin.section','clients') }}">Clients</a></div>@forelse($recentEnquiries as $item)<div class="admin-list-row"><div><strong>{{ $item->user?->name }}</strong><span>{{ $item->djProfile?->stage_name }} · {{ $item->event_type }}</span></div><span class="status-pill">{{ ucfirst($item->status) }}</span></div>@empty<div class="empty-state">No enquiries yet.</div>@endforelse</section>
<section class="admin-card admin-card-wide"><div class="panel-head"><h2>Recent bookings</h2><a href="{{ route('admin.section','bookings') }}">View all</a></div><div class="responsive-table"><table><thead><tr><th>Client</th><th>DJ</th><th>Date</th><th>Total</th><th>Status</th></tr></thead><tbody>@forelse($recentBookings as $item)<tr><td>{{ $item->client?->name }}</td><td>{{ $item->djProfile?->stage_name }}</td><td>{{ optional($item->event_date)->format('j M Y') }}</td><td>£{{ number_format((float)$item->total,2) }}</td><td><span class="status-pill">{{ ucfirst($item->status) }}</span></td></tr>@empty<tr><td colspan="5">No bookings yet.</td></tr>@endforelse</tbody></table></div></section>
<section class="admin-card"><div class="panel-head"><h2>Newest users</h2><a href="{{ route('admin.resources.index','users') }}">Manage</a></div>@forelse($recentUsers as $user)<div class="admin-list-row"><div><strong>{{ $user->name }}</strong><span>{{ $user->email }}</span></div><span>{{ $user->created_at?->diffForHumans() }}</span></div>@empty<div class="empty-state">No users yet.</div>@endforelse</section>
<section class="admin-card"><div class="panel-head"><h2>Latest enquiries</h2><a href="{{ route('admin.resources.index','clients') }}">Clients</a></div>@forelse($recentEnquiries as $item)<div class="admin-list-row"><div><strong>{{ $item->user?->name }}</strong><span>{{ $item->djProfile?->stage_name }} · {{ $item->event_type }}</span></div><span class="status-pill">{{ ucfirst($item->status) }}</span></div>@empty<div class="empty-state">No enquiries yet.</div>@endforelse</section>
<section class="admin-card admin-card-wide"><div class="panel-head"><h2>Recent bookings</h2><a href="{{ route('admin.resources.index','bookings') }}">View all</a></div><div class="responsive-table"><table><thead><tr><th>Client</th><th>DJ</th><th>Date</th><th>Total</th><th>Status</th></tr></thead><tbody>@forelse($recentBookings as $item)<tr><td>{{ $item->client?->name }}</td><td>{{ $item->djProfile?->stage_name }}</td><td>{{ optional($item->event_date)->format('j M Y') }}</td><td>£{{ number_format((float)$item->total,2) }}</td><td><span class="status-pill">{{ ucfirst($item->status) }}</span></td></tr>@empty<tr><td colspan="5">No bookings yet.</td></tr>@endforelse</tbody></table></div></section>
</div>
@endsection
-38
View File
@@ -1,38 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>{{ ucwords(str_replace('-', ' ', $section)) }} — BeatBook Admin</title>
@vite(['resources/css/app.css'])
</head>
<body>
<div class="admin">
<aside class="sidebar">
<a class="brand" href="{{ route('admin.dashboard') }}"><b>◉</b> BeatBook</a>
<p class="muted">Administration</p>
<a href="{{ route('admin.dashboard') }}">Dashboard</a>
@foreach([
'users' => 'Users', 'djs' => 'DJs & Businesses', 'clients' => 'Clients',
'bookings' => 'Bookings', 'payments' => 'Payments', 'reviews' => 'Reviews',
'messages' => 'Messages', 'notifications' => 'Notifications', 'support' => 'Support',
'reports' => 'Reports', 'content' => 'Content', 'roles' => 'Roles & Permissions',
'privacy' => 'Privacy', 'settings' => 'Settings'
] as $key => $label)
<a href="{{ route('admin.section', $key) }}">{{ $label }}</a>
@endforeach
<a href="{{ route('home') }}">Back to site</a>
</aside>
<main class="admin-main">
<div class="eyebrow">Administration</div>
<h1>{{ ucwords(str_replace('-', ' ', $section)) }}</h1>
<p style="color:#64748b">This BeatBook administration section is connected and ready for its management workflow.</p>
<div class="stats">
@foreach($counts as $label => $value)
<div class="stat"><span>{{ ucfirst($label) }}</span><strong>{{ number_format($value) }}</strong></div>
@endforeach
</div>
</main>
</div>
</body>
</html>
@@ -1,4 +0,0 @@
@extends('layouts.admin') @section('title','Bookings') @section('page-title','Bookings') @section('content')
<div class="page-heading admin-heading"><div><div class="eyebrow">Events</div><h1>Bookings</h1><p>All marketplace bookings and event values.</p></div><span class="metric-chip">{{ number_format($counts['bookings']) }} bookings</span></div>
<div class="admin-card table-card"><div class="responsive-table"><table><thead><tr><th>Client</th><th>DJ</th><th>Event date</th><th>Total</th><th>Deposit</th><th>Status</th></tr></thead><tbody>@forelse($bookings as $item)<tr><td>{{ $item->client?->name }}</td><td>{{ $item->djProfile?->stage_name }}</td><td>{{ optional($item->event_date)->format('j M Y') }}</td><td>£{{ number_format((float)$item->total,2) }}</td><td>£{{ number_format((float)$item->deposit,2) }}</td><td><span class="status-pill">{{ ucfirst($item->status) }}</span></td></tr>@empty<tr><td colspan="6">No bookings yet.</td></tr>@endforelse</tbody></table></div></div>{{ $bookings->links() }}
@endsection
@@ -1,4 +0,0 @@
@extends('layouts.admin') @section('title','Clients') @section('page-title','Clients') @section('content')
<div class="page-heading admin-heading"><div><div class="eyebrow">Customers</div><h1>Clients</h1><p>Review client activity across enquiries and bookings.</p></div><span class="metric-chip">{{ number_format($counts['clients']) }} clients</span></div>
<div class="admin-card table-card"><div class="responsive-table"><table><thead><tr><th>Client</th><th>Phone</th><th>Enquiries</th><th>Bookings</th><th>Joined</th></tr></thead><tbody>@forelse($clients as $client)<tr><td><strong>{{ $client->name }}</strong><small>{{ $client->email }}</small></td><td>{{ $client->phone ?: '—' }}</td><td>{{ $client->enquiries_count }}</td><td>{{ $client->bookings_count }}</td><td>{{ $client->created_at?->format('j M Y') }}</td></tr>@empty<tr><td colspan="5">No clients yet.</td></tr>@endforelse</tbody></table></div></div>{{ $clients->links() }}
@endsection
@@ -1,4 +0,0 @@
@extends('layouts.admin') @section('title','Content') @section('page-title','Content') @section('content')
<div class="page-heading admin-heading"><div><div class="eyebrow">Website</div><h1>Content</h1><p>Public-site content and marketplace presentation.</p></div></div>
<div class="settings-grid"><a class="admin-card action-card" href="{{ route('home') }}"><h2>Homepage</h2><p>Review hero, featured DJs, how it works and DJ proposition.</p><span>Open page →</span></a><a class="admin-card action-card" href="{{ route('djs.index') }}"><h2>DJ directory</h2><p>Review public listings, filtering and profile presentation.</p><span>Open directory →</span></a><a class="admin-card action-card" href="{{ route('privacy') }}"><h2>Legal content</h2><p>Review privacy, cookie and terms content.</p><span>Open privacy →</span></a></div>
@endsection
@@ -1,4 +0,0 @@
@extends('layouts.admin') @section('title','DJs & businesses') @section('page-title','DJs & businesses') @section('content')
<div class="page-heading admin-heading"><div><div class="eyebrow">Marketplace supply</div><h1>DJs & businesses</h1><p>Control visibility and featured placement.</p></div><span class="metric-chip">{{ number_format($counts['djs']) }} profiles</span></div>
<div class="admin-card table-card"><div class="responsive-table"><table><thead><tr><th>DJ</th><th>Owner</th><th>City</th><th>Price</th><th>Published</th><th>Featured</th></tr></thead><tbody>@forelse($djs as $dj)<tr><td><strong>{{ $dj->stage_name }}</strong><small>{{ $dj->business?->name ?: 'Independent' }}</small></td><td>{{ $dj->user?->email }}</td><td>{{ $dj->city }}</td><td>{{ $dj->price_from ? '£'.number_format((float)$dj->price_from) : '—' }}</td><td><form method="post" action="{{ route('admin.djs.published',$dj) }}">@csrf @method('PATCH')<button class="toggle-button {{ $dj->is_published ? 'on' : '' }}" type="submit">{{ $dj->is_published ? 'Published' : 'Hidden' }}</button></form></td><td><form method="post" action="{{ route('admin.djs.featured',$dj) }}">@csrf @method('PATCH')<button class="toggle-button {{ $dj->is_featured ? 'on' : '' }}" type="submit">{{ $dj->is_featured ? 'Featured' : 'Standard' }}</button></form></td></tr>@empty<tr><td colspan="6">No DJ profiles yet.</td></tr>@endforelse</tbody></table></div></div>{{ $djs->links() }}
@endsection
@@ -1,4 +0,0 @@
@extends('layouts.admin') @section('title','Messages') @section('page-title','Messages') @section('content')
<div class="page-heading admin-heading"><div><div class="eyebrow">Communication</div><h1>Messages</h1><p>Marketplace messaging will appear here once conversations are created.</p></div></div>
<div class="admin-card"><div class="feature-empty"><div class="feature-icon">✉</div><h2>No conversations yet</h2><p>Enquiry messaging can be added here without exposing private contact details between clients and DJs.</p><a class="admin-button" href="{{ route('admin.section','clients') }}">View clients</a></div></div>
@endsection
@@ -1,4 +0,0 @@
@extends('layouts.admin') @section('title','Notifications') @section('page-title','Notifications') @section('content')
<div class="page-heading admin-heading"><div><div class="eyebrow">Delivery</div><h1>Notifications</h1><p>System alerts and delivery health.</p></div></div>
<div class="settings-grid"><div class="admin-card"><h2>Notification channels</h2><div class="settings-list"><div><strong>Email</strong><span>Laravel mail channel</span><span class="status-pill">Configured</span></div><div><strong>Database</strong><span>In-app notifications</span><span class="status-pill">Ready</span></div></div></div><div class="admin-card"><h2>Recommended events</h2><p class="admin-muted">Booking confirmation, new enquiry, review request, payment receipt and support replies can be delivered from this area.</p></div></div>
@endsection
@@ -1,4 +0,0 @@
@extends('layouts.admin') @section('title','Payments') @section('page-title','Payments') @section('content')
<div class="page-heading admin-heading"><div><div class="eyebrow">Finance</div><h1>Payments</h1><p>Payment state and booking value overview.</p></div></div>
<div class="admin-card table-card"><div class="responsive-table"><table><thead><tr><th>Booking</th><th>Client</th><th>DJ</th><th>Total</th><th>Deposit</th><th>Payment</th></tr></thead><tbody>@forelse($bookings as $item)<tr><td>{{ Str::limit($item->id,10,'…') }}</td><td>{{ $item->client?->name }}</td><td>{{ $item->djProfile?->stage_name }}</td><td>£{{ number_format((float)$item->total,2) }}</td><td>£{{ number_format((float)$item->deposit,2) }}</td><td><span class="status-pill">{{ $item->paid_at ? 'Paid' : 'Outstanding' }}</span></td></tr>@empty<tr><td colspan="6">No payment records yet.</td></tr>@endforelse</tbody></table></div></div>{{ $bookings->links() }}
@endsection
@@ -1,4 +0,0 @@
@extends('layouts.admin') @section('title','Privacy') @section('page-title','Privacy') @section('content')
<div class="page-heading admin-heading"><div><div class="eyebrow">Compliance</div><h1>Privacy</h1><p>Quick access to the public legal policies and privacy controls.</p></div></div>
<div class="settings-grid"><a class="admin-card action-card" href="{{ route('privacy') }}"><h2>Privacy policy</h2><p>Review the current public privacy policy.</p><span>Open policy →</span></a><a class="admin-card action-card" href="{{ route('cookies') }}"><h2>Cookie policy</h2><p>Review necessary, analytics and marketing cookie information.</p><span>Open policy →</span></a><a class="admin-card action-card" href="{{ route('terms') }}"><h2>Terms</h2><p>Review marketplace terms shown to users.</p><span>Open terms →</span></a></div>
@endsection
@@ -1,4 +0,0 @@
@extends('layouts.admin') @section('title','Reports') @section('page-title','Reports') @section('content')
<div class="page-heading admin-heading"><div><div class="eyebrow">Performance</div><h1>Reports</h1><p>Marketplace totals calculated from live BeatBook data.</p></div></div>
<div class="admin-stats"><div class="admin-stat"><span>Booking value</span><strong>£{{ number_format((float)$report['booking_value'],2) }}</strong></div><div class="admin-stat"><span>Deposits</span><strong>£{{ number_format((float)$report['deposits'],2) }}</strong></div><div class="admin-stat"><span>Published DJs</span><strong>{{ $report['published_djs'] }}</strong></div><div class="admin-stat"><span>Pending reviews</span><strong>{{ $report['pending_reviews'] }}</strong></div></div>
@endsection
@@ -1,4 +0,0 @@
@extends('layouts.admin') @section('title','Reviews') @section('page-title','Reviews') @section('content')
<div class="page-heading admin-heading"><div><div class="eyebrow">Trust & safety</div><h1>Reviews</h1><p>Moderate feedback before it appears publicly.</p></div><span class="metric-chip">{{ number_format($counts['reviews']) }} reviews</span></div>
<div class="admin-card table-card"><div class="responsive-table"><table><thead><tr><th>Reviewer</th><th>DJ</th><th>Rating</th><th>Review</th><th>Status</th><th>Moderate</th></tr></thead><tbody>@forelse($reviews as $review)<tr><td>{{ $review->user?->name }}</td><td>{{ $review->djProfile?->stage_name }}</td><td>★ {{ $review->rating }}/5</td><td><strong>{{ $review->title ?: 'Review' }}</strong><small>{{ Str::limit($review->body,80) }}</small></td><td><span class="status-pill">{{ ucfirst($review->status) }}</span></td><td><form class="inline-controls" method="post" action="{{ route('admin.reviews.status',$review) }}">@csrf @method('PATCH')<select name="status"><option value="pending" @selected($review->status==='pending')>Pending</option><option value="published" @selected($review->status==='published')>Published</option><option value="rejected" @selected($review->status==='rejected')>Rejected</option></select><button class="admin-button">Save</button></form></td></tr>@empty<tr><td colspan="6">No reviews yet.</td></tr>@endforelse</tbody></table></div></div>{{ $reviews->links() }}
@endsection
@@ -1,4 +0,0 @@
@extends('layouts.admin') @section('title','Roles & permissions') @section('page-title','Roles & permissions') @section('content')
<div class="page-heading admin-heading"><div><div class="eyebrow">Access control</div><h1>Roles & permissions</h1><p>Roles currently available to BeatBook accounts.</p></div></div>
<div class="role-grid">@foreach($roles as $role)<div class="admin-card"><span class="role-badge">{{ $role->name }}</span><strong class="role-count">{{ $role->users_count }}</strong><p>{{ Str::plural('user',$role->users_count) }}</p></div>@endforeach</div>
@endsection
@@ -1,4 +0,0 @@
@extends('layouts.admin') @section('title','Settings') @section('page-title','Settings') @section('content')
<div class="page-heading admin-heading"><div><div class="eyebrow">Application</div><h1>Settings</h1><p>Operational controls for the BeatBook installation.</p></div></div>
<div class="settings-grid"><div class="admin-card"><h2>Environment</h2><div class="settings-list"><div><strong>Application</strong><span>{{ config('app.name') }}</span></div><div><strong>Environment</strong><span>{{ app()->environment() }}</span></div><div><strong>URL</strong><span>{{ config('app.url') }}</span></div></div></div><div class="admin-card"><h2>Maintenance</h2><p class="admin-muted">Clear application cache after configuration or content changes.</p><form method="post" action="{{ route('admin.settings.clear-cache') }}">@csrf<button class="admin-button" type="submit">Clear application cache</button></form></div></div>
@endsection
@@ -1,4 +0,0 @@
@extends('layouts.admin') @section('title','Support') @section('page-title','Support') @section('content')
<div class="page-heading admin-heading"><div><div class="eyebrow">Customer care</div><h1>Support</h1><p>Central area for customer and DJ support cases.</p></div></div>
<div class="admin-card"><div class="feature-empty"><div class="feature-icon">?</div><h2>No open support cases</h2><p>The support queue is ready for a ticket model and inbound support form when you enable that workflow.</p></div></div>
@endsection
@@ -1,4 +0,0 @@
@extends('layouts.admin') @section('title','Users') @section('page-title','Users') @section('content')
<div class="page-heading admin-heading"><div><div class="eyebrow">People</div><h1>Users</h1><p>Manage accounts and assign marketplace roles.</p></div><span class="metric-chip">{{ number_format($counts['users']) }} users</span></div>
<div class="admin-card table-card"><div class="responsive-table"><table><thead><tr><th>User</th><th>Role</th><th>Joined</th><th>Change role</th></tr></thead><tbody>@foreach($users as $user)<tr><td><strong>{{ $user->name }}</strong><small>{{ $user->email }}</small></td><td>{{ $user->getRoleNames()->join(', ') ?: 'No role' }}</td><td>{{ $user->created_at?->format('j M Y') }}</td><td><form class="inline-controls" method="post" action="{{ route('admin.users.role',$user) }}">@csrf @method('PATCH')<select name="role">@foreach(['client','dj','support','moderator','admin','super-admin'] as $role)<option value="{{ $role }}" @selected($user->hasRole($role))>{{ ucfirst($role) }}</option>@endforeach</select><button class="admin-button" type="submit">Save</button></form></td></tr>@endforeach</tbody></table></div></div>{{ $users->links() }}
@endsection