Files
ladill-frontdesk/resources/views/frontdesk/settings/edit.blade.php
T
isaacclad 4ce45f4989
Deploy Ladill Frontdesk / deploy (push) Successful in 1m5s
Align Branches and Team settings UI with Care layout.
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.
2026-07-16 08:25:44 +00:00

215 lines
15 KiB
PHP

<x-app-layout title="Settings">
@php
$settings = $organization->settings ?? [];
@endphp
<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">
<p class="text-sm leading-6 text-slate-600">
@if ($hasPaidPlan)
<span class="font-medium text-indigo-700">{{ $plan['label'] ?? 'Pro' }}</span> Ladill-provided visitor kiosks, unlimited kiosk software, integrations, and unlimited host emails, billed per branch (SMS still billed per segment).
@if ($billedBranches > 0)
Billed for {{ $billedBranches }} {{ str('branch')->plural($billedBranches) }}
({{ $activeBranchCount }} active).
@endif
@else
<span class="font-medium text-slate-900">Free</span> one branch (setup only), one kiosk, owner-only access. Multi-branch and team require Pro. Host alerts billed after {{ number_format($freeEmailAllowance) }} free emails per month.
@endif
</p>
@if (! $hasPaidPlan)
<a href="{{ route('frontdesk.pro.index') }}" class="btn-primary shrink-0 text-sm">Upgrade to Pro (GHS {{ number_format($proPriceMinor / 100, 0) }}/branch/mo)</a>
@else
<a href="{{ route('frontdesk.pro.index') }}" class="btn-secondary shrink-0 text-sm">Manage plan</a>
@endif
</div>
<dl class="mt-5 grid gap-4 border-t border-slate-100 pt-5 text-sm sm:grid-cols-2">
<div>
<dt class="text-slate-500">Host emails this month</dt>
<dd class="mt-0.5 font-semibold text-slate-900">
@if ($freeEmailAllowance === null)
{{ number_format($monthlyUsage->email_count) }} sent (unlimited on paid plans)
@else
{{ number_format($monthlyUsage->email_count) }} / {{ number_format($freeEmailAllowance) }} free
@endif
</dd>
</div>
<div>
<dt class="text-slate-500">Host SMS this month</dt>
<dd class="mt-0.5 font-semibold text-slate-900">{{ number_format($monthlyUsage->sms_count) }} sent</dd>
</div>
</dl>
<p class="mt-4 text-xs leading-5 text-slate-500">
Email {{ $emailCostFormatted }} each after free allowance · SMS from {{ $smsCostFormatted }} per segment charged to your
<a href="{{ route('frontdesk.wallet') }}" class="font-medium text-indigo-600 underline">Ladill wallet</a>.
</p>
</x-settings.card>
@endif
@if ($canViewBranches || $canViewTeam)
<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="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="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
<span class="mt-0.5 block text-xs text-slate-500">Locations, buildings, and reception desks</span>
</span>
<span class="text-slate-400">&rarr;</span>
</a>
</li>
@endif
@if ($canViewTeam)
<li>
<a href="{{ route('frontdesk.members.index') }}"
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="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
<span class="mt-0.5 block text-xs text-slate-500">Invite colleagues and assign Frontdesk roles</span>
</span>
<span class="text-slate-400">&rarr;</span>
</a>
</li>
@endif
</ul>
</x-settings.card>
@endif
<form method="POST" action="{{ route('frontdesk.settings.update') }}" enctype="multipart/form-data" class="space-y-6">
@csrf @method('PUT')
<x-settings.card title="Organization" description="Name, timezone, and branding shown on kiosks and badges.">
<div class="space-y-4">
@if ($canManage)
<div>
<label class="block text-sm font-medium text-slate-700">Name</label>
<input type="text" name="name" value="{{ old('name', $organization->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">Timezone</label>
<select name="timezone" class="mt-1 w-full rounded-lg border-slate-300 text-sm">
@foreach (timezone_identifiers_list() as $tz)
<option value="{{ $tz }}" @selected(old('timezone', $organization->timezone) === $tz)>{{ $tz }}</option>
@endforeach
</select>
</div>
<div>
<label class="block text-sm font-medium text-slate-700">Company logo</label>
<p class="mt-1 text-xs text-slate-500">PNG, JPG, WebP, or SVG up to 2&nbsp;MB.</p>
@if (\App\Support\OrganizationBranding::hasCustomLogo($organization))
<img src="{{ \App\Support\OrganizationBranding::logoUrl($organization) }}"
alt="{{ $organization->name }}"
class="mt-3 h-12 w-auto max-w-xs rounded-lg border border-slate-200 bg-white object-contain p-2">
<label class="mt-3 flex items-center gap-2 text-sm text-slate-600">
<input type="checkbox" name="remove_logo" value="1" @checked(old('remove_logo'))>
Remove custom logo
</label>
@endif
<input type="file" name="logo" accept="image/png,image/jpeg,image/webp,image/svg+xml"
class="mt-3 block w-full text-sm text-slate-600 file:mr-3 file:rounded-lg file:border-0 file:bg-indigo-50 file:px-3 file:py-2 file:text-sm file:font-medium file:text-indigo-700">
</div>
@else
<dl class="divide-y divide-slate-100 text-sm">
<div class="flex justify-between gap-4 py-3">
<dt class="text-slate-500">Name</dt>
<dd class="font-medium text-slate-900">{{ $organization->name }}</dd>
</div>
<div class="flex justify-between gap-4 py-3">
<dt class="text-slate-500">Timezone</dt>
<dd class="font-medium text-slate-900">{{ $organization->timezone }}</dd>
</div>
</dl>
@endif
</div>
</x-settings.card>
@if ($canManage)
<x-settings.card title="Reception & kiosk" description="Badge timing, visitor policy, and kiosk behaviour.">
<div class="space-y-5">
<div class="grid gap-4 sm:grid-cols-2">
<div>
<label class="block text-sm font-medium text-slate-700">Badge expiry (hours)</label>
<input type="number" name="badge_expiry_hours" value="{{ old('badge_expiry_hours', $settings['badge_expiry_hours'] ?? 8) }}" min="1" max="24" class="mt-1 w-full rounded-lg border-slate-300 text-sm">
</div>
<div>
<label class="block text-sm font-medium text-slate-700">Kiosk inactivity reset (seconds)</label>
<input type="number" name="kiosk_reset_seconds" value="{{ old('kiosk_reset_seconds', $settings['kiosk_reset_seconds'] ?? 120) }}" min="30" max="600" class="mt-1 w-full rounded-lg border-slate-300 text-sm">
</div>
<div class="sm:col-span-2">
<label class="block text-sm font-medium text-slate-700">Contractor badge expiry (hours)</label>
<input type="number" name="contractor_badge_expiry_hours" value="{{ old('contractor_badge_expiry_hours', data_get($settings, 'type_badge_expiry_hours.contractor', 12)) }}" min="1" max="24" class="mt-1 w-full max-w-xs rounded-lg border-slate-300 text-sm">
</div>
</div>
<div>
<label class="block text-sm font-medium text-slate-700">Visitor policy</label>
<textarea name="visitor_policy" rows="4" class="mt-2 w-full rounded-lg border-slate-300 text-sm">{{ old('visitor_policy', $settings['visitor_policy'] ?? '') }}</textarea>
</div>
<label class="flex items-start gap-3 rounded-xl border border-slate-100 bg-slate-50 px-4 py-3 text-sm">
<input type="checkbox" name="employee_kiosk_enabled" value="1" class="mt-0.5"
@checked(old('employee_kiosk_enabled', $settings['employee_kiosk_enabled'] ?? true))>
<span>
<span class="font-semibold text-slate-900">Employee sign-in on kiosk</span>
<span class="mt-0.5 block text-slate-600">Allow staff to sign in with employee code and PIN.</span>
</span>
</label>
<div class="rounded-xl border border-slate-100 bg-slate-50 px-4 py-3">
<p class="font-semibold text-slate-900">Ladill Queue</p>
<p class="mt-0.5 text-sm text-slate-600">Enable queue management in Frontdesk. Also turn on Frontdesk integration in Ladill Queue.</p>
<label class="mt-3 flex items-center gap-2 text-sm text-slate-700">
<input type="checkbox" name="queue_integration_enabled" value="1" @checked(data_get($settings, 'queue_integration_enabled'))>
Enable Ladill Queue integration
</label>
</div>
</div>
</x-settings.card>
<x-settings.card title="Notifications" description="How hosts are alerted when visitors arrive.">
<div class="space-y-5">
<div>
<p class="text-sm font-medium text-slate-700">Channels</p>
<div class="mt-3 flex flex-wrap gap-4">
@foreach ($notificationChannels as $key => $label)
<label class="flex items-center gap-2 text-sm text-slate-700">
<input type="checkbox" name="notification_channels[]" value="{{ $key }}"
@checked(in_array($key, old('notification_channels', $settings['notification_channels'] ?? ['email'])))>
{{ $label }}
</label>
@endforeach
</div>
</div>
<div class="border-t border-slate-100 pt-5">
<p class="text-sm font-medium text-slate-700">Events</p>
<div class="mt-3 grid gap-3 sm:grid-cols-2">
@foreach ($notificationEvents as $key => $label)
<label class="flex items-center gap-2 text-sm text-slate-700">
<input type="checkbox" name="notification_events[{{ $key }}]" value="1"
@checked(old("notification_events.{$key}", data_get($settings, "notification_events.{$key}", true)))>
{{ $label }}
</label>
@endforeach
</div>
</div>
<div class="border-t border-slate-100 pt-5">
<label class="block text-sm font-medium text-slate-700">Daily report recipients</label>
<input type="text" name="report_daily_recipients" value="{{ old('report_daily_recipients', implode(', ', $settings['report_daily_recipients'] ?? [])) }}" placeholder="admin@example.com, security@example.com" class="mt-2 w-full rounded-lg border-slate-300 text-sm">
</div>
</div>
</x-settings.card>
<div class="flex justify-end">
<button type="submit" class="btn-primary">Save settings</button>
</div>
@endif
</form>
</x-settings.page>
</x-app-layout>