import { type HTMLAttributes } from 'react'; import { type VariantProps } from 'class-variance-authority'; import type { AppointmentState } from '../_shared/entity-card'; export { isSafeEntityUrl as isSafeAppointmentUrl } from '../_shared/is-safe-url'; /** Appointment delivery channel. */ export type AppointmentType = 'inPractice' | 'telehealth'; /** First-visit tri-state flag. */ export type AppointmentFirstVisit = 'yes' | 'no' | 'unknown'; /** Operator (clinician) summary — name + optional palette colour id. */ export interface AppointmentOperator { /** Operator display name — drives the avatar initials + accessible name. */ name: string; /** Numeric palette colour id, resolved to a kit token for the colour dot. */ colorId?: number | string; } /** Patient summary — identity + optional age driver. */ export interface AppointmentPatient { /** Patient display name. */ name: string; /** Optional avatar image URL. */ avatarUrl?: string; /** ISO-8601 date of birth — when present, the card renders the age as a * suffix on the name (e.g. "Carol Danvers · 45"). */ dobIso?: string; } /** One treatment line within the appointment. */ export interface AppointmentTreatment { /** Localised care / treatment name. */ careName: string; /** Optional tooth elements (e.g. FDI ids) the treatment targets. */ elements?: string[]; } /** Booking-reason metadata captured at online-booking time. */ export interface AppointmentBookingReason { /** Localised booking-reason description. */ description: string; /** Expected duration in minutes. */ durationMin?: number; /** Advance / deposit amount in cents (non-negative). */ advanceAmountCents?: number; /** Localised specialty label. */ specialty?: string; } /** Money summary for the appointment. */ export interface AppointmentMoney { /** Total billable amount in cents. When present, rendered as a * TransactionChip. */ billableAmountCents?: number; /** Outstanding unpaid amount in cents. When > 0, rendered as a warning * TransactionChip so the front desk can flag it at a glance. */ unpaidAmountCents?: number; } /** Signing status for documents attached to the appointment. */ export interface AppointmentSigning { /** How many documents require a signature. */ required: number; /** How many have been completed so far. */ toComplete: number; } /** Boolean appointment flags surfaced as chips / indicators. */ export interface AppointmentFlags { bookedOnline?: boolean; noPatientAssigned?: boolean; highlightedAnamnesis?: boolean; billable?: boolean; } export interface AppointmentItem { /** Stable appointment identifier. */ id: string; /** ISO-8601 start instant. */ startIso: string; /** Duration in minutes. */ durationMin: number; /** Lifecycle state — drives the Badge variant + label. */ state: AppointmentState; /** Delivery channel — drives the leading type glyph. */ type: AppointmentType; /** First-visit flag. */ firstVisit?: AppointmentFirstVisit; /** Assigned operator. */ operator?: AppointmentOperator; /** Chair / room label — surfaced as a chip. */ chair?: string; /** * The care plan this appointment belongs to, when any — surfaced as a chip * (`Care plan {number}`). `url` is the deep link the consumer may use for * navigation; the chip itself is non-interactive so it never nests an anchor * inside the row's own stretched link. */ carePlan?: { number: string; url?: string; }; /** Patient identity. */ patient?: AppointmentPatient; /** Treatment lines. */ treatments?: AppointmentTreatment[]; /** Online booking-reason metadata. */ bookingReason?: AppointmentBookingReason; /** Boolean flags. */ flags?: AppointmentFlags; /** Money summary — billable + unpaid amounts. */ money?: AppointmentMoney; /** Whether this appointment is part of a recurring series. */ recurring?: boolean; /** Signing status for attached documents. */ signing?: AppointmentSigning; /** A note left by the patient at booking time. When present, a small * message icon signals it. */ bookingNote?: string; /** Optional deep link — when present (and safe) the row renders as an anchor. */ url?: string; /** * Settle the row visually without removing it from the list — a muted * wash in place of the elevated surface, shadow dropped. Text keeps its * normal foreground colour so contrast is unaffected; only the chrome * dims. For a row already concluded (done / no-show) that a host still * wants listed alongside what's still ahead. */ dimmed?: boolean; /** * Marks this as the NEXT appointment to start — a steady accent outline * (a state, not a one-off address, so it never animates) plus a small * "Next" label. The cue never rests on colour alone. */ next?: boolean; } declare const appointmentCardVariants: (props?: ({ size?: "sm" | "md" | null | undefined; interactive?: boolean | null | undefined; surface?: "elevated" | "flat" | null | undefined; selected?: boolean | null | undefined; dimmed?: boolean | null | undefined; next?: boolean | null | undefined; } & import("class-variance-authority/types").ClassProp) | undefined) => string; export interface AppointmentCardProps extends Omit, 'onClick' | 'title'>, VariantProps { /** The appointment to render. */ item: AppointmentItem; /** Visual density. */ size?: 'sm' | 'md'; /** * `'flat'` (default) — chrome-less row for use inside a bordered * `AppointmentTray`. `'elevated'` — each row carries its own card chrome * (border + shadow), for placing rows directly on a rail (AppointmentTimeline). */ surface?: 'flat' | 'elevated'; /** BCP-47 locale override for the timestamp + currency. */ locale?: string; /** ISO-4217 currency code for the advance-deposit chip. Defaults to `EUR`. */ currency?: string; /** * Show the patient identity (avatar + name as the row title). Default `true`. * Set `false` in single-patient surfaces (e.g. a patient's own * `AppointmentTimeline`) where repeating the name is redundant — the row then * leads with the operator as its title, falling back to a generic label. */ showPatient?: boolean; /** Fires when the row is activated. */ onActivate?: (item: AppointmentItem) => void; /** * Mark this row as the active/selected appointment — an info-tinted * inline-start bar plus a soft wash, so the eye keeps its place in the * list after a click. Renders `aria-current="true"` for assistive tech. */ selected?: boolean; /** * Withhold the lifecycle-state badge when the item's state is the * default/expected one (`confirmed`) — it needs no announcement, and * dropping it leaves the badge to states that actually ask for * attention. Default `false` (today's behaviour: every state, including * `confirmed`, shows its badge) so existing consumers are unaffected. */ hideDefaultStatus?: boolean; } export declare const AppointmentCard: import("react").ForwardRefExoticComponent>; //# sourceMappingURL=appointment-card.d.ts.map