Patient: tabs of the page
The tab lives in the app’s state (?tab=); the Data tab keeps its draft while another shows.
import { ArchiveIcon, CalendarPlusIcon, PhoneIcon } from '@phosphor-icons/react';
import { useState } from 'react';
import { Avatar, Notice, RecordPage, SettingGroup, SettingToggle } from '@arbol-ai/ui';
const PatientPage = () => {
const [tab, setTab] = useState('appointments');
return (
<RecordPage
actions={[{ label: 'Call', icon: <PhoneIcon />, href: 'tel:+573005550101' }]}
avatar={<Avatar name="Laura Gómez" size="xl" />}
className="px-0 md:px-0"
menu={[{ label: 'Archive patient', icon: <ArchiveIcon />, isDestructive: true }]}
menuLabel="More actions for Laura Gómez"
meta={['CC 1.020.304.050', '34 years', 'Sura EPS']}
onSectionChange={setTab}
primaryAction={{ label: 'Book', icon: <CalendarPlusIcon />, href: '#/record-page' }}
section={tab}
sections={[
{
id: 'appointments',
label: 'Appointments',
count: 12,
content: <p className="text-sm">Monday 14 · Annual check-up with Dr. Ruiz</p>,
},
{
id: 'notes',
label: 'Notes',
count: 3,
content: <p className="text-sm">Prefers morning appointments. Allergic to penicillin.</p>,
},
{
id: 'profile',
label: 'Data',
keepMounted: true,
content: (
<SettingGroup title="Contact">
<SettingToggle label="Receives reminders by WhatsApp" />
</SettingGroup>
),
},
]}
sectionsLabel="Patient sections"
summary={<Notice tone="info">Next visit: Monday 14 at 9:30, with Dr. Ruiz.</Notice>}
title="Laura Gómez"
/>
);
};
<PatientPage />Campaign: properties beside the content
Narrow the window below 1280px: the properties fold into “Campaign details” above the content.
import { PauseIcon, PencilSimpleIcon, TrashIcon } from '@phosphor-icons/react';
import { Badge, RecordPage } from '@arbol-ai/ui';
<RecordPage
actions={[{ label: 'Pause', icon: <PauseIcon /> }]}
className="px-0 md:px-0"
menu={[{ label: 'Delete campaign', icon: <TrashIcon />, isDestructive: true }]}
menuLabel="More actions for Spring reminders"
meta="WhatsApp · started Monday"
onTitleChange={() => undefined}
properties={[
{ label: 'Agent', value: 'Front desk' },
{ label: 'Line', value: '+57 601 555 0101' },
{ label: 'Contact hours', value: 'Weekdays, 8:00 to 18:00' },
{ label: 'End', value: null },
]}
propertiesAction={{ label: 'Edit settings', icon: <PencilSimpleIcon />, href: '#/record-page' }}
propertiesLabel="Campaign details"
status={<Badge tone="success">Running</Badge>}
title="Spring reminders"
titleLabel="Campaign name"
>
<p className="text-muted-foreground rounded-card border p-6 text-sm">
812 reached · 164 booked · 66% answered
</p>
<p className="text-muted-foreground rounded-card border p-6 text-sm">
The recipients table goes here.
</p>
</RecordPage>Professional: sections at their own URLs
Each section is a page; the router’s content for it is the children. Here a small router in memory follows the links.
Dra. Ana Ruiz
Internal medicineRoom 4
Weekdays, 7:00 to 13:00. Closed on holidays.
import { CalendarBlankIcon } from '@phosphor-icons/react';
import { useState } from 'react';
import { RouterProvider } from 'react-aria-components';
import { Avatar, RecordPage } from '@arbol-ai/ui';
const PROFESSIONAL_SECTIONS = {
schedule: 'Weekdays, 7:00 to 13:00. Closed on holidays.',
services: 'General consultation, follow-up visit.',
profile: 'Internal medicine · Room 4.',
} as const;
const ProfessionalPage = () => {
const [section, setSection] = useState<keyof typeof PROFESSIONAL_SECTIONS>('schedule');
return (
<RouterProvider
navigate={(href) => {
const next = href.split('/').at(-1);
if (next === 'schedule' || next === 'services' || next === 'profile') {
setSection(next);
}
}}
>
<RecordPage
actions={[{ label: 'View agenda', icon: <CalendarBlankIcon />, href: '#/record-page/agenda' }]}
avatar={<Avatar name="Ana Ruiz" size="xl" />}
className="px-0 md:px-0"
meta={['Internal medicine', 'Room 4']}
section={section}
sections={[
{
id: 'schedule',
label: 'Schedule',
href: '#/record-page/schedule',
},
{
id: 'services',
label: 'Services',
href: '#/record-page/services',
attention: 'No services yet',
},
{ id: 'profile', label: 'Profile', href: '#/record-page/profile' },
]}
sectionsLabel="Professional sections"
title="Dra. Ana Ruiz"
>
<p className="text-sm">{PROFESSIONAL_SECTIONS[section]}</p>
</RecordPage>
</RouterProvider>
);
};
<ProfessionalPage />Source
The examples above are src/blocks/record-page/record-page.examples.tsx, which the library’s tests render too.