fix(header): relocate staff role switcher to sub-tab ribbon and streamline Tier 1 so portal buttons have full clearance

This commit is contained in:
2026-09-07 17:00:20 -07:00
parent 3fa9f7e21b
commit c3e5ec1cc3
+83 -80
View File
@@ -612,11 +612,11 @@ export default function Home() {
{/* Top Hospital Command Header */}
<header className="sticky top-0 z-40 bg-white border-b border-slate-200/90 shadow-2xs">
{/* Tier 1: System Command & Tenant Navigation */}
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-2.5">
<div className="flex items-center justify-between gap-3 flex-wrap lg:flex-nowrap">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-2">
<div className="flex items-center justify-between gap-3">
{/* Left Cluster: Hospital Brand & Clinic Identity */}
<div className="flex items-center gap-3 shrink-0">
<div className="flex items-center gap-2.5">
<div className="flex items-center gap-2.5 shrink-0">
<div className="flex items-center gap-2">
<span className="w-8 h-8 rounded-lg bg-sky-700 flex items-center justify-center font-black text-xs text-white shadow-xs">
+M
</span>
@@ -627,21 +627,21 @@ export default function Home() {
v2.5
</span>
</div>
<div className="text-[10px] text-slate-400 font-mono flex items-center gap-1">
<div className="text-[10px] text-slate-400 font-mono hidden 2xl:flex items-center gap-1">
<Globe className="w-2.5 h-2.5 text-sky-700" />
https://{activeTenant.domain}
</div>
</div>
</div>
<div className="h-5 w-[1px] bg-slate-200 hidden sm:block" />
<div className="h-4 w-[1px] bg-slate-200 hidden sm:block" />
{/* Clinic Dropdown Selector */}
<div className="relative">
<select
value={activeTenantId}
onChange={(e) => handleSwitchTenant(e.target.value)}
className="appearance-none bg-slate-50 hover:bg-slate-100 border border-slate-300 text-slate-800 text-xs font-bold rounded-lg pl-2.5 pr-7 py-1.5 cursor-pointer focus:outline-none focus:border-sky-500 transition shadow-2xs max-w-[190px] sm:max-w-[240px] truncate"
className="appearance-none bg-slate-50 hover:bg-slate-100 border border-slate-300 text-slate-800 text-xs font-bold rounded-lg pl-2 pr-6 py-1.5 cursor-pointer focus:outline-none focus:border-sky-500 transition shadow-2xs max-w-[150px] sm:max-w-[190px] md:max-w-[210px] truncate"
title="Switch Clinic Location / Practice"
>
{tenants.map((t) => (
@@ -650,33 +650,33 @@ export default function Home() {
</option>
))}
</select>
<ChevronDown className="w-3.5 h-3.5 text-slate-500 absolute right-2 top-1/2 -translate-y-1/2 pointer-events-none" />
<ChevronDown className="w-3.5 h-3.5 text-slate-500 absolute right-1.5 top-1/2 -translate-y-1/2 pointer-events-none" />
</div>
</div>
{/* Center: Command Palette / Search Bar (Responsive) */}
<div className="flex-1 max-w-xs xl:max-w-sm hidden md:block">
{/* Center: Command Palette / Search Bar (Responsive, doesn't crowd out right tools) */}
<div className="hidden md:block flex-1 max-w-[200px] lg:max-w-[240px] xl:max-w-xs">
<button
type="button"
onClick={() => {
clinicalAudio.playClick();
setIsCommandPaletteOpen(true);
}}
className="w-full flex items-center justify-between px-3 py-1.5 bg-slate-50 hover:bg-slate-100 border border-slate-200 rounded-lg text-slate-500 text-xs transition shadow-2xs group"
className="w-full flex items-center justify-between px-2.5 py-1.5 bg-slate-50 hover:bg-slate-100 border border-slate-200 rounded-lg text-slate-500 text-xs transition shadow-2xs group"
>
<div className="flex items-center gap-2 truncate">
<Search className="w-3.5 h-3.5 text-slate-400 group-hover:text-sky-600 transition" />
<span className="truncate">Search patients, charts, or actions...</span>
<div className="flex items-center gap-1.5 truncate">
<Search className="w-3.5 h-3.5 text-slate-400 group-hover:text-sky-600 transition shrink-0" />
<span className="truncate text-[11px]">Search (K)...</span>
</div>
<kbd className="px-1.5 py-0.5 text-[9px] font-mono bg-white border border-slate-200 rounded text-slate-500 font-bold shrink-0 ml-2">
<kbd className="px-1.5 py-0.5 text-[9px] font-mono bg-white border border-slate-200 rounded text-slate-500 font-bold shrink-0 ml-1">
K
</kbd>
</button>
</div>
{/* Right Cluster: Quick Tools + Role Switcher + Portal Switcher */}
<div className="flex items-center gap-2 shrink-0 flex-wrap justify-end">
{/* Search button on small screens where full bar is hidden */}
{/* Right Cluster: Quick Tools + Portal Switcher */}
<div className="flex items-center gap-2 shrink-0">
{/* Search button on mobile screens where input is hidden */}
<button
type="button"
onClick={() => {
@@ -734,62 +734,7 @@ export default function Home() {
</button>
</div>
{/* Staff Role Switcher (RBAC) */}
<div className="flex items-center bg-slate-100 p-0.5 rounded-lg border border-slate-200 text-xs">
<button
type="button"
onClick={() => {
clinicalAudio.playClick();
setStaffRole('doctor');
addToast('info', 'Role: Attending Doctor (D.C.)', 'Full clinical SOAP, 2D spine & telehealth unlocked');
}}
className={`px-2 py-1 rounded-md text-[11px] font-bold transition ${
staffRole === 'doctor'
? 'bg-white text-sky-800 shadow-2xs border border-slate-200'
: 'text-slate-600 hover:text-slate-900'
}`}
title="Full Doctor Clinical Access"
>
Doctor
</button>
<button
type="button"
onClick={() => {
clinicalAudio.playClick();
setStaffRole('front_desk');
if (clinicTab === 'charting' || clinicTab === 'telehealth') {
setClinicTab('calendar');
}
addToast('alert', 'Role: Front Desk (HIPAA Safe)', 'Protected medical notes locked for privacy');
}}
className={`px-2 py-1 rounded-md text-[11px] font-bold transition ${
staffRole === 'front_desk'
? 'bg-amber-100 text-amber-900 shadow-2xs border border-amber-200'
: 'text-slate-600 hover:text-slate-900'
}`}
title="HIPAA-Safe: Hides Clinical Notes, Shows Schedule, Retail & Billing"
>
Front Desk
</button>
<button
type="button"
onClick={() => {
clinicalAudio.playClick();
setStaffRole('billing_admin');
addToast('info', 'Role: Billing Administrator', 'Superbill claims and memberships prioritized');
}}
className={`px-2 py-1 rounded-md text-[11px] font-bold transition ${
staffRole === 'billing_admin'
? 'bg-white text-emerald-800 shadow-2xs border border-slate-200'
: 'text-slate-600 hover:text-slate-900'
}`}
title="Financial & Billing Administrator"
>
Billing
</button>
</div>
{/* Portal Mode Switcher */}
{/* Portal Mode Switcher (Always 100% visible on the right) */}
<div className="flex items-center bg-slate-100 p-0.5 rounded-lg border border-slate-200 text-xs font-semibold">
<button
type="button"
@@ -888,7 +833,7 @@ export default function Home() {
{/* Pre-Launch / Pending BAA Banner */}
{portalMode === 'clinic' && activeTenant.baaStatus === 'pending' && (
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 pb-2.5">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 pb-2">
<div className="p-2.5 bg-emerald-50 border border-emerald-200/90 rounded-xl flex flex-col sm:flex-row items-center justify-between gap-2 text-xs">
<div className="flex items-center gap-2 text-emerald-950">
<span className="w-2.5 h-2.5 rounded-full bg-emerald-500 animate-pulse shrink-0" />
@@ -911,10 +856,10 @@ export default function Home() {
</div>
)}
{/* Tier 2: Sub-Tabs for Doctor Clinic OS (Cleanly Grouped, No Horizontal Overflow) */}
{/* Tier 2: Sub-Tabs for Doctor Clinic OS + Staff Role Switcher */}
{portalMode === 'clinic' && (
<div className="border-t border-slate-100 bg-slate-50/50">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-2 flex items-center justify-between flex-wrap gap-2 text-xs">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-1.5 flex items-center justify-between flex-wrap gap-2 text-xs">
{/* Grouped Clinical Workspace Navigation */}
<div className="flex items-center flex-wrap gap-1.5">
{/* Group 1: Clinical Operations */}
@@ -1042,10 +987,68 @@ export default function Home() {
</div>
</div>
{/* Right: Active Clinician Presence Indicator */}
<div className="hidden xl:flex items-center gap-2 text-xs text-slate-500 font-mono">
{/* Right Side: Staff Role Switcher (RBAC) + Attending Doctor */}
<div className="flex items-center gap-2">
{/* Staff Role Switcher */}
<div className="flex items-center bg-slate-100 p-0.5 rounded-lg border border-slate-200 text-xs">
<button
type="button"
onClick={() => {
clinicalAudio.playClick();
setStaffRole('doctor');
addToast('info', 'Role: Attending Doctor (D.C.)', 'Full clinical SOAP, 2D spine & telehealth unlocked');
}}
className={`px-2 py-1 rounded-md text-[11px] font-bold transition ${
staffRole === 'doctor'
? 'bg-white text-sky-800 shadow-2xs border border-slate-200'
: 'text-slate-600 hover:text-slate-900'
}`}
title="Full Doctor Clinical Access"
>
Doctor
</button>
<button
type="button"
onClick={() => {
clinicalAudio.playClick();
setStaffRole('front_desk');
if (clinicTab === 'charting' || clinicTab === 'telehealth') {
setClinicTab('calendar');
}
addToast('alert', 'Role: Front Desk (HIPAA Safe)', 'Protected medical notes locked for privacy');
}}
className={`px-2 py-1 rounded-md text-[11px] font-bold transition ${
staffRole === 'front_desk'
? 'bg-amber-100 text-amber-900 shadow-2xs border border-amber-200'
: 'text-slate-600 hover:text-slate-900'
}`}
title="HIPAA-Safe: Hides Clinical Notes, Shows Schedule, Retail & Billing"
>
Front Desk
</button>
<button
type="button"
onClick={() => {
clinicalAudio.playClick();
setStaffRole('billing_admin');
addToast('info', 'Role: Billing Administrator', 'Superbill claims and memberships prioritized');
}}
className={`px-2 py-1 rounded-md text-[11px] font-bold transition ${
staffRole === 'billing_admin'
? 'bg-white text-emerald-800 shadow-2xs border border-slate-200'
: 'text-slate-600 hover:text-slate-900'
}`}
title="Financial & Billing Administrator"
>
Billing
</button>
</div>
{/* Active Clinician Presence Indicator */}
<div className="hidden 2xl:flex items-center gap-1.5 text-xs text-slate-600 font-mono bg-white px-2 py-1 rounded-lg border border-slate-200 shadow-2xs">
<span className="w-2 h-2 rounded-full bg-emerald-500 animate-pulse" />
<span>Active: <strong>{activeProvider.name}</strong></span>
<span className="font-semibold">{activeProvider.name}</span>
</div>
</div>
</div>
</div>