Extract the Patients pagination into a reusable ListPagination component
(components/ui/list-pagination.tsx, carrying the pageWindow helper) and use it
on the Activity feed and the Invoices list (10/page, search resets to page 1).
Patients is refactored onto the same component, removing the duplicated block.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Compose the conversation thread from the shadcn Message, Bubble, and
Attachment components (Base UI under the hood), keeping COSS semantic colour
tokens — outgoing bubbles use the primary variant, incoming use muted, and
shared files/appointments/password-resets render as Attachment cards. Day
separators, sender grouping, and timestamps are preserved.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add the COSS Pagination primitive and page the patients list at 10 rows/page
(search resets to page 1; the page is clamped at render so a shrinking list
never strands you past the last page). Replace the flat "secondary" status
badge with semantic colours: active → success, inpatient → info, discharged →
outline. Includes the i18n keys for pagination, the AI setup notice, and the
patient record-history / PDF export features.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- settings: keep tab nav on its own row so "Developers" no longer wraps
- chat: show the "Veil active" chip once per conversation, not every turn
- chat: record cards only offer "Click for more" when they have detail
- chat: chat-history panel (pill + sheet) top-left of the AI chat with
"Start new chat"; rename sidebar "New chat" -> "Ask temetro" (Sparkles)
- meetings: disable past dates, add an Upcoming Meetings list, and use the
Empty component for empty days; scheduler can be pre-targeted via ?with
- messages: add a call button left of each inbox row -> Meetings (?with)
- toast: add a dismiss (x) button; call invites now ring 30s with "Accept"
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- chat composer: attach works with text (sr-only file input); lighter
bordered input box
- messages: defer "+" menu actions past close so file/appointment pickers fire
- tasks: top-level New task button
- chat: condensed appointment card with "View in calendar" deep-link;
appointments page auto-opens the month calendar from ?calendar=&date=
- lab: work-queue rows expand to show task detail + complete
- inventory: clickable item detail dialog
- pharmacy: Dispense action records a dispense + "Recently dispensed" feed;
expiring badge uses endDate and only flags <=2 days left
- prescriptions: keyboard nav in patient search, inventory-backed medication
combobox (free-text fallback), optional start/end dates; thread dates through
- sidebar: whole nav scrolls as one
- i18n keys for all new strings
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- new reusable <Combobox> (Base UI Autocomplete): arrow-key + Enter navigation
- New Appointment dialog: patient search and provider are now searchable
comboboxes (provider sourced from /api/staff/providers) instead of a hand-
rolled dropdown and a free-text input
- appointment rows are clickable and open an <AppointmentDetailSheet> to edit
date/time/type/provider/status or delete; "Added by AI" badge shown on rows
and in the sheet for source="ai" records
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
CommandItem rendered the icon flush against the label. Add a gap (and normalize
icon sizing) so the two no longer touch.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Appointments: a Calendar button next to Add opens a month-grid dialog
(reuses the Calendar primitive + shared ScheduleList); the schedule day is
marked and selecting it lists that day's appointments.
- Patients sub-nav: new Prescriptions page (mock list + KPIs) with a compact
"New prescription" dialog reusing the patient quick-search pattern.
- Notes: deleting a note now goes through a reusable ConfirmDialog instead of
deleting immediately.
- New top-level Messages page: two-pane email-style inbox (list + reading pane
with mock reply composer), mirroring the Notes layout.
- Sidebar logo bumped from size-9 to size-10.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Round-2 fixes to the 6 features:
- Logo: enlarge the sidebar mark, drop the inline wordmark, and show
"temetro" via a hover tooltip; bigger logo on the auth screens.
- Sidebar footer: wrap the quick-nav, clinic switcher, and user menu in a
single bordered block so it reads as one footer instead of three cards.
- Sidebar nav: highlight the active page (usePathname + data-[active]), and
add an Appointments & Schedule sub-page under Patients that auto-expands
for the current section. New mock /appointments page; reachable via ⌘K.
- Notes: redesign to a two-pane list + editor with an Empty state on the
right when nothing is selected; fix the editor so text starts top-left
(div instead of a centering <button>); compact the toolbar; add
.note-content typography in globals.css so headings/lists/etc. actually
render (the app has no typography plugin).
- Patients: new PatientDetail laid out to fit the side Sheet (stacked
full-width sections, no nested click-to-expand dialogs); keep Edit.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- lib/notes.ts: list/get/create/update/delete via the API client.
- New /notes route + nav item (and shared lib/nav.ts entry, i18n key) so it
shows in the sidebar and command palette.
- components/notes/notes-view.tsx: a note list + "New note", with save/delete
and toasts.
- components/notes/notes-editor.tsx: a Word-like COSS Toolbar driving Tiptap
(StarterKit + Placeholder) — bold/italic/underline, H1–H2, bullet/numbered
lists, undo/redo — plus a title field and Save. Installed @coss/toolbar and
@coss/toggle-group and the Tiptap packages.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Several navigation/UX additions:
- Command palette (⌘K): components/command-palette.tsx wraps the app shell
(mounted in app/(app)/layout.tsx) with a controlled COSS CommandDialog listing
the nav pages; a "Quick nav" Kbd button in the sidebar footer also opens it.
Installed @coss/kbd. Extracted the nav list into lib/nav.ts so the sidebar and
palette share one source of truth.
- Clinic switcher moved from the sidebar body into the footer; its menu now
opens a read-only "Clinic info" dialog and a "Create clinic" dialog instead of
routing to /onboarding. Shared CreateClinicForm (components/clinic/) is reused
by onboarding.
- Patients: clicking a row opens a right-side Sheet with the full record
(components/patients/patient-detail-sheet.tsx) instead of navigating to the
chat; PatientResult gained a vertical "column" layout for the Sheet.
- New Analysis page (app/(app)/analysis/) — a mock dashboard (revenue/profit,
patient volume, appointments, operations) reusing Sparkline + Card + Badge.
- Logo: set metadata.icons so the new mark appears as the browser-tab favicon.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Wire COSS's (Base UI) Sonner-style stacked toast into the app:
- Install @coss/toast (components/ui/toast.tsx) and mount <ToastProvider> in
the root layout; add a small notify.{success,error,info,warning} helper
(lib/toast.ts) over toastManager so callers don't repeat the toast shape.
- Toast on the events requested: clinic created (onboarding), auth actions
(sign in / sign up / sign out / password reset request + reset), patient
saved (create/edit), and all failure branches as error toasts (kept inline
errors as a fallback). New auth toast strings added to the en translation.
- Replace the logo everywhere: overwrite public/temetro-logo.png with the new
1024² square mark (same aspect ratio as the old 500², so existing 32×32
next/image usages stay undistorted; no reference changes needed).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Install COSS Calendar (@coss/calendar, react-day-picker) and add a co-located
DatePicker (Popover + Button trigger + Calendar) in patient-form-dialog. It
reads/writes the same formatted date string the form already uses (formatDate/
parseDate), so the Patient model is unchanged. Replace the free-text Visit 'Date'
and Problem 'Since' inputs with the picker.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
SidebarInset (variant=inset) had rounded corners + shadow but no border, so the
content card blended into the bg-sidebar backdrop. Add a subtle border (semantic
--border token: white/6% dark, black/8% light), scoped to the inset variant to
match the existing rounded-xl/shadow.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Components:
- Replace components/ui primitives with COSS equivalents from the @coss/* shadcn
registry. Add menu/preview-card/group; remove the superseded dropdown-menu,
hover-card, button-group; keep carousel (no COSS equivalent).
- Migrate live call sites to canonical COSS APIs preserving layout/behavior:
sidebar menus (nav-user, team-switcher, nav-notifications), chat-input radio
menu, patient dialogs/cards, auth forms (FieldGroup -> flex column), settings.
- ai-elements: migrate the live conversation/message with behavior parity
(Tooltip via render, Group/GroupText); repoint dormant files (hover-card ->
preview-card, dropdown-menu -> menu, button-group -> group, InputGroupButton
-> Button). Residual pre-existing Base UI type drift stays behind
ignoreBuildErrors.
Theme:
- Adopt COSS default neutral tokens in globals.css with light + dark palettes.
- Add next-themes (defaultTheme=dark, enableSystem) and drop the forced dark
class. Align font variables to the COSS contract (--font-sans/-heading/-mono).
Make scrollbars theme-aware.
i18n:
- Add i18next + react-i18next (lib/i18n/config.ts, locales/en/translation.json,
components/i18n-provider.tsx mounted in layout). Convert auth forms, sidebar
nav, and settings tabs to useTranslation() as the reference pattern.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add the shadcn login-01 and signup-03 blocks (with the base-luma field/label
components) and wire their forms to the Better Auth client: login →
signIn.email, signup → signUp.email (12-char rule, confirm match), with error
+ submitting states. Dropped the non-functional "Login with Google" button.
Render the block forms from the existing (auth)/login and (auth)/signup pages
(deleting the blocks' duplicate app/login + app/signup routes). Replace the
animated AuthShell with a static, card-based shell + brand header so
onboarding/verify/reset/accept-invite match. Drop the unsupported `eslint`
key from next.config.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Base UI's Menu.GroupLabel requires a surrounding Menu.Group (unlike
Radix's standalone Label), so using DropdownMenuLabel as a bare heading
threw "MenuGroupContext is missing" at runtime. Render a <div> directly.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>