mirror of
https://dev.azure.com/globalhealthx/EMR/_git/helix-engage
synced 2026-05-18 20:08:19 +00:00
feat: PageHeader component + refactor all 6 list pages
New reusable PageHeader component (src/components/layout/page-header.tsx) with consistent layout: title + badge + subtitle on left, controls on right, optional tabs below with no extra borders. Refactored pages: - All Leads: inline header → PageHeader - Contacts: inline header → PageHeader - Appointments v2: inline header → PageHeader with tabs - Call History: removed p-7 wrapper + TableCard.Root → flat table - Patients: removed p-7 wrapper + TableCard.Root → flat table - Missed Calls: removed TopBar → PageHeader with tabs All pages now share identical header spacing, font sizing, and control alignment. No more double borders from tab + container. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -20,6 +20,7 @@ import { Select } from '@/components/base/select/select';
|
||||
import { DatePicker } from '@/components/application/date-picker/date-picker';
|
||||
import { parseDate, today, getLocalTimeZone } from '@internationalized/date';
|
||||
import { PhoneActionCell } from '@/components/call-desk/phone-action-cell';
|
||||
import { PageHeader } from '@/components/layout/page-header';
|
||||
import { formatPhone, formatDateOnly, formatTimeOnly } from '@/lib/format';
|
||||
import { apiClient } from '@/lib/api-client';
|
||||
import { notify } from '@/lib/toast';
|
||||
@@ -551,33 +552,32 @@ export const AppointmentsPageV2 = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
{/* Header with search inline */}
|
||||
<div className="flex shrink-0 items-center justify-between border-b border-secondary px-6 py-3">
|
||||
<div>
|
||||
<h1 className="text-lg font-bold text-primary">Appointments</h1>
|
||||
</div>
|
||||
<div className="w-56">
|
||||
<Input
|
||||
placeholder="Search patient, doctor..."
|
||||
icon={SearchLg}
|
||||
size="sm"
|
||||
value={search}
|
||||
onChange={setSearch}
|
||||
aria-label="Search appointments"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<PageHeader
|
||||
title="Appointments"
|
||||
badge={filtered.length}
|
||||
controls={
|
||||
<div className="w-56">
|
||||
<Input
|
||||
placeholder="Search patient, doctor..."
|
||||
icon={SearchLg}
|
||||
size="sm"
|
||||
value={search}
|
||||
onChange={setSearch}
|
||||
aria-label="Search appointments"
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
tabs={
|
||||
<Tabs selectedKey={tab} onSelectionChange={(key) => setTab(key as StatusTab)}>
|
||||
<TabList items={tabItems} type="underline" size="sm">
|
||||
{(item) => <Tab key={item.id} id={item.id} label={item.label} badge={item.badge} />}
|
||||
</TabList>
|
||||
</Tabs>
|
||||
}
|
||||
/>
|
||||
|
||||
<div className="flex flex-1 overflow-hidden">
|
||||
<div className="flex flex-1 flex-col overflow-hidden">
|
||||
{/* Tabs */}
|
||||
<div className="flex shrink-0 items-end px-6 pt-2 pb-0.5">
|
||||
<Tabs selectedKey={tab} onSelectionChange={(key) => setTab(key as StatusTab)}>
|
||||
<TabList items={tabItems} type="underline" size="sm">
|
||||
{(item) => <Tab key={item.id} id={item.id} label={item.label} badge={item.badge} />}
|
||||
</TabList>
|
||||
</Tabs>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-1 flex-col overflow-hidden px-4 pt-3">
|
||||
{loading ? (
|
||||
|
||||
Reference in New Issue
Block a user