The placeholder only mentioned patient lookup, but the chat now answers
plain-language questions, displays records, adds, and imports. Update it to
"Ask anything, or type /patient 10293".
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add an Add-item button to the Inventory page that opens a COSS form dialog
(name required; form, strength, stock, reorder point, location, expiry). On
submit it persists via createInventory and prepends the saved row so it
appears immediately. Mirrors the appointments add-dialog pattern.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Make the chat feel alive and let the agent act on the clinic — safely.
UX (frontend):
- Stream `data-step` parts from each tool into an inline Chain-of-Thought
trace, plus a "Thinking…" shimmer while a request is in flight (works even
on the non-streamed external+Veil path).
- Replace the modal Veil consent Dialog with an inline, once-per-session
"Veil" confirmation above the input (with a "Use local model" option).
- Render new list + action-preview cards; chat-input now uses COSS tokens.
Agent (backend):
- Add display tools (listAppointments / listTasks / listPrescriptions) and
propose tools (proposeAppointment / proposeTask / proposePrescription) that
validate as a dry run and stream an approval card — nothing is written until
the clinician approves, via the existing RBAC-gated create endpoints.
- previewImport now also covers single-patient add + migration.
- System prompt: display + add only, never edit/delete or alter the schema;
stronger migration guidance. ToolContext carries the viewer for task scoping.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The chat defaulted to a Claude model, so a user who saved only a Gemini key got
a silent failure (backend derived Anthropic, found no key, errored — and the UI
showed nothing).
- Backend: resolveModel now falls back to whichever provider actually has a key
(preferring the configured one), so a Gemini key just works regardless of the
picked model. Clear 400 if no provider is configured at all.
- Frontend: the chat seeds its model/effort from the saved AI config, and now
surfaces request failures as both a persistent alert banner and a toast —
never silent.
- Settings: switching provider auto-selects that provider's default model.
- Refreshed the model catalog to current ids (Gemini 2.5 Pro/Flash + 2.0 Flash;
dropped the retired gemini-1.5-pro); per-provider default model updated.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The frontend dependency install (1000+ packages) failed in Docker with
ECONNRESET / "network aborted" mid-stream. Add npm fetch retries and a long
timeout so a transient registry drop is retried rather than failing the build.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Replace the mock chat with the live backend agent:
- chat-panel uses @ai-sdk/react useChat against /api/chat (credentials included),
passing the selected model + effort per send. The `/patient <file#>` fast-path
is kept as an instant client-side shortcut.
- Renders the agent's streamed data parts: patientCard → record cards
(PatientResult), labCard → new LabChartCard (visx area chart with a high/low
flag badge in the top-right corner + recent values), importPreview →
ImportPreviewCard (the human approval gate: review counts/issues, then commit
via POST /api/ai/import — nothing is written until approved).
- Veil consent: a one-time dialog before the first send to a cloud model,
explaining that identifiers are de-identified before leaving the clinic.
- Attached text files (csv/json/txt…) now include their content in the message
so the agent can parse an export for import.
Shared chat message/data-part types in lib/ai-chat.ts.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
New per-user AI settings section (visible to every clinician, not just admins):
- Inference mode: cloud API key vs local Ollama.
- Provider + key (OpenAI / Anthropic / Gemini) via a select; the key field is
write-only and shows a "key set" indicator from the backend's apiKeySet,
never echoing the stored secret. Default model + effort per provider.
- Local Ollama: base URL + model name with a "Test connection" probe.
- Veil: de-identification level (full / names / off) with mode-aware copy.
Talks to the new /api/ai/config + /api/ai/test endpoints via lib/ai-settings.ts.
The old mock clinical selects (specialty/facility/time range/access/response)
are dropped entirely rather than relocated — they were placeholder knobs.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Replace the five clinical context selects (access, response mode, specialty,
facility, time range) with one model picker styled like the reference design:
a primary model list with descriptions, an Effort submenu, and a "More models"
submenu. Move the Add-patient pill up into the toolbar and drop the now-empty
bottom context-selector card so the input is a single clean rounded surface.
Model/effort selection is lifted to ChatPanel so it can travel with each send
(wired to the backend agent in a later phase). Adds a shared model catalog
(lib/ai-models.ts) reused by the picker, Settings, and the chat wiring.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Pharmacy: the sidebar entry now expands into Pharmacy + a new Inventory page
(searchable medication stock with derived in-stock/low/out availability,
backed by /api/inventory). Fix the dispensing-queue "Expiring" badge so it
only flags courses ending within the next 7 days, not ones already elapsed.
- Lab "Add analysis result": the patient picker no longer lists patients until
you type and supports arrow-key + Enter selection; the test field offers a
catalog of common analyses with an Advanced option (custom analysis + ref
range); submitted results now show immediately in a Recent results feed.
- Analysis: add a Live panel (real-time line chart) and replace the flat trend
sparklines with bklit-ui area + bar charts (installed from the @bklit shadcn
registry; chart CSS variables wired into the theme for light and dark).
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>
Same layout, better inbox: avatars on conversation rows, a numeric unread
badge (kept live by the socket handler), primary-tinted timestamps for unread
rows and softer hover states. In the thread: day separators
(Today/Yesterday/date), consecutive same-sender messages within 5 minutes
grouped with one sender label + one timestamp and tightened corners, and a
"Start a conversation" button on the empty state.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The Myself/Other assignee picker looked like two loose buttons; replace it
with the COSS Tabs segmented control, with the department select (now five
departments) living in the "Other" tab panel. State semantics unchanged.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
New /lab department home: the lab's task queue (tasks assigned to the Lab
department, with done toggle) and an "Add result" dialog — pick a patient,
enter test/value/flag/date — that posts to the new labs append endpoint via
appendLabs() in lib/patients.ts.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
New /pharmacy department home: KPI cards (active prescriptions, expiring
within 7 days from parseable durations, patients on medication) over a
dispensing queue of active prescriptions (oldest first) with search, a
mark-completed action and the existing detail sheet. No create/delete UI —
prescribing stays with clinicians.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Mirror the backend role changes (drop viewer, add pharmacy + lab and the lab
statement). Replace the binary requiresClinical gating with access areas
(clinical / pharmacy / lab) probed from Better Auth permissions —
prescription:delete marks full clinicians, prescription:write the pharmacy
area, lab:write the lab area — so pharmacy doesn't inherit the AI chat or
notes. Pharmacy and lab land on their new dashboards and get their own nav
items; reception behavior is unchanged. Includes the i18n keys for the new
pages and the messages polish that lands in the following commits.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- sidebar + auth logo now invert to black in light mode (dark unchanged),
same trick the docs site uses — no second asset needed
- prescriptions page: search by patient, file number, medication,
prescriber or status, with no-match / empty states
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Records tab: data sources, import/export, retention (replaces placeholder)
- Developers tab: API base URL, access-tokens empty state, resources
- Signing tab: how-it-works steps + backup key entries
- Team member dialog: header band, per-resource permission rows with icons
and action chips, COSS Select for role change
- Care team: hint that clicking a member shows their permissions
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- ToggleRow supports controlled checked/onCheckedChange; CopyField copy works
- ProfilePanel loads/saves preferences via /api/settings, name via updateUser
- dirty tracking with a sticky save bar that follows the scroll
- Delete account: password-confirmed dialog wired to authClient.deleteUser
- clinician ID / handle now show the real session user
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Messages: search the inbox and the compose member picker.
- Care Team: clickable member rows open an employee dialog showing role +
permissions, with change-role (updateMemberRole) and remove.
- Patients: Primary Care is now a provider dropdown (defaults to self for a
doctor); add a Transfer action + dialog wired to the transfer API.
- Activity: entries are clickable, opening a detail dialog.
- Analytics: Section takes a columns prop so each row fills evenly (no orphan
card in Appointments).
- Add lib/staff.ts (listProviders), transferPatient client, rolePermissionSummary
helper, and i18n keys for all new strings.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Hide "Create clinic" (sidebar footer) for non-admins; only owner/admin can
spin up additional clinics. Onboarding for brand-new users is unaffected.
- Analysis: drop the bar charts; show line charts (Sparkline) inside KPI cards
that open a detail dialog with the full chart + per-point breakdown.
- Add Team Member: validate the username client-side (no spaces; letters,
numbers, dots, underscores) with a clear warning + field hint.
- Tasks: New Task now has an Assignee selector (Myself / Other → department).
Tasks are visible to the department they're assigned to (or the creator), and
show who created them. Backend adds assignee_role + created_by_name with
visibility filtering in listTasks; owners/admins see all.
- Care team: removing a member now asks for confirmation first (dialog) and
surfaces success/failure + refreshes.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The Analysis page only showed KPI numbers. Add two real time-series and render
them as dependency-free bar charts (matching components/chat/sparkline.tsx):
- backend: GET /api/analytics now returns `trends.patientsByMonth` (new patients
per month over the last 6 months) and `trends.appointmentsByWeekday`
(appointments per day for the current week), bucketed in JS from one query each.
- frontend: new components/analysis/bar-chart.tsx and two chart sections on the
Analysis view (Patient growth, Appointments this week), with i18n keys.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Replace the email-invitation flow with admin-provisioned staff accounts and
add role-based access that changes what each member sees.
Backend:
- Enable Better Auth `username` plugin (staff sign in by username); regenerate
auth schema (+ username/displayUsername on user) and migration 0007.
- Add `doctor` and `reception` roles to the access-control RBAC. `reception` is
scoped to scheduling + registration (no `prescription` statement).
- New `/api/staff` route: POST creates a user (auth.api.signUpEmail) and adds
them to the active clinic (auth.api.addMember); GET lists members + usernames.
Gated by requirePermission({ member: ["create"] }).
- Redact clinical PHI for the reception role in the patients service (read,
create and update) so demographics-only is enforced server-side.
Frontend:
- usernameClient + Email|Username tabs on the login form.
- lib/roles.ts: useActiveRole + Better-Auth-permission-driven nav visibility,
default landing, and a route guard (reception -> /appointments, blocked from
clinical routes). Applied to the sidebar, command palette and auth guard.
- Care team page now provisions staff via a two-step Add-team-member dialog
(details -> username/password) hitting /api/staff; removes the email-invite
and pending-invitation UI. New members are contactable from Messages
automatically (they become org members).
- Hide clinical sections of the patient form and the admin-only settings tabs
for non-clinical/non-admin roles.
All permission management stays in Better Auth (per the better-auth skills now
referenced in backend/CLAUDE.md).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Finish the i18n pass: settings panels (profile/care-team/signing), the
chat heading + input, the patient cards / detail / create-edit form, and
the notes page + rich-text editor are all keyed in en/translation.json.
All 526 static t() keys resolve. Document the new backend resources +
Socket.io realtime (backend README/CLAUDE) and the i18n coverage
(frontend CLAUDE).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Move all hardcoded UI strings in the appointments, prescriptions, tasks,
messages, activity, analysis and patients views (plus their dialogs and
detail sheets), the remaining auth pages (verify-email, forgot/reset
password, accept-invite, onboarding), the clinic form and the sidebar user
menu into i18next keys in en/translation.json. Clinical option values
(appointment types, frequencies) stay canonical. English-only; no new
locale yet.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Auto-generate notifications on patient record create/update (fan out to
the other clinic members, pushed live), and wire the sidebar bell to real
data via a useNotifications hook over the shared socket: live unread badge,
real list, mark-all-read on open. Drops the hardcoded sample array and the
dead "View all" link.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add conversations/participants/messages tables, a participant-scoped REST
API (/api/conversations) and a Socket.io server (session-authenticated
handshake; per-user + per-conversation rooms) sharing the HTTP port. New
messages broadcast live and create per-recipient notifications. Also lands
the notifications table + service + routes (used by the message flow). The
Messages page is rewritten: live threads, unread state, and a compose
dialog to start a conversation with a clinic member.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add GET /api/analytics returning real aggregates over the clinic's
patients/appointments/prescriptions/tasks, and rebuild the Analysis page
to render them. Drops the fabricated revenue/profit cards — temetro has no
billing data source.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add the activity_log table, a best-effort recordActivity() service and a
GET /api/activity feed, and write entries on create/update/delete of
patients, notes, appointments, prescriptions and tasks. The Activity page
now shows the real audit trail (actor, action, patient context, time);
the fabricated signing hashes / approval badges are gone — that vision
stays deferred.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add the tasks table, validation, service and routes (/api/tasks with a
PATCH for partial updates / the done toggle, RBAC-gated) and the frontend
data module. The tasks board now loads, creates and toggles real data
(optimistic toggle with rollback).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add the prescriptions table, validation, service and CRUD routes
(/api/prescriptions, RBAC-gated; prescriber defaults to the signed-in
clinician, prescribedAt to today) and the frontend data module. The page
now loads/persists real data and computes its status KPIs.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add the appointments table, validation, service and CRUD routes
(/api/appointments, RBAC-gated) and the matching frontend data module.
The appointments page now loads and persists real data; KPIs are computed
from it and the schedule/calendar anchor to the real current date.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Extend the clinic access-control statements and role grants with
appointment/prescription/task resources (mirrored in the frontend client
AC), and widen the requirePermission type to accept any defined resource.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Task dialog: rename Title→Subject, add a "Details" textarea (notes),
widen to sm:max-w-lg.
- Tasks & Notes: replace split-panes with full-width lists that open a
right-side Sheet on click (TaskDetailSheet, NoteDetailSheet), mirroring
the Patients table → detail Sheet pattern.
- Prescriptions: rows are now clickable and open PrescriptionDetailSheet
with the full Rx details (incl. duration + notes).
- New prescription dialog: Duration is a dropdown of presets with an
"Other" → custom input, plus a Notes textarea; NewPrescription gains
notes and threads duration/notes through to the list.
- Appointments: header search filtering by patient/type/provider,
grouped by date, with an empty state.
- Patients: pressing Enter in the search box opens the top match's record.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The source logo has wide transparent margins; the icons were squared on top of
that, leaving the mark tiny in the browser tab. Regenerate app/icon.png (256) and
app/apple-icon.png (180) cropped to the artwork's alpha bounding box with a small
7% margin so the logo reads at favicon size.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Appointments now carry a date; the Calendar button opens a Google-Calendar
style month grid (color-coded event chips, month nav, Today, click a day for
its list). Today/Upcoming sections derive from dates.
- Add-appointment dialog gains a date picker (Popover + Calendar).
- Messages rebuilt as chat threads: an input-based composer that appends to a
two-way timeline (no more toast covering the field), and the unread count is
now a filter toggle.
- Favicon: the brand logo now shows in the tab. Removed the stale default
app/favicon.ico (which shadowed it) and added app/icon.png + app/apple-icon.png
generated from the logo; dropped the redundant metadata.icons.
- Sidebar: swapped Notes <-> Messages order (both kept).
- New pages: Activity (signed-change audit timeline with hash chips + approval
status) and Tasks (two-pane care-team to-do with add dialog).
- Prescriptions: adding a medication now surfaces mock drug-interaction and
allergy warnings against the patient's record.
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>
- User menu: rename "Quick nav" to "Search"; add spacing to the clinic
submenu so it no longer touches the parent menu (sideOffset).
- Notes: lay the list, title, toolbar, and writing area out as separate
rounded panels with gaps so they're no longer stuck together.
- Sidebar: shorten the "Appointments & Schedule" label to "Appointments".
- Appointments: replace the oversized patient form with a compact
"New appointment" dialog — pick a patient via quick search by name/file
number, set time/type/provider; the entry is added to today's schedule.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Footer is now a single user row. The ⌘K command hint moved into the user
menu below Theme, and the clinic switcher became a hover submenu below that
(revealing the active clinic's name/slug/count, the switch list, and
Create clinic). Removed SidebarCommandButton and deleted team-switcher.tsx.
- Patients sub-nav (Patients / Appointments & Schedule): no icons, no
background change on hover/active — only the text color changes.
- Appointments & Schedule: added an "Add" button that opens the create-patient
dialog.
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>
Update frontend/CLAUDE.md after the COSS migration: note the sidebar theme
toggle and the always-use-semantic-tokens rule in Theming, add a 'COSS
composition gotchas' section (MenuGroup requirement, DialogPanel padding, no
Card/Avatar size prop, destructive variant, items-start Field, aliases,
ai-elements drift), and dedupe the repeated lucide-react note.
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>
- chat-input: replace the two hardcoded oklch backgrounds (leftover Linear
palette) with COSS surface tokens — outer form bg-muted, inner card bg-input.
Lighter in dark mode and theme-aware (no longer near-black in light mode),
preserving the two-tone layered look.
- nav-user: wire the previously-static Theme menu item to next-themes
(useTheme/setTheme) — toggles light/dark, with the icon (Sun/Moon) and
shortcut label reflecting the current theme.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- MenuGroupLabel must live inside a MenuGroup (Base UI context) — wrap the
label in nav-user, team-switcher, and nav-notifications. Fixes the
'MenuGroupContext is missing' runtime error.
- Patient form/detail dialogs: COSS DialogPopup has no inner padding; move the
body into DialogPanel (form as 'contents') so fields get p-6 instead of being
flush to the edges.
- Settings 'Delete' button used the default variant + bg override, keeping a
near-white border-primary in dark mode. Use variant='destructive'.
- Auth forms: COSS Field is items-start (no stretch). Make the submit button and
the password-row/grid w-full, and underline the bottom sign-in/up link.
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>
If a signed-in user has no active clinic but already belongs to one, select
it automatically; only users with zero clinics are sent to onboarding. Fixes
being asked to create a clinic on every login.
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>