Give each specialty module a distinct Heroicon-style icon.
Deploy Ladill Care / deploy (push) Successful in 1m2s

Icon names live on the specialty catalog; SVG paths resolve through a shared map and render in sidebar, dashboard, settings, and the specialty shell.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
isaacclad
2026-07-18 18:30:14 +00:00
co-authored by Cursor
parent 61b901095f
commit 1e00c31b8b
12 changed files with 200 additions and 23 deletions
+10 -5
View File
@@ -206,17 +206,22 @@
<a href="{{ $href }}"
class="rounded-2xl border border-slate-200 bg-white px-4 py-4 transition hover:border-indigo-300 hover:shadow-sm">
<div class="flex items-start justify-between gap-2">
<p class="text-sm font-semibold text-slate-900">{{ $item['definition']['nav_label'] ?? $item['definition']['label'] }}</p>
<div class="flex min-w-0 items-start gap-2.5">
<x-care.specialty-icon :module="$item['key']" boxed />
<div class="min-w-0">
<p class="text-sm font-semibold text-slate-900">{{ $item['definition']['nav_label'] ?? $item['definition']['label'] }}</p>
<p class="mt-1 text-xs text-slate-500">{{ $item['definition']['description'] ?? '' }}</p>
@if ($toSettings)
<p class="mt-2 text-[11px] font-medium text-indigo-600">Settings &amp; pricing </p>
@endif
</div>
</div>
@if (! empty($item['access_level']) && $item['access_level'] !== 'manage' && ! $toSettings)
<span class="shrink-0 rounded-full bg-amber-50 px-2 py-0.5 text-[10px] font-semibold uppercase tracking-wide text-amber-800">
{{ $item['access_level'] === 'refer' ? 'View + refer' : 'View' }}
</span>
@endif
</div>
<p class="mt-1 text-xs text-slate-500">{{ $item['definition']['description'] ?? '' }}</p>
@if ($toSettings)
<p class="mt-2 text-[11px] font-medium text-indigo-600">Settings &amp; pricing </p>
@endif
</a>
@endforeach
</div>
@@ -3,9 +3,12 @@
title="{{ $definition['label'] ?? ucfirst($moduleKey) }}"
description="{{ $definition['description'] ?? 'Module settings and service prices for '.$organization->name.'.' }}"
>
<p class="text-sm">
<a href="{{ route('care.settings.modules') }}" class="font-medium text-indigo-600 hover:text-indigo-800"> Specialty modules</a>
</p>
<div class="flex items-center gap-3">
<x-care.specialty-icon :module="$moduleKey" boxed />
<p class="text-sm">
<a href="{{ route('care.settings.modules') }}" class="font-medium text-indigo-600 hover:text-indigo-800"> Specialty modules</a>
</p>
</div>
@if (session('success'))
<p class="rounded-lg bg-emerald-50 px-3 py-2 text-sm text-emerald-800">{{ session('success') }}</p>
@@ -29,12 +29,17 @@
<div class="flex flex-col rounded-2xl border border-slate-200 bg-white p-5 shadow-sm transition {{ ! empty($enabled[$key]) || $isDefault ? 'ring-1 ring-indigo-200' : '' }}">
<div class="flex items-start justify-between gap-3">
<a href="{{ route('care.settings.modules.show', $key) }}" class="min-w-0 flex-1 hover:opacity-90">
<p class="text-sm font-semibold text-slate-900">{{ $module['label'] }}</p>
<p class="mt-1 text-xs text-slate-500">{{ $module['description'] }}</p>
@if ($isDefault)
<p class="mt-2 text-[11px] font-medium uppercase tracking-wide text-indigo-600">Included on Pro / Enterprise</p>
@endif
<p class="mt-3 text-[11px] font-medium text-indigo-600">Settings &amp; pricing </p>
<div class="flex items-start gap-2.5">
<x-care.specialty-icon :module="$key" boxed />
<div class="min-w-0">
<p class="text-sm font-semibold text-slate-900">{{ $module['label'] }}</p>
<p class="mt-1 text-xs text-slate-500">{{ $module['description'] }}</p>
@if ($isDefault)
<p class="mt-2 text-[11px] font-medium uppercase tracking-wide text-indigo-600">Included on Pro / Enterprise</p>
@endif
<p class="mt-3 text-[11px] font-medium text-indigo-600">Settings &amp; pricing </p>
</div>
</div>
</a>
<label class="{{ $isDefault ? '' : 'cursor-pointer' }}" title="Activate module" @click.stop>
<input type="checkbox" name="modules[{{ $key }}]" value="1"
+20 -7
View File
@@ -65,18 +65,24 @@
@endif
@elseif ($section === 'history')
<div class="flex flex-wrap items-center justify-between gap-3">
<div>
<h1 class="text-xl font-semibold text-slate-900">Visit history</h1>
<p class="mt-1 text-sm text-slate-500">Completed encounters for this service line.</p>
<div class="flex items-start gap-2.5">
<x-care.specialty-icon :module="$moduleKey" boxed />
<div>
<h1 class="text-xl font-semibold text-slate-900">{{ $definition['nav_label'] ?? $definition['label'] ?? ucfirst($moduleKey) }} · Visit history</h1>
<p class="mt-1 text-sm text-slate-500">Completed encounters for this service line.</p>
</div>
</div>
<a href="{{ route('care.queue.index') }}" class="text-sm font-medium text-indigo-600 hover:text-indigo-800"> Back to queue</a>
</div>
@include('care.specialty.sections.history')
@elseif ($section === 'billing')
<div class="flex flex-wrap items-center justify-between gap-3">
<div>
<h1 class="text-xl font-semibold text-slate-900">Billing</h1>
<p class="mt-1 text-sm text-slate-500">Service catalog for this module.</p>
<div class="flex items-start gap-2.5">
<x-care.specialty-icon :module="$moduleKey" boxed />
<div>
<h1 class="text-xl font-semibold text-slate-900">{{ $definition['nav_label'] ?? $definition['label'] ?? ucfirst($moduleKey) }} · Billing</h1>
<p class="mt-1 text-sm text-slate-500">Service catalog for this module.</p>
</div>
</div>
<a href="{{ route('care.queue.index') }}" class="text-sm font-medium text-indigo-600 hover:text-indigo-800"> Back to queue</a>
</div>
@@ -85,9 +91,16 @@
{{-- Queue home (overview / visits) same UI as GP Queue --}}
<div class="lg:grid lg:grid-cols-[minmax(0,1fr)_16rem] lg:items-start lg:gap-6">
<div class="min-w-0 space-y-6">
@php
$specialtyLabel = $definition['nav_label'] ?? $definition['label'] ?? ucfirst($moduleKey);
@endphp
<div class="mb-1 flex items-center gap-2.5">
<x-care.specialty-icon :module="$moduleKey" boxed />
<p class="text-sm font-semibold text-slate-700">{{ $specialtyLabel }}</p>
</div>
<x-care.page-hero
badge="Waiting · In care · Call next"
title="Patient queue"
:title="$specialtyLabel.' queue'"
description="See who is waiting, start encounters, and keep patient flow moving."
:stats="[
['value' => number_format($kpis['waiting'] ?? $queue->count()), 'label' => 'Waiting'],
@@ -0,0 +1,16 @@
@props([
'module',
'boxed' => false,
])
@php
$path = care_specialty_icon_path((string) $module);
@endphp
@if ($boxed)
<div {{ $attributes->merge(['class' => 'flex h-8 w-8 shrink-0 items-center justify-center rounded-lg bg-indigo-50']) }}>
<svg class="h-4 w-4 text-indigo-600" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24" aria-hidden="true">{!! $path !!}</svg>
</div>
@else
<svg {{ $attributes->merge(['class' => 'h-4 w-4 shrink-0']) }} fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24" aria-hidden="true">{!! $path !!}</svg>
@endif
+1 -2
View File
@@ -83,7 +83,6 @@
$organization,
(string) $organization->owner_ref,
);
$specialtyIcon = '<path stroke-linecap="round" stroke-linejoin="round" d="M9.75 3.104v5.714a2.25 2.25 0 0 1-.659 1.591L5 14.5M9.75 3.104c-.251.023-.501.05-.75.082m.75-.082a24.301 24.301 0 0 1 4.5 0m0 0v5.714c0 .846.344 1.657.955 2.247L19 14.5M14.25 3.104c.251.023.501.05.75.082M19 14.5l-1.659 1.659a2.25 2.25 0 0 1-1.591.659H8.25" />';
foreach ($specialtyService->enabledModulesForMember($organization, $member) as $item) {
$key = $item['key'];
$label = $item['definition']['nav_label'] ?? $item['definition']['label'] ?? $key;
@@ -91,7 +90,7 @@
'name' => $label,
'route' => route('care.specialty.workspace', $key),
'active' => request()->routeIs('care.specialty.*') && request()->route('module') === $key,
'icon' => $specialtyIcon,
'icon' => $specialtyService->iconSvgPath($key),
'group' => 'specialty',
];
}