Add industry packages that provision workflow stages on onboarding.
Deploy Ladill Queue / deploy (push) Successful in 1m39s

Queue Core stays generic; selecting Healthcare, Banking, Restaurant, and other industries installs departments, stages (queues), service points, workflows, terminology, and announcement profiles without code changes per vertical. Care-linked orgs skip stage materialization so Care remains the clinical provisioner.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
isaacclad
2026-07-17 18:00:31 +00:00
co-authored by Cursor
parent 0854b431bc
commit a4d8775a82
15 changed files with 2302 additions and 65 deletions
+23 -4
View File
@@ -1,7 +1,9 @@
<x-app-layout title="Set up Queue">
<div class="mx-auto max-w-xl">
<h1 class="text-2xl font-semibold text-slate-900 dark:text-white">Welcome to Ladill Queue</h1>
<p class="mt-2 text-sm text-slate-600 dark:text-slate-400">Configure your organization to start managing customer flow.</p>
<p class="mt-2 text-sm text-slate-600 dark:text-slate-400">
Choose your industry and we will provision departments, workflow stages, service points, announcements, and dashboards for you.
</p>
<form method="POST" action="{{ route('qms.onboarding.store') }}" enctype="multipart/form-data" class="mt-8 space-y-5 rounded-2xl border border-slate-200 bg-white p-6 dark:border-slate-700 dark:bg-slate-900">
@csrf
@@ -14,11 +16,14 @@
<div>
<label class="block text-sm font-medium text-slate-700 dark:text-slate-300">Industry</label>
<select name="industry" class="mt-1 w-full rounded-lg border-slate-300 text-sm dark:border-slate-600 dark:bg-slate-800">
@foreach ($industries as $value => $label)
<option value="{{ $value }}" @selected(old('industry', 'custom') === $value)>{{ $label }}</option>
<select name="industry" id="industry" class="mt-1 w-full rounded-lg border-slate-300 text-sm dark:border-slate-600 dark:bg-slate-800">
@foreach ($industries as $value => $meta)
<option value="{{ $value }}"
data-description="{{ $meta['description'] }}"
@selected(old('industry', 'custom') === $value)>{{ $meta['label'] }}</option>
@endforeach
</select>
<p id="industry-description" class="mt-2 text-xs text-slate-500 dark:text-slate-400"></p>
</div>
<div>
@@ -68,4 +73,18 @@
</button>
</form>
</div>
<script>
(function () {
const select = document.getElementById('industry');
const desc = document.getElementById('industry-description');
if (!select || !desc) return;
const sync = () => {
const option = select.options[select.selectedIndex];
desc.textContent = option?.dataset?.description || '';
};
select.addEventListener('change', sync);
sync();
})();
</script>
</x-app-layout>
+27 -1
View File
@@ -43,12 +43,22 @@
</select>
</div>
<div>
<label class="block text-sm font-medium text-slate-700">Industry</label>
<label class="block text-sm font-medium text-slate-700">Industry package</label>
<select name="industry" @disabled(! $canManage) class="mt-1 w-full rounded-lg border-slate-300 text-sm">
@foreach ($industries as $v => $l)
<option value="{{ $v }}" @selected(($organization->settings['industry'] ?? '') === $v)>{{ $l }}</option>
@endforeach
</select>
@if ($activePackage)
<p class="mt-2 text-xs text-slate-500">{{ $activePackage->description() }}</p>
<p class="mt-1 text-xs text-slate-500">
Ticket entity: <span class="font-medium text-slate-700">{{ $activePackage->ticketEntity() }}</span>
· Stages installed: {{ count(data_get($packageMeta, 'stages_installed', [])) }}
@if (data_get($packageMeta, 'skipped_stages'))
· Skipped: {{ implode(', ', data_get($packageMeta, 'skipped_stages', [])) }}
@endif
</p>
@endif
</div>
<label class="flex items-center gap-2 text-sm">
<input type="checkbox" name="notifications_enabled" value="1" @checked($organization->settings['notifications_enabled'] ?? true) @disabled(! $canManage)>
@@ -111,6 +121,22 @@
</x-settings.card>
@endif
@if ($canManage && $activePackage)
<x-settings.card title="Industry template" description="Re-sync departments, stages, service points, workflow, and announcement copy from the selected industry package. Existing tickets are kept.">
<div class="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
<p class="text-sm text-slate-600">
{{ $activePackage->label() }} uses
<span class="font-medium text-slate-900">{{ count($activePackage->stages()) }}</span> workflow stages and
industry-specific terminology ({{ $activePackage->terminology()['ticket'] ?? 'Ticket' }}).
</p>
<form method="POST" action="{{ route('qms.settings.package.reinstall') }}">
@csrf
<button type="submit" class="btn-secondary shrink-0 text-sm">Reinstall package</button>
</form>
</div>
</x-settings.card>
@endif
<x-settings.card title="Integrations" description="Allow Ladill Care and Frontdesk to manage queues in-app via the Queue API. Both apps must also enable integration in their settings.">
<div class="space-y-2">
<label class="flex items-center gap-2 text-sm">