@alfadocs/ui-kit-debug 1.48.0 → 1.49.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_chunks/{agenda-card-C4h0xMGi.js → agenda-card-CjjxlA9K.js} +2 -2
- package/dist/_chunks/{agenda-card-C4h0xMGi.js.map → agenda-card-CjjxlA9K.js.map} +1 -1
- package/dist/_chunks/{agenda-tray-DNZYW2xt.js → agenda-tray-BhZASyJm.js} +2 -2
- package/dist/_chunks/{agenda-tray-DNZYW2xt.js.map → agenda-tray-BhZASyJm.js.map} +1 -1
- package/dist/_chunks/{alia-sidebar-Crn8OGPF.js → alia-sidebar-Dx-oeOV2.js} +3 -3
- package/dist/_chunks/{alia-sidebar-Crn8OGPF.js.map → alia-sidebar-Dx-oeOV2.js.map} +1 -1
- package/dist/_chunks/{appointment-card-CvGU0QP6.js → appointment-card-BgLpE6T5.js} +2 -2
- package/dist/_chunks/{appointment-card-CvGU0QP6.js.map → appointment-card-BgLpE6T5.js.map} +1 -1
- package/dist/_chunks/{appointment-peek--dmWznLZ.js → appointment-peek-BDiCIBb-.js} +2 -2
- package/dist/_chunks/{appointment-peek--dmWznLZ.js.map → appointment-peek-BDiCIBb-.js.map} +1 -1
- package/dist/_chunks/{appointment-timeline-y9uYZMUd.js → appointment-timeline-wQ-PdkFV.js} +2 -2
- package/dist/_chunks/{appointment-timeline-y9uYZMUd.js.map → appointment-timeline-wQ-PdkFV.js.map} +1 -1
- package/dist/_chunks/{appointment-tray-BTecNeSb.js → appointment-tray-D7Gt6m8x.js} +2 -2
- package/dist/_chunks/{appointment-tray-BTecNeSb.js.map → appointment-tray-D7Gt6m8x.js.map} +1 -1
- package/dist/_chunks/{avatar-CkDeQOSI.js → avatar-BVvjKNTp.js} +2 -2
- package/dist/_chunks/avatar-BVvjKNTp.js.map +1 -0
- package/dist/_chunks/{balance-badge-cell-CA0YNJMR.js → balance-badge-cell-klaxFNL_.js} +3 -3
- package/dist/_chunks/{balance-badge-cell-CA0YNJMR.js.map → balance-badge-cell-klaxFNL_.js.map} +1 -1
- package/dist/_chunks/{booking-BQYFDcrz.js → booking-BF9pVa2n.js} +377 -381
- package/dist/_chunks/booking-BF9pVa2n.js.map +1 -0
- package/dist/_chunks/{calendar-DjoJ9ovF.js → calendar-Bt44KMNO.js} +3 -2
- package/dist/_chunks/{calendar-DjoJ9ovF.js.map → calendar-Bt44KMNO.js.map} +1 -1
- package/dist/_chunks/calendar-workspace-iwyXajja.js +10469 -0
- package/dist/_chunks/{calendar-workspace-D8zX9JWm.js.map → calendar-workspace-iwyXajja.js.map} +1 -1
- package/dist/_chunks/{chat-message-Co_NRGM4.js → chat-message-B4ihjNy3.js} +2 -2
- package/dist/_chunks/{chat-message-Co_NRGM4.js.map → chat-message-B4ihjNy3.js.map} +1 -1
- package/dist/_chunks/{clinical-note-card-DYDQ3q2x.js → clinical-note-card-B7s5BtEl.js} +2 -2
- package/dist/_chunks/{clinical-note-card-DYDQ3q2x.js.map → clinical-note-card-B7s5BtEl.js.map} +1 -1
- package/dist/_chunks/{data-table-DWOSxlsy.js → data-table-CrI3_bjH.js} +411 -410
- package/dist/_chunks/data-table-CrI3_bjH.js.map +1 -0
- package/dist/_chunks/{dependent-selector-BR_8D2Qu.js → dependent-selector-58hTg5rB.js} +2 -2
- package/dist/_chunks/{dependent-selector-BR_8D2Qu.js.map → dependent-selector-58hTg5rB.js.map} +1 -1
- package/dist/_chunks/{entity-summary-Ckz_U00H.js → entity-summary-CFJfBdVP.js} +2 -2
- package/dist/_chunks/{entity-summary-Ckz_U00H.js.map → entity-summary-CFJfBdVP.js.map} +1 -1
- package/dist/_chunks/{file-manager-CqgxLqoA.js → file-manager-C6QQPQV5.js} +2 -2
- package/dist/_chunks/{file-manager-CqgxLqoA.js.map → file-manager-C6QQPQV5.js.map} +1 -1
- package/dist/_chunks/link-cell-renderer-CkNbUsBM.js +867 -0
- package/dist/_chunks/link-cell-renderer-CkNbUsBM.js.map +1 -0
- package/dist/_chunks/{marketplace-app-shell-Dehuxbi-.js → marketplace-app-shell-1uKqs4gD.js} +2 -2
- package/dist/_chunks/{marketplace-app-shell-Dehuxbi-.js.map → marketplace-app-shell-1uKqs4gD.js.map} +1 -1
- package/dist/_chunks/{message-card-DKOtnBHy.js → message-card-C2zsvyj0.js} +2 -2
- package/dist/_chunks/{message-card-DKOtnBHy.js.map → message-card-C2zsvyj0.js.map} +1 -1
- package/dist/_chunks/{message-tray-COMEtmyr.js → message-tray-CMlmxdH2.js} +2 -2
- package/dist/_chunks/{message-tray-COMEtmyr.js.map → message-tray-CMlmxdH2.js.map} +1 -1
- package/dist/_chunks/{notes-panel-BiOxZL_0.js → notes-panel-xxpFt-I1.js} +2 -2
- package/dist/_chunks/{notes-panel-BiOxZL_0.js.map → notes-panel-xxpFt-I1.js.map} +1 -1
- package/dist/_chunks/{operator-hero-5061fkY5.js → operator-hero-DyrNLoRO.js} +2 -2
- package/dist/_chunks/{operator-hero-5061fkY5.js.map → operator-hero-DyrNLoRO.js.map} +1 -1
- package/dist/_chunks/{patient-details-C23Hdm8v.js → patient-details-tTlvrJSU.js} +2 -2
- package/dist/_chunks/{patient-details-C23Hdm8v.js.map → patient-details-tTlvrJSU.js.map} +1 -1
- package/dist/_chunks/{patient-summary-card-C36L3h7h.js → patient-summary-card-DQ__6DR-.js} +2 -2
- package/dist/_chunks/{patient-summary-card-C36L3h7h.js.map → patient-summary-card-DQ__6DR-.js.map} +1 -1
- package/dist/_chunks/{practice-profile-hero-CPy5h2yI.js → practice-profile-hero-B-WcJYNH.js} +2 -2
- package/dist/_chunks/{practice-profile-hero-CPy5h2yI.js.map → practice-profile-hero-B-WcJYNH.js.map} +1 -1
- package/dist/_chunks/{practice-results-t2BHht91.js → practice-results-EKRiqWtQ.js} +2 -2
- package/dist/_chunks/{practice-results-t2BHht91.js.map → practice-results-EKRiqWtQ.js.map} +1 -1
- package/dist/_chunks/{signature-request-15D363w5.js → signature-request-BUGeG8oD.js} +2 -2
- package/dist/_chunks/{signature-request-15D363w5.js.map → signature-request-BUGeG8oD.js.map} +1 -1
- package/dist/_chunks/{task-card-CTTQfPS6.js → task-card-jaOhnj_q.js} +31 -30
- package/dist/_chunks/task-card-jaOhnj_q.js.map +1 -0
- package/dist/_chunks/{task-tray-JA-qp_pB.js → task-tray-HHyxi9ga.js} +2 -2
- package/dist/_chunks/{task-tray-JA-qp_pB.js.map → task-tray-HHyxi9ga.js.map} +1 -1
- package/dist/_chunks/{tasks-panel-C_dVDQKJ.js → tasks-panel-DbSjq_mz.js} +2 -2
- package/dist/_chunks/{tasks-panel-C_dVDQKJ.js.map → tasks-panel-DbSjq_mz.js.map} +1 -1
- package/dist/_chunks/{timeline-61AihzYz.js → timeline-ChY7iZrs.js} +2 -2
- package/dist/_chunks/{timeline-61AihzYz.js.map → timeline-ChY7iZrs.js.map} +1 -1
- package/dist/_chunks/{use-appointment-details-read-D2FH-cHF.js → use-appointment-details-read-5-hV-2xA.js} +4 -4
- package/dist/_chunks/{use-appointment-details-read-D2FH-cHF.js.map → use-appointment-details-read-5-hV-2xA.js.map} +1 -1
- package/dist/agent-catalog.json +1 -1
- package/dist/components/agenda-card/index.js +1 -1
- package/dist/components/agenda-tray/index.js +1 -1
- package/dist/components/appointment-card/index.js +2 -2
- package/dist/components/appointment-details-panel/index.js +1 -1
- package/dist/components/appointment-peek/index.js +1 -1
- package/dist/components/appointment-timeline/index.js +1 -1
- package/dist/components/avatar/avatar.d.ts.map +1 -1
- package/dist/components/avatar/index.js +1 -1
- package/dist/components/booking/booking.d.ts.map +1 -1
- package/dist/components/booking/cascade.d.ts +5 -0
- package/dist/components/booking/cascade.d.ts.map +1 -1
- package/dist/components/booking/index.js +1 -1
- package/dist/components/calendar/calendar.d.ts.map +1 -1
- package/dist/components/calendar/index.js +1 -1
- package/dist/components/chat-message/index.js +1 -1
- package/dist/components/clinical-note-card/index.js +1 -1
- package/dist/components/data-table/filters/number-filter.d.ts +26 -12
- package/dist/components/data-table/filters/number-filter.d.ts.map +1 -1
- package/dist/components/data-table/index.js +2 -2
- package/dist/components/data-table/toolbar.d.ts.map +1 -1
- package/dist/components/dependent-selector/index.js +1 -1
- package/dist/components/entity-summary/index.js +1 -1
- package/dist/components/file-manager/index.js +1 -1
- package/dist/components/message-card/index.js +1 -1
- package/dist/components/message-tray/index.js +1 -1
- package/dist/components/notes-panel/index.js +1 -1
- package/dist/components/operator-hero/index.js +1 -1
- package/dist/components/patient-details/index.js +1 -1
- package/dist/components/patient-summary-card/index.js +1 -1
- package/dist/components/patient-table/index.js +1 -1
- package/dist/components/practice-profile-hero/index.js +1 -1
- package/dist/components/practice-results/index.js +1 -1
- package/dist/components/task-card/index.js +1 -1
- package/dist/components/task-card/task-card.d.ts +3 -2
- package/dist/components/task-card/task-card.d.ts.map +1 -1
- package/dist/components/task-tray/index.js +1 -1
- package/dist/components/tasks-panel/index.js +1 -1
- package/dist/components/timeline/index.js +1 -1
- package/dist/i18n/locales/ar.d.ts +19 -14
- package/dist/i18n/locales/ar.d.ts.map +1 -1
- package/dist/i18n/locales/ar.js +19 -14
- package/dist/i18n/locales/ar.js.map +1 -1
- package/dist/i18n/locales/de.d.ts +19 -14
- package/dist/i18n/locales/de.d.ts.map +1 -1
- package/dist/i18n/locales/de.js +19 -14
- package/dist/i18n/locales/de.js.map +1 -1
- package/dist/i18n/locales/el.d.ts +19 -14
- package/dist/i18n/locales/el.d.ts.map +1 -1
- package/dist/i18n/locales/el.js +19 -14
- package/dist/i18n/locales/el.js.map +1 -1
- package/dist/i18n/locales/en.d.ts +5 -0
- package/dist/i18n/locales/en.d.ts.map +1 -1
- package/dist/i18n/locales/en.js +6 -0
- package/dist/i18n/locales/en.js.map +1 -1
- package/dist/i18n/locales/es.d.ts +19 -14
- package/dist/i18n/locales/es.d.ts.map +1 -1
- package/dist/i18n/locales/es.js +19 -14
- package/dist/i18n/locales/es.js.map +1 -1
- package/dist/i18n/locales/fr.d.ts +19 -14
- package/dist/i18n/locales/fr.d.ts.map +1 -1
- package/dist/i18n/locales/fr.js +19 -14
- package/dist/i18n/locales/fr.js.map +1 -1
- package/dist/i18n/locales/hi.d.ts +19 -14
- package/dist/i18n/locales/hi.d.ts.map +1 -1
- package/dist/i18n/locales/hi.js +19 -14
- package/dist/i18n/locales/hi.js.map +1 -1
- package/dist/i18n/locales/it.d.ts +5 -0
- package/dist/i18n/locales/it.d.ts.map +1 -1
- package/dist/i18n/locales/it.js +6 -0
- package/dist/i18n/locales/it.js.map +1 -1
- package/dist/i18n/locales/ja.d.ts +19 -14
- package/dist/i18n/locales/ja.d.ts.map +1 -1
- package/dist/i18n/locales/ja.js +19 -14
- package/dist/i18n/locales/ja.js.map +1 -1
- package/dist/i18n/locales/nl.d.ts +19 -14
- package/dist/i18n/locales/nl.d.ts.map +1 -1
- package/dist/i18n/locales/nl.js +19 -14
- package/dist/i18n/locales/nl.js.map +1 -1
- package/dist/i18n/locales/pl.d.ts +19 -14
- package/dist/i18n/locales/pl.d.ts.map +1 -1
- package/dist/i18n/locales/pl.js +19 -14
- package/dist/i18n/locales/pl.js.map +1 -1
- package/dist/i18n/locales/pt.d.ts +19 -14
- package/dist/i18n/locales/pt.d.ts.map +1 -1
- package/dist/i18n/locales/pt.js +19 -14
- package/dist/i18n/locales/pt.js.map +1 -1
- package/dist/i18n/locales/ro.d.ts +19 -14
- package/dist/i18n/locales/ro.d.ts.map +1 -1
- package/dist/i18n/locales/ro.js +19 -14
- package/dist/i18n/locales/ro.js.map +1 -1
- package/dist/i18n/locales/ru.d.ts +19 -14
- package/dist/i18n/locales/ru.d.ts.map +1 -1
- package/dist/i18n/locales/ru.js +19 -14
- package/dist/i18n/locales/ru.js.map +1 -1
- package/dist/i18n/locales/sq.d.ts +19 -14
- package/dist/i18n/locales/sq.d.ts.map +1 -1
- package/dist/i18n/locales/sq.js +19 -14
- package/dist/i18n/locales/sq.js.map +1 -1
- package/dist/i18n/locales/sv.d.ts +19 -14
- package/dist/i18n/locales/sv.d.ts.map +1 -1
- package/dist/i18n/locales/sv.js +19 -14
- package/dist/i18n/locales/sv.js.map +1 -1
- package/dist/i18n/locales/tr.d.ts +19 -14
- package/dist/i18n/locales/tr.d.ts.map +1 -1
- package/dist/i18n/locales/tr.js +19 -14
- package/dist/i18n/locales/tr.js.map +1 -1
- package/dist/i18n/locales/zh.d.ts +19 -14
- package/dist/i18n/locales/zh.d.ts.map +1 -1
- package/dist/i18n/locales/zh.js +19 -14
- package/dist/i18n/locales/zh.js.map +1 -1
- package/dist/index.js +34 -34
- package/dist/locales/ar.json +19 -14
- package/dist/locales/de.json +19 -14
- package/dist/locales/el.json +19 -14
- package/dist/locales/en.json +5 -0
- package/dist/locales/es.json +19 -14
- package/dist/locales/fr.json +19 -14
- package/dist/locales/hi.json +19 -14
- package/dist/locales/it.json +5 -0
- package/dist/locales/ja.json +19 -14
- package/dist/locales/nl.json +19 -14
- package/dist/locales/pl.json +19 -14
- package/dist/locales/pt.json +19 -14
- package/dist/locales/ro.json +19 -14
- package/dist/locales/ru.json +19 -14
- package/dist/locales/sq.json +19 -14
- package/dist/locales/sv.json +19 -14
- package/dist/locales/tr.json +19 -14
- package/dist/locales/zh.json +19 -14
- package/dist/patterns/alia-assistant/index.js +1 -1
- package/dist/patterns/calendar/calendar-workspace.d.ts +10 -0
- package/dist/patterns/calendar/calendar-workspace.d.ts.map +1 -1
- package/dist/patterns/calendar/calendar.surface.d.ts +4 -1
- package/dist/patterns/calendar/calendar.surface.d.ts.map +1 -1
- package/dist/patterns/calendar/index.js +1 -1
- package/dist/patterns/marketplace-app-shell/index.js +1 -1
- package/dist/patterns/signature-request/index.js +1 -1
- package/dist/tokens.css +1 -1
- package/package.json +12 -12
- package/dist/_chunks/avatar-CkDeQOSI.js.map +0 -1
- package/dist/_chunks/booking-BQYFDcrz.js.map +0 -1
- package/dist/_chunks/calendar-workspace-D8zX9JWm.js +0 -10423
- package/dist/_chunks/data-table-DWOSxlsy.js.map +0 -1
- package/dist/_chunks/link-cell-renderer-Tswqf6BT.js +0 -778
- package/dist/_chunks/link-cell-renderer-Tswqf6BT.js.map +0 -1
- package/dist/_chunks/task-card-CTTQfPS6.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-appointment-details-read-D2FH-cHF.js","sources":["../../node_modules/lucide-react/dist/esm/icons/cake.mjs","../../node_modules/lucide-react/dist/esm/icons/clipboard-paste.mjs","../../node_modules/lucide-react/dist/esm/icons/id-card.mjs","../../node_modules/lucide-react/dist/esm/icons/move.mjs","../../src/components/appointment-details-panel/appointment-details-panel.agent.ts","../../src/components/appointment-details-panel/appointment-details-panel.focus.ts","../../src/components/_shared/appointment-format.ts","../../src/components/appointment-details-panel/appointment-details-panel.history.tsx","../../src/components/appointment-details-panel/appointment-details-panel.identity.tsx","../../src/components/appointment-details-panel/appointment-details-panel.info-hover.tsx","../../src/components/appointment-details-panel/appointment-details-panel.sections.tsx","../../src/components/appointment-details-panel/appointment-details-panel.tsx","../../src/components/appointment-details-panel/use-appointment-details-read.ts"],"sourcesContent":["/**\n * @license lucide-react v1.22.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M20 21v-8a2 2 0 0 0-2-2H6a2 2 0 0 0-2 2v8\", key: \"1w3rig\" }],\n [\"path\", { d: \"M4 16s.5-1 2-1 2.5 2 4 2 2.5-2 4-2 2.5 2 4 2 2-1 2-1\", key: \"n2jgmb\" }],\n [\"path\", { d: \"M2 21h20\", key: \"1nyx9w\" }],\n [\"path\", { d: \"M7 8v3\", key: \"1qtyvj\" }],\n [\"path\", { d: \"M12 8v3\", key: \"hwp4zt\" }],\n [\"path\", { d: \"M17 8v3\", key: \"1i6e5u\" }],\n [\"path\", { d: \"M7 4h.01\", key: \"1bh4kh\" }],\n [\"path\", { d: \"M12 4h.01\", key: \"1ujb9j\" }],\n [\"path\", { d: \"M17 4h.01\", key: \"1upcoc\" }]\n];\nconst Cake = createLucideIcon(\"cake\", __iconNode);\n\nexport { __iconNode, Cake as default };\n//# sourceMappingURL=cake.mjs.map\n","/**\n * @license lucide-react v1.22.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M11 14h10\", key: \"1w8e9d\" }],\n [\"path\", { d: \"M16 4h2a2 2 0 0 1 2 2v1.344\", key: \"1e62lh\" }],\n [\"path\", { d: \"m17 18 4-4-4-4\", key: \"z2g111\" }],\n [\"path\", { d: \"M8 4H6a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h12a2 2 0 0 0 1.793-1.113\", key: \"bjbb7m\" }],\n [\"rect\", { x: \"8\", y: \"2\", width: \"8\", height: \"4\", rx: \"1\", key: \"ublpy\" }]\n];\nconst ClipboardPaste = createLucideIcon(\"clipboard-paste\", __iconNode);\n\nexport { __iconNode, ClipboardPaste as default };\n//# sourceMappingURL=clipboard-paste.mjs.map\n","/**\n * @license lucide-react v1.22.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M16 10h2\", key: \"8sgtl7\" }],\n [\"path\", { d: \"M16 14h2\", key: \"epxaof\" }],\n [\"path\", { d: \"M6.17 15a3 3 0 0 1 5.66 0\", key: \"n6f512\" }],\n [\"circle\", { cx: \"9\", cy: \"11\", r: \"2\", key: \"yxgjnd\" }],\n [\"rect\", { x: \"2\", y: \"5\", width: \"20\", height: \"14\", rx: \"2\", key: \"qneu4z\" }]\n];\nconst IdCard = createLucideIcon(\"id-card\", __iconNode);\n\nexport { __iconNode, IdCard as default };\n//# sourceMappingURL=id-card.mjs.map\n","/**\n * @license lucide-react v1.22.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M12 2v20\", key: \"t6zp3m\" }],\n [\"path\", { d: \"m15 19-3 3-3-3\", key: \"11eu04\" }],\n [\"path\", { d: \"m19 9 3 3-3 3\", key: \"1mg7y2\" }],\n [\"path\", { d: \"M2 12h20\", key: \"9i4pu4\" }],\n [\"path\", { d: \"m5 9-3 3 3 3\", key: \"j64kie\" }],\n [\"path\", { d: \"m9 5 3-3 3 3\", key: \"l8vdw6\" }]\n];\nconst Move = createLucideIcon(\"move\", __iconNode);\n\nexport { __iconNode, Move as default };\n//# sourceMappingURL=move.mjs.map\n","/* -------------------------------------------------------------------- */\n/* Agent adapter: AppointmentDetailsPanel. */\n/* */\n/* Reads ids and enums only: the occurrence id, the load status, the */\n/* appointment status, the footer actions on offer, whether History is */\n/* open and whether privacy mode is on. Never a patient name, a phone */\n/* number or a note. */\n/* */\n/* set_status goes through the footer's own WorkflowStatusControl, so the */\n/* panel shows the saving state and any refusal exactly as for a click; */\n/* it is `phi` + openWorld: the status is a named patient's attendance. */\n/* The footer actions (Edit, Move, Copy, Delete, WhatsApp …) are the */\n/* host's and are reached through their data-action hooks: the host's own */\n/* confirmation guards Delete. An offered action with no hook in the */\n/* footer strip is folded into More: open More (MORE_TRIGGER below), and */\n/* its menu item carries the same data-action. */\n/* -------------------------------------------------------------------- */\n\nimport type { AgentAdapter } from '../../agent/types';\nimport type { AppointmentDetailsPanelHandle } from './appointment-details-panel';\n\n/* The footer's More trigger, found without its translated label: the one\n menu-opening icon button in the actions group. */\nconst MORE_TRIGGER =\n '[data-component=\"button-group\"] [data-component=\"icon-button\"][aria-haspopup=\"menu\"]';\n\nexport const appointmentDetailsPanelAgent: AgentAdapter<AppointmentDetailsPanelHandle> =\n {\n id: 'appointment-details-panel',\n // open and close back open_history and close_history; set_value backs\n // set_status.\n capabilities: ['open', 'close', 'set_value'],\n state: {\n eventId: {\n type: 'string | null',\n descriptionKey: 'ui.agent.appointmentDetailsPanel.state.eventId',\n description:\n 'The occurrence on screen or being read, as the host identifies it. After a failed or refused read, the occurrence it was for when the host says so. Null when there is none, or the host did not say.',\n read: (handle) => handle.getEventId(),\n },\n loadStatus: {\n type: \"'loading' | 'ready' | 'error' | 'refused'\",\n descriptionKey: 'ui.agent.appointmentDetailsPanel.state.loadStatus',\n description:\n 'Where the read is: loading, ready, failed (with Retry) or refused. Actions need ready.',\n read: (handle) => handle.getLoadStatus(),\n },\n appointmentStatus: {\n type: \"'confirmed' | 'waiting' | 'in_care' | 'done' | 'cancelled' | 'absent' | null\",\n descriptionKey:\n 'ui.agent.appointmentDetailsPanel.state.appointmentStatus',\n description:\n 'The appointment status as last saved here or read. Null when none is recorded or nothing is on screen.',\n read: (handle) => handle.getAppointmentStatus(),\n },\n allowedStatuses: {\n type: 'string[]',\n descriptionKey:\n 'ui.agent.appointmentDetailsPanel.state.allowedStatuses',\n description:\n 'The statuses set_status accepts now, in menu order. Empty when the status is read-only.',\n read: (handle) => handle.getAllowedStatuses(),\n },\n offeredActions: {\n type: 'string[]',\n descriptionKey: 'ui.agent.appointmentDetailsPanel.state.offeredActions',\n description:\n 'The footer actions on offer, as their data-action values (for example edit-appointment, delete-appointment), in footer order, including any folded into More.',\n read: (handle) => handle.getOfferedActions(),\n },\n historyOpen: {\n type: 'boolean',\n descriptionKey: 'ui.agent.appointmentDetailsPanel.state.historyOpen',\n description: 'Whether the History sub-view covers the details.',\n read: (handle) => handle.isHistoryOpen(),\n },\n privacy: {\n type: 'boolean',\n descriptionKey: 'ui.agent.appointmentDetailsPanel.state.privacy',\n description:\n 'Whether privacy mode is on. The patient identity and personal fields are then masked on screen.',\n read: (handle) => handle.isPrivacy(),\n },\n },\n actions: {\n open_history: {\n safety: 'read',\n openWorld: true,\n idempotent: true,\n errors: ['No appointment is on screen, or History is not offered.'],\n descriptionKey: 'ui.agent.appointmentDetailsPanel.actions.openHistory',\n description:\n \"Slide the appointment's history over the details, as its header button does; the host reads it then if it did not send it with the details. It lists who changed what, and when.\",\n invoke: (handle) => handle.openHistory(),\n },\n close_history: {\n safety: 'read',\n idempotent: true,\n descriptionKey: 'ui.agent.appointmentDetailsPanel.actions.closeHistory',\n description: 'Return from History to the details.',\n invoke: (handle) => handle.closeHistory(),\n },\n set_status: {\n safety: 'phi',\n openWorld: true,\n idempotent: true,\n argsType: '{ status: string }',\n argsSchema: {\n type: 'object',\n properties: {\n status: {\n type: 'string',\n enum: [\n 'confirmed',\n 'waiting',\n 'in_care',\n 'done',\n 'cancelled',\n 'absent',\n ],\n },\n },\n required: ['status'],\n },\n errors: [\n 'The status is read-only: no appointment on screen, no host save, readOnly, or no allowed statuses.',\n 'The status is not in allowedStatuses.',\n 'A status save is already in flight.',\n 'The host refused the change. The previous status stays and the panel shows the message.',\n ],\n examples: [{ args: { status: 'waiting' } }],\n descriptionKey: 'ui.agent.appointmentDetailsPanel.actions.setStatus',\n description:\n 'Save a new appointment status through the host, as the footer control does. Resolves once the host has saved it.',\n invoke: (handle, args: { status: string }) =>\n handle.setAppointmentStatus(\n args.status as Parameters<\n AppointmentDetailsPanelHandle['setAppointmentStatus']\n >[0],\n ),\n },\n retry: {\n safety: 'read',\n openWorld: true,\n errors: [\n 'Retry is not offered: the read has not failed or been refused as retryable, or the host offers no Retry.',\n ],\n descriptionKey: 'ui.agent.appointmentDetailsPanel.actions.retry',\n description:\n 'Ask the host to read the appointment again, after a failed read or a refusal it marked retryable.',\n invoke: (handle) => handle.retry(),\n },\n },\n domHooks: {\n root: {\n attr: 'data-component',\n value: 'appointment-details-panel',\n description: `Marks the panel. It also carries data-event-id and data-status. Inside, cards carry data-card (patient, appointment, notes, treatments), footer actions data-action, and the History and description sub-views data-details-subview. An action in offeredActions with no data-action in the footer strip is folded into More: click the panel's ${MORE_TRIGGER}, and its menu item carries the same data-action.`,\n },\n instanceId: {\n attr: 'data-component-id',\n sourceProp: 'id',\n description: 'Sourced from the id prop, or generated.',\n },\n },\n };\n","/* Where focus goes when the control that held it leaves the details\n panel: the panel's own parts share these, so every rescue behaves the\n same way. */\n\n/** Hands focus to `target` only when focus fell to the page: a control that\n * held it was removed. Focus the user put elsewhere stays there. */\nexport function rescueFocus(target: HTMLElement | null | undefined): void {\n const active = document.activeElement;\n if (active && active !== document.body) return;\n target?.focus({ preventScroll: true });\n}\n\n/** A heading, made focusable on demand: where focus goes when the control\n * that held it leaves the panel or one of its cards. */\nexport function focusHeading(headingId: string): void {\n const heading = document.getElementById(headingId);\n if (heading && !heading.hasAttribute('tabindex')) heading.tabIndex = -1;\n rescueFocus(heading);\n}\n","/* Pure helpers for reading one appointment: dates, the patient's age,\n phones, address and the history order. No React and no i18n lookups.\n Shared by AppointmentDetailsPanel and the calendar pattern, which\n re-exports them under their old names. */\nimport type {\n AppointmentPhoneNumber,\n AppointmentRecurrenceFrequency,\n} from '../appointment-details-panel/appointment-details-panel.types';\n\n/** A date-only value (a birthday, an all-day start) is already a local day;\n * anything else parses as the wall clock it carries. */\nexport function parseEventDate(value: string | Date): Date {\n return typeof value === 'string' && /^\\d{4}-\\d{2}-\\d{2}$/.test(value)\n ? new Date(`${value}T00:00:00`)\n : new Date(value);\n}\n\n/** \"Wednesday, 24 June 2026\" in the reader's locale; '' when unreadable. */\nexport function formatDay(locale: string, value: Date | string): string {\n try {\n return new Intl.DateTimeFormat(locale, {\n weekday: 'long',\n day: 'numeric',\n month: 'long',\n year: 'numeric',\n }).format(parseEventDate(value));\n } catch {\n return '';\n }\n}\n\n/** \"09:00–09:45\" in the reader's locale, 24-hour; '' when unreadable. */\nexport function formatTimeRange(\n locale: string,\n start: Date | string,\n end?: Date | string,\n): string {\n const s = new Date(start);\n const e = end ? new Date(end) : s;\n try {\n const fmt = new Intl.DateTimeFormat(locale, {\n hour: '2-digit',\n minute: '2-digit',\n hour12: false,\n });\n return typeof fmt.formatRange === 'function'\n ? fmt.formatRange(s, e)\n : `${fmt.format(s)} – ${fmt.format(e)}`;\n } catch {\n return '';\n }\n}\n\n/** Absolute stamp for booked-at and history lines: day and time. */\nexport const DETAIL_STAMP_FORMAT: Intl.DateTimeFormatOptions = {\n weekday: 'short',\n day: 'numeric',\n month: 'short',\n hour: '2-digit',\n minute: '2-digit',\n};\n\n/** Completed years between a birth date and `on`, the practice's clock\n * rather than the real one, so the figure never drifts under a test. */\nexport function ageInYears(dobIso: string, on: Date | string): number {\n const dob = parseEventDate(dobIso);\n const at = parseEventDate(on);\n let age = at.getFullYear() - dob.getFullYear();\n const monthDelta = at.getMonth() - dob.getMonth();\n if (monthDelta < 0 || (monthDelta === 0 && at.getDate() < dob.getDate())) {\n age -= 1;\n }\n return Math.max(0, age);\n}\n\nconst START_ISO = /^(\\d{4})-(\\d{2})-(\\d{2})T(\\d{2}):(\\d{2}):(\\d{2})$/;\n\n/** The host's zone-less wall clock as a local Date, or undefined when it is\n * not a real 'YYYY-MM-DDTHH:mm:ss' reading. Ranges are checked rather than\n * round-tripped, so a time inside a daylight-saving gap still parses. */\nexport function parseAppointmentStartIso(\n startIso: string | undefined,\n): Date | undefined {\n const match = typeof startIso === 'string' ? START_ISO.exec(startIso) : null;\n if (!match) return undefined;\n const [year, month, day, hours, minutes, seconds] = match\n .slice(1)\n .map(Number);\n const monthEnd = new Date(0);\n monthEnd.setFullYear(year, month, 0);\n if (\n month < 1 ||\n month > 12 ||\n day < 1 ||\n day > monthEnd.getDate() ||\n hours > 23 ||\n minutes > 59 ||\n seconds > 59\n )\n return undefined;\n const start = new Date(0);\n start.setFullYear(year, month - 1, day);\n start.setHours(hours, minutes, seconds, 0);\n return start;\n}\n\n/** A Timeline set to 'newest-first' is a plain column, so the DOM order\n * must already be newest first. Unreadable dates stay last, in input\n * order; equal instants keep theirs. The input is not changed. */\nexport function sortHistoryNewestFirst<T extends { atIso: string }>(\n entries: readonly T[],\n): T[] {\n return entries\n .map((entry) => {\n const parsed = Date.parse(entry.atIso);\n return { entry, time: Number.isFinite(parsed) ? parsed : -Infinity };\n })\n .sort((a, b) => (a.time === b.time ? 0 : b.time - a.time))\n .map(({ entry }) => entry);\n}\n\n/** The editor's label key for each frequency, under\n * `calendarWorkspace.editor.*`. A literal map, so key extractors see\n * every key. */\nexport const RECURRENCE_LABEL_KEY: Record<\n AppointmentRecurrenceFrequency,\n string\n> = {\n daily: 'recurrenceDaily',\n weekly: 'recurrenceWeekly',\n monthly: 'recurrenceMonthly',\n quarterly: 'recurrenceQuarterly',\n semiannual: 'recurrenceSemiannual',\n yearly: 'recurrenceYearly',\n};\n\n/** What a patient record needs for its phones. */\nexport interface PhonesSource {\n phone?: string;\n phones?: AppointmentPhoneNumber[];\n}\n\n/** Every labelled phone number. The single `phone` is the mobile when the\n * record carries no list. A record with neither has no numbers, which is\n * not the same as one labelled blank: the list comes back empty and the\n * caller omits the rows. */\nexport function patientPhones(patient: PhonesSource): AppointmentPhoneNumber[] {\n if (patient.phones) return patient.phones;\n return patient.phone ? [{ label: 'mobile', number: patient.phone }] : [];\n}\n\n/** What a patient record needs for its address. */\nexport interface AddressSource {\n address?: string;\n postalCode?: string;\n city?: string;\n}\n\n/** The address as one line, the map search's text. Empty when the host\n * sent no address at all: the caller then offers no search. */\nexport function patientAddressLine(patient: AddressSource): string {\n return [patient.address, patient.postalCode, patient.city]\n .filter((part): part is string => Boolean(part))\n .join(', ');\n}\n\n/** The map link's visible label: street and city, as the platform popover\n * prints them. The postcode belongs in the search, not in the label. */\nexport function patientAddressLabel(patient: AddressSource): string {\n return [patient.address, patient.city]\n .filter((part): part is string => Boolean(part))\n .join(', ');\n}\n\n/** Google Maps search for the patient's address: the popover's map link. */\nexport function patientMapsUrl(patient: AddressSource): string {\n const query = patientAddressLine(patient);\n return `https://www.google.com/maps/search/?api=1&query=${encodeURIComponent(query)}`;\n}\n","/* The appointment's history as a kit Timeline, newest first. Shared by the\n details panel's History sub-view and the calendar editor's. Internal to\n this directory: the calendar pattern imports it by path. */\nimport {\n ArrowRight,\n CalendarClock,\n CalendarPlus,\n Clock,\n Move,\n Pencil,\n Trash2,\n} from 'lucide-react';\nimport type { ReactNode } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { APPOINTMENT_STATE_WORKFLOW } from '../_shared/entity-card';\nimport {\n DETAIL_STAMP_FORMAT,\n sortHistoryNewestFirst,\n} from '../_shared/appointment-format';\nimport { EmptyState } from '../empty-state';\nimport { Timeline } from '../timeline';\nimport {\n useAppointmentWorkflowStatus,\n WorkflowStatusDisplay,\n} from '../workflow-status';\nimport type { AppointmentHistoryEntry } from './appointment-details-panel.types';\n\nconst detailKey = (suffix: string): string =>\n `calendarWorkspace.details.${suffix}`;\n\nexport interface AppointmentHistoryTimelineProps {\n /** In any order: the timeline sorts a copy, newest first. */\n history: readonly AppointmentHistoryEntry[];\n /** Locale for the stamps. Defaults to the active i18n language. */\n locale?: string;\n}\n\n/** One row per history entry. A status change reads as two read-only\n * status pills with an accessible \"From → To\" label; an empty history\n * shows \"No changes recorded\". */\nexport function AppointmentHistoryTimeline({\n history,\n locale,\n}: AppointmentHistoryTimelineProps) {\n const { t, i18n: runtimeI18n } = useTranslation();\n const { optionFor } = useAppointmentWorkflowStatus(null);\n const shownLocale = locale ?? runtimeI18n.language;\n const formatStamp = (iso: string): string => {\n try {\n return new Intl.DateTimeFormat(shownLocale, DETAIL_STAMP_FORMAT).format(\n new Date(iso),\n );\n } catch {\n return iso;\n }\n };\n /* History line → tone, dot glyph and the from/to detail. */\n const describe = (\n entry: AppointmentHistoryEntry,\n ): {\n type: 'info' | 'success' | 'warning' | 'error' | 'neutral';\n icon: ReactNode;\n detail?: ReactNode;\n } => {\n switch (entry.kind) {\n case 'created':\n return {\n type: 'success',\n icon: <CalendarPlus size={16} aria-hidden=\"true\" />,\n };\n case 'moved':\n return {\n type: 'info',\n icon: <Move size={16} aria-hidden=\"true\" />,\n detail: t(detailKey('history.movedDetail'), {\n from: formatStamp(entry.fromIso),\n to: formatStamp(entry.toIso),\n }),\n };\n case 'resized':\n return {\n type: 'info',\n icon: <Clock size={16} aria-hidden=\"true\" />,\n detail: t(detailKey('history.resizedDetail'), {\n from: entry.fromMin,\n to: entry.toMin,\n }),\n };\n case 'status': {\n const StatusGlyph = APPOINTMENT_STATE_WORKFLOW[entry.to].Icon;\n const fromOption = optionFor(entry.from);\n const toOption = optionFor(entry.to);\n const transitionLabel = t(detailKey('history.statusDetail'), {\n from: fromOption.label,\n to: toOption.label,\n });\n return {\n type:\n entry.to === 'cancelled' || entry.to === 'absent'\n ? 'warning'\n : 'neutral',\n icon: <StatusGlyph size={16} aria-hidden=\"true\" />,\n detail: (\n <div role=\"group\" aria-label={transitionLabel}>\n <div\n aria-hidden=\"true\"\n className=\"ds:flex ds:flex-wrap ds:items-center ds:gap-[var(--spacing-xs)]\"\n >\n <WorkflowStatusDisplay\n value={entry.from}\n option={fromOption}\n size=\"sm\"\n />\n <ArrowRight\n className=\"ds:size-4 ds:shrink-0 ds:rtl:rotate-180\"\n aria-hidden=\"true\"\n />\n <WorkflowStatusDisplay\n value={entry.to}\n option={toOption}\n size=\"sm\"\n />\n </div>\n </div>\n ),\n };\n }\n case 'edited':\n return {\n type: 'neutral',\n icon: <Pencil size={16} aria-hidden=\"true\" />,\n /* The platform log carries no field list: no \"Changed\" line. */\n detail:\n entry.fields.length > 0\n ? t(detailKey('history.editedDetail'), {\n fields: entry.fields\n .map((field) => t(detailKey(`history.fields.${field}`)))\n .join(', '),\n })\n : undefined,\n };\n case 'confirmedByPatient': {\n const ConfirmedGlyph = APPOINTMENT_STATE_WORKFLOW.confirmed.Icon;\n return {\n type: 'success',\n icon: <ConfirmedGlyph size={16} aria-hidden=\"true\" />,\n };\n }\n case 'deleted':\n return {\n type: 'error',\n icon: <Trash2 size={16} aria-hidden=\"true\" />,\n };\n }\n };\n if (history.length === 0) {\n return (\n <EmptyState\n variant=\"first-use\"\n size=\"sm\"\n title={t(detailKey('historyEmpty'))}\n />\n );\n }\n return (\n <Timeline order=\"newest-first\" aria-label={t(detailKey('historyTitle'))}>\n {sortHistoryNewestFirst(history).map((entry) => {\n const shape = describe(entry);\n return (\n <Timeline.Event\n key={entry.id}\n eventId={entry.id}\n type={shape.type}\n className=\"ds:[column-gap:var(--spacing-sm)] ds:[padding-block-end:var(--spacing-lg)] ds:before:bg-[var(--primary)]\"\n >\n <Timeline.Dot icon={shape.icon} />\n <Timeline.Content\n title={t(detailKey(`history.${entry.kind}`))}\n description={shape.detail}\n className=\"ds:[padding-block-end:0] ds:[&>[data-component=card]]:border-[color:var(--card-border)] ds:[&>[data-component=card]]:shadow-[var(--shadow-card)]\"\n /* No author (a patient confirming by link): no blank avatar. */\n actor={entry.actor.trim() ? { name: entry.actor } : undefined}\n >\n <span className=\"ds:mt-[var(--spacing-sm)] ds:inline-flex ds:items-center ds:gap-[var(--spacing-xs)]\">\n <CalendarClock\n aria-hidden=\"true\"\n className=\"ds:size-4 ds:shrink-0 ds:text-[color:var(--muted-foreground)]\"\n />\n <Timeline.Timestamp\n date={entry.atIso}\n relative={false}\n locale={shownLocale}\n />\n </span>\n </Timeline.Content>\n </Timeline.Event>\n );\n })}\n </Timeline>\n );\n}\n","/* The identity strip: avatar, name, status badge and the labelled\n indicator chips, with the anamnesis warnings below. Shown by the details\n panel when there is no patient card, and by the calendar editor above its\n form. Data-free: the caller resolves the name, the age and the status.\n Internal to this directory: the calendar pattern imports it by path. */\nimport {\n Euro,\n Globe,\n HeartPulse,\n Repeat,\n TriangleAlert,\n Video,\n} from 'lucide-react';\nimport type { ReactNode } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { formatDay } from '../_shared/appointment-format';\nimport { Alert } from '../alert';\nimport { Avatar } from '../avatar';\nimport { Badge } from '../badge';\nimport { Button } from '../button';\nimport type { CalendarEvent, CalendarEventStatus } from '../calendar';\nimport { useAppointmentWorkflowStatus } from '../workflow-status';\nimport type { AppointmentAnamnesisAnswer } from './appointment-details-panel.types';\n\ntype StatusBadgeVariant =\n | 'success'\n | 'info'\n | 'warning'\n | 'error'\n | 'accentSoft';\n\n/** The Badge variant a status wears as a chip, beside the grid card's disc.\n * The glyph and the label come from the shared workflow status options. */\nexport const APPOINTMENT_STATUS_BADGE_VARIANT: Record<\n CalendarEventStatus,\n StatusBadgeVariant\n> = {\n confirmed: 'success',\n waiting: 'info',\n in_care: 'accentSoft',\n done: 'success',\n cancelled: 'error',\n absent: 'warning',\n};\n\n/** The card flags the chips spell out. */\nexport type IndicatorFlags = Pick<\n CalendarEvent,\n | 'isBookedOnline'\n | 'hasUnassignedPatient'\n | 'hasHighlightedAnamnesis'\n | 'hasBillableAmount'\n | 'isTelehealth'\n | 'isRecurring'\n>;\n\n/** Wherever a grid card carries the disc symbols, the peek and the details\n * panel spell them out: a glyph and the full label in a semantic Badge,\n * in the same tones as the discs. */\nexport function IndicatorChips({ event }: { event: IndicatorFlags }) {\n const { t } = useTranslation();\n const key = (suffix: string): string =>\n `calendarWorkspace.details.indicators.${suffix}`;\n const chips: Array<{\n id: string;\n icon: ReactNode;\n label: string;\n variant: 'info' | 'warning' | 'accentSoft';\n }> = [];\n if (event.isBookedOnline) {\n chips.push({\n id: 'online',\n icon: <Globe aria-hidden=\"true\" />,\n label: t(key('bookedOnline')),\n variant: 'info',\n });\n }\n if (event.hasUnassignedPatient) {\n chips.push({\n id: 'unassigned',\n icon: <TriangleAlert aria-hidden=\"true\" />,\n label: t(key('unassignedPatient')),\n variant: 'warning',\n });\n }\n if (event.hasHighlightedAnamnesis) {\n chips.push({\n id: 'anamnesis',\n icon: <HeartPulse aria-hidden=\"true\" />,\n label: t(key('anamnesis')),\n variant: 'accentSoft',\n });\n }\n if (event.hasBillableAmount) {\n chips.push({\n id: 'billable',\n icon: <Euro aria-hidden=\"true\" />,\n label: t(key('billable')),\n variant: 'warning',\n });\n }\n if (event.isTelehealth) {\n chips.push({\n id: 'telehealth',\n icon: <Video aria-hidden=\"true\" />,\n label: t(key('telehealth')),\n variant: 'info',\n });\n }\n if (event.isRecurring) {\n chips.push({\n id: 'recurring',\n icon: <Repeat aria-hidden=\"true\" />,\n label: t(key('recurring')),\n variant: 'info',\n });\n }\n if (chips.length === 0) return null;\n return (\n <span className=\"ds:flex ds:flex-wrap ds:gap-[var(--spacing-2xs)]\">\n {chips.map((chip) => (\n <Badge\n key={chip.id}\n variant={chip.variant}\n size=\"sm\"\n leading={chip.icon}\n >\n {chip.label}\n </Badge>\n ))}\n </span>\n );\n}\n\nexport interface AppointmentIdentityStripProps {\n /** The name to show, never blank: the record's, else the appointment's\n * title, else \"Patient record not loaded\". */\n name: string;\n avatarSrc?: string;\n /** Someone is booked but their record did not load: says so once, beside\n * the name, so it never reads as \"no patient\". */\n unresolved?: boolean;\n status?: CalendarEventStatus;\n /** The flags the indicator chips spell out. */\n flags: IndicatorFlags;\n /** Completed years, printed beside the name. Absent = no age. */\n age?: number;\n /** Set = the name becomes a link-styled button to the patient folder. */\n onOpenPatient?: () => void;\n highlightedAnamnesisCount?: number;\n expiredAnamnesisCount?: number;\n /** The highlighted answers themselves, listed under the warning. */\n anamnesisAnswers?: readonly AppointmentAnamnesisAnswer[];\n /** Locale for the interview dates. Defaults to the active language. */\n locale?: string;\n}\n\n/** Identity strip above the details or the editor: avatar, name, status\n * badge and chips, the read-at-a-glance layer. */\nexport function AppointmentIdentityStrip({\n name,\n avatarSrc,\n unresolved = false,\n status,\n flags,\n age,\n onOpenPatient,\n highlightedAnamnesisCount = 0,\n expiredAnamnesisCount = 0,\n anamnesisAnswers = [],\n locale,\n}: AppointmentIdentityStripProps) {\n const { t, i18n: runtimeI18n } = useTranslation();\n const key = (suffix: string): string => `calendarWorkspace.details.${suffix}`;\n const { optionFor } = useAppointmentWorkflowStatus(status);\n const statusOption = status ? optionFor(status) : undefined;\n const highlighted = highlightedAnamnesisCount;\n const expired = expiredAnamnesisCount;\n return (\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-sm)] ds:p-[var(--spacing-md)] ds:pb-0\">\n <div className=\"ds:flex ds:items-center ds:gap-[var(--spacing-sm)]\">\n <Avatar name={name} src={avatarSrc} />\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-2xs)] ds:[min-inline-size:0]\">\n {/* The platform pop-over links the name to the patient folder\n and prints the age beside it. */}\n <span className=\"ds:flex ds:flex-wrap ds:items-baseline ds:gap-[var(--spacing-2xs)] ds:text-start\">\n {onOpenPatient ? (\n <Button size=\"sm\" intent=\"link\" onClick={() => onOpenPatient()}>\n {name}\n </Button>\n ) : (\n <span className=\"ds:font-[var(--font-weight-semibold)] ds:truncate\">\n {name}\n </span>\n )}\n {age !== undefined ? (\n <span className=\"type-body-sm ds:text-[color:var(--muted-foreground)]\">\n {t(key('patientAge'), { n: age })}\n </span>\n ) : null}\n </span>\n {/* Said once, next to the name it qualifies. Without it \"we could\n not load this patient\" and \"this patient has nothing recorded\"\n would look the same. */}\n {unresolved ? (\n <span className=\"type-body-sm ds:text-start ds:text-[color:var(--muted-foreground)]\">\n {t(key('patientNotLoaded'))}\n </span>\n ) : null}\n {status && statusOption ? (\n <span>\n <Badge\n variant={APPOINTMENT_STATUS_BADGE_VARIANT[status]}\n size=\"sm\"\n leading={statusOption.icon}\n >\n {statusOption.label}\n </Badge>\n </span>\n ) : null}\n <IndicatorChips event={flags} />\n </div>\n </div>\n {/* The pop-over's anamnesis warnings: the two counts and the\n highlighted answers. Present from mount, so announce=\"off\"; the\n title is a <p> so the panel's heading stays alone. */}\n {highlighted + expired > 0 ? (\n <Alert\n variant=\"warning\"\n announce=\"off\"\n icon={<HeartPulse aria-hidden=\"true\" />}\n >\n <Alert.Title as=\"p\">{t(key('anamnesisTitle'))}</Alert.Title>\n <Alert.Description>\n {[\n highlighted > 0\n ? t(key('anamnesisHighlighted'), { n: highlighted })\n : null,\n expired > 0 ? t(key('anamnesisExpired'), { n: expired }) : null,\n ]\n .filter((line): line is string => line !== null)\n .join(' · ')}\n </Alert.Description>\n {anamnesisAnswers.length > 0 ? (\n /* Question · yes or no · answer · interview date, as the\n platform's details dialog lists them. A list, not a\n Description, which renders a <p>. */\n <ul className=\"type-body-sm ds:m-0 ds:mt-[var(--spacing-xs)] ds:flex ds:list-none ds:flex-col ds:gap-[var(--spacing-2xs)] ds:p-0\">\n {anamnesisAnswers.map((answer) => (\n <li key={answer.question} className=\"ds:text-start\">\n <span className=\"ds:font-[var(--font-weight-semibold)]\">\n {answer.question}\n </span>\n {` · ${t(key(answer.yes ? 'anamnesisYes' : 'anamnesisNo'))}`}\n {answer.answer ? ` · ${answer.answer}` : ''}\n {` · ${formatDay(locale ?? runtimeI18n.language, answer.interviewIso)}`}\n </li>\n ))}\n </ul>\n ) : null}\n {/* No Renew action: re-issuing the anamnesis is a platform flow\n the kit cannot start. The expired count stays: it is a\n clinical fact, not an offer. */}\n </Alert>\n ) : null}\n </div>\n );\n}\n","/**\n * The hover card body the details panel's chips share: an eyebrow naming\n * the kind of thing, a heading restating the chip in words, and the facts\n * the chip could not fit. Ported from the calendar-rail demo's hover\n * grammar; `PatientSummaryCard.flagHover` renders it around its own chip,\n * and `InfoHover` wraps the chips the panel renders itself.\n */\nimport type { ReactNode } from 'react';\nimport { HoverCard } from '../hover-card';\n\nexport interface InfoHoverFact {\n text: ReactNode;\n /** A caveat or provenance note, quieter than the rest. */\n muted?: boolean;\n}\n\nexport function InfoHoverBody({\n eyebrow,\n heading,\n facts,\n}: {\n eyebrow: string;\n heading: string;\n facts?: readonly InfoHoverFact[];\n}): ReactNode {\n return (\n <>\n <HoverCard.Eyebrow>{eyebrow}</HoverCard.Eyebrow>\n <HoverCard.Heading>{heading}</HoverCard.Heading>\n {facts && facts.length > 0 ? (\n <HoverCard.Body>\n <ul className=\"ds:m-0 ds:flex ds:list-none ds:flex-col ds:gap-[var(--spacing-2xs)] ds:p-0 type-body-sm\">\n {facts.map((fact, index) => (\n <li\n key={index}\n className={\n fact.muted\n ? 'ds:text-[color:var(--muted-foreground)]'\n : undefined\n }\n >\n {fact.text}\n </li>\n ))}\n </ul>\n </HoverCard.Body>\n ) : null}\n </>\n );\n}\n\nconst TRIGGER =\n 'ds:inline-flex ds:cursor-pointer ds:rounded-[var(--radius-full)] ds:p-0 ds:focus-visible:outline-[length:var(--focus-ring-width)] ds:focus-visible:outline-solid ds:focus-visible:outline-[color:var(--ring)] ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)]';\n\n/**\n * Wraps a chip the panel renders itself in the same card. It carries no\n * open button: the pattern has no seam to open invoicing or the anamnesis.\n */\nexport function InfoHover({\n id,\n eyebrow,\n heading,\n facts,\n children,\n}: {\n /** Stamped as `data-chip-hover`, the trigger's DOM hook. */\n id: string;\n eyebrow: string;\n heading: string;\n facts?: readonly InfoHoverFact[];\n /** The chip; its visible text is the trigger's accessible name. */\n children: ReactNode;\n}): ReactNode {\n return (\n <HoverCard>\n {/* A real button: `asChild` onto a bare span stamps `aria-haspopup`\n on something a keyboard can never reach. */}\n <HoverCard.Trigger asChild>\n <button type=\"button\" data-chip-hover={id} className={TRIGGER}>\n {children}\n </button>\n </HoverCard.Trigger>\n <HoverCard.Content side=\"bottom\" align=\"start\" size=\"sm\">\n <InfoHoverBody eyebrow={eyebrow} heading={heading} facts={facts} />\n </HoverCard.Content>\n </HoverCard>\n );\n}\n","/* The cards of AppointmentDetailsPanel, laid out as the calendar-rail demo\n lays them out and built on the kit's primitives. Each prints one row per\n member the host sent: an absent member renders nothing, and a card with\n nothing to show renders no card. Contact is printed as read; masking is\n the host's. The operator and chair labels, the currency and the clock are\n the caller's: nothing here reads a calendar context. */\nimport {\n Armchair,\n Building2,\n Cake,\n CalendarDays,\n ClipboardList,\n Clock,\n HeartPulse,\n Hourglass,\n Mail,\n MapPin,\n NotebookPen,\n Phone,\n Repeat,\n Smartphone,\n Video,\n} from 'lucide-react';\nimport { useId, useRef, type ReactElement, type ReactNode } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { useIsomorphicLayoutEffect } from '../../hooks/use-isomorphic-layout-effect';\nimport {\n ageInYears,\n DETAIL_STAMP_FORMAT,\n formatDay,\n formatTimeRange,\n patientAddressLabel,\n patientAddressLine,\n patientMapsUrl,\n patientPhones,\n RECURRENCE_LABEL_KEY,\n} from '../_shared/appointment-format';\nimport type { PatientField } from '../_shared/patient-fields';\nimport { Alert } from '../alert';\nimport { Avatar } from '../avatar';\nimport { Badge } from '../badge';\nimport { Button, IconButton } from '../button';\nimport { Counter } from '../counter';\nimport { DescriptionList } from '../description-list';\nimport { NoteTimeline } from '../note-timeline';\nimport { PatientSummaryCard } from '../patient-summary-card';\nimport { SectionCard } from '../section-card';\nimport { Timestamp } from '../timestamp';\nimport { TransactionChip } from '../transaction-chip';\nimport { TreatmentReceipt } from '../treatment-receipt';\nimport { focusHeading } from './appointment-details-panel.focus';\nimport {\n InfoHover,\n InfoHoverBody,\n type InfoHoverFact,\n} from './appointment-details-panel.info-hover';\nimport type {\n AppointmentDetailsChairLabel,\n AppointmentDetailsNotesPreview,\n AppointmentDetailsOperatorLabel,\n AppointmentDetailsRead,\n} from './appointment-details-panel.types';\n\ninterface CardProps {\n details: AppointmentDetailsRead;\n locale: string;\n /** ISO 4217 code for every amount. */\n currency: string;\n}\n\ninterface Row {\n id: string;\n label: string;\n icon?: ReactElement;\n value: ReactNode;\n}\n\nconst key = (suffix: string): string => `calendarWorkspace.details.${suffix}`;\nconst MUTED = 'type-body-sm ds:text-[color:var(--muted-foreground)]';\n// `dir=\"ltr\"` isolates the number/address from the surrounding paragraph's\n// bidi context: a phone number or email is an LTR datum even in an RTL\n// (Arabic) rendering, and without it the digits/punctuation can reorder.\nconst telLink = (number: string) => (\n <a href={`tel:${number.replace(/\\s/g, '')}`} dir=\"ltr\">\n {number}\n </a>\n);\nconst mailLink = (email: string) => (\n <a href={`mailto:${email}`} dir=\"ltr\">\n {email}\n </a>\n);\nconst formatMoney = (\n locale: string,\n amount: number,\n currency: string,\n): string =>\n new Intl.NumberFormat(locale, { style: 'currency', currency }).format(amount);\n\n/** Term and detail pairs; nothing at all without a row. */\nfunction Rows({ rows }: { rows: Array<Row | false | null | undefined | ''> }) {\n const shown = rows.filter((entry): entry is Row => !!entry);\n if (shown.length === 0) return null;\n return (\n <DescriptionList layout=\"inline\" density=\"compact\">\n {shown.map((entry) => (\n <DescriptionList.Row\n key={entry.id}\n data-row={entry.id}\n icon={entry.icon}\n >\n <DescriptionList.Term>{entry.label}</DescriptionList.Term>\n <DescriptionList.Detail>{entry.value}</DescriptionList.Detail>\n </DescriptionList.Row>\n ))}\n </DescriptionList>\n );\n}\n\n/**\n * The kit's PatientSummaryCard: identity, the attention chips, the money\n * chips and the contact fields. Every chip explains itself in a hover\n * card; money reads worst first (owed, to invoice, paid online), labelled\n * and without glyphs.\n */\nexport function DetailsPatientCard({\n details,\n locale,\n currency,\n now,\n mapsLink = false,\n}: CardProps & {\n /** The practice clock the age is computed against. */\n now: Date | string;\n /** The user's map-link setting (platform `showPatientAddressMapLink`). */\n mapsLink?: boolean;\n}) {\n const { t } = useTranslation();\n const { patient, signing, money, booking } = details;\n if (!patient) return null;\n const signingShown = signing && signing.required > 0 ? signing : undefined;\n const pending = (signingShown?.toComplete ?? 0) > 0;\n const signingFacts: InfoHoverFact[] = signingShown\n ? [\n {\n text: !pending\n ? t(key('signingAllSigned'))\n : signingShown.requestedVia === 'sms'\n ? t(key('signingRequestedSms'))\n : signingShown.requestedVia === 'email'\n ? t(key('signingRequestedEmail'))\n : t(key('signingNotRequested')),\n },\n ...(signingShown.aesSetUp\n ? []\n : [{ text: t(key('aesMissing')), muted: true }]),\n ]\n : [];\n const highlighted = patient.highlightedAnamnesisCount ?? 0;\n const expired = patient.expiredAnamnesisCount ?? 0;\n const answerFacts: InfoHoverFact[] = (\n patient.highlightedAnamnesisAnswers ?? []\n ).map((answer) => ({\n text: [\n answer.question,\n t(key(answer.yes ? 'anamnesisYes' : 'anamnesisNo')),\n answer.answer,\n formatDay(locale, answer.interviewIso),\n ]\n .filter(Boolean)\n .join(' · '),\n }));\n const query = patientAddressLine(patient);\n const addressLabel = patientAddressLabel(patient) || query;\n const fields: PatientField[] = [\n ...(patient.dobIso\n ? [\n {\n id: 'dob',\n label: t(key('dob')),\n icon: <Cake />,\n value: `${formatDay(locale, patient.dobIso)} ${t(\n key('patientAge'),\n {\n n: ageInYears(patient.dobIso, now),\n },\n )}`,\n },\n ]\n : []),\n ...patientPhones(patient).map((phone, index) => {\n const hasLabel =\n phone.label === 'mobile' ||\n phone.label === 'home' ||\n phone.label === 'work';\n return {\n id: `phone-${index}`,\n label: hasLabel\n ? t(`calendarWorkspace.print.phoneLabels.${phone.label}`)\n : t(key('phone')),\n icon: phone.label === 'mobile' ? <Smartphone /> : <Phone />,\n value: telLink(phone.number),\n };\n }),\n ...(patient.email\n ? [\n {\n id: 'email',\n label: t(key('email')),\n icon: <Mail />,\n value: mailLink(patient.email),\n },\n ]\n : []),\n ...(mapsLink\n ? [\n {\n id: 'address',\n label: t(key('address')),\n icon: <MapPin />,\n value: query ? (\n <a\n href={patientMapsUrl(patient)}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n aria-label={`${t(key('mapsLink'))}: ${addressLabel}`}\n >\n {addressLabel}\n </a>\n ) : (\n <span className={MUTED}>{t(key('noAddress'))}</span>\n ),\n },\n ]\n : []),\n ];\n const unpaid = money?.unpaidAmount ?? 0;\n const billable = money?.billableAmount ?? 0;\n const paidOnline = booking?.paidOnlineAmount ?? 0;\n /* A money chip under its hover card: the amount again, and whose it is. */\n const chip = (\n state: 'debt' | 'to-invoice' | 'settled',\n amount: number,\n id: string,\n headingKey: string,\n factKey: string,\n /** The money's own name, where the state's word would mislead. */\n label?: string,\n ) => (\n <InfoHover\n id={id}\n eyebrow={t(key('hoverBilling'))}\n heading={t(key(headingKey), {\n amount: formatMoney(locale, amount, currency),\n })}\n facts={[{ text: t(key(factKey)) }]}\n >\n <TransactionChip\n data-chip={id}\n state={state}\n amount={amount}\n currency={currency}\n locale={locale}\n size=\"md\"\n showLabel\n label={label}\n showIcon={false}\n />\n </InfoHover>\n );\n return (\n <PatientSummaryCard\n data-card=\"patient\"\n name={patient.name}\n avatarUrl={patient.avatarSrc}\n locale={locale}\n surface=\"elevated\"\n density=\"compact\"\n flags={{\n unsignedDocumentsCount: signingShown?.toComplete ?? 0,\n highlightedAnamnesisCount: highlighted,\n }}\n flagHover={{\n ...(signingShown\n ? {\n unsignedDocuments: (\n <InfoHoverBody\n eyebrow={t(key('sectionSigning'))}\n heading={\n signingShown.toComplete === 1\n ? t(key('signingToSignOne'))\n : t(key('signingToSignMany'), {\n n: signingShown.toComplete,\n })\n }\n facts={signingFacts}\n />\n ),\n }\n : {}),\n highlightedAnamnesis: (\n <InfoHoverBody\n eyebrow={t(key('anamnesisTitle'))}\n heading={t(key('anamnesisHighlighted'), { n: highlighted })}\n facts={answerFacts}\n />\n ),\n }}\n extraChips={\n unpaid > 0 || billable > 0 || paidOnline > 0 || expired > 0 ? (\n <>\n {/* One group, so no other chip lands between the money chips. */}\n <span className=\"ds:inline-flex ds:flex-wrap ds:items-center ds:gap-[var(--spacing-xs)]\">\n {unpaid > 0\n ? chip(\n 'debt',\n unpaid,\n 'unpaid',\n 'hoverUnpaidHeading',\n 'hoverUnpaidFact',\n )\n : null}\n {billable > 0\n ? chip(\n 'to-invoice',\n billable,\n 'billable',\n 'hoverBillableHeading',\n 'hoverBillableFact',\n )\n : null}\n {paidOnline > 0\n ? chip(\n 'settled',\n paidOnline,\n 'paidOnline',\n 'hoverPaidOnlineHeading',\n 'hoverPaidOnlineFact',\n /* A deposit is settled money, but \"Settled\" hides where\n it came from: the chip says what its hover card says. */\n t(key('paidOnline')),\n )\n : null}\n </span>\n {expired > 0 ? (\n <InfoHover\n id=\"anamnesisExpired\"\n eyebrow={t(key('anamnesisTitle'))}\n heading={t(key('anamnesisExpired'), { n: expired })}\n facts={[{ text: t(key('hoverAnamnesisExpiredFact')) }]}\n >\n <Badge\n data-chip=\"anamnesisExpired\"\n variant=\"warning\"\n size=\"md\"\n leading={<HeartPulse />}\n >\n {t(key('anamnesisExpired'), { n: expired })}\n </Badge>\n </InfoHover>\n ) : null}\n </>\n ) : undefined\n }\n /* Controlled, so a field this patient has and the last one did not (a\n third phone, the address once the map link is on) is shown too. */\n visibleFieldOrder={fields.map((field) => field.id)}\n sections={\n fields.length > 0\n ? [{ id: 'contact', heading: t(key('sectionPatient')), fields }]\n : undefined\n }\n />\n );\n}\n\n/**\n * When, how long, who and where, the series rule, and what the booking\n * site recorded. Operator and chair names are the caller's labels, so an\n * id without one prints no row. `description` is the caller's slot for the\n * description, above the facts.\n */\nexport function DetailsAppointmentCard({\n details,\n locale,\n currency,\n operator,\n chair,\n description,\n privacy = false,\n}: CardProps & {\n operator?: AppointmentDetailsOperatorLabel;\n chair?: AppointmentDetailsChairLabel;\n description?: ReactNode;\n /** Privacy mode: what the booker typed is dropped; when they booked stays. */\n privacy?: boolean;\n}) {\n const { t } = useTranslation();\n const { appointment, booking, patient } = details;\n const editor = (suffix: string) => t(`calendarWorkspace.editor.${suffix}`);\n /* A zone-less wall clock parses as local time. */\n const start = new Date(appointment.startIso);\n const end = new Date(start.getTime() + appointment.durationMin * 60_000);\n const timed = Number.isFinite(start.getTime());\n const { recurrence } = appointment;\n const frequencyKey = recurrence && RECURRENCE_LABEL_KEY[recurrence.frequency];\n const frequency = frequencyKey\n ? t(`calendarWorkspace.editor.${frequencyKey}`)\n : undefined;\n const bookingRows: Array<Row | false | undefined | ''> = booking\n ? [\n booking.bookedAtIso && {\n id: 'bookedAt',\n label: t(key('bookedAt')),\n value: (\n <Timestamp\n value={booking.bookedAtIso}\n format=\"absolute\"\n shape=\"bare\"\n locale={locale}\n absoluteFormat={DETAIL_STAMP_FORMAT}\n />\n ),\n },\n booking.typedName && {\n id: 'bookingName',\n label: t(key('bookingName')),\n value: booking.typedName,\n },\n booking.phone && {\n id: 'bookingPhone',\n label: t(key('bookingPhone')),\n value: telLink(booking.phone),\n },\n booking.email && {\n id: 'bookingEmail',\n label: t(key('bookingEmail')),\n value: mailLink(booking.email),\n },\n booking.note && {\n id: 'bookingNote',\n label: t(key('bookingNote')),\n value: booking.note,\n },\n /* With a patient the amount is a chip on the patient card. */\n !patient &&\n booking.paidOnlineAmount !== undefined && {\n id: 'paidOnline',\n label: t(key('paidOnline')),\n value: formatMoney(locale, booking.paidOnlineAmount, currency),\n },\n ]\n : [];\n /* Privacy keeps the one booking fact that names nobody: when. */\n const shownBookingRows = privacy\n ? bookingRows.filter((row) => row && row.id === 'bookedAt')\n : bookingRows;\n const hasBooking = shownBookingRows.some(Boolean);\n return (\n <SectionCard\n data-card=\"appointment\"\n title={t(key('sectionAppointment'))}\n headingLevel={3}\n >\n {description}\n <Rows\n rows={[\n timed && {\n id: 'date',\n label: editor('date'),\n icon: <CalendarDays />,\n value: formatDay(locale, start),\n },\n timed && {\n id: 'time',\n label: t(key('time')),\n icon: <Clock />,\n value: appointment.allDay\n ? editor('allDay')\n : formatTimeRange(locale, start, end),\n },\n !appointment.allDay && {\n id: 'duration',\n label: editor('duration'),\n icon: <Hourglass />,\n value: `${appointment.durationMin} ${editor('durationUnit')}`,\n },\n appointment.isTelehealth && {\n id: 'type',\n label: editor('type'),\n icon: <Video />,\n value: editor('typeTelehealth'),\n },\n operator && {\n id: 'operator',\n label: t(key('operator')),\n /* A person, as on the grid: the avatar fills the icon slot. */\n icon: (\n <Avatar name={operator.name} src={operator.avatarSrc} size=\"xs\" />\n ),\n value: operator.name,\n },\n chair && {\n id: 'chair',\n label: t(key('chair')),\n icon: <Armchair />,\n value: (\n <Badge variant=\"neutral\" size=\"sm\" leading={<Armchair />}>\n {chair.name}\n </Badge>\n ),\n },\n appointment.branchLabel && {\n id: 'branch',\n label: editor('branch'),\n icon: <Building2 />,\n value: appointment.branchLabel,\n },\n frequency &&\n recurrence && {\n id: 'series',\n label: t(key('seriesLabel')),\n icon: <Repeat />,\n value:\n recurrence.count === undefined\n ? frequency\n : t(key('seriesRule'), {\n frequency,\n count: recurrence.count,\n }),\n },\n ]}\n />\n {hasBooking ? (\n <div\n data-block=\"booking\"\n className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-xs)]\"\n >\n <h4 className=\"ds:m-0 type-label ds:text-[color:var(--muted-foreground)]\">\n {t(key('sectionBooking'))}\n </h4>\n <Rows rows={shownBookingRows} />\n </div>\n ) : null}\n </SectionCard>\n );\n}\n\n/** The linked plan, by number when the host has one, and the kit's\n * TreatmentReceipt: one line per treatment, a price only when the host\n * sends one (the editor's price gate), and a total only when every line\n * is priced. */\nexport function DetailsTreatmentsCard({\n details,\n locale,\n currency,\n privacy = false,\n}: CardProps & {\n /** Privacy mode: the plan's free-text name goes, as on the hover peek. */\n privacy?: boolean;\n}) {\n const { t } = useTranslation();\n const { care } = details;\n const plan = privacy ? undefined : care?.plan;\n if (!care || (!plan && care.lines.length === 0)) return null;\n return (\n <SectionCard\n data-card=\"treatments\"\n title={t(key('sectionTreatments'))}\n headingLevel={3}\n >\n {plan ? (\n <span className=\"ds:flex ds:items-center ds:gap-[var(--spacing-xs)] type-title-item\">\n <ClipboardList\n aria-hidden=\"true\"\n className=\"ds:size-4 ds:shrink-0 ds:text-[color:var(--muted-foreground)]\"\n />\n {plan.number\n ? t(key('planLine'), { number: plan.number, name: plan.name })\n : plan.name}\n </span>\n ) : null}\n {care.lines.length > 0 ? (\n <TreatmentReceipt\n lines={care.lines.map(({ entryId, careId: _careId, ...line }) => ({\n id: entryId,\n ...line,\n }))}\n locale={locale}\n currency={currency}\n />\n ) : null}\n </SectionCard>\n );\n}\n\nconst NOTES_PREVIEWED = 3;\n\n/** The patient's latest notes, pinned first, as the host holds them. A\n * click on a note opens the Notes tool at it; the header button opens the\n * tool from the keyboard. */\nexport function DetailsNotesCard({\n preview,\n onOpenNotes,\n locale,\n}: {\n preview: AppointmentDetailsNotesPreview;\n onOpenNotes?: (noteId?: string) => void;\n locale?: string;\n}) {\n const { t } = useTranslation();\n const headingId = useId();\n const status = preview.status ?? 'ready';\n /* Retry leaves with the error it answered: the card's heading keeps the\n focus until the read settles. */\n const retried = useRef(false);\n useIsomorphicLayoutEffect(() => {\n if (!retried.current) return;\n if (status !== 'loading') retried.current = false;\n focusHeading(headingId);\n }, [status, headingId]);\n const count =\n preview.total ?? (status === 'ready' ? preview.notes.length : null);\n const more = Math.max(0, (count ?? 0) - NOTES_PREVIEWED);\n const openLabel =\n more > 0 ? t(key('notesMore'), { n: more }) : t(key('notesPreviewOpen'));\n return (\n <SectionCard\n /* `data-card`, not `data-component`: SectionCard's own marker must\n survive, or the kit's cascade reset loses this element. */\n data-card=\"notes\"\n headingId={headingId}\n headingLevel={3}\n title={\n count === null\n ? t('notesPanel.title')\n : t(key('notesPreviewTitle'), { count })\n }\n headerAction={\n onOpenNotes && (count ?? 0) > 0 ? (\n <span className=\"ds:relative ds:inline-flex\">\n <IconButton\n icon={<NotebookPen aria-hidden=\"true\" />}\n intent=\"outline\"\n size=\"sm\"\n data-action=\"open-patient-notes\"\n aria-label={openLabel}\n tooltip={openLabel}\n onClick={() => onOpenNotes()}\n />\n {more > 0 ? (\n /* Decorative: the button's name already says the count. */\n <Counter\n variant=\"outline\"\n size=\"sm\"\n background=\"surface\"\n count={more}\n aria-hidden=\"true\"\n className=\"ds:pointer-events-none ds:absolute ds:-top-[var(--spacing-2xs)] ds:-end-[var(--spacing-2xs)]\"\n />\n ) : null}\n </span>\n ) : undefined\n }\n >\n {status === 'error' ? (\n <Alert variant=\"error\">\n <Alert.Description>{t('notesPanel.loadError')}</Alert.Description>\n {preview.onRetry ? (\n <Alert.Action>\n <Button\n intent=\"secondary\"\n size=\"sm\"\n onClick={() => {\n retried.current = true;\n preview.onRetry?.();\n }}\n >\n {t('notesPanel.retry')}\n </Button>\n </Alert.Action>\n ) : null}\n </Alert>\n ) : null}\n {preview.notes.length === 0 && status === 'loading' ? (\n <>\n <span role=\"status\" className=\"ds:sr-only\">\n {t('notesPanel.loading')}\n </span>\n <NoteTimeline notes={[]} loading loadingRows={2} />\n </>\n ) : status !== 'error' || preview.notes.length > 0 ? (\n /* A note click, or Enter or Space on it, goes straight to that note\n in the Notes tool; the header button opens the tool at the top. */\n <NoteTimeline\n notes={preview.notes}\n maxItems={NOTES_PREVIEWED}\n locale={locale}\n aria-labelledby={headingId}\n onNoteActivate={onOpenNotes}\n emptyState={\n <p className=\"ds:m-0 type-body-sm ds:text-[color:var(--muted-foreground)]\">\n {t(key('notesPreviewEmpty'))}\n </p>\n }\n />\n ) : null}\n </SectionCard>\n );\n}\n","/* -------------------------------------------------------------------- */\n/* AppointmentDetailsPanel */\n/* */\n/* One appointment occurrence, read-only apart from its status and its */\n/* description: a header with History, the patient, appointment, notes */\n/* and treatments cards, and a pinned footer with the status control and */\n/* the host's actions. History and the description editor slide over the */\n/* body as PanelSubviews. While there is no read it shows a skeleton, an */\n/* error with Retry, or a refusal. */\n/* */\n/* Everything comes from props: the read, the operator and chair labels, */\n/* the currency, the practice clock and one handler per action. An absent */\n/* handler withholds its control, and each handler receives the event id */\n/* of the read it acted on. The calendar pattern's details panel is an */\n/* adapter over this component. */\n/* */\n/* DOM hooks: the root carries data-component=\"appointment-details-panel\" */\n/* with data-component-id, data-event-id and data-status; cards carry */\n/* data-card, footer actions data-action, sub-views data-details-subview. */\n/* -------------------------------------------------------------------- */\nimport { cva } from 'class-variance-authority';\nimport {\n CalendarClock,\n Camera,\n ChevronDown,\n ClipboardList,\n ClipboardPaste,\n Copy,\n File,\n FileText,\n Folder,\n History as HistoryIcon,\n IdCard,\n Move,\n Pencil,\n Plus,\n ReceiptEuro,\n SquareCheckBig,\n Trash2,\n Video,\n} from 'lucide-react';\nimport {\n forwardRef,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n type HTMLAttributes,\n type MutableRefObject,\n type ReactNode,\n} from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { useAgentRegistration } from '../../agent/registry';\nimport { useIsomorphicLayoutEffect } from '../../hooks/use-isomorphic-layout-effect';\nimport { composeRefs } from '../_shared/compose-refs';\nimport { getErrorMessage } from '../_shared/get-error-message';\nimport { handledRejection } from '../_shared/handled-rejection';\nimport {\n PrivacyHiddenLine,\n PrivacyIdentityCard,\n} from '../_shared/privacy-mask';\nimport { Alert } from '../alert';\nimport { Button, IconButton } from '../button';\nimport { ButtonGroup, type ButtonGroupOverflowItem } from '../button-group';\nimport type { CalendarEventStatus } from '../calendar';\nimport { DropdownMenu } from '../dropdown-menu';\nimport { EditableDescription } from '../editable-description';\nimport { NoteTimeline } from '../note-timeline';\nimport { PanelHeader } from '../panel-header';\nimport { PanelSubview } from '../panel-subview';\nimport { PatientSummaryCard } from '../patient-summary-card';\nimport { SectionCard } from '../section-card';\nimport { CONTENT_ENTER_CLASS, Skeleton } from '../skeleton';\nimport { TextArea } from '../text-area';\nimport { Tooltip } from '../tooltip';\nimport { TreatmentReceipt } from '../treatment-receipt';\nimport { WhatsAppGlyph } from '../whatsapp-button';\nimport {\n APPOINTMENT_WORKFLOW_STATUSES,\n isCalendarEventStatus,\n useAppointmentWorkflowStatus,\n WorkflowStatusControl,\n WorkflowStatusDisplay,\n type WorkflowStatusControlHandle,\n} from '../workflow-status';\nimport { appointmentDetailsPanelAgent } from './appointment-details-panel.agent';\nimport { focusHeading, rescueFocus } from './appointment-details-panel.focus';\nimport { AppointmentHistoryTimeline } from './appointment-details-panel.history';\nimport { AppointmentIdentityStrip } from './appointment-details-panel.identity';\nimport {\n DetailsAppointmentCard,\n DetailsNotesCard,\n DetailsPatientCard,\n DetailsTreatmentsCard,\n} from './appointment-details-panel.sections';\nimport type {\n AppointmentDetailsChairLabel,\n AppointmentDetailsHistory,\n AppointmentDetailsNotesPreview,\n AppointmentDetailsOperatorLabel,\n AppointmentDetailsRead,\n AppointmentDetailsState,\n AppointmentDocumentKind,\n} from './appointment-details-panel.types';\n\n/* -------------------------------------------------------------------- */\n/* Public API */\n/* -------------------------------------------------------------------- */\n\nexport interface AppointmentDetailsPanelProps extends Omit<\n HTMLAttributes<HTMLDivElement>,\n 'children' | 'title' | 'onCopy'\n> {\n /** The read, or the shell state while there is none. Pair it with\n * `useAppointmentDetailsRead`, which keeps the latest selection. */\n state: AppointmentDetailsState;\n /** Retry from the error shell and from a retryable refusal. Without it,\n * no Retry button. */\n onRetry?: () => void;\n /** The appointment's patient id when the read carries no record: an id\n * without a record reads \"Patient record not loaded\", never \"no\n * patient\". Default `read.patient?.id`. */\n patientId?: string;\n /** The operator's label, resolved by the host from\n * `appointment.operatorId`. Absent = no operator row. */\n operator?: AppointmentDetailsOperatorLabel;\n /** The chair's label. Absent = no chair row. */\n chair?: AppointmentDetailsChairLabel;\n /** ISO 4217 code for the money chips, the paid-online row and the\n * treatment prices. Default 'EUR'. */\n currency?: string;\n /** The practice clock the patient's age is computed against. Default:\n * the real clock. */\n now?: Date | string;\n /** Locale for dates, times and amounts. Default: the active language. */\n locale?: string;\n /** Header title. Default \"Appointment details\". Ignored under `privacy`,\n * so a patient name can never reach the header. */\n title?: string;\n /** Privacy mode: the identity is masked; the photo, contact fields,\n * chips, description, notes, the booker's contact, the plan name and\n * `whatsappUrl` are withheld. Time, operator, chair, status, treatments\n * and History stay. A display mask on top of the host's server-side\n * masking, never instead of it. */\n privacy?: boolean;\n /** The grid's mask for this appointment; bullets without one. Read only\n * under `privacy`. */\n privacyTitle?: string;\n /** The user's map-link setting (platform `showPatientAddressMapLink`). */\n mapsLink?: boolean;\n /** The latest notes of this appointment's patient, and only theirs: set\n * `patientId` and notes for another patient show as loading. Without\n * it, no notes card. Pass it only when the appointment has a patient. */\n notesPreview?: AppointmentDetailsNotesPreview;\n /** Open the host's Notes tool, at one note when a note was clicked.\n * Without it, the preview opens nothing. */\n onOpenNotes?: (noteId?: string) => void;\n /** The appointment's history, read by the host once History opens.\n * Present = the user may read it, so the header offers History. Set its\n * `eventId`: entries for another occurrence show as loading. Wins over\n * `read.history`, the shortcut for a history sent with the read. */\n history?: AppointmentDetailsHistory;\n /** History opened, from its button or the agent: start the host's read.\n * Called on every opening. */\n onOpenHistory?: (eventId: string) => void;\n /** Withholds Edit, Move, Copy, Delete, the status change and the\n * description edit. Join, WhatsApp, Create task and the documents menu\n * are the host's to withhold. */\n readOnly?: boolean;\n /** Save a new status. Reject with a translated Error: the control keeps\n * the old status and shows the message. Absent = status read-only.\n * Every handler's last argument is the event id of the read it acted\n * on: write to that appointment, never to \"the current selection\". */\n onStatusChange?: (\n status: CalendarEventStatus,\n eventId: string,\n ) => Promise<void>;\n /** The statuses this user may set, in any order; the menu keeps the\n * platform's. Default: all six. The current status is always shown, and\n * disabled when not allowed. With no status to move to (an empty list,\n * or the current one alone) the status is shown read-only. */\n allowedStatuses?: readonly CalendarEventStatus[];\n /** Save a new description from the pencil's sub-view. Reject with a\n * translated Error: the sub-view stays open and shows it. Absent = the\n * description is read-only. */\n onDescriptionChange?: (description: string, eventId: string) => Promise<void>;\n /** Hand over to the host's editor. */\n onEdit?: (eventId: string) => void;\n /** Arm the host's move placement. */\n onMove?: (eventId: string) => void;\n /** Start the host's copy. With treatments on the read, a menu asks for\n * the appointment alone or with its treatments. */\n onCopy?: (withTreatments: boolean, eventId: string) => void;\n /** Start the host's delete. The host owns the confirmation, the series\n * scope and any care-plan clean-up. */\n onDelete?: (eventId: string) => void;\n /** Join the video visit. The host keeps the session code. */\n onJoinTelehealth?: (eventId: string) => void;\n /** The host's WhatsApp bridge. Wins over `whatsappUrl` as the one\n * button. Withhold it yourself where the user may not message the\n * patient. */\n onWhatsApp?: (eventId: string) => void;\n /** A host-composed WhatsApp link, opened in a new tab. Withheld under\n * `privacy`, because it carries the patient's number. */\n whatsappUrl?: string;\n /** Server-built link to the task page, opened in the same tab. */\n createTaskUrl?: string;\n /** The create-document kinds the user may use, and what each does. The\n * menu keeps the platform's order. */\n documents?: {\n kinds: readonly AppointmentDocumentKind[];\n onCreate: (kind: AppointmentDocumentKind, eventId: string) => void;\n };\n}\n\n/** Curated agent handle: ids and enums only, never patient data. */\nexport interface AppointmentDetailsPanelHandle {\n /** The occurrence on screen or being read, or the one a failed or\n * refused read was for when the state says; null otherwise. */\n getEventId: () => string | null;\n getLoadStatus: () => AppointmentDetailsState['status'];\n /** The status as last saved here or read; null for none, or no read. */\n getAppointmentStatus: () => CalendarEventStatus | null;\n /** The statuses `setAppointmentStatus` accepts now; [] when the status\n * cannot be changed. */\n getAllowedStatuses: () => CalendarEventStatus[];\n /** The footer's `data-action` values, in footer order. */\n getOfferedActions: () => string[];\n isHistoryOpen: () => boolean;\n isPrivacy: () => boolean;\n /** Throws when History is not offered. */\n openHistory: () => void;\n closeHistory: () => void;\n /** The footer control's own path: it shows the saving state and any\n * refusal. Rejects when the change is not offered, not allowed, or a\n * save is in flight, including one started in the same tick. */\n setAppointmentStatus: (status: CalendarEventStatus) => Promise<void>;\n /** Throws when no Retry is offered. */\n retry: () => void;\n}\n\n/* -------------------------------------------------------------------- */\n/* Styles */\n/* -------------------------------------------------------------------- */\n\nconst rootVariants = cva('ds:flex ds:h-full ds:min-h-0 ds:flex-col');\n\nconst footerVariants = cva(\n 'ds:flex ds:shrink-0 ds:items-center ds:justify-end ds:gap-[var(--spacing-xs)] ds:border-t ds:border-[color:var(--border)] ds:p-[var(--spacing-sm)]',\n);\n\n/* The read-only status takes focus only when the control it replaced\n held it, so it shows the kit's ring then. */\nconst statusShownVariants = cva(\n 'ds:shrink-0 ds:rounded-[var(--radius-md)] ds:focus-visible:outline-[length:var(--focus-ring-width)] ds:focus-visible:outline-solid ds:focus-visible:outline-ring ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)]',\n);\n\n/* Accessible themes keep the kit's raised target; default themes match\n the 32px status control through Button size=\"sm\". */\nconst ACCESSIBLE_TARGET =\n 'ds:[.theme-accessible_&]:[min-block-size:var(--min-target-size)]';\n/* The status control's className lands on its root div, not the trigger\n inside it, so target the direct child. */\nconst ACCESSIBLE_TARGET_STATUS_CONTROL =\n 'ds:[.theme-accessible_&>button]:[min-block-size:var(--min-target-size)]';\n/* ButtonGroup owns its More trigger and no prop reaches it. Reach it from\n outside by the Ellipsis glyph it renders, which does not translate. */\nconst ACCESSIBLE_TARGET_OVERFLOW_TRIGGER = [\n 'ds:[.theme-accessible_&_button:has(svg.lucide-ellipsis)]:[min-block-size:var(--min-target-size)]',\n 'ds:[.theme-accessible_&_button:has(svg.lucide-ellipsis)]:[min-inline-size:var(--min-target-size)]',\n].join(' ');\n\n/* How many term and detail rows the Appointment card shows while it loads:\n date, time, operator, chair. Uneven widths, so they read as facts. */\nconst SKELETON_FACT_WIDTHS = ['40%', '33%', '50%', '25%'] as const;\n\n/* The platform's create-menu order; the host's order and duplicate kinds\n do not change it. */\nconst DOCUMENT_KINDS: readonly AppointmentDocumentKind[] = [\n 'bill',\n 'folder',\n 'template',\n 'empty',\n 'identification',\n 'webcam',\n];\n\n/** Each create-menu item's glyph, per the icon map's duty for that kind. */\nconst DOCUMENT_ICON: Record<AppointmentDocumentKind, ReactNode> = {\n bill: <ReceiptEuro aria-hidden=\"true\" />,\n folder: <Folder aria-hidden=\"true\" />,\n template: <FileText aria-hidden=\"true\" />,\n empty: <File aria-hidden=\"true\" />,\n identification: <IdCard aria-hidden=\"true\" />,\n webcam: <Camera aria-hidden=\"true\" />,\n};\n\nconst key = (suffix: string): string => `calendarWorkspace.details.${suffix}`;\n\n/* -------------------------------------------------------------------- */\n/* Parts */\n/* -------------------------------------------------------------------- */\n\n/** One entry of a footer menu. A menu carries an icon on every item or on\n * none, so the icon is required. */\ntype MenuOption = ButtonGroupOverflowItem & { icon: ReactNode };\n\n/** A footer action that opens a menu. The label is `children` because\n * ButtonGroup keys its collapse stage off a string child, and the options\n * are `overflowItems` too, so More repeats them in a submenu when the\n * action folds away. */\nfunction MenuAction({\n children: label,\n startIcon,\n overflowItems: options,\n 'data-action': action,\n intent,\n background,\n size,\n hideLabel,\n}: {\n children: string;\n startIcon: ReactNode;\n overflowItems: readonly MenuOption[];\n /** On the trigger. ButtonGroup clears it on its measuring copies. */\n 'data-action'?: string;\n /** ButtonGroup: this action shows its own tooltip. */\n 'data-overflow-tip'?: false;\n intent?: 'outline' | 'primary';\n background?: 'transparent' | 'surface';\n size?: 'sm' | 'md' | 'lg';\n hideLabel?: boolean;\n}) {\n return (\n <DropdownMenu.Root>\n <Tooltip label={label} side=\"top\">\n <DropdownMenu.Trigger asChild>\n <Button\n intent={intent}\n background={background}\n size={size}\n data-action={action}\n className={ACCESSIBLE_TARGET}\n startIcon={startIcon}\n aria-haspopup=\"menu\"\n /* The chevron stays when the label folds: it says this opens a\n menu rather than acting. */\n endIcon={<ChevronDown aria-hidden=\"true\" />}\n >\n {hideLabel ? <span className=\"ds:sr-only\">{label}</span> : label}\n </Button>\n </DropdownMenu.Trigger>\n </Tooltip>\n <DropdownMenu.Content align=\"end\">\n {options.map((option) => (\n <DropdownMenu.Item\n key={option.label}\n data-action={option.action}\n startIcon={option.icon}\n onSelect={option.onSelect}\n >\n {option.label}\n </DropdownMenu.Item>\n ))}\n </DropdownMenu.Content>\n </DropdownMenu.Root>\n );\n}\n\n/** The body while the read is in flight: every card already in place,\n * holding a placeholder in the shape of what will land there, so nothing\n * jumps when the answer arrives. */\nfunction DetailsSkeleton() {\n const { t } = useTranslation();\n return (\n <>\n <span role=\"status\" className=\"ds:sr-only\">\n {t('common.loading')}\n </span>\n <div\n aria-hidden=\"true\"\n /* Cards keep their natural height; the column clips at the panel's\n edge, as the scrolling body it stands in for would. */\n className=\"ds:flex ds:min-h-0 ds:flex-1 ds:flex-col ds:gap-[var(--spacing-sm)] ds:overflow-hidden ds:p-[var(--spacing-md)] ds:[&>*]:shrink-0\"\n >\n <PatientSummaryCard\n name=\"\"\n loading\n surface=\"elevated\"\n density=\"compact\"\n />\n <SectionCard title={t(key('sectionAppointment'))} headingLevel={3}>\n <EditableDescription loading maxLines={2} />\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-sm)]\">\n {SKELETON_FACT_WIDTHS.map((width, index) => (\n <div\n key={width}\n className=\"ds:flex ds:items-center ds:gap-[var(--spacing-sm)]\"\n >\n <Skeleton\n variant=\"rounded\"\n stagger={index + 2}\n width=\"var(--spacing-md)\"\n height=\"var(--spacing-md)\"\n className=\"ds:shrink-0\"\n />\n <Skeleton\n variant=\"text\"\n size=\"sm\"\n stagger={index + 2}\n width={width}\n />\n </div>\n ))}\n </div>\n </SectionCard>\n <SectionCard title={t('notesPanel.title')} headingLevel={3}>\n <NoteTimeline notes={[]} loading loadingRows={2} />\n </SectionCard>\n <SectionCard title={t(key('sectionTreatments'))} headingLevel={3}>\n <TreatmentReceipt lines={[]} loading />\n </SectionCard>\n </div>\n <div\n aria-hidden=\"true\"\n className=\"ds:flex ds:shrink-0 ds:items-center ds:gap-[var(--spacing-sm)] ds:border-t ds:border-[color:var(--border)] ds:p-[var(--spacing-md)]\"\n >\n <Skeleton variant=\"rounded\" width=\"33%\" height=\"var(--spacing-xl)\" />\n <Skeleton\n variant=\"rounded\"\n stagger={1}\n height=\"var(--spacing-xl)\"\n className=\"ds:flex-1\"\n />\n </div>\n </>\n );\n}\n\n/** The History sub-view's body: a skeleton while the host reads, an error\n * with Retry, or the timeline. */\nfunction HistoryBody({\n history,\n locale,\n onRetry,\n}: {\n history: AppointmentDetailsHistory;\n locale: string;\n onRetry?: () => void;\n}) {\n const { t } = useTranslation();\n const status = history.status ?? (history.entries ? 'ready' : 'loading');\n const entries = status === 'error' ? undefined : history.entries;\n const loading = status === 'loading' || (status !== 'error' && !entries);\n /* One polite line for the life of the sub-view, outside any busy part:\n it says the read is under way, then how it settled. It starts empty,\n so its first words are announced too. An error has its own alert. */\n const [speaking, setSpeaking] = useState(false);\n useEffect(() => setSpeaking(true), []);\n let settled = '';\n if (loading) settled = t('common.loading');\n else if (entries)\n settled =\n entries.length === 0\n ? t(key('historyEmpty'))\n : t(key('historyLoaded'), { n: entries.length });\n let body: ReactNode;\n if (status === 'error')\n body = (\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-sm)]\">\n <Alert variant=\"error\">\n <Alert.Description>\n {history.message?.trim() || t('emptyState.error.description')}\n </Alert.Description>\n </Alert>\n {onRetry ? (\n <Button\n intent=\"outline\"\n data-action=\"retry-history\"\n onClick={() => onRetry()}\n >\n {t('emptyState.error.cta')}\n </Button>\n ) : null}\n </div>\n );\n else if (loading || !entries)\n body = (\n <div\n aria-hidden=\"true\"\n className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-md)]\"\n >\n {SKELETON_FACT_WIDTHS.slice(0, 3).map((width, index) => (\n <div\n key={width}\n className=\"ds:flex ds:items-start ds:gap-[var(--spacing-sm)]\"\n >\n <Skeleton\n variant=\"circular\"\n stagger={index}\n width=\"var(--spacing-xl)\"\n height=\"var(--spacing-xl)\"\n className=\"ds:shrink-0\"\n />\n <Skeleton\n variant=\"rounded\"\n stagger={index}\n width={width}\n height=\"var(--spacing-2xl)\"\n />\n </div>\n ))}\n </div>\n );\n else body = <AppointmentHistoryTimeline history={entries} locale={locale} />;\n return (\n <>\n <span role=\"status\" className=\"ds:sr-only\">\n {speaking ? settled : ''}\n </span>\n {body}\n </>\n );\n}\n\n/** What the agent handle reads from the appointment on screen. */\ninterface LiveDetails {\n status: CalendarEventStatus | null;\n allowed: CalendarEventStatus[];\n offered: string[];\n historyAvailable: boolean;\n historyOpen: boolean;\n openHistory: () => void;\n closeHistory: () => void;\n}\n\ninterface DetailsContentProps extends Omit<\n AppointmentDetailsPanelProps,\n 'state' | 'onRetry' | 'currency' | 'now' | 'locale' | 'title'\n> {\n read: AppointmentDetailsRead;\n refreshing: boolean;\n currency: string;\n now: Date | string;\n locale: string;\n shownTitle: string;\n /** The panel heading's id, for putting focus back in the panel. */\n headingId: string;\n /** Fade in: the read arrived where the skeleton or an error stood. */\n enter: boolean;\n live: MutableRefObject<LiveDetails | null>;\n statusControl: MutableRefObject<WorkflowStatusControlHandle | null>;\n}\n\n/** One appointment. Keyed by its event id, so the sub-views, the draft and\n * what was saved here reset for the next appointment. */\nfunction DetailsContent({\n read,\n refreshing,\n currency,\n now,\n locale,\n shownTitle,\n headingId,\n enter,\n live,\n statusControl,\n patientId = read.patient?.id,\n operator,\n chair,\n privacy = false,\n privacyTitle,\n mapsLink,\n notesPreview,\n onOpenNotes,\n history: hostHistory,\n onOpenHistory,\n readOnly = false,\n onStatusChange,\n allowedStatuses = APPOINTMENT_WORKFLOW_STATUSES,\n onDescriptionChange,\n onEdit,\n onMove,\n onCopy,\n onDelete,\n onJoinTelehealth,\n onWhatsApp,\n whatsappUrl: hostWhatsappUrl,\n createTaskUrl,\n documents,\n}: DetailsContentProps) {\n const { t } = useTranslation();\n const { eventId } = read;\n /* Decided once: a later render must not cut the fade short. */\n const [entering] = useState(enter);\n const card = { details: read, locale, currency };\n /* The host's own read wins; a history sent with the read is the\n shortcut. Either one offers History. A late answer for an earlier\n appointment shows as loading, never under this one. */\n const history: AppointmentDetailsHistory | undefined = hostHistory\n ? hostHistory.eventId !== undefined && hostHistory.eventId !== eventId\n ? { status: 'loading' }\n : hostHistory\n : read.history\n ? { entries: read.history }\n : undefined;\n /* Notes for another patient never show under this appointment: they\n read as loading until the host catches up, and without a patient\n there is no card. */\n const notesForPatient =\n notesPreview?.patientId === undefined ||\n notesPreview.patientId === patientId;\n const notes: AppointmentDetailsNotesPreview | undefined = !notesPreview\n ? undefined\n : notesForPatient\n ? notesPreview\n : patientId\n ? { notes: [], status: 'loading', total: null }\n : undefined;\n const editorOffered = Boolean(onDescriptionChange) && !readOnly && !privacy;\n /* Both sub-views stay mounted and slide over the body; PanelSubview owns\n the focus in and back. A sub-view whose seam is withdrawn is shown\n closed at once, and its state is reset below. */\n const [historyOpen, setHistoryOpen] = useState(false);\n const [editingDescription, setEditingDescription] = useState(false);\n const historyShown = historyOpen && history !== undefined;\n const editorShown = editingDescription && editorOffered;\n const openHistory = () => {\n if (historyShown || !history) return;\n setHistoryOpen(true);\n onOpenHistory?.(eventId);\n };\n /* A refresh or a prop change can withdraw a sub-view while it is open:\n close it for good, so it never slides back by itself, and put focus\n back in the panel rather than on the page. */\n const shownBefore = useRef({ history: false, editor: false });\n useIsomorphicLayoutEffect(() => {\n const before = shownBefore.current;\n shownBefore.current = { history: historyShown, editor: editorShown };\n const lostHistory = before.history && history === undefined;\n const lostEditor = before.editor && !editorOffered;\n if (lostHistory) setHistoryOpen(false);\n if (lostEditor) setEditingDescription(false);\n if (lostHistory || lostEditor) focusHeading(headingId);\n });\n /* Retry in the History sub-view leaves with the error: the sub-view keeps\n the focus until the read settles. */\n const historyRef = useRef<HTMLElement>(null);\n const historyRetried = useRef(false);\n const historyStatus =\n history?.status ?? (history?.entries ? 'ready' : 'loading');\n useIsomorphicLayoutEffect(() => {\n if (!historyRetried.current) return;\n if (historyStatus !== 'loading') historyRetried.current = false;\n rescueFocus(historyRef.current);\n }, [historyStatus]);\n /* The description as last saved here; the read is the starting point. */\n const [description, setDescription] = useState(read.appointment.name ?? '');\n /* A fresh read from the host wins over what was saved here. */\n useEffect(() => {\n setDescription(read.appointment.name ?? '');\n }, [read.appointment.name]);\n const [descriptionDraft, setDescriptionDraft] = useState('');\n const [descriptionSaving, setDescriptionSaving] = useState(false);\n const [descriptionError, setDescriptionError] = useState<string>();\n const descriptionFieldRef = useRef<HTMLTextAreaElement>(null);\n /* Filled when the sub-view opens, never by remounting it open. */\n useEffect(() => {\n if (!editingDescription) return;\n setDescriptionDraft(description);\n setDescriptionError(undefined);\n // eslint-disable-next-line react-hooks/exhaustive-deps -- seed once per opening\n }, [editingDescription]);\n const saveDescription = async (): Promise<void> => {\n if (!onDescriptionChange) return;\n const next = descriptionDraft.trim();\n setDescriptionSaving(true);\n setDescriptionError(undefined);\n try {\n await onDescriptionChange(next, eventId);\n setDescription(next);\n setEditingDescription(false);\n } catch (error) {\n setDescriptionError(\n getErrorMessage(error, t(key('descriptionSaveFailed'))),\n );\n } finally {\n setDescriptionSaving(false);\n }\n };\n\n /* The status as last saved here; the read is the starting point. */\n const [status, setStatus] = useState(read.appointment.status);\n useEffect(() => {\n setStatus(read.appointment.status);\n }, [read.appointment.status]);\n /* A re-read that lands wins too, even when it repeats what the panel\n read before the save: someone may have changed it back. */\n const wasRefreshing = useRef(refreshing);\n useIsomorphicLayoutEffect(() => {\n const landed = wasRefreshing.current && !refreshing;\n wasRefreshing.current = refreshing;\n if (!landed) return;\n setStatus(read.appointment.status);\n setDescription(read.appointment.name ?? '');\n }, [refreshing]);\n /* In the platform's order, whatever the host's; unknowns dropped. */\n const permitted = APPOINTMENT_WORKFLOW_STATUSES.filter((option) =>\n allowedStatuses.includes(option),\n );\n const appointmentStatus = useAppointmentWorkflowStatus(status, {\n statuses: permitted,\n /* Shown so the control can say it, but not a choice. */\n disabledStatuses: status && !permitted.includes(status) ? [status] : [],\n });\n /* A control with nothing to move to would only refuse: show the status. */\n const statusEditable =\n Boolean(onStatusChange) &&\n !readOnly &&\n permitted.some((option) => option !== status);\n /* WorkflowStatusControl shows the saving state and the refusal. A\n refusal without a message keeps the panel's own wording. */\n const changeStatus = async (next: string): Promise<void> => {\n if (!onStatusChange || !isCalendarEventStatus(next)) return;\n try {\n await onStatusChange(next, eventId);\n } catch (error) {\n throw new Error(getErrorMessage(error, t(key('statusSaveFailed'))));\n }\n setStatus(next);\n };\n\n /* The composed link carries the patient's number: withheld under\n privacy. */\n const whatsappUrl = privacy ? undefined : hostWhatsappUrl;\n const documentKinds = DOCUMENT_KINDS.filter((kind) =>\n documents?.kinds.includes(kind),\n );\n const copyMenu = (read.care?.lines.length ?? 0) > 0;\n const assigned = patientId !== undefined && patientId !== '';\n\n const statusLabel = t(key('status'));\n const statusName = `${statusLabel}: ${appointmentStatus.option.label}`;\n const statusShownRef = useRef<HTMLDivElement>(null);\n /* A save or a re-read can leave nothing to move to: the control gives\n way to the read-only status, which takes the focus the control held\n and says the outcome. */\n const statusWasEditable = useRef(statusEditable);\n useIsomorphicLayoutEffect(() => {\n const lost = statusWasEditable.current && !statusEditable;\n statusWasEditable.current = statusEditable;\n if (!lost) return;\n if (statusShownRef.current) rescueFocus(statusShownRef.current);\n else focusHeading(headingId);\n });\n const statusNode = statusEditable ? (\n <WorkflowStatusControl\n ref={statusControl}\n value={appointmentStatus.value}\n options={appointmentStatus.options}\n size=\"sm\"\n workflowLabel={statusLabel}\n /* The trigger carries the actions' painted surface and, in the\n accessible themes, their raised target too. */\n className={`ds:[&>button]:bg-[color:var(--background)] ${ACCESSIBLE_TARGET_STATUS_CONTROL}`}\n aria-label={statusName}\n onValueChange={changeStatus}\n />\n ) : status ? (\n /* Named as the control is, \"Status: Confirmed\": the small display\n prints the value alone. */\n <div\n ref={statusShownRef}\n role=\"group\"\n aria-label={statusName}\n tabIndex={-1}\n data-status-display=\"\"\n className={statusShownVariants()}\n >\n <WorkflowStatusDisplay\n value={appointmentStatus.value}\n size=\"sm\"\n workflowLabel={statusLabel}\n option={appointmentStatus.option}\n />\n </div>\n ) : null;\n\n /* The footer's actions, in order, each under its data-action. */\n const entries: Array<[string, ReactNode]> = [];\n if (onJoinTelehealth)\n entries.push([\n 'join-telehealth',\n <Button\n key=\"join\"\n intent=\"primary\"\n data-action=\"join-telehealth\"\n className={ACCESSIBLE_TARGET}\n startIcon={<Video aria-hidden=\"true\" />}\n onClick={() => onJoinTelehealth(eventId)}\n >\n {t(key('joinTelehealth'))}\n </Button>,\n ]);\n if (!readOnly && onEdit)\n entries.push([\n 'edit-appointment',\n <Button\n key=\"edit\"\n data-action=\"edit-appointment\"\n className={ACCESSIBLE_TARGET}\n startIcon={<Pencil aria-hidden=\"true\" />}\n onClick={() => onEdit(eventId)}\n >\n {t('calendarWorkspace.editor.editTitle')}\n </Button>,\n ]);\n if (!readOnly && onMove)\n entries.push([\n 'move-appointment',\n <Button\n key=\"move\"\n data-action=\"move-appointment\"\n className={ACCESSIBLE_TARGET}\n startIcon={<Move aria-hidden=\"true\" />}\n onClick={() => onMove(eventId)}\n >\n {t(key('move'))}\n </Button>,\n ]);\n if (!readOnly && onCopy)\n entries.push([\n 'copy-appointment',\n copyMenu ? (\n <MenuAction\n key=\"copy\"\n data-action=\"copy-appointment\"\n data-overflow-tip={false}\n startIcon={<ClipboardPaste aria-hidden=\"true\" />}\n overflowItems={[\n {\n label: t('calendarWorkspace.editor.duplicateAppointmentOnly'),\n icon: <Copy aria-hidden=\"true\" />,\n action: 'copy-appointment-only',\n onSelect: () => onCopy(false, eventId),\n },\n {\n label: t('calendarWorkspace.editor.duplicateWithTreatments'),\n icon: <ClipboardList aria-hidden=\"true\" />,\n action: 'copy-appointment-with-treatments',\n onSelect: () => onCopy(true, eventId),\n },\n ]}\n >\n {t(key('copy'))}\n </MenuAction>\n ) : (\n <Button\n key=\"copy\"\n data-action=\"copy-appointment\"\n className={ACCESSIBLE_TARGET}\n startIcon={<ClipboardPaste aria-hidden=\"true\" />}\n onClick={() => onCopy(false, eventId)}\n >\n {t(key('copy'))}\n </Button>\n ),\n ]);\n if (documents && documentKinds.length > 0)\n entries.push([\n 'open-create-document',\n <MenuAction\n key=\"documents\"\n data-action=\"open-create-document\"\n data-overflow-tip={false}\n startIcon={<Plus aria-hidden=\"true\" />}\n overflowItems={documentKinds.map((kind) => ({\n label: t(key(`documents.${kind}`)),\n icon: DOCUMENT_ICON[kind],\n action: `create-document-${kind}`,\n onSelect: () => documents.onCreate(kind, eventId),\n }))}\n >\n {t(key('documents.label'))}\n </MenuAction>,\n ]);\n if (onWhatsApp)\n entries.push([\n 'open-whatsapp',\n <Button\n key=\"whatsapp\"\n data-action=\"open-whatsapp\"\n className={ACCESSIBLE_TARGET}\n startIcon={<WhatsAppGlyph aria-hidden=\"true\" />}\n onClick={() => onWhatsApp(eventId)}\n >\n {t(key('remindWhatsApp'))}\n </Button>,\n ]);\n else if (whatsappUrl)\n entries.push([\n 'open-whatsapp',\n <Button\n key=\"whatsapp\"\n asChild\n /* A link folds to its icon, then into More, which follows it. */\n data-action=\"open-whatsapp\"\n className={ACCESSIBLE_TARGET}\n startIcon={<WhatsAppGlyph aria-hidden=\"true\" />}\n >\n <a href={whatsappUrl} target=\"_blank\" rel=\"noopener noreferrer\">\n {t(key('remindWhatsApp'))}\n </a>\n </Button>,\n ]);\n if (createTaskUrl)\n entries.push([\n 'create-task',\n <Button\n key=\"task\"\n asChild\n data-action=\"create-task\"\n className={ACCESSIBLE_TARGET}\n startIcon={<SquareCheckBig aria-hidden=\"true\" />}\n >\n <a href={createTaskUrl}>{t(key('createTask'))}</a>\n </Button>,\n ]);\n /* Last, so it is the first to fold into More at a narrow width. */\n if (!readOnly && onDelete)\n entries.push([\n 'delete-appointment',\n <Button\n key=\"delete\"\n intent=\"destructiveOutline\"\n data-action=\"delete-appointment\"\n className={ACCESSIBLE_TARGET}\n startIcon={<Trash2 aria-hidden=\"true\" />}\n onClick={() => onDelete(eventId)}\n >\n {t('calendarWorkspace.editor.delete')}\n </Button>,\n ]);\n const actions = entries.map(([, node]) => node);\n\n live.current = {\n status: status ?? null,\n allowed: statusEditable ? permitted : [],\n offered: entries.map(([id]) => id),\n historyAvailable: history !== undefined,\n historyOpen: historyShown,\n openHistory,\n closeHistory: () => setHistoryOpen(false),\n };\n\n const backLabel = t(key('historyBack'));\n return (\n <div\n className={`ds:flex ds:min-h-0 ds:flex-1 ds:flex-col ${entering ? CONTENT_ENTER_CLASS : ''}`}\n >\n <PanelSubview.Host>\n <PanelHeader\n title={shownTitle}\n headingId={headingId}\n icon={<CalendarClock aria-hidden=\"true\" />}\n sticky\n divider\n actions={\n history ? (\n <IconButton\n size=\"sm\"\n intent=\"ghost\"\n icon={<HistoryIcon aria-hidden=\"true\" />}\n aria-label={t(key('historyAction'))}\n tooltip={t(key('historyAction'))}\n data-action=\"open-history\"\n onClick={openHistory}\n />\n ) : undefined\n }\n />\n <div\n /* eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex -- the body scrolls inside the rail; axe scrollable-region-focusable needs the tab stop */\n tabIndex={0}\n aria-busy={refreshing || undefined}\n className=\"ds:[min-block-size:0] ds:flex-1 ds:overflow-y-auto\"\n >\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-sm)] ds:p-[var(--spacing-md)]\">\n {privacy ? (\n <PrivacyIdentityCard mask={privacyTitle} />\n ) : read.patient ? (\n <DetailsPatientCard {...card} now={now} mapsLink={mapsLink} />\n ) : (\n /* No patient card to carry the identity: a patient-less, an\n unassigned or an unresolved booking keeps the strip. */\n <AppointmentIdentityStrip\n name={\n read.appointment.title.trim()\n ? read.appointment.title\n : t(key('patientNotLoaded'))\n }\n unresolved={assigned}\n status={status}\n flags={{\n isTelehealth: read.appointment.isTelehealth,\n isBookedOnline: read.appointment.bookedOnline,\n isRecurring: read.appointment.recurrence !== undefined,\n hasUnassignedPatient:\n read.appointment.bookedOnline && !assigned,\n hasHighlightedAnamnesis: false,\n hasBillableAmount: (read.money?.billableAmount ?? 0) > 0,\n }}\n locale={locale}\n />\n )}\n <DetailsAppointmentCard\n {...card}\n operator={operator}\n chair={chair}\n privacy={privacy}\n description={\n /* Not keyed on the text: the pencil must survive a save,\n so the sub-view can hand focus back to it. An empty\n read-only description prints nothing. Privacy hides the\n text and the pencil. */\n privacy ? (\n description ? (\n <PrivacyHiddenLine block=\"description\" />\n ) : undefined\n ) : description || (onDescriptionChange && !readOnly) ? (\n <EditableDescription\n data-block=\"description\"\n role=\"group\"\n aria-label={t('calendarWorkspace.editor.description')}\n value={description}\n editLabel={t(key('editDescription'))}\n onEdit={\n onDescriptionChange && !readOnly\n ? () => setEditingDescription(true)\n : undefined\n }\n />\n ) : undefined\n }\n />\n {notes && privacy ? (\n <SectionCard\n data-card=\"notes\"\n title={t('notesPanel.title')}\n headingLevel={3}\n >\n <PrivacyHiddenLine />\n </SectionCard>\n ) : notes ? (\n <DetailsNotesCard\n preview={notes}\n onOpenNotes={notesForPatient ? onOpenNotes : undefined}\n locale={locale}\n />\n ) : null}\n <DetailsTreatmentsCard {...card} privacy={privacy} />\n </div>\n </div>\n {statusNode || actions.length > 0 ? (\n /* The body scrolls; the status and the actions stay put. The\n status keeps its own segment and never folds. The actions fold\n to icons, then into More, never onto a second line. */\n <div className={footerVariants()}>\n {statusNode}\n {actions.length > 0 ? (\n <ButtonGroup\n label={t(key('actionsLabel'))}\n overflow=\"menu\"\n collapseToIcons\n background=\"surface\"\n size=\"sm\"\n className={`ds:min-w-0 ds:flex-1 ds:text-end ${ACCESSIBLE_TARGET_OVERFLOW_TRIGGER}`}\n >\n {actions}\n </ButtonGroup>\n ) : null}\n </div>\n ) : null}\n {history ? (\n <PanelSubview\n ref={historyRef}\n open={historyShown}\n icon={<HistoryIcon aria-hidden=\"true\" />}\n title={t(key('historyTitle'))}\n backLabel={backLabel}\n headingLevel={3}\n onBack={() => setHistoryOpen(false)}\n data-details-subview=\"history\"\n >\n <div className=\"ds:p-[var(--spacing-md)]\">\n <HistoryBody\n history={history}\n locale={locale}\n onRetry={\n history.onRetry\n ? () => {\n historyRetried.current = true;\n history.onRetry?.();\n }\n : undefined\n }\n />\n </div>\n </PanelSubview>\n ) : null}\n {editorOffered ? (\n <PanelSubview\n open={editorShown}\n icon={<Pencil aria-hidden=\"true\" />}\n title={t(key('editDescription'))}\n backLabel={backLabel}\n headingLevel={3}\n initialFocusRef={descriptionFieldRef}\n /* Back and Escape wait for a save in flight, as Cancel does: a\n late answer must not close an editor the user reopened. */\n onBack={() => {\n if (!descriptionSaving) setEditingDescription(false);\n }}\n data-details-subview=\"description\"\n footer={\n <>\n <Button\n intent=\"secondary\"\n disabled={descriptionSaving}\n onClick={() => setEditingDescription(false)}\n >\n {t(key('noteCancel'))}\n </Button>\n <Button\n intent=\"primary\"\n data-action=\"save-description\"\n loading={descriptionSaving}\n onClick={() => void saveDescription()}\n >\n {t(key('descriptionSave'))}\n </Button>\n </>\n }\n >\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-sm)] ds:p-[var(--spacing-md)]\">\n {descriptionError ? (\n <Alert variant=\"error\">\n <Alert.Description>{descriptionError}</Alert.Description>\n </Alert>\n ) : null}\n <TextArea\n ref={descriptionFieldRef}\n value={descriptionDraft}\n minRows={6}\n autoResize\n aria-label={t('calendarWorkspace.editor.description')}\n onChange={(event) => setDescriptionDraft(event.target.value)}\n />\n </div>\n </PanelSubview>\n ) : null}\n </PanelSubview.Host>\n </div>\n );\n}\n\n/* -------------------------------------------------------------------- */\n/* Component */\n/* -------------------------------------------------------------------- */\n\n/**\n * The appointment details panel: a props-driven rail panel for one\n * occurrence. Mount it as a `fill` tool in ControlRoomRail, which adds its\n * favourite and close controls to the panel's own header.\n */\nexport const AppointmentDetailsPanel = forwardRef<\n HTMLDivElement,\n AppointmentDetailsPanelProps\n>(function AppointmentDetailsPanel(\n {\n state,\n onRetry,\n patientId,\n operator,\n chair,\n currency = 'EUR',\n now,\n locale,\n title,\n privacy = false,\n privacyTitle,\n mapsLink,\n notesPreview,\n onOpenNotes,\n history,\n onOpenHistory,\n readOnly = false,\n onStatusChange,\n allowedStatuses,\n onDescriptionChange,\n onEdit,\n onMove,\n onCopy,\n onDelete,\n onJoinTelehealth,\n onWhatsApp,\n whatsappUrl,\n createTaskUrl,\n documents,\n id,\n className,\n ...rest\n },\n ref,\n) {\n const { t, i18n: runtimeI18n } = useTranslation();\n const reactId = useId();\n const instanceId = id ?? reactId;\n const headingId = useId();\n const shownLocale = locale ?? runtimeI18n.language;\n /* A host title never reaches the header under privacy: it may be a\n patient's name. */\n const shownTitle = !privacy && title?.trim() ? title : t(key('region'));\n const read = state.status === 'ready' ? state.read : undefined;\n /* An error or a refusal names the occurrence it answers when it can. */\n const eventId = state.status === 'ready' ? state.read.eventId : state.eventId;\n /* The read fades in only where this panel showed a shell before it. A\n panel mounted with its read, or re-reading one, does not flash. */\n const previousStatus = useRef<AppointmentDetailsState['status'] | undefined>(\n undefined,\n );\n const enter =\n previousStatus.current !== undefined && previousStatus.current !== 'ready';\n useEffect(() => {\n previousStatus.current = state.status;\n }, [state.status]);\n const retryOffered =\n Boolean(onRetry) &&\n (state.status === 'error' ||\n (state.status === 'refused' && state.retryable === true));\n /* A swap between the read and the skeleton, the error or the refusal\n mounts a new tree, and whatever held focus leaves with the old one.\n Whether the panel held it is read now, while that node is still here. */\n const rootRef = useRef<HTMLDivElement>(null);\n const setRoot = useMemo(() => composeRefs(ref, rootRef), [ref]);\n const heldFocus = useRef(false);\n if (typeof document !== 'undefined')\n heldFocus.current =\n rootRef.current?.contains(document.activeElement) ?? false;\n const shape = read ? `ready:${read.eventId}` : state.status;\n /* After Retry, and after any swap while the panel held focus, the\n heading takes it: the new tree has no control where focus was. After\n Retry it keeps it until the read settles. */\n const retried = useRef(false);\n useIsomorphicLayoutEffect(() => {\n if (retried.current) {\n if (state.status !== 'loading') retried.current = false;\n focusHeading(headingId);\n } else if (heldFocus.current) focusHeading(headingId);\n }, [shape, headingId]);\n\n /* ---- Agent handle ------------------------------------------------ */\n const live = useRef<LiveDetails | null>(null);\n if (!read) live.current = null;\n const statusControl = useRef<WorkflowStatusControlHandle | null>(null);\n const snapshot = useRef({ state, eventId, privacy, retryOffered, onRetry });\n snapshot.current = { state, eventId, privacy, retryOffered, onRetry };\n const handle = useMemo<AppointmentDetailsPanelHandle>(\n () => ({\n getEventId: () => snapshot.current.eventId ?? null,\n getLoadStatus: () => snapshot.current.state.status,\n getAppointmentStatus: () => live.current?.status ?? null,\n getAllowedStatuses: () => [...(live.current?.allowed ?? [])],\n getOfferedActions: () => [...(live.current?.offered ?? [])],\n isHistoryOpen: () => live.current?.historyOpen ?? false,\n isPrivacy: () => snapshot.current.privacy,\n openHistory: () => {\n if (!live.current?.historyAvailable)\n throw new Error('AppointmentDetailsPanel: History is not offered.');\n live.current.openHistory();\n },\n closeHistory: () => {\n live.current?.closeHistory();\n },\n setAppointmentStatus: (next) => {\n const details = live.current;\n const control = statusControl.current;\n if (!details || !control || details.allowed.length === 0)\n return handledRejection(\n new Error('AppointmentDetailsPanel: the status is read-only.'),\n );\n if (next === details.status) return Promise.resolve();\n if (!details.allowed.includes(next))\n return handledRejection(\n new Error(`AppointmentDetailsPanel: \"${next}\" is not allowed.`),\n );\n const inFlight = () =>\n handledRejection(\n new Error('AppointmentDetailsPanel: a status save is in flight.'),\n );\n if (control.getIsSaving()) return inFlight();\n /* The control declines a change while a save is in flight, even\n one started in this same tick, before its handle re-renders. */\n const saved = control.setValue(next);\n return saved === undefined ? inFlight() : saved;\n },\n retry: () => {\n const { retryOffered: offered, onRetry: host } = snapshot.current;\n if (!offered || !host)\n throw new Error('AppointmentDetailsPanel: Retry is not offered.');\n host();\n },\n }),\n [],\n );\n useAgentRegistration(appointmentDetailsPanelAgent, handle, instanceId);\n\n const header = (\n <PanelHeader\n title={shownTitle}\n headingId={headingId}\n icon={<CalendarClock aria-hidden=\"true\" />}\n sticky\n divider\n />\n );\n let body: ReactNode;\n if (state.status === 'ready') {\n body = (\n <DetailsContent\n key={state.read.eventId}\n read={state.read}\n refreshing={state.refreshing === true}\n currency={currency}\n now={now ?? new Date()}\n locale={shownLocale}\n shownTitle={shownTitle}\n headingId={headingId}\n enter={enter}\n live={live}\n statusControl={statusControl}\n patientId={patientId}\n operator={operator}\n chair={chair}\n privacy={privacy}\n privacyTitle={privacyTitle}\n mapsLink={mapsLink}\n notesPreview={notesPreview}\n onOpenNotes={onOpenNotes}\n history={history}\n onOpenHistory={onOpenHistory}\n readOnly={readOnly}\n onStatusChange={onStatusChange}\n allowedStatuses={allowedStatuses}\n onDescriptionChange={onDescriptionChange}\n onEdit={onEdit}\n onMove={onMove}\n onCopy={onCopy}\n onDelete={onDelete}\n onJoinTelehealth={onJoinTelehealth}\n onWhatsApp={onWhatsApp}\n whatsappUrl={whatsappUrl}\n createTaskUrl={createTaskUrl}\n documents={documents}\n />\n );\n } else if (state.status === 'loading') {\n body = (\n <>\n {header}\n <DetailsSkeleton />\n </>\n );\n } else {\n body = (\n <>\n {header}\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-sm)] ds:p-[var(--spacing-md)]\">\n <Alert variant={state.status === 'error' ? 'error' : 'warning'}>\n <Alert.Description>\n {state.status === 'error'\n ? state.message?.trim() || t('emptyState.error.description')\n : state.reason}\n </Alert.Description>\n </Alert>\n {retryOffered ? (\n <Button\n intent=\"outline\"\n data-action=\"retry-load\"\n onClick={() => {\n retried.current = true;\n onRetry?.();\n }}\n >\n {t('emptyState.error.cta')}\n </Button>\n ) : null}\n </div>\n </>\n );\n }\n\n return (\n <div\n ref={setRoot}\n id={id}\n data-component=\"appointment-details-panel\"\n data-component-id={instanceId}\n data-event-id={eventId}\n data-status={state.status}\n aria-busy={state.status === 'loading' || undefined}\n className={rootVariants({ className })}\n {...rest}\n >\n {body}\n </div>\n );\n});\nAppointmentDetailsPanel.displayName = 'AppointmentDetailsPanel';\n","import { useCallback, useEffect, useRef, useState } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { useIsomorphicLayoutEffect } from '../../hooks/use-isomorphic-layout-effect';\nimport { getErrorMessage } from '../_shared/get-error-message';\nimport { parseAppointmentStartIso } from '../_shared/appointment-format';\nimport type {\n AppointmentDetailsRead,\n AppointmentDetailsState,\n UseAppointmentDetailsReadOptions,\n} from './appointment-details-panel.types';\n\ntype Settled<T extends AppointmentDetailsRead> = Exclude<\n AppointmentDetailsState<T>,\n { status: 'loading' }\n>;\n\n/** The last answer, and the request it answered. */\ninterface Answer<T extends AppointmentDetailsRead> {\n eventId: string;\n /** Which selection of `eventId` asked: coming back to an id is a new one. */\n selection: number;\n request: string;\n value: Settled<T>;\n}\n\nexport interface AppointmentDetailsReadResult<\n T extends AppointmentDetailsRead = AppointmentDetailsRead,\n> {\n /** Pass as AppointmentDetailsPanel `state`. Null while `eventId` is null:\n * there is no selection, so render no panel. */\n state: AppointmentDetailsState<T> | null;\n /** Pass as AppointmentDetailsPanel `onRetry`: reads the same occurrence\n * again. */\n retry: () => void;\n}\n\n/**\n * Reads one occurrence so that the latest selection always wins. A new\n * `eventId` aborts the read in flight and shows the skeleton, even for an\n * id shown before; a late answer for an earlier request is dropped. The\n * error and refused states carry the `eventId` they answer. An answer for\n * another appointment, or with an unreadable `startIso`, becomes an error,\n * so the panel never shows one patient's name with another's appointment.\n * A new `reloadKey` reads\n * the same occurrence again while the current read stays on screen\n * (`refreshing`); if that read fails, the panel shows the error rather than\n * going back to the older read. A null `eventId` reads nothing and returns\n * a null `state`.\n *\n * The latest `load` is the one called, so an inline loader never loops:\n * only `eventId`, `reloadKey` and `retry` start a read.\n */\nexport function useAppointmentDetailsRead<\n T extends AppointmentDetailsRead = AppointmentDetailsRead,\n>(\n options: UseAppointmentDetailsReadOptions<T> & { eventId: string },\n): AppointmentDetailsReadResult<T> & { state: AppointmentDetailsState<T> };\nexport function useAppointmentDetailsRead<\n T extends AppointmentDetailsRead = AppointmentDetailsRead,\n>(\n options: UseAppointmentDetailsReadOptions<T>,\n): AppointmentDetailsReadResult<T>;\nexport function useAppointmentDetailsRead<\n T extends AppointmentDetailsRead = AppointmentDetailsRead,\n>({\n eventId,\n load,\n reloadKey,\n}: UseAppointmentDetailsReadOptions<T>): AppointmentDetailsReadResult<T> {\n const { t } = useTranslation();\n const failure = useRef('');\n failure.current = t('emptyState.error.description');\n /* Held, not a dependency: a host's inline loader must not read again on\n every render. */\n const loadRef = useRef(load);\n useIsomorphicLayoutEffect(() => {\n loadRef.current = load;\n });\n const [retries, setRetries] = useState(0);\n const [answer, setAnswer] = useState<Answer<T>>();\n const request = JSON.stringify([reloadKey ?? null, retries]);\n /* Counts selections: going to B and back to A before B answers reads A\n afresh behind the skeleton, never A's older answer as final. */\n const [selection, setSelection] = useState({ eventId, count: 0 });\n const selectionCount =\n selection.eventId === eventId ? selection.count : selection.count + 1;\n if (selection.eventId !== eventId)\n setSelection({ eventId, count: selectionCount });\n\n useEffect(() => {\n if (eventId === null) {\n /* A cleared selection forgets its answer: selecting the same\n appointment again starts from the skeleton. */\n setAnswer(undefined);\n return undefined;\n }\n const controller = new AbortController();\n const settle = (value: Settled<T>) => {\n if (!controller.signal.aborted)\n setAnswer({ eventId, selection: selectionCount, request, value });\n };\n Promise.resolve()\n .then(() => loadRef.current(eventId, { signal: controller.signal }))\n .then((value) => {\n if (value.status !== 'ready') {\n settle({\n status: 'refused',\n eventId,\n reason: value.reason,\n retryable: value.retryable,\n });\n return;\n }\n /* Never another appointment, and never a start the panel cannot\n place in the day. */\n if (\n value.details?.eventId !== eventId ||\n !parseAppointmentStartIso(value.details.appointment?.startIso)\n )\n throw new Error(failure.current);\n settle({ status: 'ready', read: value.details });\n })\n .catch((error: unknown) => {\n settle({\n status: 'error',\n eventId,\n message: getErrorMessage(error, failure.current),\n });\n });\n return () => controller.abort();\n }, [eventId, selectionCount, request]);\n\n const retry = useCallback(() => setRetries((previous) => previous + 1), []);\n\n if (eventId === null) return { state: null, retry };\n const current =\n answer?.eventId === eventId && answer.selection === selectionCount\n ? answer\n : undefined;\n let state: AppointmentDetailsState<T> = { status: 'loading', eventId };\n if (current?.request === request) state = current.value;\n else if (current?.value.status === 'ready')\n /* A re-read of the same occurrence keeps what is on screen. */\n state = { status: 'ready', read: current.value.read, refreshing: true };\n return { state, retry };\n}\n"],"names":["__iconNode","Cake","createLucideIcon","ClipboardPaste","IdCard","Move","MORE_TRIGGER","appointmentDetailsPanelAgent","handle","args","rescueFocus","target","active","focusHeading","headingId","heading","parseEventDate","value","formatDay","locale","formatTimeRange","start","end","s","e","fmt","DETAIL_STAMP_FORMAT","ageInYears","dobIso","on","dob","at","age","monthDelta","START_ISO","parseAppointmentStartIso","startIso","match","year","month","day","hours","minutes","seconds","monthEnd","sortHistoryNewestFirst","entries","entry","parsed","a","b","RECURRENCE_LABEL_KEY","patientPhones","patient","patientAddressLine","part","patientAddressLabel","patientMapsUrl","query","detailKey","suffix","AppointmentHistoryTimeline","history","t","runtimeI18n","useTranslation","optionFor","useAppointmentWorkflowStatus","shownLocale","formatStamp","iso","describe","jsx","CalendarPlus","Clock","StatusGlyph","APPOINTMENT_STATE_WORKFLOW","fromOption","toOption","transitionLabel","jsxs","WorkflowStatusDisplay","ArrowRight","Pencil","field","ConfirmedGlyph","Trash2","EmptyState","Timeline","shape","CalendarClock","APPOINTMENT_STATUS_BADGE_VARIANT","IndicatorChips","event","key","chips","Globe","TriangleAlert","HeartPulse","Euro","Video","Repeat","chip","Badge","AppointmentIdentityStrip","name","avatarSrc","unresolved","status","flags","onOpenPatient","highlightedAnamnesisCount","expiredAnamnesisCount","anamnesisAnswers","statusOption","highlighted","expired","Avatar","Button","Alert","line","answer","InfoHoverBody","eyebrow","facts","Fragment","HoverCard","fact","index","TRIGGER","InfoHover","id","children","MUTED","telLink","number","mailLink","email","formatMoney","amount","currency","Rows","rows","shown","DescriptionList","DetailsPatientCard","details","now","mapsLink","signing","money","booking","signingShown","pending","signingFacts","answerFacts","addressLabel","fields","phone","hasLabel","Smartphone","Phone","Mail","MapPin","unpaid","billable","paidOnline","state","headingKey","factKey","label","TransactionChip","PatientSummaryCard","DetailsAppointmentCard","operator","chair","description","privacy","appointment","editor","timed","recurrence","frequencyKey","frequency","bookingRows","Timestamp","shownBookingRows","row","hasBooking","SectionCard","CalendarDays","Hourglass","Armchair","Building2","DetailsTreatmentsCard","care","plan","ClipboardList","TreatmentReceipt","entryId","_careId","NOTES_PREVIEWED","DetailsNotesCard","preview","onOpenNotes","useId","retried","useRef","useIsomorphicLayoutEffect","count","more","openLabel","IconButton","NotebookPen","Counter","_a","NoteTimeline","rootVariants","cva","footerVariants","statusShownVariants","ACCESSIBLE_TARGET","ACCESSIBLE_TARGET_STATUS_CONTROL","ACCESSIBLE_TARGET_OVERFLOW_TRIGGER","SKELETON_FACT_WIDTHS","DOCUMENT_KINDS","DOCUMENT_ICON","ReceiptEuro","Folder","FileText","File","Camera","MenuAction","startIcon","options","action","intent","background","size","hideLabel","DropdownMenu","Tooltip","ChevronDown","option","DetailsSkeleton","EditableDescription","width","Skeleton","HistoryBody","onRetry","loading","speaking","setSpeaking","useState","useEffect","settled","body","DetailsContent","read","refreshing","shownTitle","enter","live","statusControl","patientId","privacyTitle","notesPreview","hostHistory","onOpenHistory","readOnly","onStatusChange","allowedStatuses","APPOINTMENT_WORKFLOW_STATUSES","onDescriptionChange","onEdit","onMove","onCopy","onDelete","onJoinTelehealth","onWhatsApp","hostWhatsappUrl","createTaskUrl","documents","eventId","entering","card","notesForPatient","notes","editorOffered","historyOpen","setHistoryOpen","editingDescription","setEditingDescription","historyShown","editorShown","openHistory","shownBefore","before","lostHistory","lostEditor","historyRef","historyRetried","historyStatus","setDescription","descriptionDraft","setDescriptionDraft","descriptionSaving","setDescriptionSaving","descriptionError","setDescriptionError","descriptionFieldRef","saveDescription","next","error","getErrorMessage","setStatus","wasRefreshing","landed","permitted","appointmentStatus","statusEditable","changeStatus","isCalendarEventStatus","whatsappUrl","documentKinds","kind","copyMenu","assigned","statusLabel","statusName","statusShownRef","statusWasEditable","lost","statusNode","WorkflowStatusControl","Copy","Plus","WhatsAppGlyph","SquareCheckBig","actions","node","backLabel","CONTENT_ENTER_CLASS","PanelSubview","PanelHeader","HistoryIcon","PrivacyIdentityCard","_b","PrivacyHiddenLine","ButtonGroup","TextArea","AppointmentDetailsPanel","forwardRef","title","className","rest","ref","reactId","instanceId","previousStatus","retryOffered","rootRef","setRoot","useMemo","composeRefs","heldFocus","snapshot","control","handledRejection","inFlight","saved","offered","host","useAgentRegistration","header","useAppointmentDetailsRead","load","reloadKey","failure","loadRef","retries","setRetries","setAnswer","request","selection","setSelection","selectionCount","controller","settle","retry","useCallback","previous","current"],"mappings":"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","x_google_ignoreList":[0,1,2,3]}
|
|
1
|
+
{"version":3,"file":"use-appointment-details-read-5-hV-2xA.js","sources":["../../node_modules/lucide-react/dist/esm/icons/cake.mjs","../../node_modules/lucide-react/dist/esm/icons/clipboard-paste.mjs","../../node_modules/lucide-react/dist/esm/icons/id-card.mjs","../../node_modules/lucide-react/dist/esm/icons/move.mjs","../../src/components/appointment-details-panel/appointment-details-panel.agent.ts","../../src/components/appointment-details-panel/appointment-details-panel.focus.ts","../../src/components/_shared/appointment-format.ts","../../src/components/appointment-details-panel/appointment-details-panel.history.tsx","../../src/components/appointment-details-panel/appointment-details-panel.identity.tsx","../../src/components/appointment-details-panel/appointment-details-panel.info-hover.tsx","../../src/components/appointment-details-panel/appointment-details-panel.sections.tsx","../../src/components/appointment-details-panel/appointment-details-panel.tsx","../../src/components/appointment-details-panel/use-appointment-details-read.ts"],"sourcesContent":["/**\n * @license lucide-react v1.22.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M20 21v-8a2 2 0 0 0-2-2H6a2 2 0 0 0-2 2v8\", key: \"1w3rig\" }],\n [\"path\", { d: \"M4 16s.5-1 2-1 2.5 2 4 2 2.5-2 4-2 2.5 2 4 2 2-1 2-1\", key: \"n2jgmb\" }],\n [\"path\", { d: \"M2 21h20\", key: \"1nyx9w\" }],\n [\"path\", { d: \"M7 8v3\", key: \"1qtyvj\" }],\n [\"path\", { d: \"M12 8v3\", key: \"hwp4zt\" }],\n [\"path\", { d: \"M17 8v3\", key: \"1i6e5u\" }],\n [\"path\", { d: \"M7 4h.01\", key: \"1bh4kh\" }],\n [\"path\", { d: \"M12 4h.01\", key: \"1ujb9j\" }],\n [\"path\", { d: \"M17 4h.01\", key: \"1upcoc\" }]\n];\nconst Cake = createLucideIcon(\"cake\", __iconNode);\n\nexport { __iconNode, Cake as default };\n//# sourceMappingURL=cake.mjs.map\n","/**\n * @license lucide-react v1.22.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M11 14h10\", key: \"1w8e9d\" }],\n [\"path\", { d: \"M16 4h2a2 2 0 0 1 2 2v1.344\", key: \"1e62lh\" }],\n [\"path\", { d: \"m17 18 4-4-4-4\", key: \"z2g111\" }],\n [\"path\", { d: \"M8 4H6a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h12a2 2 0 0 0 1.793-1.113\", key: \"bjbb7m\" }],\n [\"rect\", { x: \"8\", y: \"2\", width: \"8\", height: \"4\", rx: \"1\", key: \"ublpy\" }]\n];\nconst ClipboardPaste = createLucideIcon(\"clipboard-paste\", __iconNode);\n\nexport { __iconNode, ClipboardPaste as default };\n//# sourceMappingURL=clipboard-paste.mjs.map\n","/**\n * @license lucide-react v1.22.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M16 10h2\", key: \"8sgtl7\" }],\n [\"path\", { d: \"M16 14h2\", key: \"epxaof\" }],\n [\"path\", { d: \"M6.17 15a3 3 0 0 1 5.66 0\", key: \"n6f512\" }],\n [\"circle\", { cx: \"9\", cy: \"11\", r: \"2\", key: \"yxgjnd\" }],\n [\"rect\", { x: \"2\", y: \"5\", width: \"20\", height: \"14\", rx: \"2\", key: \"qneu4z\" }]\n];\nconst IdCard = createLucideIcon(\"id-card\", __iconNode);\n\nexport { __iconNode, IdCard as default };\n//# sourceMappingURL=id-card.mjs.map\n","/**\n * @license lucide-react v1.22.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M12 2v20\", key: \"t6zp3m\" }],\n [\"path\", { d: \"m15 19-3 3-3-3\", key: \"11eu04\" }],\n [\"path\", { d: \"m19 9 3 3-3 3\", key: \"1mg7y2\" }],\n [\"path\", { d: \"M2 12h20\", key: \"9i4pu4\" }],\n [\"path\", { d: \"m5 9-3 3 3 3\", key: \"j64kie\" }],\n [\"path\", { d: \"m9 5 3-3 3 3\", key: \"l8vdw6\" }]\n];\nconst Move = createLucideIcon(\"move\", __iconNode);\n\nexport { __iconNode, Move as default };\n//# sourceMappingURL=move.mjs.map\n","/* -------------------------------------------------------------------- */\n/* Agent adapter: AppointmentDetailsPanel. */\n/* */\n/* Reads ids and enums only: the occurrence id, the load status, the */\n/* appointment status, the footer actions on offer, whether History is */\n/* open and whether privacy mode is on. Never a patient name, a phone */\n/* number or a note. */\n/* */\n/* set_status goes through the footer's own WorkflowStatusControl, so the */\n/* panel shows the saving state and any refusal exactly as for a click; */\n/* it is `phi` + openWorld: the status is a named patient's attendance. */\n/* The footer actions (Edit, Move, Copy, Delete, WhatsApp …) are the */\n/* host's and are reached through their data-action hooks: the host's own */\n/* confirmation guards Delete. An offered action with no hook in the */\n/* footer strip is folded into More: open More (MORE_TRIGGER below), and */\n/* its menu item carries the same data-action. */\n/* -------------------------------------------------------------------- */\n\nimport type { AgentAdapter } from '../../agent/types';\nimport type { AppointmentDetailsPanelHandle } from './appointment-details-panel';\n\n/* The footer's More trigger, found without its translated label: the one\n menu-opening icon button in the actions group. */\nconst MORE_TRIGGER =\n '[data-component=\"button-group\"] [data-component=\"icon-button\"][aria-haspopup=\"menu\"]';\n\nexport const appointmentDetailsPanelAgent: AgentAdapter<AppointmentDetailsPanelHandle> =\n {\n id: 'appointment-details-panel',\n // open and close back open_history and close_history; set_value backs\n // set_status.\n capabilities: ['open', 'close', 'set_value'],\n state: {\n eventId: {\n type: 'string | null',\n descriptionKey: 'ui.agent.appointmentDetailsPanel.state.eventId',\n description:\n 'The occurrence on screen or being read, as the host identifies it. After a failed or refused read, the occurrence it was for when the host says so. Null when there is none, or the host did not say.',\n read: (handle) => handle.getEventId(),\n },\n loadStatus: {\n type: \"'loading' | 'ready' | 'error' | 'refused'\",\n descriptionKey: 'ui.agent.appointmentDetailsPanel.state.loadStatus',\n description:\n 'Where the read is: loading, ready, failed (with Retry) or refused. Actions need ready.',\n read: (handle) => handle.getLoadStatus(),\n },\n appointmentStatus: {\n type: \"'confirmed' | 'waiting' | 'in_care' | 'done' | 'cancelled' | 'absent' | null\",\n descriptionKey:\n 'ui.agent.appointmentDetailsPanel.state.appointmentStatus',\n description:\n 'The appointment status as last saved here or read. Null when none is recorded or nothing is on screen.',\n read: (handle) => handle.getAppointmentStatus(),\n },\n allowedStatuses: {\n type: 'string[]',\n descriptionKey:\n 'ui.agent.appointmentDetailsPanel.state.allowedStatuses',\n description:\n 'The statuses set_status accepts now, in menu order. Empty when the status is read-only.',\n read: (handle) => handle.getAllowedStatuses(),\n },\n offeredActions: {\n type: 'string[]',\n descriptionKey: 'ui.agent.appointmentDetailsPanel.state.offeredActions',\n description:\n 'The footer actions on offer, as their data-action values (for example edit-appointment, delete-appointment), in footer order, including any folded into More.',\n read: (handle) => handle.getOfferedActions(),\n },\n historyOpen: {\n type: 'boolean',\n descriptionKey: 'ui.agent.appointmentDetailsPanel.state.historyOpen',\n description: 'Whether the History sub-view covers the details.',\n read: (handle) => handle.isHistoryOpen(),\n },\n privacy: {\n type: 'boolean',\n descriptionKey: 'ui.agent.appointmentDetailsPanel.state.privacy',\n description:\n 'Whether privacy mode is on. The patient identity and personal fields are then masked on screen.',\n read: (handle) => handle.isPrivacy(),\n },\n },\n actions: {\n open_history: {\n safety: 'read',\n openWorld: true,\n idempotent: true,\n errors: ['No appointment is on screen, or History is not offered.'],\n descriptionKey: 'ui.agent.appointmentDetailsPanel.actions.openHistory',\n description:\n \"Slide the appointment's history over the details, as its header button does; the host reads it then if it did not send it with the details. It lists who changed what, and when.\",\n invoke: (handle) => handle.openHistory(),\n },\n close_history: {\n safety: 'read',\n idempotent: true,\n descriptionKey: 'ui.agent.appointmentDetailsPanel.actions.closeHistory',\n description: 'Return from History to the details.',\n invoke: (handle) => handle.closeHistory(),\n },\n set_status: {\n safety: 'phi',\n openWorld: true,\n idempotent: true,\n argsType: '{ status: string }',\n argsSchema: {\n type: 'object',\n properties: {\n status: {\n type: 'string',\n enum: [\n 'confirmed',\n 'waiting',\n 'in_care',\n 'done',\n 'cancelled',\n 'absent',\n ],\n },\n },\n required: ['status'],\n },\n errors: [\n 'The status is read-only: no appointment on screen, no host save, readOnly, or no allowed statuses.',\n 'The status is not in allowedStatuses.',\n 'A status save is already in flight.',\n 'The host refused the change. The previous status stays and the panel shows the message.',\n ],\n examples: [{ args: { status: 'waiting' } }],\n descriptionKey: 'ui.agent.appointmentDetailsPanel.actions.setStatus',\n description:\n 'Save a new appointment status through the host, as the footer control does. Resolves once the host has saved it.',\n invoke: (handle, args: { status: string }) =>\n handle.setAppointmentStatus(\n args.status as Parameters<\n AppointmentDetailsPanelHandle['setAppointmentStatus']\n >[0],\n ),\n },\n retry: {\n safety: 'read',\n openWorld: true,\n errors: [\n 'Retry is not offered: the read has not failed or been refused as retryable, or the host offers no Retry.',\n ],\n descriptionKey: 'ui.agent.appointmentDetailsPanel.actions.retry',\n description:\n 'Ask the host to read the appointment again, after a failed read or a refusal it marked retryable.',\n invoke: (handle) => handle.retry(),\n },\n },\n domHooks: {\n root: {\n attr: 'data-component',\n value: 'appointment-details-panel',\n description: `Marks the panel. It also carries data-event-id and data-status. Inside, cards carry data-card (patient, appointment, notes, treatments), footer actions data-action, and the History and description sub-views data-details-subview. An action in offeredActions with no data-action in the footer strip is folded into More: click the panel's ${MORE_TRIGGER}, and its menu item carries the same data-action.`,\n },\n instanceId: {\n attr: 'data-component-id',\n sourceProp: 'id',\n description: 'Sourced from the id prop, or generated.',\n },\n },\n };\n","/* Where focus goes when the control that held it leaves the details\n panel: the panel's own parts share these, so every rescue behaves the\n same way. */\n\n/** Hands focus to `target` only when focus fell to the page: a control that\n * held it was removed. Focus the user put elsewhere stays there. */\nexport function rescueFocus(target: HTMLElement | null | undefined): void {\n const active = document.activeElement;\n if (active && active !== document.body) return;\n target?.focus({ preventScroll: true });\n}\n\n/** A heading, made focusable on demand: where focus goes when the control\n * that held it leaves the panel or one of its cards. */\nexport function focusHeading(headingId: string): void {\n const heading = document.getElementById(headingId);\n if (heading && !heading.hasAttribute('tabindex')) heading.tabIndex = -1;\n rescueFocus(heading);\n}\n","/* Pure helpers for reading one appointment: dates, the patient's age,\n phones, address and the history order. No React and no i18n lookups.\n Shared by AppointmentDetailsPanel and the calendar pattern, which\n re-exports them under their old names. */\nimport type {\n AppointmentPhoneNumber,\n AppointmentRecurrenceFrequency,\n} from '../appointment-details-panel/appointment-details-panel.types';\n\n/** A date-only value (a birthday, an all-day start) is already a local day;\n * anything else parses as the wall clock it carries. */\nexport function parseEventDate(value: string | Date): Date {\n return typeof value === 'string' && /^\\d{4}-\\d{2}-\\d{2}$/.test(value)\n ? new Date(`${value}T00:00:00`)\n : new Date(value);\n}\n\n/** \"Wednesday, 24 June 2026\" in the reader's locale; '' when unreadable. */\nexport function formatDay(locale: string, value: Date | string): string {\n try {\n return new Intl.DateTimeFormat(locale, {\n weekday: 'long',\n day: 'numeric',\n month: 'long',\n year: 'numeric',\n }).format(parseEventDate(value));\n } catch {\n return '';\n }\n}\n\n/** \"09:00–09:45\" in the reader's locale, 24-hour; '' when unreadable. */\nexport function formatTimeRange(\n locale: string,\n start: Date | string,\n end?: Date | string,\n): string {\n const s = new Date(start);\n const e = end ? new Date(end) : s;\n try {\n const fmt = new Intl.DateTimeFormat(locale, {\n hour: '2-digit',\n minute: '2-digit',\n hour12: false,\n });\n return typeof fmt.formatRange === 'function'\n ? fmt.formatRange(s, e)\n : `${fmt.format(s)} – ${fmt.format(e)}`;\n } catch {\n return '';\n }\n}\n\n/** Absolute stamp for booked-at and history lines: day and time. */\nexport const DETAIL_STAMP_FORMAT: Intl.DateTimeFormatOptions = {\n weekday: 'short',\n day: 'numeric',\n month: 'short',\n hour: '2-digit',\n minute: '2-digit',\n};\n\n/** Completed years between a birth date and `on`, the practice's clock\n * rather than the real one, so the figure never drifts under a test. */\nexport function ageInYears(dobIso: string, on: Date | string): number {\n const dob = parseEventDate(dobIso);\n const at = parseEventDate(on);\n let age = at.getFullYear() - dob.getFullYear();\n const monthDelta = at.getMonth() - dob.getMonth();\n if (monthDelta < 0 || (monthDelta === 0 && at.getDate() < dob.getDate())) {\n age -= 1;\n }\n return Math.max(0, age);\n}\n\nconst START_ISO = /^(\\d{4})-(\\d{2})-(\\d{2})T(\\d{2}):(\\d{2}):(\\d{2})$/;\n\n/** The host's zone-less wall clock as a local Date, or undefined when it is\n * not a real 'YYYY-MM-DDTHH:mm:ss' reading. Ranges are checked rather than\n * round-tripped, so a time inside a daylight-saving gap still parses. */\nexport function parseAppointmentStartIso(\n startIso: string | undefined,\n): Date | undefined {\n const match = typeof startIso === 'string' ? START_ISO.exec(startIso) : null;\n if (!match) return undefined;\n const [year, month, day, hours, minutes, seconds] = match\n .slice(1)\n .map(Number);\n const monthEnd = new Date(0);\n monthEnd.setFullYear(year, month, 0);\n if (\n month < 1 ||\n month > 12 ||\n day < 1 ||\n day > monthEnd.getDate() ||\n hours > 23 ||\n minutes > 59 ||\n seconds > 59\n )\n return undefined;\n const start = new Date(0);\n start.setFullYear(year, month - 1, day);\n start.setHours(hours, minutes, seconds, 0);\n return start;\n}\n\n/** A Timeline set to 'newest-first' is a plain column, so the DOM order\n * must already be newest first. Unreadable dates stay last, in input\n * order; equal instants keep theirs. The input is not changed. */\nexport function sortHistoryNewestFirst<T extends { atIso: string }>(\n entries: readonly T[],\n): T[] {\n return entries\n .map((entry) => {\n const parsed = Date.parse(entry.atIso);\n return { entry, time: Number.isFinite(parsed) ? parsed : -Infinity };\n })\n .sort((a, b) => (a.time === b.time ? 0 : b.time - a.time))\n .map(({ entry }) => entry);\n}\n\n/** The editor's label key for each frequency, under\n * `calendarWorkspace.editor.*`. A literal map, so key extractors see\n * every key. */\nexport const RECURRENCE_LABEL_KEY: Record<\n AppointmentRecurrenceFrequency,\n string\n> = {\n daily: 'recurrenceDaily',\n weekly: 'recurrenceWeekly',\n monthly: 'recurrenceMonthly',\n quarterly: 'recurrenceQuarterly',\n semiannual: 'recurrenceSemiannual',\n yearly: 'recurrenceYearly',\n};\n\n/** What a patient record needs for its phones. */\nexport interface PhonesSource {\n phone?: string;\n phones?: AppointmentPhoneNumber[];\n}\n\n/** Every labelled phone number. The single `phone` is the mobile when the\n * record carries no list. A record with neither has no numbers, which is\n * not the same as one labelled blank: the list comes back empty and the\n * caller omits the rows. */\nexport function patientPhones(patient: PhonesSource): AppointmentPhoneNumber[] {\n if (patient.phones) return patient.phones;\n return patient.phone ? [{ label: 'mobile', number: patient.phone }] : [];\n}\n\n/** What a patient record needs for its address. */\nexport interface AddressSource {\n address?: string;\n postalCode?: string;\n city?: string;\n}\n\n/** The address as one line, the map search's text. Empty when the host\n * sent no address at all: the caller then offers no search. */\nexport function patientAddressLine(patient: AddressSource): string {\n return [patient.address, patient.postalCode, patient.city]\n .filter((part): part is string => Boolean(part))\n .join(', ');\n}\n\n/** The map link's visible label: street and city, as the platform popover\n * prints them. The postcode belongs in the search, not in the label. */\nexport function patientAddressLabel(patient: AddressSource): string {\n return [patient.address, patient.city]\n .filter((part): part is string => Boolean(part))\n .join(', ');\n}\n\n/** Google Maps search for the patient's address: the popover's map link. */\nexport function patientMapsUrl(patient: AddressSource): string {\n const query = patientAddressLine(patient);\n return `https://www.google.com/maps/search/?api=1&query=${encodeURIComponent(query)}`;\n}\n","/* The appointment's history as a kit Timeline, newest first. Shared by the\n details panel's History sub-view and the calendar editor's. Internal to\n this directory: the calendar pattern imports it by path. */\nimport {\n ArrowRight,\n CalendarClock,\n CalendarPlus,\n Clock,\n Move,\n Pencil,\n Trash2,\n} from 'lucide-react';\nimport type { ReactNode } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { APPOINTMENT_STATE_WORKFLOW } from '../_shared/entity-card';\nimport {\n DETAIL_STAMP_FORMAT,\n sortHistoryNewestFirst,\n} from '../_shared/appointment-format';\nimport { EmptyState } from '../empty-state';\nimport { Timeline } from '../timeline';\nimport {\n useAppointmentWorkflowStatus,\n WorkflowStatusDisplay,\n} from '../workflow-status';\nimport type { AppointmentHistoryEntry } from './appointment-details-panel.types';\n\nconst detailKey = (suffix: string): string =>\n `calendarWorkspace.details.${suffix}`;\n\nexport interface AppointmentHistoryTimelineProps {\n /** In any order: the timeline sorts a copy, newest first. */\n history: readonly AppointmentHistoryEntry[];\n /** Locale for the stamps. Defaults to the active i18n language. */\n locale?: string;\n}\n\n/** One row per history entry. A status change reads as two read-only\n * status pills with an accessible \"From → To\" label; an empty history\n * shows \"No changes recorded\". */\nexport function AppointmentHistoryTimeline({\n history,\n locale,\n}: AppointmentHistoryTimelineProps) {\n const { t, i18n: runtimeI18n } = useTranslation();\n const { optionFor } = useAppointmentWorkflowStatus(null);\n const shownLocale = locale ?? runtimeI18n.language;\n const formatStamp = (iso: string): string => {\n try {\n return new Intl.DateTimeFormat(shownLocale, DETAIL_STAMP_FORMAT).format(\n new Date(iso),\n );\n } catch {\n return iso;\n }\n };\n /* History line → tone, dot glyph and the from/to detail. */\n const describe = (\n entry: AppointmentHistoryEntry,\n ): {\n type: 'info' | 'success' | 'warning' | 'error' | 'neutral';\n icon: ReactNode;\n detail?: ReactNode;\n } => {\n switch (entry.kind) {\n case 'created':\n return {\n type: 'success',\n icon: <CalendarPlus size={16} aria-hidden=\"true\" />,\n };\n case 'moved':\n return {\n type: 'info',\n icon: <Move size={16} aria-hidden=\"true\" />,\n detail: t(detailKey('history.movedDetail'), {\n from: formatStamp(entry.fromIso),\n to: formatStamp(entry.toIso),\n }),\n };\n case 'resized':\n return {\n type: 'info',\n icon: <Clock size={16} aria-hidden=\"true\" />,\n detail: t(detailKey('history.resizedDetail'), {\n from: entry.fromMin,\n to: entry.toMin,\n }),\n };\n case 'status': {\n const StatusGlyph = APPOINTMENT_STATE_WORKFLOW[entry.to].Icon;\n const fromOption = optionFor(entry.from);\n const toOption = optionFor(entry.to);\n const transitionLabel = t(detailKey('history.statusDetail'), {\n from: fromOption.label,\n to: toOption.label,\n });\n return {\n type:\n entry.to === 'cancelled' || entry.to === 'absent'\n ? 'warning'\n : 'neutral',\n icon: <StatusGlyph size={16} aria-hidden=\"true\" />,\n detail: (\n <div role=\"group\" aria-label={transitionLabel}>\n <div\n aria-hidden=\"true\"\n className=\"ds:flex ds:flex-wrap ds:items-center ds:gap-[var(--spacing-xs)]\"\n >\n <WorkflowStatusDisplay\n value={entry.from}\n option={fromOption}\n size=\"sm\"\n />\n <ArrowRight\n className=\"ds:size-4 ds:shrink-0 ds:rtl:rotate-180\"\n aria-hidden=\"true\"\n />\n <WorkflowStatusDisplay\n value={entry.to}\n option={toOption}\n size=\"sm\"\n />\n </div>\n </div>\n ),\n };\n }\n case 'edited':\n return {\n type: 'neutral',\n icon: <Pencil size={16} aria-hidden=\"true\" />,\n /* The platform log carries no field list: no \"Changed\" line. */\n detail:\n entry.fields.length > 0\n ? t(detailKey('history.editedDetail'), {\n fields: entry.fields\n .map((field) => t(detailKey(`history.fields.${field}`)))\n .join(', '),\n })\n : undefined,\n };\n case 'confirmedByPatient': {\n const ConfirmedGlyph = APPOINTMENT_STATE_WORKFLOW.confirmed.Icon;\n return {\n type: 'success',\n icon: <ConfirmedGlyph size={16} aria-hidden=\"true\" />,\n };\n }\n case 'deleted':\n return {\n type: 'error',\n icon: <Trash2 size={16} aria-hidden=\"true\" />,\n };\n }\n };\n if (history.length === 0) {\n return (\n <EmptyState\n variant=\"first-use\"\n size=\"sm\"\n title={t(detailKey('historyEmpty'))}\n />\n );\n }\n return (\n <Timeline order=\"newest-first\" aria-label={t(detailKey('historyTitle'))}>\n {sortHistoryNewestFirst(history).map((entry) => {\n const shape = describe(entry);\n return (\n <Timeline.Event\n key={entry.id}\n eventId={entry.id}\n type={shape.type}\n className=\"ds:[column-gap:var(--spacing-sm)] ds:[padding-block-end:var(--spacing-lg)] ds:before:bg-[var(--primary)]\"\n >\n <Timeline.Dot icon={shape.icon} />\n <Timeline.Content\n title={t(detailKey(`history.${entry.kind}`))}\n description={shape.detail}\n className=\"ds:[padding-block-end:0] ds:[&>[data-component=card]]:border-[color:var(--card-border)] ds:[&>[data-component=card]]:shadow-[var(--shadow-card)]\"\n /* No author (a patient confirming by link): no blank avatar. */\n actor={entry.actor.trim() ? { name: entry.actor } : undefined}\n >\n <span className=\"ds:mt-[var(--spacing-sm)] ds:inline-flex ds:items-center ds:gap-[var(--spacing-xs)]\">\n <CalendarClock\n aria-hidden=\"true\"\n className=\"ds:size-4 ds:shrink-0 ds:text-[color:var(--muted-foreground)]\"\n />\n <Timeline.Timestamp\n date={entry.atIso}\n relative={false}\n locale={shownLocale}\n />\n </span>\n </Timeline.Content>\n </Timeline.Event>\n );\n })}\n </Timeline>\n );\n}\n","/* The identity strip: avatar, name, status badge and the labelled\n indicator chips, with the anamnesis warnings below. Shown by the details\n panel when there is no patient card, and by the calendar editor above its\n form. Data-free: the caller resolves the name, the age and the status.\n Internal to this directory: the calendar pattern imports it by path. */\nimport {\n Euro,\n Globe,\n HeartPulse,\n Repeat,\n TriangleAlert,\n Video,\n} from 'lucide-react';\nimport type { ReactNode } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { formatDay } from '../_shared/appointment-format';\nimport { Alert } from '../alert';\nimport { Avatar } from '../avatar';\nimport { Badge } from '../badge';\nimport { Button } from '../button';\nimport type { CalendarEvent, CalendarEventStatus } from '../calendar';\nimport { useAppointmentWorkflowStatus } from '../workflow-status';\nimport type { AppointmentAnamnesisAnswer } from './appointment-details-panel.types';\n\ntype StatusBadgeVariant =\n | 'success'\n | 'info'\n | 'warning'\n | 'error'\n | 'accentSoft';\n\n/** The Badge variant a status wears as a chip, beside the grid card's disc.\n * The glyph and the label come from the shared workflow status options. */\nexport const APPOINTMENT_STATUS_BADGE_VARIANT: Record<\n CalendarEventStatus,\n StatusBadgeVariant\n> = {\n confirmed: 'success',\n waiting: 'info',\n in_care: 'accentSoft',\n done: 'success',\n cancelled: 'error',\n absent: 'warning',\n};\n\n/** The card flags the chips spell out. */\nexport type IndicatorFlags = Pick<\n CalendarEvent,\n | 'isBookedOnline'\n | 'hasUnassignedPatient'\n | 'hasHighlightedAnamnesis'\n | 'hasBillableAmount'\n | 'isTelehealth'\n | 'isRecurring'\n>;\n\n/** Wherever a grid card carries the disc symbols, the peek and the details\n * panel spell them out: a glyph and the full label in a semantic Badge,\n * in the same tones as the discs. */\nexport function IndicatorChips({ event }: { event: IndicatorFlags }) {\n const { t } = useTranslation();\n const key = (suffix: string): string =>\n `calendarWorkspace.details.indicators.${suffix}`;\n const chips: Array<{\n id: string;\n icon: ReactNode;\n label: string;\n variant: 'info' | 'warning' | 'accentSoft';\n }> = [];\n if (event.isBookedOnline) {\n chips.push({\n id: 'online',\n icon: <Globe aria-hidden=\"true\" />,\n label: t(key('bookedOnline')),\n variant: 'info',\n });\n }\n if (event.hasUnassignedPatient) {\n chips.push({\n id: 'unassigned',\n icon: <TriangleAlert aria-hidden=\"true\" />,\n label: t(key('unassignedPatient')),\n variant: 'warning',\n });\n }\n if (event.hasHighlightedAnamnesis) {\n chips.push({\n id: 'anamnesis',\n icon: <HeartPulse aria-hidden=\"true\" />,\n label: t(key('anamnesis')),\n variant: 'accentSoft',\n });\n }\n if (event.hasBillableAmount) {\n chips.push({\n id: 'billable',\n icon: <Euro aria-hidden=\"true\" />,\n label: t(key('billable')),\n variant: 'warning',\n });\n }\n if (event.isTelehealth) {\n chips.push({\n id: 'telehealth',\n icon: <Video aria-hidden=\"true\" />,\n label: t(key('telehealth')),\n variant: 'info',\n });\n }\n if (event.isRecurring) {\n chips.push({\n id: 'recurring',\n icon: <Repeat aria-hidden=\"true\" />,\n label: t(key('recurring')),\n variant: 'info',\n });\n }\n if (chips.length === 0) return null;\n return (\n <span className=\"ds:flex ds:flex-wrap ds:gap-[var(--spacing-2xs)]\">\n {chips.map((chip) => (\n <Badge\n key={chip.id}\n variant={chip.variant}\n size=\"sm\"\n leading={chip.icon}\n >\n {chip.label}\n </Badge>\n ))}\n </span>\n );\n}\n\nexport interface AppointmentIdentityStripProps {\n /** The name to show, never blank: the record's, else the appointment's\n * title, else \"Patient record not loaded\". */\n name: string;\n avatarSrc?: string;\n /** Someone is booked but their record did not load: says so once, beside\n * the name, so it never reads as \"no patient\". */\n unresolved?: boolean;\n status?: CalendarEventStatus;\n /** The flags the indicator chips spell out. */\n flags: IndicatorFlags;\n /** Completed years, printed beside the name. Absent = no age. */\n age?: number;\n /** Set = the name becomes a link-styled button to the patient folder. */\n onOpenPatient?: () => void;\n highlightedAnamnesisCount?: number;\n expiredAnamnesisCount?: number;\n /** The highlighted answers themselves, listed under the warning. */\n anamnesisAnswers?: readonly AppointmentAnamnesisAnswer[];\n /** Locale for the interview dates. Defaults to the active language. */\n locale?: string;\n}\n\n/** Identity strip above the details or the editor: avatar, name, status\n * badge and chips, the read-at-a-glance layer. */\nexport function AppointmentIdentityStrip({\n name,\n avatarSrc,\n unresolved = false,\n status,\n flags,\n age,\n onOpenPatient,\n highlightedAnamnesisCount = 0,\n expiredAnamnesisCount = 0,\n anamnesisAnswers = [],\n locale,\n}: AppointmentIdentityStripProps) {\n const { t, i18n: runtimeI18n } = useTranslation();\n const key = (suffix: string): string => `calendarWorkspace.details.${suffix}`;\n const { optionFor } = useAppointmentWorkflowStatus(status);\n const statusOption = status ? optionFor(status) : undefined;\n const highlighted = highlightedAnamnesisCount;\n const expired = expiredAnamnesisCount;\n return (\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-sm)] ds:p-[var(--spacing-md)] ds:pb-0\">\n <div className=\"ds:flex ds:items-center ds:gap-[var(--spacing-sm)]\">\n <Avatar name={name} src={avatarSrc} />\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-2xs)] ds:[min-inline-size:0]\">\n {/* The platform pop-over links the name to the patient folder\n and prints the age beside it. */}\n <span className=\"ds:flex ds:flex-wrap ds:items-baseline ds:gap-[var(--spacing-2xs)] ds:text-start\">\n {onOpenPatient ? (\n <Button size=\"sm\" intent=\"link\" onClick={() => onOpenPatient()}>\n {name}\n </Button>\n ) : (\n <span className=\"ds:font-[var(--font-weight-semibold)] ds:truncate\">\n {name}\n </span>\n )}\n {age !== undefined ? (\n <span className=\"type-body-sm ds:text-[color:var(--muted-foreground)]\">\n {t(key('patientAge'), { n: age })}\n </span>\n ) : null}\n </span>\n {/* Said once, next to the name it qualifies. Without it \"we could\n not load this patient\" and \"this patient has nothing recorded\"\n would look the same. */}\n {unresolved ? (\n <span className=\"type-body-sm ds:text-start ds:text-[color:var(--muted-foreground)]\">\n {t(key('patientNotLoaded'))}\n </span>\n ) : null}\n {status && statusOption ? (\n <span>\n <Badge\n variant={APPOINTMENT_STATUS_BADGE_VARIANT[status]}\n size=\"sm\"\n leading={statusOption.icon}\n >\n {statusOption.label}\n </Badge>\n </span>\n ) : null}\n <IndicatorChips event={flags} />\n </div>\n </div>\n {/* The pop-over's anamnesis warnings: the two counts and the\n highlighted answers. Present from mount, so announce=\"off\"; the\n title is a <p> so the panel's heading stays alone. */}\n {highlighted + expired > 0 ? (\n <Alert\n variant=\"warning\"\n announce=\"off\"\n icon={<HeartPulse aria-hidden=\"true\" />}\n >\n <Alert.Title as=\"p\">{t(key('anamnesisTitle'))}</Alert.Title>\n <Alert.Description>\n {[\n highlighted > 0\n ? t(key('anamnesisHighlighted'), { n: highlighted })\n : null,\n expired > 0 ? t(key('anamnesisExpired'), { n: expired }) : null,\n ]\n .filter((line): line is string => line !== null)\n .join(' · ')}\n </Alert.Description>\n {anamnesisAnswers.length > 0 ? (\n /* Question · yes or no · answer · interview date, as the\n platform's details dialog lists them. A list, not a\n Description, which renders a <p>. */\n <ul className=\"type-body-sm ds:m-0 ds:mt-[var(--spacing-xs)] ds:flex ds:list-none ds:flex-col ds:gap-[var(--spacing-2xs)] ds:p-0\">\n {anamnesisAnswers.map((answer) => (\n <li key={answer.question} className=\"ds:text-start\">\n <span className=\"ds:font-[var(--font-weight-semibold)]\">\n {answer.question}\n </span>\n {` · ${t(key(answer.yes ? 'anamnesisYes' : 'anamnesisNo'))}`}\n {answer.answer ? ` · ${answer.answer}` : ''}\n {` · ${formatDay(locale ?? runtimeI18n.language, answer.interviewIso)}`}\n </li>\n ))}\n </ul>\n ) : null}\n {/* No Renew action: re-issuing the anamnesis is a platform flow\n the kit cannot start. The expired count stays: it is a\n clinical fact, not an offer. */}\n </Alert>\n ) : null}\n </div>\n );\n}\n","/**\n * The hover card body the details panel's chips share: an eyebrow naming\n * the kind of thing, a heading restating the chip in words, and the facts\n * the chip could not fit. Ported from the calendar-rail demo's hover\n * grammar; `PatientSummaryCard.flagHover` renders it around its own chip,\n * and `InfoHover` wraps the chips the panel renders itself.\n */\nimport type { ReactNode } from 'react';\nimport { HoverCard } from '../hover-card';\n\nexport interface InfoHoverFact {\n text: ReactNode;\n /** A caveat or provenance note, quieter than the rest. */\n muted?: boolean;\n}\n\nexport function InfoHoverBody({\n eyebrow,\n heading,\n facts,\n}: {\n eyebrow: string;\n heading: string;\n facts?: readonly InfoHoverFact[];\n}): ReactNode {\n return (\n <>\n <HoverCard.Eyebrow>{eyebrow}</HoverCard.Eyebrow>\n <HoverCard.Heading>{heading}</HoverCard.Heading>\n {facts && facts.length > 0 ? (\n <HoverCard.Body>\n <ul className=\"ds:m-0 ds:flex ds:list-none ds:flex-col ds:gap-[var(--spacing-2xs)] ds:p-0 type-body-sm\">\n {facts.map((fact, index) => (\n <li\n key={index}\n className={\n fact.muted\n ? 'ds:text-[color:var(--muted-foreground)]'\n : undefined\n }\n >\n {fact.text}\n </li>\n ))}\n </ul>\n </HoverCard.Body>\n ) : null}\n </>\n );\n}\n\nconst TRIGGER =\n 'ds:inline-flex ds:cursor-pointer ds:rounded-[var(--radius-full)] ds:p-0 ds:focus-visible:outline-[length:var(--focus-ring-width)] ds:focus-visible:outline-solid ds:focus-visible:outline-[color:var(--ring)] ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)]';\n\n/**\n * Wraps a chip the panel renders itself in the same card. It carries no\n * open button: the pattern has no seam to open invoicing or the anamnesis.\n */\nexport function InfoHover({\n id,\n eyebrow,\n heading,\n facts,\n children,\n}: {\n /** Stamped as `data-chip-hover`, the trigger's DOM hook. */\n id: string;\n eyebrow: string;\n heading: string;\n facts?: readonly InfoHoverFact[];\n /** The chip; its visible text is the trigger's accessible name. */\n children: ReactNode;\n}): ReactNode {\n return (\n <HoverCard>\n {/* A real button: `asChild` onto a bare span stamps `aria-haspopup`\n on something a keyboard can never reach. */}\n <HoverCard.Trigger asChild>\n <button type=\"button\" data-chip-hover={id} className={TRIGGER}>\n {children}\n </button>\n </HoverCard.Trigger>\n <HoverCard.Content side=\"bottom\" align=\"start\" size=\"sm\">\n <InfoHoverBody eyebrow={eyebrow} heading={heading} facts={facts} />\n </HoverCard.Content>\n </HoverCard>\n );\n}\n","/* The cards of AppointmentDetailsPanel, laid out as the calendar-rail demo\n lays them out and built on the kit's primitives. Each prints one row per\n member the host sent: an absent member renders nothing, and a card with\n nothing to show renders no card. Contact is printed as read; masking is\n the host's. The operator and chair labels, the currency and the clock are\n the caller's: nothing here reads a calendar context. */\nimport {\n Armchair,\n Building2,\n Cake,\n CalendarDays,\n ClipboardList,\n Clock,\n HeartPulse,\n Hourglass,\n Mail,\n MapPin,\n NotebookPen,\n Phone,\n Repeat,\n Smartphone,\n Video,\n} from 'lucide-react';\nimport { useId, useRef, type ReactElement, type ReactNode } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { useIsomorphicLayoutEffect } from '../../hooks/use-isomorphic-layout-effect';\nimport {\n ageInYears,\n DETAIL_STAMP_FORMAT,\n formatDay,\n formatTimeRange,\n patientAddressLabel,\n patientAddressLine,\n patientMapsUrl,\n patientPhones,\n RECURRENCE_LABEL_KEY,\n} from '../_shared/appointment-format';\nimport type { PatientField } from '../_shared/patient-fields';\nimport { Alert } from '../alert';\nimport { Avatar } from '../avatar';\nimport { Badge } from '../badge';\nimport { Button, IconButton } from '../button';\nimport { Counter } from '../counter';\nimport { DescriptionList } from '../description-list';\nimport { NoteTimeline } from '../note-timeline';\nimport { PatientSummaryCard } from '../patient-summary-card';\nimport { SectionCard } from '../section-card';\nimport { Timestamp } from '../timestamp';\nimport { TransactionChip } from '../transaction-chip';\nimport { TreatmentReceipt } from '../treatment-receipt';\nimport { focusHeading } from './appointment-details-panel.focus';\nimport {\n InfoHover,\n InfoHoverBody,\n type InfoHoverFact,\n} from './appointment-details-panel.info-hover';\nimport type {\n AppointmentDetailsChairLabel,\n AppointmentDetailsNotesPreview,\n AppointmentDetailsOperatorLabel,\n AppointmentDetailsRead,\n} from './appointment-details-panel.types';\n\ninterface CardProps {\n details: AppointmentDetailsRead;\n locale: string;\n /** ISO 4217 code for every amount. */\n currency: string;\n}\n\ninterface Row {\n id: string;\n label: string;\n icon?: ReactElement;\n value: ReactNode;\n}\n\nconst key = (suffix: string): string => `calendarWorkspace.details.${suffix}`;\nconst MUTED = 'type-body-sm ds:text-[color:var(--muted-foreground)]';\n// `dir=\"ltr\"` isolates the number/address from the surrounding paragraph's\n// bidi context: a phone number or email is an LTR datum even in an RTL\n// (Arabic) rendering, and without it the digits/punctuation can reorder.\nconst telLink = (number: string) => (\n <a href={`tel:${number.replace(/\\s/g, '')}`} dir=\"ltr\">\n {number}\n </a>\n);\nconst mailLink = (email: string) => (\n <a href={`mailto:${email}`} dir=\"ltr\">\n {email}\n </a>\n);\nconst formatMoney = (\n locale: string,\n amount: number,\n currency: string,\n): string =>\n new Intl.NumberFormat(locale, { style: 'currency', currency }).format(amount);\n\n/** Term and detail pairs; nothing at all without a row. */\nfunction Rows({ rows }: { rows: Array<Row | false | null | undefined | ''> }) {\n const shown = rows.filter((entry): entry is Row => !!entry);\n if (shown.length === 0) return null;\n return (\n <DescriptionList layout=\"inline\" density=\"compact\">\n {shown.map((entry) => (\n <DescriptionList.Row\n key={entry.id}\n data-row={entry.id}\n icon={entry.icon}\n >\n <DescriptionList.Term>{entry.label}</DescriptionList.Term>\n <DescriptionList.Detail>{entry.value}</DescriptionList.Detail>\n </DescriptionList.Row>\n ))}\n </DescriptionList>\n );\n}\n\n/**\n * The kit's PatientSummaryCard: identity, the attention chips, the money\n * chips and the contact fields. Every chip explains itself in a hover\n * card; money reads worst first (owed, to invoice, paid online), labelled\n * and without glyphs.\n */\nexport function DetailsPatientCard({\n details,\n locale,\n currency,\n now,\n mapsLink = false,\n}: CardProps & {\n /** The practice clock the age is computed against. */\n now: Date | string;\n /** The user's map-link setting (platform `showPatientAddressMapLink`). */\n mapsLink?: boolean;\n}) {\n const { t } = useTranslation();\n const { patient, signing, money, booking } = details;\n if (!patient) return null;\n const signingShown = signing && signing.required > 0 ? signing : undefined;\n const pending = (signingShown?.toComplete ?? 0) > 0;\n const signingFacts: InfoHoverFact[] = signingShown\n ? [\n {\n text: !pending\n ? t(key('signingAllSigned'))\n : signingShown.requestedVia === 'sms'\n ? t(key('signingRequestedSms'))\n : signingShown.requestedVia === 'email'\n ? t(key('signingRequestedEmail'))\n : t(key('signingNotRequested')),\n },\n ...(signingShown.aesSetUp\n ? []\n : [{ text: t(key('aesMissing')), muted: true }]),\n ]\n : [];\n const highlighted = patient.highlightedAnamnesisCount ?? 0;\n const expired = patient.expiredAnamnesisCount ?? 0;\n const answerFacts: InfoHoverFact[] = (\n patient.highlightedAnamnesisAnswers ?? []\n ).map((answer) => ({\n text: [\n answer.question,\n t(key(answer.yes ? 'anamnesisYes' : 'anamnesisNo')),\n answer.answer,\n formatDay(locale, answer.interviewIso),\n ]\n .filter(Boolean)\n .join(' · '),\n }));\n const query = patientAddressLine(patient);\n const addressLabel = patientAddressLabel(patient) || query;\n const fields: PatientField[] = [\n ...(patient.dobIso\n ? [\n {\n id: 'dob',\n label: t(key('dob')),\n icon: <Cake />,\n value: `${formatDay(locale, patient.dobIso)} ${t(\n key('patientAge'),\n {\n n: ageInYears(patient.dobIso, now),\n },\n )}`,\n },\n ]\n : []),\n ...patientPhones(patient).map((phone, index) => {\n const hasLabel =\n phone.label === 'mobile' ||\n phone.label === 'home' ||\n phone.label === 'work';\n return {\n id: `phone-${index}`,\n label: hasLabel\n ? t(`calendarWorkspace.print.phoneLabels.${phone.label}`)\n : t(key('phone')),\n icon: phone.label === 'mobile' ? <Smartphone /> : <Phone />,\n value: telLink(phone.number),\n };\n }),\n ...(patient.email\n ? [\n {\n id: 'email',\n label: t(key('email')),\n icon: <Mail />,\n value: mailLink(patient.email),\n },\n ]\n : []),\n ...(mapsLink\n ? [\n {\n id: 'address',\n label: t(key('address')),\n icon: <MapPin />,\n value: query ? (\n <a\n href={patientMapsUrl(patient)}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n aria-label={`${t(key('mapsLink'))}: ${addressLabel}`}\n >\n {addressLabel}\n </a>\n ) : (\n <span className={MUTED}>{t(key('noAddress'))}</span>\n ),\n },\n ]\n : []),\n ];\n const unpaid = money?.unpaidAmount ?? 0;\n const billable = money?.billableAmount ?? 0;\n const paidOnline = booking?.paidOnlineAmount ?? 0;\n /* A money chip under its hover card: the amount again, and whose it is. */\n const chip = (\n state: 'debt' | 'to-invoice' | 'settled',\n amount: number,\n id: string,\n headingKey: string,\n factKey: string,\n /** The money's own name, where the state's word would mislead. */\n label?: string,\n ) => (\n <InfoHover\n id={id}\n eyebrow={t(key('hoverBilling'))}\n heading={t(key(headingKey), {\n amount: formatMoney(locale, amount, currency),\n })}\n facts={[{ text: t(key(factKey)) }]}\n >\n <TransactionChip\n data-chip={id}\n state={state}\n amount={amount}\n currency={currency}\n locale={locale}\n size=\"md\"\n showLabel\n label={label}\n showIcon={false}\n />\n </InfoHover>\n );\n return (\n <PatientSummaryCard\n data-card=\"patient\"\n name={patient.name}\n avatarUrl={patient.avatarSrc}\n locale={locale}\n surface=\"elevated\"\n density=\"compact\"\n flags={{\n unsignedDocumentsCount: signingShown?.toComplete ?? 0,\n highlightedAnamnesisCount: highlighted,\n }}\n flagHover={{\n ...(signingShown\n ? {\n unsignedDocuments: (\n <InfoHoverBody\n eyebrow={t(key('sectionSigning'))}\n heading={\n signingShown.toComplete === 1\n ? t(key('signingToSignOne'))\n : t(key('signingToSignMany'), {\n n: signingShown.toComplete,\n })\n }\n facts={signingFacts}\n />\n ),\n }\n : {}),\n highlightedAnamnesis: (\n <InfoHoverBody\n eyebrow={t(key('anamnesisTitle'))}\n heading={t(key('anamnesisHighlighted'), { n: highlighted })}\n facts={answerFacts}\n />\n ),\n }}\n extraChips={\n unpaid > 0 || billable > 0 || paidOnline > 0 || expired > 0 ? (\n <>\n {/* One group, so no other chip lands between the money chips. */}\n <span className=\"ds:inline-flex ds:flex-wrap ds:items-center ds:gap-[var(--spacing-xs)]\">\n {unpaid > 0\n ? chip(\n 'debt',\n unpaid,\n 'unpaid',\n 'hoverUnpaidHeading',\n 'hoverUnpaidFact',\n )\n : null}\n {billable > 0\n ? chip(\n 'to-invoice',\n billable,\n 'billable',\n 'hoverBillableHeading',\n 'hoverBillableFact',\n )\n : null}\n {paidOnline > 0\n ? chip(\n 'settled',\n paidOnline,\n 'paidOnline',\n 'hoverPaidOnlineHeading',\n 'hoverPaidOnlineFact',\n /* A deposit is settled money, but \"Settled\" hides where\n it came from: the chip says what its hover card says. */\n t(key('paidOnline')),\n )\n : null}\n </span>\n {expired > 0 ? (\n <InfoHover\n id=\"anamnesisExpired\"\n eyebrow={t(key('anamnesisTitle'))}\n heading={t(key('anamnesisExpired'), { n: expired })}\n facts={[{ text: t(key('hoverAnamnesisExpiredFact')) }]}\n >\n <Badge\n data-chip=\"anamnesisExpired\"\n variant=\"warning\"\n size=\"md\"\n leading={<HeartPulse />}\n >\n {t(key('anamnesisExpired'), { n: expired })}\n </Badge>\n </InfoHover>\n ) : null}\n </>\n ) : undefined\n }\n /* Controlled, so a field this patient has and the last one did not (a\n third phone, the address once the map link is on) is shown too. */\n visibleFieldOrder={fields.map((field) => field.id)}\n sections={\n fields.length > 0\n ? [{ id: 'contact', heading: t(key('sectionPatient')), fields }]\n : undefined\n }\n />\n );\n}\n\n/**\n * When, how long, who and where, the series rule, and what the booking\n * site recorded. Operator and chair names are the caller's labels, so an\n * id without one prints no row. `description` is the caller's slot for the\n * description, above the facts.\n */\nexport function DetailsAppointmentCard({\n details,\n locale,\n currency,\n operator,\n chair,\n description,\n privacy = false,\n}: CardProps & {\n operator?: AppointmentDetailsOperatorLabel;\n chair?: AppointmentDetailsChairLabel;\n description?: ReactNode;\n /** Privacy mode: what the booker typed is dropped; when they booked stays. */\n privacy?: boolean;\n}) {\n const { t } = useTranslation();\n const { appointment, booking, patient } = details;\n const editor = (suffix: string) => t(`calendarWorkspace.editor.${suffix}`);\n /* A zone-less wall clock parses as local time. */\n const start = new Date(appointment.startIso);\n const end = new Date(start.getTime() + appointment.durationMin * 60_000);\n const timed = Number.isFinite(start.getTime());\n const { recurrence } = appointment;\n const frequencyKey = recurrence && RECURRENCE_LABEL_KEY[recurrence.frequency];\n const frequency = frequencyKey\n ? t(`calendarWorkspace.editor.${frequencyKey}`)\n : undefined;\n const bookingRows: Array<Row | false | undefined | ''> = booking\n ? [\n booking.bookedAtIso && {\n id: 'bookedAt',\n label: t(key('bookedAt')),\n value: (\n <Timestamp\n value={booking.bookedAtIso}\n format=\"absolute\"\n shape=\"bare\"\n locale={locale}\n absoluteFormat={DETAIL_STAMP_FORMAT}\n />\n ),\n },\n booking.typedName && {\n id: 'bookingName',\n label: t(key('bookingName')),\n value: booking.typedName,\n },\n booking.phone && {\n id: 'bookingPhone',\n label: t(key('bookingPhone')),\n value: telLink(booking.phone),\n },\n booking.email && {\n id: 'bookingEmail',\n label: t(key('bookingEmail')),\n value: mailLink(booking.email),\n },\n booking.note && {\n id: 'bookingNote',\n label: t(key('bookingNote')),\n value: booking.note,\n },\n /* With a patient the amount is a chip on the patient card. */\n !patient &&\n booking.paidOnlineAmount !== undefined && {\n id: 'paidOnline',\n label: t(key('paidOnline')),\n value: formatMoney(locale, booking.paidOnlineAmount, currency),\n },\n ]\n : [];\n /* Privacy keeps the one booking fact that names nobody: when. */\n const shownBookingRows = privacy\n ? bookingRows.filter((row) => row && row.id === 'bookedAt')\n : bookingRows;\n const hasBooking = shownBookingRows.some(Boolean);\n return (\n <SectionCard\n data-card=\"appointment\"\n title={t(key('sectionAppointment'))}\n headingLevel={3}\n >\n {description}\n <Rows\n rows={[\n timed && {\n id: 'date',\n label: editor('date'),\n icon: <CalendarDays />,\n value: formatDay(locale, start),\n },\n timed && {\n id: 'time',\n label: t(key('time')),\n icon: <Clock />,\n value: appointment.allDay\n ? editor('allDay')\n : formatTimeRange(locale, start, end),\n },\n !appointment.allDay && {\n id: 'duration',\n label: editor('duration'),\n icon: <Hourglass />,\n value: `${appointment.durationMin} ${editor('durationUnit')}`,\n },\n appointment.isTelehealth && {\n id: 'type',\n label: editor('type'),\n icon: <Video />,\n value: editor('typeTelehealth'),\n },\n operator && {\n id: 'operator',\n label: t(key('operator')),\n /* A person, as on the grid: the avatar fills the icon slot. */\n icon: (\n <Avatar name={operator.name} src={operator.avatarSrc} size=\"xs\" />\n ),\n value: operator.name,\n },\n chair && {\n id: 'chair',\n label: t(key('chair')),\n icon: <Armchair />,\n value: (\n <Badge variant=\"neutral\" size=\"sm\" leading={<Armchair />}>\n {chair.name}\n </Badge>\n ),\n },\n appointment.branchLabel && {\n id: 'branch',\n label: editor('branch'),\n icon: <Building2 />,\n value: appointment.branchLabel,\n },\n frequency &&\n recurrence && {\n id: 'series',\n label: t(key('seriesLabel')),\n icon: <Repeat />,\n value:\n recurrence.count === undefined\n ? frequency\n : t(key('seriesRule'), {\n frequency,\n count: recurrence.count,\n }),\n },\n ]}\n />\n {hasBooking ? (\n <div\n data-block=\"booking\"\n className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-xs)]\"\n >\n <h4 className=\"ds:m-0 type-label ds:text-[color:var(--muted-foreground)]\">\n {t(key('sectionBooking'))}\n </h4>\n <Rows rows={shownBookingRows} />\n </div>\n ) : null}\n </SectionCard>\n );\n}\n\n/** The linked plan, by number when the host has one, and the kit's\n * TreatmentReceipt: one line per treatment, a price only when the host\n * sends one (the editor's price gate), and a total only when every line\n * is priced. */\nexport function DetailsTreatmentsCard({\n details,\n locale,\n currency,\n privacy = false,\n}: CardProps & {\n /** Privacy mode: the plan's free-text name goes, as on the hover peek. */\n privacy?: boolean;\n}) {\n const { t } = useTranslation();\n const { care } = details;\n const plan = privacy ? undefined : care?.plan;\n if (!care || (!plan && care.lines.length === 0)) return null;\n return (\n <SectionCard\n data-card=\"treatments\"\n title={t(key('sectionTreatments'))}\n headingLevel={3}\n >\n {plan ? (\n <span className=\"ds:flex ds:items-center ds:gap-[var(--spacing-xs)] type-title-item\">\n <ClipboardList\n aria-hidden=\"true\"\n className=\"ds:size-4 ds:shrink-0 ds:text-[color:var(--muted-foreground)]\"\n />\n {plan.number\n ? t(key('planLine'), { number: plan.number, name: plan.name })\n : plan.name}\n </span>\n ) : null}\n {care.lines.length > 0 ? (\n <TreatmentReceipt\n lines={care.lines.map(({ entryId, careId: _careId, ...line }) => ({\n id: entryId,\n ...line,\n }))}\n locale={locale}\n currency={currency}\n />\n ) : null}\n </SectionCard>\n );\n}\n\nconst NOTES_PREVIEWED = 3;\n\n/** The patient's latest notes, pinned first, as the host holds them. A\n * click on a note opens the Notes tool at it; the header button opens the\n * tool from the keyboard. */\nexport function DetailsNotesCard({\n preview,\n onOpenNotes,\n locale,\n}: {\n preview: AppointmentDetailsNotesPreview;\n onOpenNotes?: (noteId?: string) => void;\n locale?: string;\n}) {\n const { t } = useTranslation();\n const headingId = useId();\n const status = preview.status ?? 'ready';\n /* Retry leaves with the error it answered: the card's heading keeps the\n focus until the read settles. */\n const retried = useRef(false);\n useIsomorphicLayoutEffect(() => {\n if (!retried.current) return;\n if (status !== 'loading') retried.current = false;\n focusHeading(headingId);\n }, [status, headingId]);\n const count =\n preview.total ?? (status === 'ready' ? preview.notes.length : null);\n const more = Math.max(0, (count ?? 0) - NOTES_PREVIEWED);\n const openLabel =\n more > 0 ? t(key('notesMore'), { n: more }) : t(key('notesPreviewOpen'));\n return (\n <SectionCard\n /* `data-card`, not `data-component`: SectionCard's own marker must\n survive, or the kit's cascade reset loses this element. */\n data-card=\"notes\"\n headingId={headingId}\n headingLevel={3}\n title={\n count === null\n ? t('notesPanel.title')\n : t(key('notesPreviewTitle'), { count })\n }\n headerAction={\n onOpenNotes && (count ?? 0) > 0 ? (\n <span className=\"ds:relative ds:inline-flex\">\n <IconButton\n icon={<NotebookPen aria-hidden=\"true\" />}\n intent=\"outline\"\n size=\"sm\"\n data-action=\"open-patient-notes\"\n aria-label={openLabel}\n tooltip={openLabel}\n onClick={() => onOpenNotes()}\n />\n {more > 0 ? (\n /* Decorative: the button's name already says the count. */\n <Counter\n variant=\"outline\"\n size=\"sm\"\n background=\"surface\"\n count={more}\n aria-hidden=\"true\"\n className=\"ds:pointer-events-none ds:absolute ds:-top-[var(--spacing-2xs)] ds:-end-[var(--spacing-2xs)]\"\n />\n ) : null}\n </span>\n ) : undefined\n }\n >\n {status === 'error' ? (\n <Alert variant=\"error\">\n <Alert.Description>{t('notesPanel.loadError')}</Alert.Description>\n {preview.onRetry ? (\n <Alert.Action>\n <Button\n intent=\"secondary\"\n size=\"sm\"\n onClick={() => {\n retried.current = true;\n preview.onRetry?.();\n }}\n >\n {t('notesPanel.retry')}\n </Button>\n </Alert.Action>\n ) : null}\n </Alert>\n ) : null}\n {preview.notes.length === 0 && status === 'loading' ? (\n <>\n <span role=\"status\" className=\"ds:sr-only\">\n {t('notesPanel.loading')}\n </span>\n <NoteTimeline notes={[]} loading loadingRows={2} />\n </>\n ) : status !== 'error' || preview.notes.length > 0 ? (\n /* A note click, or Enter or Space on it, goes straight to that note\n in the Notes tool; the header button opens the tool at the top. */\n <NoteTimeline\n notes={preview.notes}\n maxItems={NOTES_PREVIEWED}\n locale={locale}\n aria-labelledby={headingId}\n onNoteActivate={onOpenNotes}\n emptyState={\n <p className=\"ds:m-0 type-body-sm ds:text-[color:var(--muted-foreground)]\">\n {t(key('notesPreviewEmpty'))}\n </p>\n }\n />\n ) : null}\n </SectionCard>\n );\n}\n","/* -------------------------------------------------------------------- */\n/* AppointmentDetailsPanel */\n/* */\n/* One appointment occurrence, read-only apart from its status and its */\n/* description: a header with History, the patient, appointment, notes */\n/* and treatments cards, and a pinned footer with the status control and */\n/* the host's actions. History and the description editor slide over the */\n/* body as PanelSubviews. While there is no read it shows a skeleton, an */\n/* error with Retry, or a refusal. */\n/* */\n/* Everything comes from props: the read, the operator and chair labels, */\n/* the currency, the practice clock and one handler per action. An absent */\n/* handler withholds its control, and each handler receives the event id */\n/* of the read it acted on. The calendar pattern's details panel is an */\n/* adapter over this component. */\n/* */\n/* DOM hooks: the root carries data-component=\"appointment-details-panel\" */\n/* with data-component-id, data-event-id and data-status; cards carry */\n/* data-card, footer actions data-action, sub-views data-details-subview. */\n/* -------------------------------------------------------------------- */\nimport { cva } from 'class-variance-authority';\nimport {\n CalendarClock,\n Camera,\n ChevronDown,\n ClipboardList,\n ClipboardPaste,\n Copy,\n File,\n FileText,\n Folder,\n History as HistoryIcon,\n IdCard,\n Move,\n Pencil,\n Plus,\n ReceiptEuro,\n SquareCheckBig,\n Trash2,\n Video,\n} from 'lucide-react';\nimport {\n forwardRef,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n type HTMLAttributes,\n type MutableRefObject,\n type ReactNode,\n} from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { useAgentRegistration } from '../../agent/registry';\nimport { useIsomorphicLayoutEffect } from '../../hooks/use-isomorphic-layout-effect';\nimport { composeRefs } from '../_shared/compose-refs';\nimport { getErrorMessage } from '../_shared/get-error-message';\nimport { handledRejection } from '../_shared/handled-rejection';\nimport {\n PrivacyHiddenLine,\n PrivacyIdentityCard,\n} from '../_shared/privacy-mask';\nimport { Alert } from '../alert';\nimport { Button, IconButton } from '../button';\nimport { ButtonGroup, type ButtonGroupOverflowItem } from '../button-group';\nimport type { CalendarEventStatus } from '../calendar';\nimport { DropdownMenu } from '../dropdown-menu';\nimport { EditableDescription } from '../editable-description';\nimport { NoteTimeline } from '../note-timeline';\nimport { PanelHeader } from '../panel-header';\nimport { PanelSubview } from '../panel-subview';\nimport { PatientSummaryCard } from '../patient-summary-card';\nimport { SectionCard } from '../section-card';\nimport { CONTENT_ENTER_CLASS, Skeleton } from '../skeleton';\nimport { TextArea } from '../text-area';\nimport { Tooltip } from '../tooltip';\nimport { TreatmentReceipt } from '../treatment-receipt';\nimport { WhatsAppGlyph } from '../whatsapp-button';\nimport {\n APPOINTMENT_WORKFLOW_STATUSES,\n isCalendarEventStatus,\n useAppointmentWorkflowStatus,\n WorkflowStatusControl,\n WorkflowStatusDisplay,\n type WorkflowStatusControlHandle,\n} from '../workflow-status';\nimport { appointmentDetailsPanelAgent } from './appointment-details-panel.agent';\nimport { focusHeading, rescueFocus } from './appointment-details-panel.focus';\nimport { AppointmentHistoryTimeline } from './appointment-details-panel.history';\nimport { AppointmentIdentityStrip } from './appointment-details-panel.identity';\nimport {\n DetailsAppointmentCard,\n DetailsNotesCard,\n DetailsPatientCard,\n DetailsTreatmentsCard,\n} from './appointment-details-panel.sections';\nimport type {\n AppointmentDetailsChairLabel,\n AppointmentDetailsHistory,\n AppointmentDetailsNotesPreview,\n AppointmentDetailsOperatorLabel,\n AppointmentDetailsRead,\n AppointmentDetailsState,\n AppointmentDocumentKind,\n} from './appointment-details-panel.types';\n\n/* -------------------------------------------------------------------- */\n/* Public API */\n/* -------------------------------------------------------------------- */\n\nexport interface AppointmentDetailsPanelProps extends Omit<\n HTMLAttributes<HTMLDivElement>,\n 'children' | 'title' | 'onCopy'\n> {\n /** The read, or the shell state while there is none. Pair it with\n * `useAppointmentDetailsRead`, which keeps the latest selection. */\n state: AppointmentDetailsState;\n /** Retry from the error shell and from a retryable refusal. Without it,\n * no Retry button. */\n onRetry?: () => void;\n /** The appointment's patient id when the read carries no record: an id\n * without a record reads \"Patient record not loaded\", never \"no\n * patient\". Default `read.patient?.id`. */\n patientId?: string;\n /** The operator's label, resolved by the host from\n * `appointment.operatorId`. Absent = no operator row. */\n operator?: AppointmentDetailsOperatorLabel;\n /** The chair's label. Absent = no chair row. */\n chair?: AppointmentDetailsChairLabel;\n /** ISO 4217 code for the money chips, the paid-online row and the\n * treatment prices. Default 'EUR'. */\n currency?: string;\n /** The practice clock the patient's age is computed against. Default:\n * the real clock. */\n now?: Date | string;\n /** Locale for dates, times and amounts. Default: the active language. */\n locale?: string;\n /** Header title. Default \"Appointment details\". Ignored under `privacy`,\n * so a patient name can never reach the header. */\n title?: string;\n /** Privacy mode: the identity is masked; the photo, contact fields,\n * chips, description, notes, the booker's contact, the plan name and\n * `whatsappUrl` are withheld. Time, operator, chair, status, treatments\n * and History stay. A display mask on top of the host's server-side\n * masking, never instead of it. */\n privacy?: boolean;\n /** The grid's mask for this appointment; bullets without one. Read only\n * under `privacy`. */\n privacyTitle?: string;\n /** The user's map-link setting (platform `showPatientAddressMapLink`). */\n mapsLink?: boolean;\n /** The latest notes of this appointment's patient, and only theirs: set\n * `patientId` and notes for another patient show as loading. Without\n * it, no notes card. Pass it only when the appointment has a patient. */\n notesPreview?: AppointmentDetailsNotesPreview;\n /** Open the host's Notes tool, at one note when a note was clicked.\n * Without it, the preview opens nothing. */\n onOpenNotes?: (noteId?: string) => void;\n /** The appointment's history, read by the host once History opens.\n * Present = the user may read it, so the header offers History. Set its\n * `eventId`: entries for another occurrence show as loading. Wins over\n * `read.history`, the shortcut for a history sent with the read. */\n history?: AppointmentDetailsHistory;\n /** History opened, from its button or the agent: start the host's read.\n * Called on every opening. */\n onOpenHistory?: (eventId: string) => void;\n /** Withholds Edit, Move, Copy, Delete, the status change and the\n * description edit. Join, WhatsApp, Create task and the documents menu\n * are the host's to withhold. */\n readOnly?: boolean;\n /** Save a new status. Reject with a translated Error: the control keeps\n * the old status and shows the message. Absent = status read-only.\n * Every handler's last argument is the event id of the read it acted\n * on: write to that appointment, never to \"the current selection\". */\n onStatusChange?: (\n status: CalendarEventStatus,\n eventId: string,\n ) => Promise<void>;\n /** The statuses this user may set, in any order; the menu keeps the\n * platform's. Default: all six. The current status is always shown, and\n * disabled when not allowed. With no status to move to (an empty list,\n * or the current one alone) the status is shown read-only. */\n allowedStatuses?: readonly CalendarEventStatus[];\n /** Save a new description from the pencil's sub-view. Reject with a\n * translated Error: the sub-view stays open and shows it. Absent = the\n * description is read-only. */\n onDescriptionChange?: (description: string, eventId: string) => Promise<void>;\n /** Hand over to the host's editor. */\n onEdit?: (eventId: string) => void;\n /** Arm the host's move placement. */\n onMove?: (eventId: string) => void;\n /** Start the host's copy. With treatments on the read, a menu asks for\n * the appointment alone or with its treatments. */\n onCopy?: (withTreatments: boolean, eventId: string) => void;\n /** Start the host's delete. The host owns the confirmation, the series\n * scope and any care-plan clean-up. */\n onDelete?: (eventId: string) => void;\n /** Join the video visit. The host keeps the session code. */\n onJoinTelehealth?: (eventId: string) => void;\n /** The host's WhatsApp bridge. Wins over `whatsappUrl` as the one\n * button. Withhold it yourself where the user may not message the\n * patient. */\n onWhatsApp?: (eventId: string) => void;\n /** A host-composed WhatsApp link, opened in a new tab. Withheld under\n * `privacy`, because it carries the patient's number. */\n whatsappUrl?: string;\n /** Server-built link to the task page, opened in the same tab. */\n createTaskUrl?: string;\n /** The create-document kinds the user may use, and what each does. The\n * menu keeps the platform's order. */\n documents?: {\n kinds: readonly AppointmentDocumentKind[];\n onCreate: (kind: AppointmentDocumentKind, eventId: string) => void;\n };\n}\n\n/** Curated agent handle: ids and enums only, never patient data. */\nexport interface AppointmentDetailsPanelHandle {\n /** The occurrence on screen or being read, or the one a failed or\n * refused read was for when the state says; null otherwise. */\n getEventId: () => string | null;\n getLoadStatus: () => AppointmentDetailsState['status'];\n /** The status as last saved here or read; null for none, or no read. */\n getAppointmentStatus: () => CalendarEventStatus | null;\n /** The statuses `setAppointmentStatus` accepts now; [] when the status\n * cannot be changed. */\n getAllowedStatuses: () => CalendarEventStatus[];\n /** The footer's `data-action` values, in footer order. */\n getOfferedActions: () => string[];\n isHistoryOpen: () => boolean;\n isPrivacy: () => boolean;\n /** Throws when History is not offered. */\n openHistory: () => void;\n closeHistory: () => void;\n /** The footer control's own path: it shows the saving state and any\n * refusal. Rejects when the change is not offered, not allowed, or a\n * save is in flight, including one started in the same tick. */\n setAppointmentStatus: (status: CalendarEventStatus) => Promise<void>;\n /** Throws when no Retry is offered. */\n retry: () => void;\n}\n\n/* -------------------------------------------------------------------- */\n/* Styles */\n/* -------------------------------------------------------------------- */\n\nconst rootVariants = cva('ds:flex ds:h-full ds:min-h-0 ds:flex-col');\n\nconst footerVariants = cva(\n 'ds:flex ds:shrink-0 ds:items-center ds:justify-end ds:gap-[var(--spacing-xs)] ds:border-t ds:border-[color:var(--border)] ds:p-[var(--spacing-sm)]',\n);\n\n/* The read-only status takes focus only when the control it replaced\n held it, so it shows the kit's ring then. */\nconst statusShownVariants = cva(\n 'ds:shrink-0 ds:rounded-[var(--radius-md)] ds:focus-visible:outline-[length:var(--focus-ring-width)] ds:focus-visible:outline-solid ds:focus-visible:outline-ring ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)]',\n);\n\n/* Accessible themes keep the kit's raised target; default themes match\n the 32px status control through Button size=\"sm\". */\nconst ACCESSIBLE_TARGET =\n 'ds:[.theme-accessible_&]:[min-block-size:var(--min-target-size)]';\n/* The status control's className lands on its root div, not the trigger\n inside it, so target the direct child. */\nconst ACCESSIBLE_TARGET_STATUS_CONTROL =\n 'ds:[.theme-accessible_&>button]:[min-block-size:var(--min-target-size)]';\n/* ButtonGroup owns its More trigger and no prop reaches it. Reach it from\n outside by the Ellipsis glyph it renders, which does not translate. */\nconst ACCESSIBLE_TARGET_OVERFLOW_TRIGGER = [\n 'ds:[.theme-accessible_&_button:has(svg.lucide-ellipsis)]:[min-block-size:var(--min-target-size)]',\n 'ds:[.theme-accessible_&_button:has(svg.lucide-ellipsis)]:[min-inline-size:var(--min-target-size)]',\n].join(' ');\n\n/* How many term and detail rows the Appointment card shows while it loads:\n date, time, operator, chair. Uneven widths, so they read as facts. */\nconst SKELETON_FACT_WIDTHS = ['40%', '33%', '50%', '25%'] as const;\n\n/* The platform's create-menu order; the host's order and duplicate kinds\n do not change it. */\nconst DOCUMENT_KINDS: readonly AppointmentDocumentKind[] = [\n 'bill',\n 'folder',\n 'template',\n 'empty',\n 'identification',\n 'webcam',\n];\n\n/** Each create-menu item's glyph, per the icon map's duty for that kind. */\nconst DOCUMENT_ICON: Record<AppointmentDocumentKind, ReactNode> = {\n bill: <ReceiptEuro aria-hidden=\"true\" />,\n folder: <Folder aria-hidden=\"true\" />,\n template: <FileText aria-hidden=\"true\" />,\n empty: <File aria-hidden=\"true\" />,\n identification: <IdCard aria-hidden=\"true\" />,\n webcam: <Camera aria-hidden=\"true\" />,\n};\n\nconst key = (suffix: string): string => `calendarWorkspace.details.${suffix}`;\n\n/* -------------------------------------------------------------------- */\n/* Parts */\n/* -------------------------------------------------------------------- */\n\n/** One entry of a footer menu. A menu carries an icon on every item or on\n * none, so the icon is required. */\ntype MenuOption = ButtonGroupOverflowItem & { icon: ReactNode };\n\n/** A footer action that opens a menu. The label is `children` because\n * ButtonGroup keys its collapse stage off a string child, and the options\n * are `overflowItems` too, so More repeats them in a submenu when the\n * action folds away. */\nfunction MenuAction({\n children: label,\n startIcon,\n overflowItems: options,\n 'data-action': action,\n intent,\n background,\n size,\n hideLabel,\n}: {\n children: string;\n startIcon: ReactNode;\n overflowItems: readonly MenuOption[];\n /** On the trigger. ButtonGroup clears it on its measuring copies. */\n 'data-action'?: string;\n /** ButtonGroup: this action shows its own tooltip. */\n 'data-overflow-tip'?: false;\n intent?: 'outline' | 'primary';\n background?: 'transparent' | 'surface';\n size?: 'sm' | 'md' | 'lg';\n hideLabel?: boolean;\n}) {\n return (\n <DropdownMenu.Root>\n <Tooltip label={label} side=\"top\">\n <DropdownMenu.Trigger asChild>\n <Button\n intent={intent}\n background={background}\n size={size}\n data-action={action}\n className={ACCESSIBLE_TARGET}\n startIcon={startIcon}\n aria-haspopup=\"menu\"\n /* The chevron stays when the label folds: it says this opens a\n menu rather than acting. */\n endIcon={<ChevronDown aria-hidden=\"true\" />}\n >\n {hideLabel ? <span className=\"ds:sr-only\">{label}</span> : label}\n </Button>\n </DropdownMenu.Trigger>\n </Tooltip>\n <DropdownMenu.Content align=\"end\">\n {options.map((option) => (\n <DropdownMenu.Item\n key={option.label}\n data-action={option.action}\n startIcon={option.icon}\n onSelect={option.onSelect}\n >\n {option.label}\n </DropdownMenu.Item>\n ))}\n </DropdownMenu.Content>\n </DropdownMenu.Root>\n );\n}\n\n/** The body while the read is in flight: every card already in place,\n * holding a placeholder in the shape of what will land there, so nothing\n * jumps when the answer arrives. */\nfunction DetailsSkeleton() {\n const { t } = useTranslation();\n return (\n <>\n <span role=\"status\" className=\"ds:sr-only\">\n {t('common.loading')}\n </span>\n <div\n aria-hidden=\"true\"\n /* Cards keep their natural height; the column clips at the panel's\n edge, as the scrolling body it stands in for would. */\n className=\"ds:flex ds:min-h-0 ds:flex-1 ds:flex-col ds:gap-[var(--spacing-sm)] ds:overflow-hidden ds:p-[var(--spacing-md)] ds:[&>*]:shrink-0\"\n >\n <PatientSummaryCard\n name=\"\"\n loading\n surface=\"elevated\"\n density=\"compact\"\n />\n <SectionCard title={t(key('sectionAppointment'))} headingLevel={3}>\n <EditableDescription loading maxLines={2} />\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-sm)]\">\n {SKELETON_FACT_WIDTHS.map((width, index) => (\n <div\n key={width}\n className=\"ds:flex ds:items-center ds:gap-[var(--spacing-sm)]\"\n >\n <Skeleton\n variant=\"rounded\"\n stagger={index + 2}\n width=\"var(--spacing-md)\"\n height=\"var(--spacing-md)\"\n className=\"ds:shrink-0\"\n />\n <Skeleton\n variant=\"text\"\n size=\"sm\"\n stagger={index + 2}\n width={width}\n />\n </div>\n ))}\n </div>\n </SectionCard>\n <SectionCard title={t('notesPanel.title')} headingLevel={3}>\n <NoteTimeline notes={[]} loading loadingRows={2} />\n </SectionCard>\n <SectionCard title={t(key('sectionTreatments'))} headingLevel={3}>\n <TreatmentReceipt lines={[]} loading />\n </SectionCard>\n </div>\n <div\n aria-hidden=\"true\"\n className=\"ds:flex ds:shrink-0 ds:items-center ds:gap-[var(--spacing-sm)] ds:border-t ds:border-[color:var(--border)] ds:p-[var(--spacing-md)]\"\n >\n <Skeleton variant=\"rounded\" width=\"33%\" height=\"var(--spacing-xl)\" />\n <Skeleton\n variant=\"rounded\"\n stagger={1}\n height=\"var(--spacing-xl)\"\n className=\"ds:flex-1\"\n />\n </div>\n </>\n );\n}\n\n/** The History sub-view's body: a skeleton while the host reads, an error\n * with Retry, or the timeline. */\nfunction HistoryBody({\n history,\n locale,\n onRetry,\n}: {\n history: AppointmentDetailsHistory;\n locale: string;\n onRetry?: () => void;\n}) {\n const { t } = useTranslation();\n const status = history.status ?? (history.entries ? 'ready' : 'loading');\n const entries = status === 'error' ? undefined : history.entries;\n const loading = status === 'loading' || (status !== 'error' && !entries);\n /* One polite line for the life of the sub-view, outside any busy part:\n it says the read is under way, then how it settled. It starts empty,\n so its first words are announced too. An error has its own alert. */\n const [speaking, setSpeaking] = useState(false);\n useEffect(() => setSpeaking(true), []);\n let settled = '';\n if (loading) settled = t('common.loading');\n else if (entries)\n settled =\n entries.length === 0\n ? t(key('historyEmpty'))\n : t(key('historyLoaded'), { n: entries.length });\n let body: ReactNode;\n if (status === 'error')\n body = (\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-sm)]\">\n <Alert variant=\"error\">\n <Alert.Description>\n {history.message?.trim() || t('emptyState.error.description')}\n </Alert.Description>\n </Alert>\n {onRetry ? (\n <Button\n intent=\"outline\"\n data-action=\"retry-history\"\n onClick={() => onRetry()}\n >\n {t('emptyState.error.cta')}\n </Button>\n ) : null}\n </div>\n );\n else if (loading || !entries)\n body = (\n <div\n aria-hidden=\"true\"\n className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-md)]\"\n >\n {SKELETON_FACT_WIDTHS.slice(0, 3).map((width, index) => (\n <div\n key={width}\n className=\"ds:flex ds:items-start ds:gap-[var(--spacing-sm)]\"\n >\n <Skeleton\n variant=\"circular\"\n stagger={index}\n width=\"var(--spacing-xl)\"\n height=\"var(--spacing-xl)\"\n className=\"ds:shrink-0\"\n />\n <Skeleton\n variant=\"rounded\"\n stagger={index}\n width={width}\n height=\"var(--spacing-2xl)\"\n />\n </div>\n ))}\n </div>\n );\n else body = <AppointmentHistoryTimeline history={entries} locale={locale} />;\n return (\n <>\n <span role=\"status\" className=\"ds:sr-only\">\n {speaking ? settled : ''}\n </span>\n {body}\n </>\n );\n}\n\n/** What the agent handle reads from the appointment on screen. */\ninterface LiveDetails {\n status: CalendarEventStatus | null;\n allowed: CalendarEventStatus[];\n offered: string[];\n historyAvailable: boolean;\n historyOpen: boolean;\n openHistory: () => void;\n closeHistory: () => void;\n}\n\ninterface DetailsContentProps extends Omit<\n AppointmentDetailsPanelProps,\n 'state' | 'onRetry' | 'currency' | 'now' | 'locale' | 'title'\n> {\n read: AppointmentDetailsRead;\n refreshing: boolean;\n currency: string;\n now: Date | string;\n locale: string;\n shownTitle: string;\n /** The panel heading's id, for putting focus back in the panel. */\n headingId: string;\n /** Fade in: the read arrived where the skeleton or an error stood. */\n enter: boolean;\n live: MutableRefObject<LiveDetails | null>;\n statusControl: MutableRefObject<WorkflowStatusControlHandle | null>;\n}\n\n/** One appointment. Keyed by its event id, so the sub-views, the draft and\n * what was saved here reset for the next appointment. */\nfunction DetailsContent({\n read,\n refreshing,\n currency,\n now,\n locale,\n shownTitle,\n headingId,\n enter,\n live,\n statusControl,\n patientId = read.patient?.id,\n operator,\n chair,\n privacy = false,\n privacyTitle,\n mapsLink,\n notesPreview,\n onOpenNotes,\n history: hostHistory,\n onOpenHistory,\n readOnly = false,\n onStatusChange,\n allowedStatuses = APPOINTMENT_WORKFLOW_STATUSES,\n onDescriptionChange,\n onEdit,\n onMove,\n onCopy,\n onDelete,\n onJoinTelehealth,\n onWhatsApp,\n whatsappUrl: hostWhatsappUrl,\n createTaskUrl,\n documents,\n}: DetailsContentProps) {\n const { t } = useTranslation();\n const { eventId } = read;\n /* Decided once: a later render must not cut the fade short. */\n const [entering] = useState(enter);\n const card = { details: read, locale, currency };\n /* The host's own read wins; a history sent with the read is the\n shortcut. Either one offers History. A late answer for an earlier\n appointment shows as loading, never under this one. */\n const history: AppointmentDetailsHistory | undefined = hostHistory\n ? hostHistory.eventId !== undefined && hostHistory.eventId !== eventId\n ? { status: 'loading' }\n : hostHistory\n : read.history\n ? { entries: read.history }\n : undefined;\n /* Notes for another patient never show under this appointment: they\n read as loading until the host catches up, and without a patient\n there is no card. */\n const notesForPatient =\n notesPreview?.patientId === undefined ||\n notesPreview.patientId === patientId;\n const notes: AppointmentDetailsNotesPreview | undefined = !notesPreview\n ? undefined\n : notesForPatient\n ? notesPreview\n : patientId\n ? { notes: [], status: 'loading', total: null }\n : undefined;\n const editorOffered = Boolean(onDescriptionChange) && !readOnly && !privacy;\n /* Both sub-views stay mounted and slide over the body; PanelSubview owns\n the focus in and back. A sub-view whose seam is withdrawn is shown\n closed at once, and its state is reset below. */\n const [historyOpen, setHistoryOpen] = useState(false);\n const [editingDescription, setEditingDescription] = useState(false);\n const historyShown = historyOpen && history !== undefined;\n const editorShown = editingDescription && editorOffered;\n const openHistory = () => {\n if (historyShown || !history) return;\n setHistoryOpen(true);\n onOpenHistory?.(eventId);\n };\n /* A refresh or a prop change can withdraw a sub-view while it is open:\n close it for good, so it never slides back by itself, and put focus\n back in the panel rather than on the page. */\n const shownBefore = useRef({ history: false, editor: false });\n useIsomorphicLayoutEffect(() => {\n const before = shownBefore.current;\n shownBefore.current = { history: historyShown, editor: editorShown };\n const lostHistory = before.history && history === undefined;\n const lostEditor = before.editor && !editorOffered;\n if (lostHistory) setHistoryOpen(false);\n if (lostEditor) setEditingDescription(false);\n if (lostHistory || lostEditor) focusHeading(headingId);\n });\n /* Retry in the History sub-view leaves with the error: the sub-view keeps\n the focus until the read settles. */\n const historyRef = useRef<HTMLElement>(null);\n const historyRetried = useRef(false);\n const historyStatus =\n history?.status ?? (history?.entries ? 'ready' : 'loading');\n useIsomorphicLayoutEffect(() => {\n if (!historyRetried.current) return;\n if (historyStatus !== 'loading') historyRetried.current = false;\n rescueFocus(historyRef.current);\n }, [historyStatus]);\n /* The description as last saved here; the read is the starting point. */\n const [description, setDescription] = useState(read.appointment.name ?? '');\n /* A fresh read from the host wins over what was saved here. */\n useEffect(() => {\n setDescription(read.appointment.name ?? '');\n }, [read.appointment.name]);\n const [descriptionDraft, setDescriptionDraft] = useState('');\n const [descriptionSaving, setDescriptionSaving] = useState(false);\n const [descriptionError, setDescriptionError] = useState<string>();\n const descriptionFieldRef = useRef<HTMLTextAreaElement>(null);\n /* Filled when the sub-view opens, never by remounting it open. */\n useEffect(() => {\n if (!editingDescription) return;\n setDescriptionDraft(description);\n setDescriptionError(undefined);\n // eslint-disable-next-line react-hooks/exhaustive-deps -- seed once per opening\n }, [editingDescription]);\n const saveDescription = async (): Promise<void> => {\n if (!onDescriptionChange) return;\n const next = descriptionDraft.trim();\n setDescriptionSaving(true);\n setDescriptionError(undefined);\n try {\n await onDescriptionChange(next, eventId);\n setDescription(next);\n setEditingDescription(false);\n } catch (error) {\n setDescriptionError(\n getErrorMessage(error, t(key('descriptionSaveFailed'))),\n );\n } finally {\n setDescriptionSaving(false);\n }\n };\n\n /* The status as last saved here; the read is the starting point. */\n const [status, setStatus] = useState(read.appointment.status);\n useEffect(() => {\n setStatus(read.appointment.status);\n }, [read.appointment.status]);\n /* A re-read that lands wins too, even when it repeats what the panel\n read before the save: someone may have changed it back. */\n const wasRefreshing = useRef(refreshing);\n useIsomorphicLayoutEffect(() => {\n const landed = wasRefreshing.current && !refreshing;\n wasRefreshing.current = refreshing;\n if (!landed) return;\n setStatus(read.appointment.status);\n setDescription(read.appointment.name ?? '');\n }, [refreshing]);\n /* In the platform's order, whatever the host's; unknowns dropped. */\n const permitted = APPOINTMENT_WORKFLOW_STATUSES.filter((option) =>\n allowedStatuses.includes(option),\n );\n const appointmentStatus = useAppointmentWorkflowStatus(status, {\n statuses: permitted,\n /* Shown so the control can say it, but not a choice. */\n disabledStatuses: status && !permitted.includes(status) ? [status] : [],\n });\n /* A control with nothing to move to would only refuse: show the status. */\n const statusEditable =\n Boolean(onStatusChange) &&\n !readOnly &&\n permitted.some((option) => option !== status);\n /* WorkflowStatusControl shows the saving state and the refusal. A\n refusal without a message keeps the panel's own wording. */\n const changeStatus = async (next: string): Promise<void> => {\n if (!onStatusChange || !isCalendarEventStatus(next)) return;\n try {\n await onStatusChange(next, eventId);\n } catch (error) {\n throw new Error(getErrorMessage(error, t(key('statusSaveFailed'))));\n }\n setStatus(next);\n };\n\n /* The composed link carries the patient's number: withheld under\n privacy. */\n const whatsappUrl = privacy ? undefined : hostWhatsappUrl;\n const documentKinds = DOCUMENT_KINDS.filter((kind) =>\n documents?.kinds.includes(kind),\n );\n const copyMenu = (read.care?.lines.length ?? 0) > 0;\n const assigned = patientId !== undefined && patientId !== '';\n\n const statusLabel = t(key('status'));\n const statusName = `${statusLabel}: ${appointmentStatus.option.label}`;\n const statusShownRef = useRef<HTMLDivElement>(null);\n /* A save or a re-read can leave nothing to move to: the control gives\n way to the read-only status, which takes the focus the control held\n and says the outcome. */\n const statusWasEditable = useRef(statusEditable);\n useIsomorphicLayoutEffect(() => {\n const lost = statusWasEditable.current && !statusEditable;\n statusWasEditable.current = statusEditable;\n if (!lost) return;\n if (statusShownRef.current) rescueFocus(statusShownRef.current);\n else focusHeading(headingId);\n });\n const statusNode = statusEditable ? (\n <WorkflowStatusControl\n ref={statusControl}\n value={appointmentStatus.value}\n options={appointmentStatus.options}\n size=\"sm\"\n workflowLabel={statusLabel}\n /* The trigger carries the actions' painted surface and, in the\n accessible themes, their raised target too. */\n className={`ds:[&>button]:bg-[color:var(--background)] ${ACCESSIBLE_TARGET_STATUS_CONTROL}`}\n aria-label={statusName}\n onValueChange={changeStatus}\n />\n ) : status ? (\n /* Named as the control is, \"Status: Confirmed\": the small display\n prints the value alone. */\n <div\n ref={statusShownRef}\n role=\"group\"\n aria-label={statusName}\n tabIndex={-1}\n data-status-display=\"\"\n className={statusShownVariants()}\n >\n <WorkflowStatusDisplay\n value={appointmentStatus.value}\n size=\"sm\"\n workflowLabel={statusLabel}\n option={appointmentStatus.option}\n />\n </div>\n ) : null;\n\n /* The footer's actions, in order, each under its data-action. */\n const entries: Array<[string, ReactNode]> = [];\n if (onJoinTelehealth)\n entries.push([\n 'join-telehealth',\n <Button\n key=\"join\"\n intent=\"primary\"\n data-action=\"join-telehealth\"\n className={ACCESSIBLE_TARGET}\n startIcon={<Video aria-hidden=\"true\" />}\n onClick={() => onJoinTelehealth(eventId)}\n >\n {t(key('joinTelehealth'))}\n </Button>,\n ]);\n if (!readOnly && onEdit)\n entries.push([\n 'edit-appointment',\n <Button\n key=\"edit\"\n data-action=\"edit-appointment\"\n className={ACCESSIBLE_TARGET}\n startIcon={<Pencil aria-hidden=\"true\" />}\n onClick={() => onEdit(eventId)}\n >\n {t('calendarWorkspace.editor.editTitle')}\n </Button>,\n ]);\n if (!readOnly && onMove)\n entries.push([\n 'move-appointment',\n <Button\n key=\"move\"\n data-action=\"move-appointment\"\n className={ACCESSIBLE_TARGET}\n startIcon={<Move aria-hidden=\"true\" />}\n onClick={() => onMove(eventId)}\n >\n {t(key('move'))}\n </Button>,\n ]);\n if (!readOnly && onCopy)\n entries.push([\n 'copy-appointment',\n copyMenu ? (\n <MenuAction\n key=\"copy\"\n data-action=\"copy-appointment\"\n data-overflow-tip={false}\n startIcon={<ClipboardPaste aria-hidden=\"true\" />}\n overflowItems={[\n {\n label: t('calendarWorkspace.editor.duplicateAppointmentOnly'),\n icon: <Copy aria-hidden=\"true\" />,\n action: 'copy-appointment-only',\n onSelect: () => onCopy(false, eventId),\n },\n {\n label: t('calendarWorkspace.editor.duplicateWithTreatments'),\n icon: <ClipboardList aria-hidden=\"true\" />,\n action: 'copy-appointment-with-treatments',\n onSelect: () => onCopy(true, eventId),\n },\n ]}\n >\n {t(key('copy'))}\n </MenuAction>\n ) : (\n <Button\n key=\"copy\"\n data-action=\"copy-appointment\"\n className={ACCESSIBLE_TARGET}\n startIcon={<ClipboardPaste aria-hidden=\"true\" />}\n onClick={() => onCopy(false, eventId)}\n >\n {t(key('copy'))}\n </Button>\n ),\n ]);\n if (documents && documentKinds.length > 0)\n entries.push([\n 'open-create-document',\n <MenuAction\n key=\"documents\"\n data-action=\"open-create-document\"\n data-overflow-tip={false}\n startIcon={<Plus aria-hidden=\"true\" />}\n overflowItems={documentKinds.map((kind) => ({\n label: t(key(`documents.${kind}`)),\n icon: DOCUMENT_ICON[kind],\n action: `create-document-${kind}`,\n onSelect: () => documents.onCreate(kind, eventId),\n }))}\n >\n {t(key('documents.label'))}\n </MenuAction>,\n ]);\n if (onWhatsApp)\n entries.push([\n 'open-whatsapp',\n <Button\n key=\"whatsapp\"\n data-action=\"open-whatsapp\"\n className={ACCESSIBLE_TARGET}\n startIcon={<WhatsAppGlyph aria-hidden=\"true\" />}\n onClick={() => onWhatsApp(eventId)}\n >\n {t(key('remindWhatsApp'))}\n </Button>,\n ]);\n else if (whatsappUrl)\n entries.push([\n 'open-whatsapp',\n <Button\n key=\"whatsapp\"\n asChild\n /* A link folds to its icon, then into More, which follows it. */\n data-action=\"open-whatsapp\"\n className={ACCESSIBLE_TARGET}\n startIcon={<WhatsAppGlyph aria-hidden=\"true\" />}\n >\n <a href={whatsappUrl} target=\"_blank\" rel=\"noopener noreferrer\">\n {t(key('remindWhatsApp'))}\n </a>\n </Button>,\n ]);\n if (createTaskUrl)\n entries.push([\n 'create-task',\n <Button\n key=\"task\"\n asChild\n data-action=\"create-task\"\n className={ACCESSIBLE_TARGET}\n startIcon={<SquareCheckBig aria-hidden=\"true\" />}\n >\n <a href={createTaskUrl}>{t(key('createTask'))}</a>\n </Button>,\n ]);\n /* Last, so it is the first to fold into More at a narrow width. */\n if (!readOnly && onDelete)\n entries.push([\n 'delete-appointment',\n <Button\n key=\"delete\"\n intent=\"destructiveOutline\"\n data-action=\"delete-appointment\"\n className={ACCESSIBLE_TARGET}\n startIcon={<Trash2 aria-hidden=\"true\" />}\n onClick={() => onDelete(eventId)}\n >\n {t('calendarWorkspace.editor.delete')}\n </Button>,\n ]);\n const actions = entries.map(([, node]) => node);\n\n live.current = {\n status: status ?? null,\n allowed: statusEditable ? permitted : [],\n offered: entries.map(([id]) => id),\n historyAvailable: history !== undefined,\n historyOpen: historyShown,\n openHistory,\n closeHistory: () => setHistoryOpen(false),\n };\n\n const backLabel = t(key('historyBack'));\n return (\n <div\n className={`ds:flex ds:min-h-0 ds:flex-1 ds:flex-col ${entering ? CONTENT_ENTER_CLASS : ''}`}\n >\n <PanelSubview.Host>\n <PanelHeader\n title={shownTitle}\n headingId={headingId}\n icon={<CalendarClock aria-hidden=\"true\" />}\n sticky\n divider\n actions={\n history ? (\n <IconButton\n size=\"sm\"\n intent=\"ghost\"\n icon={<HistoryIcon aria-hidden=\"true\" />}\n aria-label={t(key('historyAction'))}\n tooltip={t(key('historyAction'))}\n data-action=\"open-history\"\n onClick={openHistory}\n />\n ) : undefined\n }\n />\n <div\n /* eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex -- the body scrolls inside the rail; axe scrollable-region-focusable needs the tab stop */\n tabIndex={0}\n aria-busy={refreshing || undefined}\n className=\"ds:[min-block-size:0] ds:flex-1 ds:overflow-y-auto\"\n >\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-sm)] ds:p-[var(--spacing-md)]\">\n {privacy ? (\n <PrivacyIdentityCard mask={privacyTitle} />\n ) : read.patient ? (\n <DetailsPatientCard {...card} now={now} mapsLink={mapsLink} />\n ) : (\n /* No patient card to carry the identity: a patient-less, an\n unassigned or an unresolved booking keeps the strip. */\n <AppointmentIdentityStrip\n name={\n read.appointment.title.trim()\n ? read.appointment.title\n : t(key('patientNotLoaded'))\n }\n unresolved={assigned}\n status={status}\n flags={{\n isTelehealth: read.appointment.isTelehealth,\n isBookedOnline: read.appointment.bookedOnline,\n isRecurring: read.appointment.recurrence !== undefined,\n hasUnassignedPatient:\n read.appointment.bookedOnline && !assigned,\n hasHighlightedAnamnesis: false,\n hasBillableAmount: (read.money?.billableAmount ?? 0) > 0,\n }}\n locale={locale}\n />\n )}\n <DetailsAppointmentCard\n {...card}\n operator={operator}\n chair={chair}\n privacy={privacy}\n description={\n /* Not keyed on the text: the pencil must survive a save,\n so the sub-view can hand focus back to it. An empty\n read-only description prints nothing. Privacy hides the\n text and the pencil. */\n privacy ? (\n description ? (\n <PrivacyHiddenLine block=\"description\" />\n ) : undefined\n ) : description || (onDescriptionChange && !readOnly) ? (\n <EditableDescription\n data-block=\"description\"\n role=\"group\"\n aria-label={t('calendarWorkspace.editor.description')}\n value={description}\n editLabel={t(key('editDescription'))}\n onEdit={\n onDescriptionChange && !readOnly\n ? () => setEditingDescription(true)\n : undefined\n }\n />\n ) : undefined\n }\n />\n {notes && privacy ? (\n <SectionCard\n data-card=\"notes\"\n title={t('notesPanel.title')}\n headingLevel={3}\n >\n <PrivacyHiddenLine />\n </SectionCard>\n ) : notes ? (\n <DetailsNotesCard\n preview={notes}\n onOpenNotes={notesForPatient ? onOpenNotes : undefined}\n locale={locale}\n />\n ) : null}\n <DetailsTreatmentsCard {...card} privacy={privacy} />\n </div>\n </div>\n {statusNode || actions.length > 0 ? (\n /* The body scrolls; the status and the actions stay put. The\n status keeps its own segment and never folds. The actions fold\n to icons, then into More, never onto a second line. */\n <div className={footerVariants()}>\n {statusNode}\n {actions.length > 0 ? (\n <ButtonGroup\n label={t(key('actionsLabel'))}\n overflow=\"menu\"\n collapseToIcons\n background=\"surface\"\n size=\"sm\"\n className={`ds:min-w-0 ds:flex-1 ds:text-end ${ACCESSIBLE_TARGET_OVERFLOW_TRIGGER}`}\n >\n {actions}\n </ButtonGroup>\n ) : null}\n </div>\n ) : null}\n {history ? (\n <PanelSubview\n ref={historyRef}\n open={historyShown}\n icon={<HistoryIcon aria-hidden=\"true\" />}\n title={t(key('historyTitle'))}\n backLabel={backLabel}\n headingLevel={3}\n onBack={() => setHistoryOpen(false)}\n data-details-subview=\"history\"\n >\n <div className=\"ds:p-[var(--spacing-md)]\">\n <HistoryBody\n history={history}\n locale={locale}\n onRetry={\n history.onRetry\n ? () => {\n historyRetried.current = true;\n history.onRetry?.();\n }\n : undefined\n }\n />\n </div>\n </PanelSubview>\n ) : null}\n {editorOffered ? (\n <PanelSubview\n open={editorShown}\n icon={<Pencil aria-hidden=\"true\" />}\n title={t(key('editDescription'))}\n backLabel={backLabel}\n headingLevel={3}\n initialFocusRef={descriptionFieldRef}\n /* Back and Escape wait for a save in flight, as Cancel does: a\n late answer must not close an editor the user reopened. */\n onBack={() => {\n if (!descriptionSaving) setEditingDescription(false);\n }}\n data-details-subview=\"description\"\n footer={\n <>\n <Button\n intent=\"secondary\"\n disabled={descriptionSaving}\n onClick={() => setEditingDescription(false)}\n >\n {t(key('noteCancel'))}\n </Button>\n <Button\n intent=\"primary\"\n data-action=\"save-description\"\n loading={descriptionSaving}\n onClick={() => void saveDescription()}\n >\n {t(key('descriptionSave'))}\n </Button>\n </>\n }\n >\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-sm)] ds:p-[var(--spacing-md)]\">\n {descriptionError ? (\n <Alert variant=\"error\">\n <Alert.Description>{descriptionError}</Alert.Description>\n </Alert>\n ) : null}\n <TextArea\n ref={descriptionFieldRef}\n value={descriptionDraft}\n minRows={6}\n autoResize\n aria-label={t('calendarWorkspace.editor.description')}\n onChange={(event) => setDescriptionDraft(event.target.value)}\n />\n </div>\n </PanelSubview>\n ) : null}\n </PanelSubview.Host>\n </div>\n );\n}\n\n/* -------------------------------------------------------------------- */\n/* Component */\n/* -------------------------------------------------------------------- */\n\n/**\n * The appointment details panel: a props-driven rail panel for one\n * occurrence. Mount it as a `fill` tool in ControlRoomRail, which adds its\n * favourite and close controls to the panel's own header.\n */\nexport const AppointmentDetailsPanel = forwardRef<\n HTMLDivElement,\n AppointmentDetailsPanelProps\n>(function AppointmentDetailsPanel(\n {\n state,\n onRetry,\n patientId,\n operator,\n chair,\n currency = 'EUR',\n now,\n locale,\n title,\n privacy = false,\n privacyTitle,\n mapsLink,\n notesPreview,\n onOpenNotes,\n history,\n onOpenHistory,\n readOnly = false,\n onStatusChange,\n allowedStatuses,\n onDescriptionChange,\n onEdit,\n onMove,\n onCopy,\n onDelete,\n onJoinTelehealth,\n onWhatsApp,\n whatsappUrl,\n createTaskUrl,\n documents,\n id,\n className,\n ...rest\n },\n ref,\n) {\n const { t, i18n: runtimeI18n } = useTranslation();\n const reactId = useId();\n const instanceId = id ?? reactId;\n const headingId = useId();\n const shownLocale = locale ?? runtimeI18n.language;\n /* A host title never reaches the header under privacy: it may be a\n patient's name. */\n const shownTitle = !privacy && title?.trim() ? title : t(key('region'));\n const read = state.status === 'ready' ? state.read : undefined;\n /* An error or a refusal names the occurrence it answers when it can. */\n const eventId = state.status === 'ready' ? state.read.eventId : state.eventId;\n /* The read fades in only where this panel showed a shell before it. A\n panel mounted with its read, or re-reading one, does not flash. */\n const previousStatus = useRef<AppointmentDetailsState['status'] | undefined>(\n undefined,\n );\n const enter =\n previousStatus.current !== undefined && previousStatus.current !== 'ready';\n useEffect(() => {\n previousStatus.current = state.status;\n }, [state.status]);\n const retryOffered =\n Boolean(onRetry) &&\n (state.status === 'error' ||\n (state.status === 'refused' && state.retryable === true));\n /* A swap between the read and the skeleton, the error or the refusal\n mounts a new tree, and whatever held focus leaves with the old one.\n Whether the panel held it is read now, while that node is still here. */\n const rootRef = useRef<HTMLDivElement>(null);\n const setRoot = useMemo(() => composeRefs(ref, rootRef), [ref]);\n const heldFocus = useRef(false);\n if (typeof document !== 'undefined')\n heldFocus.current =\n rootRef.current?.contains(document.activeElement) ?? false;\n const shape = read ? `ready:${read.eventId}` : state.status;\n /* After Retry, and after any swap while the panel held focus, the\n heading takes it: the new tree has no control where focus was. After\n Retry it keeps it until the read settles. */\n const retried = useRef(false);\n useIsomorphicLayoutEffect(() => {\n if (retried.current) {\n if (state.status !== 'loading') retried.current = false;\n focusHeading(headingId);\n } else if (heldFocus.current) focusHeading(headingId);\n }, [shape, headingId]);\n\n /* ---- Agent handle ------------------------------------------------ */\n const live = useRef<LiveDetails | null>(null);\n if (!read) live.current = null;\n const statusControl = useRef<WorkflowStatusControlHandle | null>(null);\n const snapshot = useRef({ state, eventId, privacy, retryOffered, onRetry });\n snapshot.current = { state, eventId, privacy, retryOffered, onRetry };\n const handle = useMemo<AppointmentDetailsPanelHandle>(\n () => ({\n getEventId: () => snapshot.current.eventId ?? null,\n getLoadStatus: () => snapshot.current.state.status,\n getAppointmentStatus: () => live.current?.status ?? null,\n getAllowedStatuses: () => [...(live.current?.allowed ?? [])],\n getOfferedActions: () => [...(live.current?.offered ?? [])],\n isHistoryOpen: () => live.current?.historyOpen ?? false,\n isPrivacy: () => snapshot.current.privacy,\n openHistory: () => {\n if (!live.current?.historyAvailable)\n throw new Error('AppointmentDetailsPanel: History is not offered.');\n live.current.openHistory();\n },\n closeHistory: () => {\n live.current?.closeHistory();\n },\n setAppointmentStatus: (next) => {\n const details = live.current;\n const control = statusControl.current;\n if (!details || !control || details.allowed.length === 0)\n return handledRejection(\n new Error('AppointmentDetailsPanel: the status is read-only.'),\n );\n if (next === details.status) return Promise.resolve();\n if (!details.allowed.includes(next))\n return handledRejection(\n new Error(`AppointmentDetailsPanel: \"${next}\" is not allowed.`),\n );\n const inFlight = () =>\n handledRejection(\n new Error('AppointmentDetailsPanel: a status save is in flight.'),\n );\n if (control.getIsSaving()) return inFlight();\n /* The control declines a change while a save is in flight, even\n one started in this same tick, before its handle re-renders. */\n const saved = control.setValue(next);\n return saved === undefined ? inFlight() : saved;\n },\n retry: () => {\n const { retryOffered: offered, onRetry: host } = snapshot.current;\n if (!offered || !host)\n throw new Error('AppointmentDetailsPanel: Retry is not offered.');\n host();\n },\n }),\n [],\n );\n useAgentRegistration(appointmentDetailsPanelAgent, handle, instanceId);\n\n const header = (\n <PanelHeader\n title={shownTitle}\n headingId={headingId}\n icon={<CalendarClock aria-hidden=\"true\" />}\n sticky\n divider\n />\n );\n let body: ReactNode;\n if (state.status === 'ready') {\n body = (\n <DetailsContent\n key={state.read.eventId}\n read={state.read}\n refreshing={state.refreshing === true}\n currency={currency}\n now={now ?? new Date()}\n locale={shownLocale}\n shownTitle={shownTitle}\n headingId={headingId}\n enter={enter}\n live={live}\n statusControl={statusControl}\n patientId={patientId}\n operator={operator}\n chair={chair}\n privacy={privacy}\n privacyTitle={privacyTitle}\n mapsLink={mapsLink}\n notesPreview={notesPreview}\n onOpenNotes={onOpenNotes}\n history={history}\n onOpenHistory={onOpenHistory}\n readOnly={readOnly}\n onStatusChange={onStatusChange}\n allowedStatuses={allowedStatuses}\n onDescriptionChange={onDescriptionChange}\n onEdit={onEdit}\n onMove={onMove}\n onCopy={onCopy}\n onDelete={onDelete}\n onJoinTelehealth={onJoinTelehealth}\n onWhatsApp={onWhatsApp}\n whatsappUrl={whatsappUrl}\n createTaskUrl={createTaskUrl}\n documents={documents}\n />\n );\n } else if (state.status === 'loading') {\n body = (\n <>\n {header}\n <DetailsSkeleton />\n </>\n );\n } else {\n body = (\n <>\n {header}\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-sm)] ds:p-[var(--spacing-md)]\">\n <Alert variant={state.status === 'error' ? 'error' : 'warning'}>\n <Alert.Description>\n {state.status === 'error'\n ? state.message?.trim() || t('emptyState.error.description')\n : state.reason}\n </Alert.Description>\n </Alert>\n {retryOffered ? (\n <Button\n intent=\"outline\"\n data-action=\"retry-load\"\n onClick={() => {\n retried.current = true;\n onRetry?.();\n }}\n >\n {t('emptyState.error.cta')}\n </Button>\n ) : null}\n </div>\n </>\n );\n }\n\n return (\n <div\n ref={setRoot}\n id={id}\n data-component=\"appointment-details-panel\"\n data-component-id={instanceId}\n data-event-id={eventId}\n data-status={state.status}\n aria-busy={state.status === 'loading' || undefined}\n className={rootVariants({ className })}\n {...rest}\n >\n {body}\n </div>\n );\n});\nAppointmentDetailsPanel.displayName = 'AppointmentDetailsPanel';\n","import { useCallback, useEffect, useRef, useState } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { useIsomorphicLayoutEffect } from '../../hooks/use-isomorphic-layout-effect';\nimport { getErrorMessage } from '../_shared/get-error-message';\nimport { parseAppointmentStartIso } from '../_shared/appointment-format';\nimport type {\n AppointmentDetailsRead,\n AppointmentDetailsState,\n UseAppointmentDetailsReadOptions,\n} from './appointment-details-panel.types';\n\ntype Settled<T extends AppointmentDetailsRead> = Exclude<\n AppointmentDetailsState<T>,\n { status: 'loading' }\n>;\n\n/** The last answer, and the request it answered. */\ninterface Answer<T extends AppointmentDetailsRead> {\n eventId: string;\n /** Which selection of `eventId` asked: coming back to an id is a new one. */\n selection: number;\n request: string;\n value: Settled<T>;\n}\n\nexport interface AppointmentDetailsReadResult<\n T extends AppointmentDetailsRead = AppointmentDetailsRead,\n> {\n /** Pass as AppointmentDetailsPanel `state`. Null while `eventId` is null:\n * there is no selection, so render no panel. */\n state: AppointmentDetailsState<T> | null;\n /** Pass as AppointmentDetailsPanel `onRetry`: reads the same occurrence\n * again. */\n retry: () => void;\n}\n\n/**\n * Reads one occurrence so that the latest selection always wins. A new\n * `eventId` aborts the read in flight and shows the skeleton, even for an\n * id shown before; a late answer for an earlier request is dropped. The\n * error and refused states carry the `eventId` they answer. An answer for\n * another appointment, or with an unreadable `startIso`, becomes an error,\n * so the panel never shows one patient's name with another's appointment.\n * A new `reloadKey` reads\n * the same occurrence again while the current read stays on screen\n * (`refreshing`); if that read fails, the panel shows the error rather than\n * going back to the older read. A null `eventId` reads nothing and returns\n * a null `state`.\n *\n * The latest `load` is the one called, so an inline loader never loops:\n * only `eventId`, `reloadKey` and `retry` start a read.\n */\nexport function useAppointmentDetailsRead<\n T extends AppointmentDetailsRead = AppointmentDetailsRead,\n>(\n options: UseAppointmentDetailsReadOptions<T> & { eventId: string },\n): AppointmentDetailsReadResult<T> & { state: AppointmentDetailsState<T> };\nexport function useAppointmentDetailsRead<\n T extends AppointmentDetailsRead = AppointmentDetailsRead,\n>(\n options: UseAppointmentDetailsReadOptions<T>,\n): AppointmentDetailsReadResult<T>;\nexport function useAppointmentDetailsRead<\n T extends AppointmentDetailsRead = AppointmentDetailsRead,\n>({\n eventId,\n load,\n reloadKey,\n}: UseAppointmentDetailsReadOptions<T>): AppointmentDetailsReadResult<T> {\n const { t } = useTranslation();\n const failure = useRef('');\n failure.current = t('emptyState.error.description');\n /* Held, not a dependency: a host's inline loader must not read again on\n every render. */\n const loadRef = useRef(load);\n useIsomorphicLayoutEffect(() => {\n loadRef.current = load;\n });\n const [retries, setRetries] = useState(0);\n const [answer, setAnswer] = useState<Answer<T>>();\n const request = JSON.stringify([reloadKey ?? null, retries]);\n /* Counts selections: going to B and back to A before B answers reads A\n afresh behind the skeleton, never A's older answer as final. */\n const [selection, setSelection] = useState({ eventId, count: 0 });\n const selectionCount =\n selection.eventId === eventId ? selection.count : selection.count + 1;\n if (selection.eventId !== eventId)\n setSelection({ eventId, count: selectionCount });\n\n useEffect(() => {\n if (eventId === null) {\n /* A cleared selection forgets its answer: selecting the same\n appointment again starts from the skeleton. */\n setAnswer(undefined);\n return undefined;\n }\n const controller = new AbortController();\n const settle = (value: Settled<T>) => {\n if (!controller.signal.aborted)\n setAnswer({ eventId, selection: selectionCount, request, value });\n };\n Promise.resolve()\n .then(() => loadRef.current(eventId, { signal: controller.signal }))\n .then((value) => {\n if (value.status !== 'ready') {\n settle({\n status: 'refused',\n eventId,\n reason: value.reason,\n retryable: value.retryable,\n });\n return;\n }\n /* Never another appointment, and never a start the panel cannot\n place in the day. */\n if (\n value.details?.eventId !== eventId ||\n !parseAppointmentStartIso(value.details.appointment?.startIso)\n )\n throw new Error(failure.current);\n settle({ status: 'ready', read: value.details });\n })\n .catch((error: unknown) => {\n settle({\n status: 'error',\n eventId,\n message: getErrorMessage(error, failure.current),\n });\n });\n return () => controller.abort();\n }, [eventId, selectionCount, request]);\n\n const retry = useCallback(() => setRetries((previous) => previous + 1), []);\n\n if (eventId === null) return { state: null, retry };\n const current =\n answer?.eventId === eventId && answer.selection === selectionCount\n ? answer\n : undefined;\n let state: AppointmentDetailsState<T> = { status: 'loading', eventId };\n if (current?.request === request) state = current.value;\n else if (current?.value.status === 'ready')\n /* A re-read of the same occurrence keeps what is on screen. */\n state = { status: 'ready', read: current.value.read, refreshing: true };\n return { state, retry };\n}\n"],"names":["__iconNode","Cake","createLucideIcon","ClipboardPaste","IdCard","Move","MORE_TRIGGER","appointmentDetailsPanelAgent","handle","args","rescueFocus","target","active","focusHeading","headingId","heading","parseEventDate","value","formatDay","locale","formatTimeRange","start","end","s","e","fmt","DETAIL_STAMP_FORMAT","ageInYears","dobIso","on","dob","at","age","monthDelta","START_ISO","parseAppointmentStartIso","startIso","match","year","month","day","hours","minutes","seconds","monthEnd","sortHistoryNewestFirst","entries","entry","parsed","a","b","RECURRENCE_LABEL_KEY","patientPhones","patient","patientAddressLine","part","patientAddressLabel","patientMapsUrl","query","detailKey","suffix","AppointmentHistoryTimeline","history","t","runtimeI18n","useTranslation","optionFor","useAppointmentWorkflowStatus","shownLocale","formatStamp","iso","describe","jsx","CalendarPlus","Clock","StatusGlyph","APPOINTMENT_STATE_WORKFLOW","fromOption","toOption","transitionLabel","jsxs","WorkflowStatusDisplay","ArrowRight","Pencil","field","ConfirmedGlyph","Trash2","EmptyState","Timeline","shape","CalendarClock","APPOINTMENT_STATUS_BADGE_VARIANT","IndicatorChips","event","key","chips","Globe","TriangleAlert","HeartPulse","Euro","Video","Repeat","chip","Badge","AppointmentIdentityStrip","name","avatarSrc","unresolved","status","flags","onOpenPatient","highlightedAnamnesisCount","expiredAnamnesisCount","anamnesisAnswers","statusOption","highlighted","expired","Avatar","Button","Alert","line","answer","InfoHoverBody","eyebrow","facts","Fragment","HoverCard","fact","index","TRIGGER","InfoHover","id","children","MUTED","telLink","number","mailLink","email","formatMoney","amount","currency","Rows","rows","shown","DescriptionList","DetailsPatientCard","details","now","mapsLink","signing","money","booking","signingShown","pending","signingFacts","answerFacts","addressLabel","fields","phone","hasLabel","Smartphone","Phone","Mail","MapPin","unpaid","billable","paidOnline","state","headingKey","factKey","label","TransactionChip","PatientSummaryCard","DetailsAppointmentCard","operator","chair","description","privacy","appointment","editor","timed","recurrence","frequencyKey","frequency","bookingRows","Timestamp","shownBookingRows","row","hasBooking","SectionCard","CalendarDays","Hourglass","Armchair","Building2","DetailsTreatmentsCard","care","plan","ClipboardList","TreatmentReceipt","entryId","_careId","NOTES_PREVIEWED","DetailsNotesCard","preview","onOpenNotes","useId","retried","useRef","useIsomorphicLayoutEffect","count","more","openLabel","IconButton","NotebookPen","Counter","_a","NoteTimeline","rootVariants","cva","footerVariants","statusShownVariants","ACCESSIBLE_TARGET","ACCESSIBLE_TARGET_STATUS_CONTROL","ACCESSIBLE_TARGET_OVERFLOW_TRIGGER","SKELETON_FACT_WIDTHS","DOCUMENT_KINDS","DOCUMENT_ICON","ReceiptEuro","Folder","FileText","File","Camera","MenuAction","startIcon","options","action","intent","background","size","hideLabel","DropdownMenu","Tooltip","ChevronDown","option","DetailsSkeleton","EditableDescription","width","Skeleton","HistoryBody","onRetry","loading","speaking","setSpeaking","useState","useEffect","settled","body","DetailsContent","read","refreshing","shownTitle","enter","live","statusControl","patientId","privacyTitle","notesPreview","hostHistory","onOpenHistory","readOnly","onStatusChange","allowedStatuses","APPOINTMENT_WORKFLOW_STATUSES","onDescriptionChange","onEdit","onMove","onCopy","onDelete","onJoinTelehealth","onWhatsApp","hostWhatsappUrl","createTaskUrl","documents","eventId","entering","card","notesForPatient","notes","editorOffered","historyOpen","setHistoryOpen","editingDescription","setEditingDescription","historyShown","editorShown","openHistory","shownBefore","before","lostHistory","lostEditor","historyRef","historyRetried","historyStatus","setDescription","descriptionDraft","setDescriptionDraft","descriptionSaving","setDescriptionSaving","descriptionError","setDescriptionError","descriptionFieldRef","saveDescription","next","error","getErrorMessage","setStatus","wasRefreshing","landed","permitted","appointmentStatus","statusEditable","changeStatus","isCalendarEventStatus","whatsappUrl","documentKinds","kind","copyMenu","assigned","statusLabel","statusName","statusShownRef","statusWasEditable","lost","statusNode","WorkflowStatusControl","Copy","Plus","WhatsAppGlyph","SquareCheckBig","actions","node","backLabel","CONTENT_ENTER_CLASS","PanelSubview","PanelHeader","HistoryIcon","PrivacyIdentityCard","_b","PrivacyHiddenLine","ButtonGroup","TextArea","AppointmentDetailsPanel","forwardRef","title","className","rest","ref","reactId","instanceId","previousStatus","retryOffered","rootRef","setRoot","useMemo","composeRefs","heldFocus","snapshot","control","handledRejection","inFlight","saved","offered","host","useAgentRegistration","header","useAppointmentDetailsRead","load","reloadKey","failure","loadRef","retries","setRetries","setAnswer","request","selection","setSelection","selectionCount","controller","settle","retry","useCallback","previous","current"],"mappings":"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","x_google_ignoreList":[0,1,2,3]}
|