Files
ladill-care/resources/views/care/settings/edit.blade.php
T
isaaccladandCursor 656f402e8f
Deploy Ladill Care / deploy (push) Successful in 38s
Restrict lab catalog pricing to admins only.
Split catalog CRUD onto lab.catalog.manage so technicians keep lab.manage for queue and results workflow without setting investigation prices.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-18 18:58:57 +00:00

300 lines
21 KiB
PHP

<x-app-layout title="Settings">
<x-settings.page title="Facility settings" description="Configure facility details, locations, staff access, and messaging for {{ $organization->name }}.">
<form method="POST" action="{{ route('care.settings.update') }}" enctype="multipart/form-data" class="space-y-6">
@csrf @method('PUT')
<x-settings.card title="Organization" description="Name, facility type, timezone, and branding for your facility.">
<div class="space-y-5">
<div>
<label class="block text-sm font-medium text-slate-700">Organization name</label>
<input type="text" name="name" value="{{ old('name', $organization->name) }}" @disabled(! $canManage) 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">Facility type</label>
<select name="facility_type" @disabled(! $canManage) class="mt-1 w-full rounded-lg border-slate-300 text-sm">
@foreach ($facilityTypes as $value => $label)
<option value="{{ $value }}" @selected(old('facility_type', data_get($organization->settings, 'facility_type', 'clinic')) === $value)>{{ $label }}</option>
@endforeach
</select>
</div>
<div>
<label class="block text-sm font-medium text-slate-700">Timezone</label>
<select name="timezone" @disabled(! $canManage) 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>
@if ($canManage)
<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. Shown in patient emails.</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-teal-50 file:px-3 file:py-2 file:text-sm file:font-medium file:text-teal-700">
</div>
@endif
</div>
</x-settings.card>
@if ($canViewBranches || $canViewTeam || $canViewDevices || $canViewDisplays || ($canManageLabCatalog ?? false))
<x-settings.card title="Branches & team" description="Locations, staff access, and clinical hardware for this facility. Multi-branch management requires Care Pro.">
<ul class="space-y-3">
@if ($canViewBranches)
<li>
<a href="{{ route('care.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">
@if ($hasBranchesFeature)
Clinic locations and sites ({{ $branchCount }} configured)
@else
Free includes one branch from setup · manage locations on Pro
@endif
</span>
</span>
<span class="text-slate-400">&rarr;</span>
</a>
</li>
@endif
@if ($canViewTeam)
<li>
<a href="{{ route('care.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
<span class="mt-0.5 block text-xs text-slate-500">Invite colleagues and assign Care roles</span>
</span>
<span class="text-slate-400">&rarr;</span>
</a>
</li>
@endif
@if ($canViewDevices)
<li>
<a href="{{ route('care.devices.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>
Devices
@if (! $hasClinicalDevicesFeature)
<span class="ml-2 rounded-full bg-amber-50 px-2 py-0.5 text-[10px] font-semibold uppercase tracking-wide text-amber-700">Agent · Pro</span>
@endif
<span class="mt-0.5 block text-xs text-slate-500">
Barcode scanners (browser) · agent-connected vitals / lab hardware
</span>
</span>
<span class="text-slate-400">&rarr;</span>
</a>
</li>
@endif
@if ($canViewDisplays && ($queueIntegrationEnabled || $canUseQueueIntegration))
<li>
<a href="{{ route('care.displays.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>
Waiting displays
<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>
<span class="mt-0.5 block text-xs text-slate-500">
TV boards and browser voice announcements for called tickets
</span>
</span>
<span class="text-slate-400">&rarr;</span>
</a>
</li>
@endif
<li>
<a href="{{ route('care.settings.gp-pricing') }}"
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>
GP pricing
<span class="mt-0.5 block text-xs text-slate-500">Consultation, registration, and clinic service prices</span>
</span>
<span class="text-slate-400">&rarr;</span>
</a>
</li>
@if (! empty($hasPaidPlan) && ($canManageLabCatalog ?? false))
<li>
<a href="{{ route('care.lab.catalog.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>
Laboratory catalog
<span class="mt-0.5 block text-xs text-slate-500">Investigation types and lab test prices (admins only)</span>
</span>
<span class="text-slate-400">&rarr;</span>
</a>
</li>
@endif
<li>
<a href="{{ route('care.settings.modules') }}"
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>
Modules
@if (empty($canUseSpecialtyModules))
<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">Dentistry, eye care, physiotherapy, maternity, radiology activate &amp; set prices</span>
</span>
<span class="text-slate-400">&rarr;</span>
</a>
</li>
</ul>
</x-settings.card>
@endif
@if ($canManage)
<x-settings.card title="Clinical forms" description="Patient history checklists, condition-specific forms (stroke, diabetes, COPD, and more), and follow-up scores on visits and patient charts.">
<label class="flex items-start gap-3 text-sm">
<input type="checkbox" name="assessments_engine" value="1"
@checked(old('assessments_engine', $assessmentsEngineEnabled ?? true))
class="mt-0.5 rounded border-slate-300">
<span>
<span class="font-medium text-slate-800">Show clinical forms on consultations</span>
<span class="mt-0.5 block text-xs text-slate-500">
Adds a patient history form and condition pathways on each visit.
Find them on Queue consultations, or open a patient chart for history, pathways, and follow-up scores.
</span>
</span>
</label>
</x-settings.card>
<x-settings.card title="Patient journey workflow" description="Move each visit through configured stages and control when it may enter a service queue.">
<div class="space-y-4">
<label class="flex items-start gap-3 text-sm">
<input type="checkbox" name="workflow_engine" value="1"
@checked(old('workflow_engine', $workflowEngineEnabled ?? false))
class="mt-0.5 rounded border-slate-300">
<span>
<span class="font-medium text-slate-800">Track visits through the facility workflow</span>
<span class="mt-0.5 block text-xs text-slate-500">
Check-in starts the selected workflow. Staff advance the visit stage-by-stage, and Queue only receives the patient at the matching service stage.
</span>
</span>
</label>
<label class="flex items-start gap-3 text-sm {{ empty($hasBillingFeature) ? 'opacity-60' : '' }}">
<input type="checkbox" name="financial_gates" value="1"
@checked(old('financial_gates', $financialGatesEnabled ?? false))
@disabled(empty($hasBillingFeature))
class="mt-0.5 rounded border-slate-300">
<span>
<span class="font-medium text-slate-800">Enforce payment and authorization gates</span>
<span class="mt-0.5 block text-xs text-slate-500">
Blocks service Queue activation until payment, insurance authorization, approved credit, waiver, or override clears the stage.
@if (empty($hasBillingFeature)) Billing on Care Pro or Enterprise is required. @endif
</span>
</span>
</label>
</div>
</x-settings.card>
<x-settings.card title="Messaging" description="Patient email and SMS use suite messaging by default — no Bird or SMS API keys required.">
<p class="text-sm text-slate-600">
Set a Ladill mailbox (From address) and optional SMS sender ID under Account Messaging.
Plan allowances cover included sends; Pro overage bills your wallet.
</p>
<div class="mt-3 flex flex-wrap gap-x-4 gap-y-2 text-sm font-medium">
<a href="{{ $messagingSettingsUrl ?? '#' }}" class="text-teal-700 underline" target="_blank" rel="noopener">
Account messaging settings
</a>
<a href="{{ route('care.integrations') }}" class="text-slate-500 underline">
Advanced: optional product API keys
</a>
</div>
</x-settings.card>
<x-settings.card title="Patient notifications" description="Automatically notify patients when appointments are booked or video visits are scheduled via suite messaging (mailbox + plan allowances).">
<div class="space-y-4 text-sm">
<div>
<p class="font-medium text-slate-800">When an appointment is booked</p>
<div class="mt-2 space-y-2">
<label class="flex items-start gap-2">
<input type="checkbox" name="notify_appointment_booked_sms" value="1"
@checked(old('notify_appointment_booked_sms', data_get($organization->settings, 'notify_appointment_booked_sms')))
class="mt-0.5">
<span>
Send SMS confirmation
@unless ($messagingSmsReady)
<span class="block text-xs text-amber-700">Platform SMS is not configured on this Care instance, and no product SMS key is connected.</span>
@endunless
</span>
</label>
<label class="flex items-start gap-2">
<input type="checkbox" name="notify_appointment_booked_email" value="1"
@checked(old('notify_appointment_booked_email', data_get($organization->settings, 'notify_appointment_booked_email')))
class="mt-0.5">
<span>
Send email confirmation
@unless ($messagingEmailReady)
<span class="block text-xs text-amber-700">Platform email is not configured, and no Bird key is connected. Set a mailbox under Account Messaging after platform keys are live.</span>
@endunless
</span>
</label>
</div>
</div>
<div>
<p class="font-medium text-slate-800">When a video visit is scheduled</p>
<div class="mt-2 space-y-2">
<label class="flex items-start gap-2">
<input type="checkbox" name="notify_video_scheduled_sms" value="1"
@checked(old('notify_video_scheduled_sms', data_get($organization->settings, 'notify_video_scheduled_sms')))
class="mt-0.5">
<span>
Send SMS with join link
@unless ($messagingSmsReady)
<span class="block text-xs text-amber-700">Platform SMS is not configured on this Care instance, and no product SMS key is connected.</span>
@endunless
</span>
</label>
<label class="flex items-start gap-2">
<input type="checkbox" name="notify_video_scheduled_email" value="1"
@checked(old('notify_video_scheduled_email', data_get($organization->settings, 'notify_video_scheduled_email')))
class="mt-0.5">
<span>
Send email with join link
<span class="block text-xs text-slate-500">Uses suite messaging when available; otherwise Meet may email the invite.</span>
</span>
</label>
</div>
</div>
</div>
</x-settings.card>
<x-settings.card title="Service queues" description="Enable in-app ticket numbers and Call next → Serve → Complete on patient queue, pharmacy, lab, billing, and specialty modules. Requires Care Pro or Enterprise.">
@if (! empty($canUseQueueIntegration))
<label class="flex items-center gap-2 text-sm">
<input type="checkbox" name="queue_integration_enabled" value="1" @checked(data_get($organization->settings, 'queue_integration_enabled'))>
Enable service queues
</label>
@else
<div class="rounded-xl border border-amber-100 bg-amber-50 px-4 py-3 text-sm text-amber-900">
<p class="font-medium">Service queues are a Pro feature</p>
<p class="mt-1 text-amber-800">Free includes core patient records, appointments &amp; consults, and basic workflows. Upgrade for ticket numbers and call-next on clinical lines.</p>
<a href="{{ route('care.pro.index') }}" class="mt-3 inline-flex text-sm font-semibold text-indigo-700 hover:text-indigo-900">View Care Pro plans </a>
</div>
<input type="hidden" name="queue_integration_enabled" value="0">
@endif
</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>