@ampath/esm-dha-workflow-app 4.0.0-next.43 → 4.0.0-next.445

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.
Files changed (937) hide show
  1. package/README.md +47 -0
  2. package/dist/1100.js +1 -0
  3. package/dist/1100.js.map +1 -0
  4. package/dist/{197.js → 1197.js} +1 -1
  5. package/dist/1371.js +2 -0
  6. package/dist/1371.js.LICENSE.txt +282 -0
  7. package/dist/1371.js.map +1 -0
  8. package/dist/1435.js +1 -0
  9. package/dist/1435.js.map +1 -0
  10. package/dist/1673.js +1 -0
  11. package/dist/1673.js.map +1 -0
  12. package/dist/1843.js +1 -0
  13. package/dist/1843.js.map +1 -0
  14. package/dist/1931.js +1 -0
  15. package/dist/1931.js.map +1 -0
  16. package/dist/2272.js +2 -0
  17. package/dist/2272.js.map +1 -0
  18. package/dist/2383.js +1 -0
  19. package/dist/2383.js.map +1 -0
  20. package/dist/2439.js +1 -0
  21. package/dist/2439.js.map +1 -0
  22. package/dist/2535.js +1 -0
  23. package/dist/2535.js.map +1 -0
  24. package/dist/2592.js +1 -0
  25. package/dist/2592.js.map +1 -0
  26. package/dist/2632.js +1 -0
  27. package/dist/2632.js.map +1 -0
  28. package/dist/2635.js +1 -0
  29. package/dist/2635.js.map +1 -0
  30. package/dist/2663.js +1 -0
  31. package/dist/2663.js.map +1 -0
  32. package/dist/2687.js +1 -0
  33. package/dist/2687.js.map +1 -0
  34. package/dist/2802.js +1 -0
  35. package/dist/2802.js.map +1 -0
  36. package/dist/2808.js +1 -0
  37. package/dist/2808.js.map +1 -0
  38. package/dist/282.js +1 -1
  39. package/dist/282.js.LICENSE.txt +3 -3
  40. package/dist/282.js.map +1 -1
  41. package/dist/2848.js +1 -0
  42. package/dist/2848.js.map +1 -0
  43. package/dist/3.js +1 -0
  44. package/dist/3.js.map +1 -0
  45. package/dist/3016.js +1 -0
  46. package/dist/3016.js.map +1 -0
  47. package/dist/3041.js +1 -0
  48. package/dist/3041.js.map +1 -0
  49. package/dist/3099.js +1 -0
  50. package/dist/3182.js +1 -0
  51. package/dist/3182.js.map +1 -0
  52. package/dist/3184.js +2 -0
  53. package/dist/3184.js.map +1 -0
  54. package/dist/3196.js +1 -0
  55. package/dist/3196.js.map +1 -0
  56. package/dist/3242.js +1 -0
  57. package/dist/3242.js.map +1 -0
  58. package/dist/3270.js +1 -0
  59. package/dist/3270.js.map +1 -0
  60. package/dist/3288.js +1 -0
  61. package/dist/3288.js.map +1 -0
  62. package/dist/3311.js +2 -0
  63. package/dist/3311.js.LICENSE.txt +9 -0
  64. package/dist/3311.js.map +1 -0
  65. package/dist/3558.js +1 -0
  66. package/dist/3558.js.map +1 -0
  67. package/dist/3612.js +1 -0
  68. package/dist/3612.js.map +1 -0
  69. package/dist/3636.js +1 -0
  70. package/dist/3636.js.map +1 -0
  71. package/dist/3654.js +1 -0
  72. package/dist/3654.js.map +1 -0
  73. package/dist/3794.js +1 -0
  74. package/dist/3794.js.map +1 -0
  75. package/dist/3816.js +1 -0
  76. package/dist/3816.js.map +1 -0
  77. package/dist/3897.js +1 -0
  78. package/dist/3897.js.map +1 -0
  79. package/dist/3949.js +1 -0
  80. package/dist/3949.js.map +1 -0
  81. package/dist/4055.js +1 -0
  82. package/dist/408.js +1 -0
  83. package/dist/408.js.map +1 -0
  84. package/dist/409.js +1 -0
  85. package/dist/409.js.map +1 -0
  86. package/dist/411.js +1 -0
  87. package/dist/411.js.map +1 -0
  88. package/dist/4225.js +1 -0
  89. package/dist/4225.js.map +1 -0
  90. package/dist/4300.js +1 -0
  91. package/dist/{335.js → 4335.js} +1 -1
  92. package/dist/4353.js +1 -0
  93. package/dist/4353.js.map +1 -0
  94. package/dist/4399.js +1 -0
  95. package/dist/4399.js.map +1 -0
  96. package/dist/4569.js +1 -0
  97. package/dist/4569.js.map +1 -0
  98. package/dist/{652.js → 4652.js} +1 -1
  99. package/dist/474.js +1 -0
  100. package/dist/474.js.map +1 -0
  101. package/dist/4993.js +1 -0
  102. package/dist/4993.js.map +1 -0
  103. package/dist/5006.js +1 -0
  104. package/dist/5006.js.map +1 -0
  105. package/dist/5119.js +1 -0
  106. package/dist/5119.js.map +1 -0
  107. package/dist/5138.js +1 -0
  108. package/dist/5138.js.map +1 -0
  109. package/dist/5179.js +1 -0
  110. package/dist/5179.js.map +1 -0
  111. package/dist/5244.js +1 -0
  112. package/dist/5244.js.map +1 -0
  113. package/dist/5353.js +1 -0
  114. package/dist/5353.js.map +1 -0
  115. package/dist/5377.js +1 -0
  116. package/dist/5377.js.map +1 -0
  117. package/dist/5413.js +1 -0
  118. package/dist/5413.js.map +1 -0
  119. package/dist/5422.js +1 -0
  120. package/dist/5422.js.map +1 -0
  121. package/dist/5500.js +1 -0
  122. package/dist/5500.js.map +1 -0
  123. package/dist/5754.js +1 -0
  124. package/dist/5754.js.map +1 -0
  125. package/dist/5805.js +1 -0
  126. package/dist/5805.js.map +1 -0
  127. package/dist/6048.js +1 -0
  128. package/dist/6048.js.map +1 -0
  129. package/dist/6055.js +1 -0
  130. package/dist/6055.js.map +1 -0
  131. package/dist/6206.js +1 -0
  132. package/dist/6206.js.map +1 -0
  133. package/dist/6279.js +1 -0
  134. package/dist/6279.js.map +1 -0
  135. package/dist/6399.js +1 -0
  136. package/dist/6399.js.map +1 -0
  137. package/dist/6540.js +2 -0
  138. package/dist/6540.js.map +1 -0
  139. package/dist/6606.js +1 -0
  140. package/dist/6606.js.map +1 -0
  141. package/dist/6682.js +1 -0
  142. package/dist/6682.js.map +1 -0
  143. package/dist/6802.js +1 -0
  144. package/dist/6802.js.map +1 -0
  145. package/dist/7024.js +1 -0
  146. package/dist/7024.js.map +1 -0
  147. package/dist/72.js +1 -0
  148. package/dist/72.js.map +1 -0
  149. package/dist/7269.js +1 -0
  150. package/dist/7269.js.map +1 -0
  151. package/dist/7332.js +1 -0
  152. package/dist/7332.js.map +1 -0
  153. package/dist/7369.js +1 -0
  154. package/dist/7369.js.map +1 -0
  155. package/dist/7593.js +1 -0
  156. package/dist/7593.js.map +1 -0
  157. package/dist/7694.js +1 -0
  158. package/dist/7694.js.map +1 -0
  159. package/dist/7698.js +1 -0
  160. package/dist/7698.js.map +1 -0
  161. package/dist/7734.js +1 -0
  162. package/dist/7734.js.map +1 -0
  163. package/dist/774.js +1 -0
  164. package/dist/774.js.map +1 -0
  165. package/dist/7852.js +1 -0
  166. package/dist/7852.js.map +1 -0
  167. package/dist/7949.js +2 -0
  168. package/dist/{246.js.LICENSE.txt → 7949.js.LICENSE.txt} +1 -10
  169. package/dist/7949.js.map +1 -0
  170. package/dist/7958.js +1 -0
  171. package/dist/7958.js.map +1 -0
  172. package/dist/8137.js +1 -0
  173. package/dist/8137.js.map +1 -0
  174. package/dist/8167.js +1 -0
  175. package/dist/8167.js.map +1 -0
  176. package/dist/818.js +1 -0
  177. package/dist/818.js.map +1 -0
  178. package/dist/8250.js +1 -0
  179. package/dist/8250.js.map +1 -0
  180. package/dist/8308.js +1 -0
  181. package/dist/8308.js.map +1 -0
  182. package/dist/8735.js +1 -0
  183. package/dist/8735.js.map +1 -0
  184. package/dist/8947.js +1 -0
  185. package/dist/8947.js.map +1 -0
  186. package/dist/8961.js +1 -0
  187. package/dist/8961.js.map +1 -0
  188. package/dist/902.js +1 -0
  189. package/dist/902.js.map +1 -0
  190. package/dist/9062.js +1 -0
  191. package/dist/9062.js.map +1 -0
  192. package/dist/9134.js +1 -0
  193. package/dist/9134.js.map +1 -0
  194. package/dist/9249.js +1 -0
  195. package/dist/9249.js.map +1 -0
  196. package/dist/9418.js +2 -0
  197. package/dist/9418.js.LICENSE.txt +1 -0
  198. package/dist/9418.js.map +1 -0
  199. package/dist/9429.js +1 -0
  200. package/dist/9429.js.map +1 -0
  201. package/dist/9442.js +1 -0
  202. package/dist/9442.js.map +1 -0
  203. package/dist/961.js +1 -1
  204. package/dist/961.js.map +1 -1
  205. package/dist/968.js +1 -0
  206. package/dist/968.js.map +1 -0
  207. package/dist/9709.js +1 -0
  208. package/dist/9709.js.map +1 -0
  209. package/dist/9768.js +1 -0
  210. package/dist/9768.js.map +1 -0
  211. package/dist/9770.js +1 -0
  212. package/dist/9770.js.map +1 -0
  213. package/dist/9879.js +1 -0
  214. package/dist/9879.js.map +1 -0
  215. package/dist/9974.js +1 -0
  216. package/dist/9974.js.map +1 -0
  217. package/dist/esm-dha-workflow-app.js +1 -1
  218. package/dist/esm-dha-workflow-app.js.buildmanifest.json +2284 -210
  219. package/dist/esm-dha-workflow-app.js.map +1 -1
  220. package/dist/main.js +1 -1
  221. package/dist/main.js.map +1 -1
  222. package/dist/routes.json +1 -1
  223. package/jest.config.js +4 -0
  224. package/local-config.json +9 -0
  225. package/package.json +29 -11
  226. package/src/admissions/admission-request-list/admission-request-list.scss +0 -0
  227. package/src/admissions/admission-request-list/admission-request-list.tsx +263 -0
  228. package/src/admissions/admissions-dashboard.component.scss +15 -0
  229. package/src/admissions/admissions-dashboard.component.tsx +277 -0
  230. package/src/admissions/admissions.resource.ts +233 -0
  231. package/src/admissions/admitted-list/admitted-patients-list.tsx +268 -0
  232. package/src/admissions/awaiting-discharge-list/awaiting-discharge-list.tsx +197 -0
  233. package/src/admissions/bed-assigment-request/bed-assignment-request-list.tsx +134 -0
  234. package/src/admissions/constants/index.ts +33 -0
  235. package/src/admissions/discharged-list/discharged-list.scss +0 -0
  236. package/src/admissions/discharged-list/discharged-list.tsx +67 -0
  237. package/src/admissions/form-entry-workspace/form-entry-workspace.tsx +62 -0
  238. package/src/admissions/inpatient/admission-history/patient-admission-history.tsx +76 -0
  239. package/src/admissions/inpatient/admission-requests/patient-admission-requests.scss +19 -0
  240. package/src/admissions/inpatient/admission-requests/patient-admission-requests.tsx +72 -0
  241. package/src/admissions/inpatient/inpatient-admissions.component.scss +7 -0
  242. package/src/admissions/inpatient/inpatient-admissions.component.tsx +46 -0
  243. package/src/admissions/modal/add-bill-items/add-bill-items.modal.scss +17 -0
  244. package/src/admissions/modal/add-bill-items/add-bill-items.modal.tsx +220 -0
  245. package/src/admissions/modal/admit-elsewhere/admit-elsewhere.modal.scss +23 -0
  246. package/src/admissions/modal/admit-elsewhere/admit-elsewhere.modal.tsx +156 -0
  247. package/src/admissions/modal/admit-patient/admit-patient.modal.scss +0 -0
  248. package/src/admissions/modal/admit-patient/admit-patient.modal.tsx +111 -0
  249. package/src/admissions/modal/bed-swap/bed-swap.modal.scss +0 -0
  250. package/src/admissions/modal/bed-swap/bed-swap.modal.tsx +102 -0
  251. package/src/admissions/modal/cancel-admission-request/cancel-admission-request.scss +11 -0
  252. package/src/admissions/modal/cancel-admission-request/cancel-admission-request.tsx +105 -0
  253. package/src/admissions/modal/discharge/discharge-patient.modal.scss +13 -0
  254. package/src/admissions/modal/discharge/discharge-patient.modal.tsx +86 -0
  255. package/src/admissions/types/index.ts +263 -0
  256. package/src/appointments/appointments.component.scss +6 -0
  257. package/src/appointments/appointments.component.tsx +8 -1
  258. package/src/billing/admin/claims/claims-list.component.scss +13 -0
  259. package/src/billing/admin/claims/claims-list.component.tsx +163 -0
  260. package/src/billing/admin/claims-admin-dashboard.component.scss +0 -0
  261. package/src/billing/admin/claims-admin-dashboard.component.tsx +32 -0
  262. package/src/billing/api/billing.api.ts +139 -0
  263. package/src/billing/billing-claims.resource.ts +1112 -0
  264. package/src/billing/billing-dashboard-link.component.tsx +31 -0
  265. package/src/billing/billing-dashboard-reset.ts +27 -0
  266. package/src/billing/billing-root.tsx +37 -0
  267. package/src/billing/dashboard/billingDashboard.component.scss +0 -0
  268. package/src/billing/dashboard/billingDashboard.component.tsx +25 -0
  269. package/src/billing/dashboard/v2/active-visits/active-visits.component.tsx +257 -0
  270. package/src/billing/dashboard/v2/active-visits/active-visits.resource.ts +85 -0
  271. package/src/billing/dashboard/v2/active-visits/active-visits.scss +15 -0
  272. package/src/billing/dashboard/v2/active-visits.component.tsx +102 -0
  273. package/src/billing/dashboard/v2/admissions/admission-requests-tab.component.tsx +79 -0
  274. package/src/billing/dashboard/v2/billing-and-claims-patient-chart.component.tsx +52 -0
  275. package/src/billing/dashboard/v2/billing-claims-dashboard.component.scss +221 -0
  276. package/src/billing/dashboard/v2/billing-claims-dashboard.component.tsx +342 -0
  277. package/src/billing/dashboard/v2/cash-checklist/bill-document.component.scss +90 -0
  278. package/src/billing/dashboard/v2/cash-checklist/bill-document.component.tsx +101 -0
  279. package/src/billing/dashboard/v2/cash-checklist/cash-checklist.component.scss +199 -0
  280. package/src/billing/dashboard/v2/cash-checklist/cash-checklist.component.tsx +361 -0
  281. package/src/billing/dashboard/v2/cash-checklist/cash-checklist.resource.ts +239 -0
  282. package/src/billing/dashboard/v2/cash-checklist/payment-drawer.component.scss +246 -0
  283. package/src/billing/dashboard/v2/cash-checklist/payment-drawer.component.tsx +182 -0
  284. package/src/billing/dashboard/v2/claim-statuses.ts +143 -0
  285. package/src/billing/dashboard/v2/claim-visits/claim-diagnosis-details/claim-diagnosis-details.component.scss +0 -0
  286. package/src/billing/dashboard/v2/claim-visits/claim-diagnosis-details/claim-diagnosis-details.component.tsx +35 -0
  287. package/src/billing/dashboard/v2/claim-visits/claim-diagnosis-details/claim-diagnosis-panel.component.scss +67 -0
  288. package/src/billing/dashboard/v2/claim-visits/claim-diagnosis-details/claim-diagnosis-panel.component.tsx +90 -0
  289. package/src/billing/dashboard/v2/claim-visits/claim-doctors/claim-doctors.scss +28 -0
  290. package/src/billing/dashboard/v2/claim-visits/claim-doctors/claim-doctors.tsx +36 -0
  291. package/src/billing/dashboard/v2/claim-visits/claim-history/claim-history.component.scss +119 -0
  292. package/src/billing/dashboard/v2/claim-visits/claim-history/claim-history.component.tsx +198 -0
  293. package/src/billing/dashboard/v2/claim-visits/claim-intervention-details/claim-intervention-details.component.scss +5 -0
  294. package/src/billing/dashboard/v2/claim-visits/claim-intervention-details/claim-intervention-details.component.tsx +160 -0
  295. package/src/billing/dashboard/v2/claim-visits/claim-intervention-details/claim-intervention-panel.component.scss +105 -0
  296. package/src/billing/dashboard/v2/claim-visits/claim-intervention-details/claim-intervention-panel.component.tsx +184 -0
  297. package/src/billing/dashboard/v2/claim-visits/claim-intervention-details/intervention-attachments.component.scss +161 -0
  298. package/src/billing/dashboard/v2/claim-visits/claim-intervention-details/intervention-attachments.component.tsx +328 -0
  299. package/src/billing/dashboard/v2/claim-visits/claim-invoice-details/claim-invoice-details.component.tsx +96 -0
  300. package/src/billing/dashboard/v2/claim-visits/claim-invoice-details/claim-invoice-document.component.tsx +236 -0
  301. package/src/billing/dashboard/v2/claim-visits/claim-invoice-details/claim-invoice-panel.component.scss +98 -0
  302. package/src/billing/dashboard/v2/claim-visits/claim-invoice-details/claim-invoice-panel.component.tsx +293 -0
  303. package/src/billing/dashboard/v2/claim-visits/claim-invoice-line-details/claim-invoice-line-details.component.scss +133 -0
  304. package/src/billing/dashboard/v2/claim-visits/claim-invoice-line-details/claim-invoice-line-details.component.tsx +217 -0
  305. package/src/billing/dashboard/v2/claim-visits/claim-list/claim-visits.component.scss +28 -0
  306. package/src/billing/dashboard/v2/claim-visits/claim-list/claim-visits.component.tsx +315 -0
  307. package/src/billing/dashboard/v2/claim-visits/claim-visit-details/claim-details-by-token.component.tsx +150 -0
  308. package/src/billing/dashboard/v2/claim-visits/claim-visit-details/claim-details-page.component.scss +13 -0
  309. package/src/billing/dashboard/v2/claim-visits/claim-visit-details/claim-details-page.component.tsx +116 -0
  310. package/src/billing/dashboard/v2/claim-visits/claim-visit-details/claim-visit-details.component.scss +338 -0
  311. package/src/billing/dashboard/v2/claim-visits/claim-visit-details/claim-visit-details.component.tsx +616 -0
  312. package/src/billing/dashboard/v2/claim-visits/modal/claim-doctors/add-claim-doctor/add-claim-doctor.modal.scss +5 -0
  313. package/src/billing/dashboard/v2/claim-visits/modal/claim-doctors/add-claim-doctor/add-claim-doctor.modal.tsx +49 -0
  314. package/src/billing/dashboard/v2/claim-visits/modal/claim-visit-details/claim-visit-details.modal.scss +17 -0
  315. package/src/billing/dashboard/v2/claim-visits/modal/claim-visit-details/claim-visit-details.modal.tsx +56 -0
  316. package/src/billing/dashboard/v2/claim-visits/modal/close-claim/close-claim.modal.scss +0 -0
  317. package/src/billing/dashboard/v2/claim-visits/modal/close-claim/close-claim.modal.tsx +129 -0
  318. package/src/billing/dashboard/v2/claim-visits/modal/submit-claim/submit-claim.modal.tsx +280 -0
  319. package/src/billing/dashboard/v2/claim-visits/shared/_empty-state.scss +28 -0
  320. package/src/billing/dashboard/v2/claim-visits/shared/record-cards.component.scss +298 -0
  321. package/src/billing/dashboard/v2/claim-visits/shared/record-cards.component.tsx +252 -0
  322. package/src/billing/dashboard/v2/claim-visits/shared/record-details.workspace.scss +42 -0
  323. package/src/billing/dashboard/v2/claim-visits/shared/record-details.workspace.tsx +67 -0
  324. package/src/billing/dashboard/v2/claim-visits/shared/record-table.component.scss +61 -0
  325. package/src/billing/dashboard/v2/claim-visits/shared/record-table.component.tsx +150 -0
  326. package/src/billing/dashboard/v2/claim-visits/switch-intervention/switch-intervention.resource.ts +51 -0
  327. package/src/billing/dashboard/v2/claim-visits/switch-intervention/switch-intervention.workspace.scss +191 -0
  328. package/src/billing/dashboard/v2/claim-visits/switch-intervention/switch-intervention.workspace.tsx +660 -0
  329. package/src/billing/dashboard/v2/claim-workspace/claim-workspace.component.scss +595 -0
  330. package/src/billing/dashboard/v2/claim-workspace/claim-workspace.component.tsx +810 -0
  331. package/src/billing/dashboard/v2/claim-workspace/claim-workspace.resource.ts +282 -0
  332. package/src/billing/dashboard/v2/claims-accounting/bill-utils.ts +134 -0
  333. package/src/billing/dashboard/v2/claims-accounting/claim-detail.component.tsx +346 -0
  334. package/src/billing/dashboard/v2/claims-accounting/claims-accounting.component.scss +546 -0
  335. package/src/billing/dashboard/v2/claims-accounting/claims-accounting.component.tsx +206 -0
  336. package/src/billing/dashboard/v2/claims-accounting/claims-accounting.resource.ts +337 -0
  337. package/src/billing/dashboard/v2/claims-accounting/invoice-document.component.scss +90 -0
  338. package/src/billing/dashboard/v2/claims-accounting/invoice-document.component.tsx +90 -0
  339. package/src/billing/dashboard/v2/claims-accounting/remittances.component.tsx +169 -0
  340. package/src/billing/dashboard/v2/claims-accounting/remittances.resource.ts +46 -0
  341. package/src/billing/dashboard/v2/claims-accounting/status-meta.ts +25 -0
  342. package/src/billing/dashboard/v2/clearance/cash-patients.scss +18 -0
  343. package/src/billing/dashboard/v2/clearance/cash.component.tsx +145 -0
  344. package/src/billing/dashboard/v2/clearance/clearance.component.scss +84 -0
  345. package/src/billing/dashboard/v2/clearance/clearance.component.tsx +225 -0
  346. package/src/billing/dashboard/v2/clearance/pay-cash.component.tsx +199 -0
  347. package/src/billing/dashboard/v2/clearance/pay-cash.scss +28 -0
  348. package/src/billing/dashboard/v2/clearance/prepaid-services.component.tsx +112 -0
  349. package/src/billing/dashboard/v2/facility-bills/claim-status.ts +249 -0
  350. package/src/billing/dashboard/v2/facility-bills/facility-bills.component.scss +140 -0
  351. package/src/billing/dashboard/v2/facility-bills/facility-bills.component.tsx +688 -0
  352. package/src/billing/dashboard/v2/facility-bills/preauths-datatables/pending-preauths.component.tsx +132 -0
  353. package/src/billing/dashboard/v2/facility-bills/preauths-datatables/preauth-preview-table.component.tsx +267 -0
  354. package/src/billing/dashboard/v2/facility-bills/preauths.component.tsx +130 -0
  355. package/src/billing/dashboard/v2/inpatient-requests/inpatient-requests.component.scss +22 -0
  356. package/src/billing/dashboard/v2/inpatient-requests/inpatient-requests.component.tsx +382 -0
  357. package/src/billing/dashboard/v2/inpatient-requests/modal/start-inpatient-claim/start-inpatient-claim.component.scss +0 -0
  358. package/src/billing/dashboard/v2/inpatient-requests/modal/start-inpatient-claim/start-inpatient-claim.component.tsx +0 -0
  359. package/src/billing/dashboard/v2/new-facility-bills/bills-table.component.tsx +78 -0
  360. package/src/billing/dashboard/v2/new-facility-bills/bills-table.scss +18 -0
  361. package/src/billing/dashboard/v2/new-facility-bills/new-facility-bills.component.tsx +64 -0
  362. package/src/billing/dashboard/v2/new-facility-bills/new-facility-bills.scss +146 -0
  363. package/src/billing/dashboard/v2/patient-bill-details/attachments/add-attachments.component.tsx +234 -0
  364. package/src/billing/dashboard/v2/patient-bill-details/attachments/attachment.component.tsx +157 -0
  365. package/src/billing/dashboard/v2/patient-bill-details/attachments/attachments.scss +92 -0
  366. package/src/billing/dashboard/v2/patient-bill-details/attachments/case-summary/case-summary.scss +295 -0
  367. package/src/billing/dashboard/v2/patient-bill-details/attachments/case-summary/case-summary.tsx +326 -0
  368. package/src/billing/dashboard/v2/patient-bill-details/attachments/death-notification.component.tsx +162 -0
  369. package/src/billing/dashboard/v2/patient-bill-details/attachments/death-notification.resource.ts +112 -0
  370. package/src/billing/dashboard/v2/patient-bill-details/attachments/death-notification.scss +88 -0
  371. package/src/billing/dashboard/v2/patient-bill-details/attachments/dialysis/dialysis-chart.scss +238 -0
  372. package/src/billing/dashboard/v2/patient-bill-details/attachments/dialysis/dialysis-chart.tsx +269 -0
  373. package/src/billing/dashboard/v2/patient-bill-details/attachments/discharge-summary/discharge-summary.scss +96 -0
  374. package/src/billing/dashboard/v2/patient-bill-details/attachments/discharge-summary/discharge-summary.tsx +124 -0
  375. package/src/billing/dashboard/v2/patient-bill-details/attachments/final-bill.component.tsx +152 -0
  376. package/src/billing/dashboard/v2/patient-bill-details/attachments/final-bill.scss +225 -0
  377. package/src/billing/dashboard/v2/patient-bill-details/attachments/general-discharge-summary/general-discharge-summary.scss +182 -0
  378. package/src/billing/dashboard/v2/patient-bill-details/attachments/general-discharge-summary/general-discharge-summary.tsx +173 -0
  379. package/src/billing/dashboard/v2/patient-bill-details/attachments/generate-attachments.component.tsx +450 -0
  380. package/src/billing/dashboard/v2/patient-bill-details/attachments/invoice.component.tsx +151 -0
  381. package/src/billing/dashboard/v2/patient-bill-details/attachments/invoice.scss +225 -0
  382. package/src/billing/dashboard/v2/patient-bill-details/attachments/type.ts +44 -0
  383. package/src/billing/dashboard/v2/patient-bill-details/bill-details/bill-details.scss +107 -0
  384. package/src/billing/dashboard/v2/patient-bill-details/bill-details/bill-details.tsx +508 -0
  385. package/src/billing/dashboard/v2/patient-bill-details/bill-details-page.component.scss +30 -0
  386. package/src/billing/dashboard/v2/patient-bill-details/bill-details-page.component.tsx +94 -0
  387. package/src/billing/dashboard/v2/patient-bill-details/claim-details/claim-details-skeleton.component.scss +89 -0
  388. package/src/billing/dashboard/v2/patient-bill-details/claim-details/claim-details-skeleton.component.tsx +53 -0
  389. package/src/billing/dashboard/v2/patient-bill-details/claim-details/patient-claim-details.component.scss +32 -0
  390. package/src/billing/dashboard/v2/patient-bill-details/claim-details/patient-claim-details.component.tsx +215 -0
  391. package/src/billing/dashboard/v2/patient-bill-details/modals/add-claim-diagnosis/add-claim-diagnosis.modal.scss +0 -0
  392. package/src/billing/dashboard/v2/patient-bill-details/modals/add-claim-diagnosis/add-claim-diagnosis.modal.tsx +99 -0
  393. package/src/billing/dashboard/v2/patient-bill-details/modals/add-claim-line/add-claim-line.modal.tsx +187 -0
  394. package/src/billing/dashboard/v2/patient-bill-details/patient-bill-details.scss +153 -0
  395. package/src/billing/dashboard/v2/patient-bill-details/patient-bill-details.tsx +458 -0
  396. package/src/billing/dashboard/v2/patient-bill-details/payment-mode.ts +124 -0
  397. package/src/billing/dashboard/v2/patient-bill-details/workspaces/add-claim-line/add-claim-line.workspace.scss +27 -0
  398. package/src/billing/dashboard/v2/patient-bill-details/workspaces/add-claim-line/add-claim-line.workspace.tsx +234 -0
  399. package/src/billing/dashboard/v2/patient-bill-details/workspaces/bill-item-payment/bill-item-payment.workspace.scss +27 -0
  400. package/src/billing/dashboard/v2/patient-bill-details/workspaces/bill-item-payment/bill-item-payment.workspace.tsx +123 -0
  401. package/src/billing/dashboard/v2/preauth/preauth-attachments.component.tsx +389 -0
  402. package/src/billing/dashboard/v2/preauth/preauth-list.component.scss +38 -0
  403. package/src/billing/dashboard/v2/preauth/preauth-list.component.tsx +241 -0
  404. package/src/billing/dashboard/v2/preauth/preauth-status-tag.component.tsx +75 -0
  405. package/src/billing/dashboard/v2/preauth/preauth-typed-fields.md +125 -0
  406. package/src/billing/dashboard/v2/preauth/preauth.resource.ts +1032 -0
  407. package/src/billing/dashboard/v2/preauth/preauth.workspace.scss +91 -0
  408. package/src/billing/dashboard/v2/preauth/preauth.workspace.tsx +1802 -0
  409. package/src/billing/dashboard/v2/preauth/preauthorizations-tab.component.tsx +53 -0
  410. package/src/billing/dashboard/v2/sha-claims/sha-claims-table.component.tsx +36 -0
  411. package/src/billing/dashboard/v2/sha-claims/sha-claims.component.tsx +60 -0
  412. package/src/billing/dashboard/v2/sha-claims/sha-claims.scss +8 -0
  413. package/src/billing/dashboard/v2/shared/dash-board-card/dash-board-card.component.scss +17 -0
  414. package/src/billing/dashboard/v2/shared/dash-board-card/dash-board-card.component.tsx +15 -0
  415. package/src/billing/dashboard/v2/shared/empty-state.component.scss +24 -0
  416. package/src/billing/dashboard/v2/shared/empty-state.component.tsx +13 -0
  417. package/src/billing/dashboard/v2/shared/scroll-to-top.component.scss +54 -0
  418. package/src/billing/dashboard/v2/shared/scroll-to-top.component.tsx +54 -0
  419. package/src/billing/dashboard/v2/shared/table-toolbar.component.scss +77 -0
  420. package/src/billing/dashboard/v2/shared/table-toolbar.component.tsx +48 -0
  421. package/src/billing/dashboard/v2/types/index.ts +534 -0
  422. package/src/billing/dashboard/v3/active-visits/active-visits.component.tsx +256 -0
  423. package/src/billing/dashboard/v3/active-visits/active-visits.resource.ts +57 -0
  424. package/src/billing/dashboard/v3/active-visits/active-visits.scss +15 -0
  425. package/src/billing/dashboard/v3/cash-checklist/bill-document.component.scss +90 -0
  426. package/src/billing/dashboard/v3/cash-checklist/bill-document.component.tsx +101 -0
  427. package/src/billing/dashboard/v3/cash-checklist/cash-checklist.component.scss +199 -0
  428. package/src/billing/dashboard/v3/cash-checklist/cash-checklist.component.tsx +361 -0
  429. package/src/billing/dashboard/v3/cash-checklist/cash-checklist.resource.ts +240 -0
  430. package/src/billing/dashboard/v3/cash-checklist/payment-drawer.component.scss +246 -0
  431. package/src/billing/dashboard/v3/cash-checklist/payment-drawer.component.tsx +182 -0
  432. package/src/billing/dashboard/v3/claim-visits/claim-diagnosis-details/claim-diagnosis-details.component.scss +0 -0
  433. package/src/billing/dashboard/v3/claim-visits/claim-diagnosis-details/claim-diagnosis-details.component.tsx +44 -0
  434. package/src/billing/dashboard/v3/claim-visits/claim-doctors/claim-doctors.scss +5 -0
  435. package/src/billing/dashboard/v3/claim-visits/claim-doctors/claim-doctors.tsx +40 -0
  436. package/src/billing/dashboard/v3/claim-visits/claim-documents/claim-documents.scss +10 -0
  437. package/src/billing/dashboard/v3/claim-visits/claim-documents/claim-documents.tsx +25 -0
  438. package/src/billing/dashboard/v3/claim-visits/claim-intervention-details/claim-intervention-details.component.tsx +268 -0
  439. package/src/billing/dashboard/v3/claim-visits/claim-invoice-details/claim-invoice-details.component.scss +6 -0
  440. package/src/billing/dashboard/v3/claim-visits/claim-invoice-details/claim-invoice-details.component.tsx +85 -0
  441. package/src/billing/dashboard/v3/claim-visits/claim-invoice-line-details/claim-invoice-line-details.component.scss +0 -0
  442. package/src/billing/dashboard/v3/claim-visits/claim-invoice-line-details/claim-invoice-line-details.component.tsx +109 -0
  443. package/src/billing/dashboard/v3/claim-visits/claim-visit-details/claim-visit-details.component.scss +103 -0
  444. package/src/billing/dashboard/v3/claim-visits/claim-visit-details/claim-visit-details.component.tsx +519 -0
  445. package/src/billing/dashboard/v3/claim-visits/claim-visits.component.scss +5 -0
  446. package/src/billing/dashboard/v3/claim-visits/claim-visits.component.tsx +139 -0
  447. package/src/billing/dashboard/v3/claim-visits/modal/claim-doctors/add-claim-doctor/add-claim-doctor.modal.scss +5 -0
  448. package/src/billing/dashboard/v3/claim-visits/modal/claim-doctors/add-claim-doctor/add-claim-doctor.modal.tsx +49 -0
  449. package/src/billing/dashboard/v3/claim-visits/modal/claim-invoice-lines/claim-invoice-lines.modal.scss +7 -0
  450. package/src/billing/dashboard/v3/claim-visits/modal/claim-invoice-lines/claim-invoice-lines.modal.tsx +35 -0
  451. package/src/billing/dashboard/v3/claim-visits/modal/claim-visit-details/claim-visit-details.modal.scss +6 -0
  452. package/src/billing/dashboard/v3/claim-visits/modal/claim-visit-details/claim-visit-details.modal.tsx +33 -0
  453. package/src/billing/dashboard/v3/claim-visits/modal/close-claim/close-claim.modal.scss +0 -0
  454. package/src/billing/dashboard/v3/claim-visits/modal/close-claim/close-claim.modal.tsx +129 -0
  455. package/src/billing/dashboard/v3/claim-visits/modal/identify-emergency-unknown-patient/identify-emergencu-unknown-patient.scss +407 -0
  456. package/src/billing/dashboard/v3/claim-visits/modal/identify-emergency-unknown-patient/identify-emergency-unknown-patient.component.tsx +523 -0
  457. package/src/billing/dashboard/v3/claim-visits/modal/identify-emergency-unknown-patient/identify-patient-helper.ts +77 -0
  458. package/src/billing/dashboard/v3/claim-visits/modal/submit-claim/submit-claim.modal.tsx +280 -0
  459. package/src/billing/dashboard/v3/claim-visits/modal/submit-emergency-claim/submit-emergency-claim.component.tsx +91 -0
  460. package/src/billing/dashboard/v3/claim-visits/modal/submit-emergency-claim/submit-emergency.scss +14 -0
  461. package/src/billing/dashboard/v3/claim-visits/payer-preview/index.scss +140 -0
  462. package/src/billing/dashboard/v3/claim-visits/payer-preview/payer-preview-tile.component.tsx +55 -0
  463. package/src/billing/dashboard/v3/claim-visits/payer-preview/payer-preview-workspace.component.tsx +171 -0
  464. package/src/billing/dashboard/v3/claim-visits/payer-preview/tables/payer-claim-doctors.component.tsx +54 -0
  465. package/src/billing/dashboard/v3/claim-visits/payer-preview/tables/payer-claim-lines.component.tsx +48 -0
  466. package/src/billing/dashboard/v3/claim-visits/payer-preview/tables/payer-claim-notes.component.tsx +47 -0
  467. package/src/billing/dashboard/v3/claim-visits/payer-preview/tables/payer-diagnoses.component.tsx +44 -0
  468. package/src/billing/dashboard/v3/claim-visits/payer-preview/tables/payer-interventions.component.tsx +44 -0
  469. package/src/billing/dashboard/v3/claim-visits/switch-intervention/switch-intervention.resource.ts +51 -0
  470. package/src/billing/dashboard/v3/claim-visits/switch-intervention/switch-intervention.workspace.scss +191 -0
  471. package/src/billing/dashboard/v3/claim-visits/switch-intervention/switch-intervention.workspace.tsx +644 -0
  472. package/src/billing/dashboard/v3/claim-workspace/claim-workspace.component.scss +595 -0
  473. package/src/billing/dashboard/v3/claim-workspace/claim-workspace.component.tsx +810 -0
  474. package/src/billing/dashboard/v3/claim-workspace/claim-workspace.resource.ts +282 -0
  475. package/src/billing/dashboard/v3/claims-accounting/bill-utils.ts +134 -0
  476. package/src/billing/dashboard/v3/claims-accounting/claim-detail.component.tsx +346 -0
  477. package/src/billing/dashboard/v3/claims-accounting/claims-accounting.component.scss +546 -0
  478. package/src/billing/dashboard/v3/claims-accounting/claims-accounting.component.tsx +206 -0
  479. package/src/billing/dashboard/v3/claims-accounting/claims-accounting.resource.ts +337 -0
  480. package/src/billing/dashboard/v3/claims-accounting/invoice-document.component.scss +90 -0
  481. package/src/billing/dashboard/v3/claims-accounting/invoice-document.component.tsx +90 -0
  482. package/src/billing/dashboard/v3/claims-accounting/remittances.component.tsx +169 -0
  483. package/src/billing/dashboard/v3/claims-accounting/remittances.resource.ts +46 -0
  484. package/src/billing/dashboard/v3/claims-accounting/status-meta.ts +25 -0
  485. package/src/billing/dashboard/v3/claims-stats-dashboard/claim-stat/claim-stat.component.scss +27 -0
  486. package/src/billing/dashboard/v3/claims-stats-dashboard/claim-stat/claim-stat.component.tsx +41 -0
  487. package/src/billing/dashboard/v3/claims-stats-dashboard/claims-stats-dashboard.component.scss +16 -0
  488. package/src/billing/dashboard/v3/claims-stats-dashboard/claims-stats-dashboard.component.tsx +184 -0
  489. package/src/billing/dashboard/v3/claims-stats-dashboard/modal/claim-stats-list/claim-stats-list.modal.scss +0 -0
  490. package/src/billing/dashboard/v3/claims-stats-dashboard/modal/claim-stats-list/claim-stats-list.modal.tsx +27 -0
  491. package/src/billing/dashboard/v3/clearance/clearance.component.scss +100 -0
  492. package/src/billing/dashboard/v3/clearance/clearance.component.tsx +0 -0
  493. package/src/billing/dashboard/v3/clearance/prepaid-services.component.tsx +112 -0
  494. package/src/billing/dashboard/v3/facility-bills/claim-status.ts +243 -0
  495. package/src/billing/dashboard/v3/facility-bills/facility-bills.component.scss +92 -0
  496. package/src/billing/dashboard/v3/facility-bills/facility-bills.component.tsx +306 -0
  497. package/src/billing/dashboard/v3/facility-bills/preauths-datatables/pending-preauths.component.tsx +132 -0
  498. package/src/billing/dashboard/v3/facility-bills/preauths-datatables/preauth-preview-table.component.tsx +232 -0
  499. package/src/billing/dashboard/v3/facility-bills/preauths.component.tsx +127 -0
  500. package/src/billing/dashboard/v3/patient-bill-details/attachments/add-attachments.component.tsx +228 -0
  501. package/src/billing/dashboard/v3/patient-bill-details/attachments/attachment.component.tsx +157 -0
  502. package/src/billing/dashboard/v3/patient-bill-details/attachments/attachments.scss +92 -0
  503. package/src/billing/dashboard/v3/patient-bill-details/attachments/case-summary/case-summary-helper.ts +58 -0
  504. package/src/billing/dashboard/v3/patient-bill-details/attachments/case-summary/case-summary.scss +295 -0
  505. package/src/billing/dashboard/v3/patient-bill-details/attachments/case-summary/case-summary.tsx +287 -0
  506. package/src/billing/dashboard/v3/patient-bill-details/attachments/dialysis/dialysis-chart.scss +238 -0
  507. package/src/billing/dashboard/v3/patient-bill-details/attachments/dialysis/dialysis-chart.tsx +352 -0
  508. package/src/billing/dashboard/v3/patient-bill-details/attachments/dialysis/dialysis-helper.ts +117 -0
  509. package/src/billing/dashboard/v3/patient-bill-details/attachments/discharge-summary/discharge-summary.scss +96 -0
  510. package/src/billing/dashboard/v3/patient-bill-details/attachments/discharge-summary/discharge-summary.tsx +126 -0
  511. package/src/billing/dashboard/v3/patient-bill-details/attachments/final-bill.component.tsx +75 -0
  512. package/src/billing/dashboard/v3/patient-bill-details/attachments/general-discharge-summary/general-discharge-summary.scss +182 -0
  513. package/src/billing/dashboard/v3/patient-bill-details/attachments/general-discharge-summary/general-discharge-summary.tsx +253 -0
  514. package/src/billing/dashboard/v3/patient-bill-details/attachments/generate-attachments.component.tsx +450 -0
  515. package/src/billing/dashboard/v3/patient-bill-details/attachments/invoice.component.tsx +151 -0
  516. package/src/billing/dashboard/v3/patient-bill-details/attachments/invoice.scss +225 -0
  517. package/src/billing/dashboard/v3/patient-bill-details/attachments/lab-results/lab-orders.component.tsx +198 -0
  518. package/src/billing/dashboard/v3/patient-bill-details/attachments/lab-results/lab-orders.scss +227 -0
  519. package/src/billing/dashboard/v3/patient-bill-details/attachments/medical-report/medical-report.component.tsx +346 -0
  520. package/src/billing/dashboard/v3/patient-bill-details/attachments/medical-report/medical-report.scss +265 -0
  521. package/src/billing/dashboard/v3/patient-bill-details/attachments/proforma-invoice/proforma-invoice.component.tsx +347 -0
  522. package/src/billing/dashboard/v3/patient-bill-details/attachments/proforma-invoice/proforma-invoice.scss +285 -0
  523. package/src/billing/dashboard/v3/patient-bill-details/attachments/type.ts +280 -0
  524. package/src/billing/dashboard/v3/patient-bill-details/attachments/ultrasound-report/ultrasound-report.scss +273 -0
  525. package/src/billing/dashboard/v3/patient-bill-details/attachments/ultrasound-report/utlrasound-report.component.tsx +435 -0
  526. package/src/billing/dashboard/v3/patient-bill-details/bill-details/bill-details.scss +17 -0
  527. package/src/billing/dashboard/v3/patient-bill-details/bill-details/bill-details.tsx +377 -0
  528. package/src/billing/dashboard/v3/patient-bill-details/claim-details/patient-claim-details.component.scss +0 -0
  529. package/src/billing/dashboard/v3/patient-bill-details/claim-details/patient-claim-details.component.tsx +71 -0
  530. package/src/billing/dashboard/v3/patient-bill-details/modals/add-claim-diagnosis/add-claim-diagnosis.modal.scss +0 -0
  531. package/src/billing/dashboard/v3/patient-bill-details/modals/add-claim-diagnosis/add-claim-diagnosis.modal.tsx +99 -0
  532. package/src/billing/dashboard/v3/patient-bill-details/modals/add-claim-line/add-claim-line.modal.scss +14 -0
  533. package/src/billing/dashboard/v3/patient-bill-details/modals/add-claim-line/add-claim-line.modal.tsx +156 -0
  534. package/src/billing/dashboard/v3/patient-bill-details/modals/bill-item-payment/bill-item-payment.modal.scss +6 -0
  535. package/src/billing/dashboard/v3/patient-bill-details/modals/bill-item-payment/bill-item-payment.modal.tsx +137 -0
  536. package/src/billing/dashboard/v3/patient-bill-details/modals/claim-details/claim-details.modal.scss +28 -0
  537. package/src/billing/dashboard/v3/patient-bill-details/modals/claim-details/claim-details.modal.tsx +170 -0
  538. package/src/billing/dashboard/v3/patient-bill-details/modals/pomsf/pomsf-scheme-balance.util.test.ts +56 -0
  539. package/src/billing/dashboard/v3/patient-bill-details/modals/pomsf/pomsf-scheme-balance.util.ts +27 -0
  540. package/src/billing/dashboard/v3/patient-bill-details/modals/pomsf/set-effective-pomsf-coverage.component.tsx +128 -0
  541. package/src/billing/dashboard/v3/patient-bill-details/modals/pomsf/set-effective-pomsf-coverage.scss +27 -0
  542. package/src/billing/dashboard/v3/patient-bill-details/patient-bill-details.scss +85 -0
  543. package/src/billing/dashboard/v3/patient-bill-details/patient-bill-details.tsx +363 -0
  544. package/src/billing/dashboard/v3/patient-bill-details/patient-visit-details.tsx +256 -0
  545. package/src/billing/dashboard/v3/patient-bill-details/patient-visit.scss +9 -0
  546. package/src/billing/dashboard/v3/patient-bill-details/visit-diagnosis-details/visit-diagnosis-details.component.scss +0 -0
  547. package/src/billing/dashboard/v3/patient-bill-details/visit-diagnosis-details/visit-diagnosis-details.component.tsx +102 -0
  548. package/src/billing/dashboard/v3/preauth/elective/elective-authorize.resource.ts +284 -0
  549. package/src/billing/dashboard/v3/preauth/elective/elective-preauth-request.workspace.scss +125 -0
  550. package/src/billing/dashboard/v3/preauth/elective/elective-preauth-request.workspace.tsx +1184 -0
  551. package/src/billing/dashboard/v3/preauth/elective/elective-preauth.component.scss +15 -0
  552. package/src/billing/dashboard/v3/preauth/elective/elective-preauth.component.tsx +377 -0
  553. package/src/billing/dashboard/v3/preauth/elective/elective-preauth.resource.ts +1378 -0
  554. package/src/billing/dashboard/v3/preauth/elective/elective-requests-list.component.tsx +357 -0
  555. package/src/billing/dashboard/v3/preauth/preauth-attachments.component.tsx +388 -0
  556. package/src/billing/dashboard/v3/preauth/preauth-list.component.scss +34 -0
  557. package/src/billing/dashboard/v3/preauth/preauth-list.component.tsx +300 -0
  558. package/src/billing/dashboard/v3/preauth/preauth-status-tag.component.tsx +75 -0
  559. package/src/billing/dashboard/v3/preauth/preauth-typed-fields.md +125 -0
  560. package/src/billing/dashboard/v3/preauth/preauth.resource.ts +1549 -0
  561. package/src/billing/dashboard/v3/preauth/preauth.workspace.scss +176 -0
  562. package/src/billing/dashboard/v3/preauth/preauth.workspace.tsx +2458 -0
  563. package/src/billing/dashboard/v3/preauth/preauthorizations-tab.component.tsx +55 -0
  564. package/src/billing/dashboard/v3/shared/empty-state.component.scss +25 -0
  565. package/src/billing/dashboard/v3/shared/empty-state.component.tsx +13 -0
  566. package/src/billing/dashboard/v3/shared/table-toolbar.component.scss +64 -0
  567. package/src/billing/dashboard/v3/shared/table-toolbar.component.tsx +48 -0
  568. package/src/billing/dashboard/v3/types/index.ts +450 -0
  569. package/src/billing/extensions/generate-order-bill-button/generate-order-bill-button.extension.tsx +55 -0
  570. package/src/billing/extensions/generate-order-bill-button/generate-order-bill-button.scss +16 -0
  571. package/src/billing/extensions/visit-billing/visit-billing.extension.scss +0 -0
  572. package/src/billing/extensions/visit-billing/visit-billing.extension.tsx +514 -0
  573. package/src/billing/invoice/bill.resource.ts +47 -0
  574. package/src/billing/invoice/invoice-header/header-card/header-card.scss +17 -0
  575. package/src/billing/invoice/invoice-header/header-card/header-card.tsx +21 -0
  576. package/src/billing/invoice/invoice.scss +113 -0
  577. package/src/billing/invoice/invoice.tsx +1441 -0
  578. package/src/billing/invoice/line-items/line-items.scss +0 -0
  579. package/src/billing/invoice/line-items/line-items.tsx +120 -0
  580. package/src/billing/invoice/modal/delete-bill-item/delete-bill-item.modal.scss +23 -0
  581. package/src/billing/invoice/modal/delete-bill-item/delete-bill-item.modal.tsx +114 -0
  582. package/src/billing/invoice/modal/edit-bill-item/edit-bill-item.modal.scss +0 -0
  583. package/src/billing/invoice/modal/edit-bill-item/edit-bill-item.modal.tsx +122 -0
  584. package/src/billing/invoice/payment-details/payment-details.scss +0 -0
  585. package/src/billing/invoice/payment-details/payment-details.tsx +43 -0
  586. package/src/billing/invoice/print-invoice/print-receipt.component.tsx +44 -0
  587. package/src/billing/invoice/print-invoice/print-receipt.scss +14 -0
  588. package/src/billing/maternity-discharge.resource.ts +21 -0
  589. package/src/billing/reports/billing-and-claims-reports-dashboard.scss +40 -0
  590. package/src/billing/reports/billing-and-claims-reports-dashboard.tsx +32 -0
  591. package/src/billing/reports/claims/claims-report-dashboard.scss +55 -0
  592. package/src/billing/reports/claims/claims-report-dashboard.tsx +136 -0
  593. package/src/billing/reports/claims/summary-data/summary-data.scss +24 -0
  594. package/src/billing/reports/claims/summary-data/summary-data.tsx +184 -0
  595. package/src/billing/types/index.ts +411 -0
  596. package/src/billing/utils/index.ts +17 -0
  597. package/src/billing/widgets/billingTotalsRow.component.scss +0 -0
  598. package/src/billing/widgets/billingTotalsRow.component.tsx +712 -0
  599. package/src/billing/workspaces/create-order-bill-form-workspace/create-order-bill-form.resource.ts +223 -0
  600. package/src/billing/workspaces/create-order-bill-form-workspace/create-order-bill-form.scss +58 -0
  601. package/src/billing/workspaces/create-order-bill-form-workspace/create-order-bill-form.workspace.tsx +874 -0
  602. package/src/billing/workspaces/create-order-bill-form-workspace/schema.ts +20 -0
  603. package/src/billing/workspaces/create-order-bill-form-workspace/types.ts +49 -0
  604. package/src/bookings/bookings.component.scss +7 -0
  605. package/src/bookings/bookings.component.tsx +35 -0
  606. package/src/bookings/daily/daily-bookings.resource.ts +2 -1
  607. package/src/case-summary/case-summary.extension.scss +13 -0
  608. package/src/case-summary/case-summary.extension.tsx +40 -0
  609. package/src/case-summary/case-summary.resource.test.ts +69 -0
  610. package/src/case-summary/case-summary.resource.ts +52 -0
  611. package/src/case-summary/components/case-summary-printable.component.scss +174 -0
  612. package/src/case-summary/components/case-summary-printable.component.tsx +288 -0
  613. package/src/case-summary/components/case-summary-printable.utils.ts +51 -0
  614. package/src/case-summary/types/case-summary.types.ts +152 -0
  615. package/src/claims/claims.component.scss +70 -0
  616. package/src/claims/claims.component.tsx +743 -0
  617. package/src/claims/claims.resource.ts +1855 -0
  618. package/src/claims/index.ts +365 -0
  619. package/src/claims/interventions.resource.ts +131 -0
  620. package/src/claims/utils.ts +64 -0
  621. package/src/config-schema.ts +264 -0
  622. package/src/context/patient-context.tsx +27 -0
  623. package/src/critical-care-unit/critical-care-root.tsx +23 -0
  624. package/src/critical-care-unit/hdu/hdu-queues.component.scss +7 -0
  625. package/src/critical-care-unit/hdu/hdu-queues.component.tsx +31 -0
  626. package/src/critical-care-unit/hdu/queues/consultation/hdu-consultation.tsx +18 -0
  627. package/src/critical-care-unit/icu/icu-queues.component.scss +7 -0
  628. package/src/critical-care-unit/icu/icu-queues.component.tsx +31 -0
  629. package/src/critical-care-unit/icu/queues/consultation/icu-consultation.tsx +17 -0
  630. package/src/critical-care-unit/icu-burns/icu-burns-queues.component.scss +7 -0
  631. package/src/critical-care-unit/icu-burns/icu-burns-queues.component.tsx +30 -0
  632. package/src/critical-care-unit/icu-burns/queues/consultation/icu-burns-consultation.tsx +17 -0
  633. package/src/critical-care-unit/nicu/nicu-queues.component.scss +7 -0
  634. package/src/critical-care-unit/nicu/nicu-queues.component.tsx +31 -0
  635. package/src/critical-care-unit/nicu/queues/consultation/nicu-consultation.tsx +17 -0
  636. package/src/critical-care-unit/picu/picu-queues.component.scss +7 -0
  637. package/src/critical-care-unit/picu/picu-queues.component.tsx +31 -0
  638. package/src/critical-care-unit/picu/queues/consultation/picu-consultation.tsx +17 -0
  639. package/src/dashboard/charts/chart.component.scss +24 -0
  640. package/src/dashboard/charts/chart.component.tsx +56 -0
  641. package/src/dashboard/dashboard.component.scss +48 -3
  642. package/src/dashboard/dashboard.component.tsx +29 -38
  643. package/src/dashboard/overview/overview.component.scss +40 -59
  644. package/src/dashboard/overview/overview.component.tsx +55 -41
  645. package/src/dashboard-meta/accounting-dashboard.meta.ts +6 -0
  646. package/src/dashboard-meta/admissions-dashboard.meta.ts +6 -0
  647. package/src/dashboard-meta/billing-dashboard.meta.ts +6 -0
  648. package/src/dashboard-meta/bookings-dashboard.meta.ts +6 -0
  649. package/src/dashboard-meta/case-summary.meta.ts +6 -0
  650. package/src/dashboard-meta/claims-admin.meta.ts +6 -0
  651. package/src/dashboard-meta/consultation-dashboard.meta.ts +6 -0
  652. package/src/dashboard-meta/dha-workflow-dashboard.meta.ts +6 -0
  653. package/src/dashboard-meta/elective-preauth.meta.ts +6 -0
  654. package/src/dashboard-meta/emt-dashboard.meta.ts +6 -0
  655. package/src/dashboard-meta/inpatient-admissions.meta.ts +6 -0
  656. package/src/dashboard-meta/maternity-dashboard.meta.ts +6 -0
  657. package/src/dashboard-meta/mch-dashboard.meta.ts +6 -0
  658. package/src/dashboard-meta/registers-dashboard.meta.ts +6 -0
  659. package/src/{registry-dashboard.meta.ts → dashboard-meta/registry-dashboard.meta.ts} +2 -2
  660. package/src/dashboard-meta/service-queue-admin.meta.ts +6 -0
  661. package/src/dashboard-meta/shr-dashboard.meta.ts +19 -0
  662. package/src/dashboard-meta/specialized-clinics-dashboard.meta.ts +6 -0
  663. package/src/dashboard-meta/telemedicine-dashboard.meta.ts +6 -0
  664. package/src/dashboard-meta/telemedicine-patient-chart.meta.ts +6 -0
  665. package/src/dashboard-meta/triage-dashboard.meta.ts +6 -0
  666. package/src/death-reporting/death-reporting-form-button.component.tsx +50 -0
  667. package/src/death-reporting/death-reporting-form-button.resource.ts +64 -0
  668. package/src/emt/cr-lookup.resource.test.ts +88 -0
  669. package/src/emt/cr-lookup.resource.ts +42 -0
  670. package/src/emt/emt-queue.component.test.tsx +353 -0
  671. package/src/emt/emt-queue.component.tsx +463 -0
  672. package/src/emt/emt-queue.scss +85 -0
  673. package/src/emt/emt.resource.test.ts +247 -0
  674. package/src/emt/emt.resource.ts +150 -0
  675. package/src/emt/handover-modal/handover-modal.component.test.tsx +273 -0
  676. package/src/emt/handover-modal/handover-modal.component.tsx +538 -0
  677. package/src/emt/handover-modal/handover-modal.scss +113 -0
  678. package/src/emt/types/emt.types.ts +137 -0
  679. package/src/index.ts +236 -10
  680. package/src/mnch/maternity/maternity-queues.component.scss +7 -0
  681. package/src/mnch/maternity/maternity-queues.component.tsx +32 -0
  682. package/src/mnch/maternity/queues/triage/maternity-triage.tsx +15 -0
  683. package/src/mnch/mch/mch-queues.component.scss +10 -0
  684. package/src/mnch/mch/mch-queues.component.tsx +36 -0
  685. package/src/{mch → mnch/mch}/queues/consultation/mch-consultation.tsx +2 -2
  686. package/src/{mch → mnch/mch}/queues/triage/mch-triage.tsx +2 -2
  687. package/src/mnch/mnch-root.tsx +17 -0
  688. package/src/mortuary/mortuary.component.tsx +2 -2
  689. package/src/pharmacy/pharmacy.component.scss +16 -0
  690. package/src/pharmacy/pharmacy.component.tsx +11 -6
  691. package/src/registers/registers.component.tsx +8 -0
  692. package/src/registry/drawer/emr-compare.component.scss +263 -0
  693. package/src/registry/drawer/emr-compare.component.tsx +302 -0
  694. package/src/registry/drawer/emr-compare.resource.ts +181 -0
  695. package/src/registry/drawer/emr-create-preview.component.tsx +123 -0
  696. package/src/registry/drawer/otp-verification-step.component.tsx +398 -0
  697. package/src/registry/drawer/pomsf-balance.util.test.ts +177 -0
  698. package/src/registry/drawer/pomsf-balance.util.ts +116 -0
  699. package/src/registry/drawer/verification.resource.ts +60 -0
  700. package/src/registry/drawer/workflow-drawer.component.scss +1242 -0
  701. package/src/registry/drawer/workflow-drawer.component.tsx +1542 -0
  702. package/src/registry/eligibility/eligibility-details/eligibility-details.scss +38 -0
  703. package/src/registry/eligibility/eligibility-details/eligibility-details.tsx +101 -0
  704. package/src/registry/eligibility/eliigibility-tags/eligibility-tags.scss +16 -0
  705. package/src/registry/eligibility/eliigibility-tags/eligibility-tags.tsx +120 -0
  706. package/src/registry/eligibility/modal/eligibility-details.modal.scss +0 -0
  707. package/src/registry/eligibility/modal/eligibility-details.modal.tsx +45 -0
  708. package/src/registry/emergency/emergency-extension.component.tsx +599 -0
  709. package/src/registry/emergency/emergency-helper.ts +47 -0
  710. package/src/registry/emergency/emergency.resource.ts +291 -0
  711. package/src/registry/emergency/emergency.scss +123 -0
  712. package/src/registry/emergency/otp-component.tsx +289 -0
  713. package/src/registry/emergency/type/index.ts +77 -0
  714. package/src/registry/emergency/unidentified/unidentified-registration.component.tsx +154 -0
  715. package/src/registry/emergency/unidentified/unidentified-registration.scss +0 -0
  716. package/src/registry/emergency/unidentified/unidentified.component.tsx +376 -0
  717. package/src/registry/emergency/unidentified/unidentified.scss +0 -0
  718. package/src/registry/hie.resource.ts +481 -0
  719. package/src/registry/hie.types.ts +63 -0
  720. package/src/registry/modal/biometrics-verification-modal/biometrics-verification-modal.scss +277 -0
  721. package/src/registry/modal/biometrics-verification-modal/biometrics-verification-modal.tsx +218 -0
  722. package/src/registry/modal/biometrics-verification-modal/type.ts +39 -0
  723. package/src/registry/modal/client-details-modal/client-details-modal.tsx +65 -29
  724. package/src/registry/modal/otp-modal/otp-whitlisting-modal.component.tsx +809 -0
  725. package/src/registry/modal/otp-modal/otp-whitlisting-modal.scss +354 -0
  726. package/src/registry/modal/otp-modal/otp-whitlisting.scss +0 -0
  727. package/src/registry/modal/otp-verification-modal/claims-consent.scss +72 -0
  728. package/src/registry/modal/otp-verification-modal/claims-consent.tsx +135 -0
  729. package/src/registry/modal/otp-verification-modal/extension/claims-consent.extension.tsx +130 -0
  730. package/src/registry/modal/otp-verification-modal/otp-verification-modal.scss +15 -3
  731. package/src/registry/modal/otp-verification-modal/otp-verification-modal.tsx +136 -44
  732. package/src/registry/modal/send-to-triage/payment-details.tsx +120 -0
  733. package/src/registry/modal/send-to-triage/payment-method.component.tsx +54 -0
  734. package/src/registry/modal/send-to-triage/send-to-queue.modal.tsx +991 -0
  735. package/src/registry/modal/send-to-triage/send-to-queue.workspace.tsx +24 -0
  736. package/src/registry/modal/send-to-triage/send-to-triage.modal.scss +156 -3
  737. package/src/registry/modal/send-to-triage/send-to-triage.modal.tsx +1086 -130
  738. package/src/registry/modal/start-patient-visit/start-patient-visit.modal.scss +34 -0
  739. package/src/registry/modal/start-patient-visit/start-patient-visit.modal.tsx +231 -0
  740. package/src/registry/payment-details/payment-options/payment-options.scss +13 -0
  741. package/src/registry/payment-details/payment-options/payment-options.tsx +61 -14
  742. package/src/registry/registration-list/registration-list.component.scss +32 -0
  743. package/src/registry/registration-list/registration-list.component.tsx +103 -0
  744. package/src/registry/registry-entry.tsx +11 -0
  745. package/src/registry/registry.component.scss +402 -78
  746. package/src/registry/registry.component.tsx +732 -220
  747. package/src/registry/registry.resource.ts +22 -3
  748. package/src/registry/types/index.ts +126 -9
  749. package/src/registry/utils/error-handler.ts +54 -0
  750. package/src/registry/utils/format-dependant-display-data.ts +1 -1
  751. package/src/registry/utils/hie-client-adapter.ts +7 -4
  752. package/src/registry/utils/mask-data.ts +40 -0
  753. package/src/registry/utils/phone-number-formatter.ts +11 -0
  754. package/src/resources/dashboard.resource.ts +20 -0
  755. package/src/resources/identifier-types.ts +2 -0
  756. package/src/resources/patient-resource.ts +7 -2
  757. package/src/resources/queue.resource.ts +3 -3
  758. package/src/resources/superset.resource.ts +41 -0
  759. package/src/resources/visit.resource.ts +19 -1
  760. package/src/root.component.tsx +9 -7
  761. package/src/routes.json +658 -30
  762. package/src/service-queues/admin/queue/modal/create-queue/create-queue.modal.scss +31 -0
  763. package/src/service-queues/admin/queue/modal/create-queue/create-queue.modal.tsx +193 -0
  764. package/src/service-queues/admin/queue/modal/edit-queue/edit-queue.modal.scss +0 -0
  765. package/src/service-queues/admin/queue/modal/edit-queue/edit-queue.modal.tsx +201 -0
  766. package/src/service-queues/admin/queue/queue-list/queue-list.scss +33 -0
  767. package/src/service-queues/admin/queue/queue-list/queue-list.tsx +113 -0
  768. package/src/service-queues/admin/queue-entry/queue-entry-list.component.scss +6 -0
  769. package/src/service-queues/admin/queue-entry/queue-entry-list.component.tsx +137 -0
  770. package/src/service-queues/admin/queue-room/modal/create-queue-room/create-queue-room.modal.scss +31 -0
  771. package/src/service-queues/admin/queue-room/modal/create-queue-room/create-queue-room.modal.tsx +137 -0
  772. package/src/service-queues/admin/queue-room/modal/edit-queue-room/edit-queue-room.modal.scss +0 -0
  773. package/src/service-queues/admin/queue-room/modal/edit-queue-room/edit-queue-room.modal.tsx +146 -0
  774. package/src/service-queues/admin/queue-room/queue-room-list/queue-room-list.scss +22 -0
  775. package/src/service-queues/admin/queue-room/queue-room-list/queue-room-list.tsx +120 -0
  776. package/src/service-queues/admin/service-queue-admin-dashboard.component.scss +6 -0
  777. package/src/service-queues/admin/service-queue-admin-dashboard.component.tsx +35 -0
  778. package/src/service-queues/consultation/consultation.component.tsx +9 -0
  779. package/src/service-queues/extensions/service-queue-patient-banner/service-queue-patient-banner.scss +30 -0
  780. package/src/service-queues/extensions/service-queue-patient-banner/service-queue-patient-banner.tsx +108 -0
  781. package/src/service-queues/modals/daily-report-patient-list/daily-report-patient-list.scss +26 -0
  782. package/src/service-queues/modals/daily-report-patient-list/daily-report-patient-list.tsx +110 -0
  783. package/src/service-queues/modals/move/move-patient.component.scss +1 -1
  784. package/src/service-queues/modals/move/move-patient.component.tsx +31 -17
  785. package/src/service-queues/queue-list/check-in.service.ts +26 -0
  786. package/src/service-queues/queue-list/queue-list.component.scss +37 -0
  787. package/src/service-queues/queue-list/queue-list.component.tsx +296 -60
  788. package/src/service-queues/service-queue/service-queue.component.tsx +151 -8
  789. package/src/service-queues/service-queue/stats/stat-details/stat-details.component.scss +5 -0
  790. package/src/service-queues/service-queue/stats/stat-details/stat-details.component.tsx +36 -7
  791. package/src/service-queues/service-queue.tsx +22 -16
  792. package/src/service-queues/service-queues.resource.ts +293 -2
  793. package/src/service-queues/service.resource.ts +1 -1
  794. package/src/shared/constants/concepts.ts +70 -0
  795. package/src/shared/constants/patient-category.ts +6 -0
  796. package/src/shared/constants/patient-type.ts +10 -0
  797. package/src/shared/constants/visit-types.ts +9 -0
  798. package/src/shared/services/billable-service.resource.ts +121 -0
  799. package/src/shared/services/billing.resource.ts +112 -0
  800. package/src/shared/services/claims.resource.ts +47 -0
  801. package/src/shared/services/client-payment-mode.resource.ts +27 -0
  802. package/src/shared/services/client-payment.resource.ts +17 -0
  803. package/src/shared/services/consultation-clearance.resource.ts +210 -0
  804. package/src/shared/services/eligibility.resource.ts +20 -0
  805. package/src/shared/services/encounters.resource.ts +33 -0
  806. package/src/shared/types/index.ts +156 -0
  807. package/src/shared/ui/aggregate-stat-card/aggregate-stat-card.scss +42 -0
  808. package/src/shared/ui/aggregate-stat-card/aggregate-stat-card.tsx +42 -0
  809. package/src/shared/ui/confirm-modal/confirm.modal.scss +18 -0
  810. package/src/shared/ui/confirm-modal/confirm.modal.tsx +38 -0
  811. package/src/shared/ui/facility-worker-slot/facility-worker.component-slot.component.scss +39 -0
  812. package/src/shared/ui/facility-worker-slot/facility-worker.component-slot.component.tsx +19 -0
  813. package/src/shared/ui/otp-input/otp-input.component.scss +12 -12
  814. package/src/shared/ui/otp-input/otp-input.component.tsx +13 -6
  815. package/src/{service-queues/service-queue/stats → shared/ui}/stat-card/stat-card.component.tsx +6 -3
  816. package/src/shared/utils/format-title-case.ts +8 -0
  817. package/src/shared/utils/get-base-url.ts +15 -0
  818. package/src/shared/utils/get-tag-type.ts +75 -0
  819. package/src/shr/shr-close-visit-form.component.tsx +102 -0
  820. package/src/shr/shr-code-systems.json +363 -0
  821. package/src/shr/shr-terminology.resource.test.ts +66 -0
  822. package/src/shr/shr-terminology.resource.ts +64 -0
  823. package/src/shr/shr-viewer/shr-categories.test.ts +241 -0
  824. package/src/shr/shr-viewer/shr-categories.ts +209 -0
  825. package/src/shr/shr-viewer/shr-presentation.test.ts +511 -0
  826. package/src/shr/shr-viewer/shr-presentation.ts +883 -0
  827. package/src/shr/shr-viewer/shr-viewer.component.test.tsx +176 -0
  828. package/src/shr/shr-viewer/shr-viewer.component.tsx +432 -0
  829. package/src/shr/shr-viewer/shr-viewer.scss +239 -0
  830. package/src/shr/shr-visit-sync.test.ts +88 -0
  831. package/src/shr/shr-visit-sync.ts +62 -0
  832. package/src/shr/shr.component.tsx +730 -0
  833. package/src/shr/shr.resource.test.ts +737 -0
  834. package/src/shr/shr.resource.ts +463 -0
  835. package/src/shr/shr.scss +114 -0
  836. package/src/shr/shr.types.ts +682 -0
  837. package/src/shr/workspaces/shr-consent-workspace/schema.ts +53 -0
  838. package/src/shr/workspaces/shr-consent-workspace/shr-consent.scss +71 -0
  839. package/src/shr/workspaces/shr-consent-workspace/shr-consent.workspace.tsx +686 -0
  840. package/src/side-nav-menu/accounting-nav-link-config.ts +16 -0
  841. package/src/side-nav-menu/accounting-nav-links.tsx +42 -0
  842. package/src/side-nav-menu/critical-care-nav-links.tsx +42 -0
  843. package/src/side-nav-menu/critical-care-unit-nav-link-config.ts +28 -0
  844. package/src/side-nav-menu/mnch-nav-link-config.ts +16 -0
  845. package/src/side-nav-menu/mnch-nav-links.tsx +42 -0
  846. package/src/side-nav-menu/nav-link-config.ts +5 -5
  847. package/src/side-nav-menu/specialized-clinics-nav-link-config.ts +32 -0
  848. package/src/side-nav-menu/specialized-clinics-nav-links.tsx +42 -0
  849. package/src/specialized-clinics/dental/dental-queues.component.scss +7 -0
  850. package/src/specialized-clinics/dental/dental-queues.component.tsx +36 -0
  851. package/src/specialized-clinics/dental/queues/consultation/dental-consultation.tsx +15 -0
  852. package/src/specialized-clinics/dental/queues/triage/dental-triage.tsx +15 -0
  853. package/src/specialized-clinics/diagnostic-and-imaging/diagnostic-and-imaging.component.scss +7 -0
  854. package/src/specialized-clinics/diagnostic-and-imaging/diagnostic-and-imaging.component.tsx +36 -0
  855. package/src/specialized-clinics/diagnostic-and-imaging/queues/consultation/diagnosis-and-imaging-consultation.tsx +15 -0
  856. package/src/specialized-clinics/diagnostic-and-imaging/queues/triage/diagnosis-and-imaging-triage.tsx +15 -0
  857. package/src/specialized-clinics/oncology/oncology-queues.component.scss +7 -0
  858. package/src/specialized-clinics/oncology/oncology-queues.component.tsx +36 -0
  859. package/src/specialized-clinics/oncology/queues/consultation/oncology-consultation.tsx +15 -0
  860. package/src/specialized-clinics/oncology/queues/triage/oncology-triage.tsx +15 -0
  861. package/src/specialized-clinics/ophthalmology/ophthalmology-queues.component.scss +7 -0
  862. package/src/specialized-clinics/ophthalmology/ophthalmology-queues.component.tsx +36 -0
  863. package/src/specialized-clinics/ophthalmology/queues/consultation/ophthalmology-consultation.tsx +15 -0
  864. package/src/specialized-clinics/ophthalmology/queues/triage/ophthalmology-triage.tsx +15 -0
  865. package/src/specialized-clinics/psychiatry/psychiatry-queues.component.scss +7 -0
  866. package/src/specialized-clinics/psychiatry/psychiatry-queues.component.tsx +36 -0
  867. package/src/specialized-clinics/psychiatry/queues/consultation/psychiatry-consultation.tsx +15 -0
  868. package/src/specialized-clinics/psychiatry/queues/triage/psychiatry-triage.tsx +15 -0
  869. package/src/specialized-clinics/renal/queues/consultation/dialysis-consultation.tsx +15 -0
  870. package/src/specialized-clinics/renal/queues/triage/renal-triage.tsx +15 -0
  871. package/src/specialized-clinics/renal/renal-queues.component.scss +7 -0
  872. package/src/specialized-clinics/renal/renal-queues.component.tsx +36 -0
  873. package/src/specialized-clinics/specialized-clinics-root.tsx +25 -0
  874. package/src/telemedicine/telemedicine-patient-chart.component.test.tsx +123 -0
  875. package/src/telemedicine/telemedicine-patient-chart.component.tsx +131 -0
  876. package/src/telemedicine/telemedicine.component.test.tsx +113 -0
  877. package/src/telemedicine/telemedicine.component.tsx +310 -0
  878. package/src/telemedicine/telemedicine.resource.test.ts +171 -0
  879. package/src/telemedicine/telemedicine.resource.ts +125 -0
  880. package/src/telemedicine/telemedicine.scss +91 -0
  881. package/src/triage/triage.component.scss +6 -0
  882. package/src/triage/triage.component.tsx +4 -0
  883. package/src/types/types.ts +56 -1
  884. package/tools/fetch-shr-code-systems.mjs +135 -0
  885. package/tools/strip-openmrs-declaration-maps.mjs +44 -0
  886. package/tools/update-openmrs-deps.mjs +36 -5
  887. package/translations/en.json +135 -0
  888. package/tsconfig.json +7 -4
  889. package/webpack.config.js +74 -1
  890. package/dist/104.js +0 -2
  891. package/dist/104.js.map +0 -1
  892. package/dist/15.js +0 -1
  893. package/dist/15.js.map +0 -1
  894. package/dist/184.js +0 -2
  895. package/dist/184.js.map +0 -1
  896. package/dist/246.js +0 -2
  897. package/dist/246.js.map +0 -1
  898. package/dist/255.js +0 -1
  899. package/dist/255.js.map +0 -1
  900. package/dist/28.js +0 -1
  901. package/dist/28.js.map +0 -1
  902. package/dist/300.js +0 -1
  903. package/dist/327.js +0 -1
  904. package/dist/327.js.map +0 -1
  905. package/dist/339.js +0 -1
  906. package/dist/339.js.map +0 -1
  907. package/dist/353.js +0 -1
  908. package/dist/353.js.map +0 -1
  909. package/dist/420.js +0 -1
  910. package/dist/420.js.map +0 -1
  911. package/dist/540.js +0 -2
  912. package/dist/540.js.map +0 -1
  913. package/dist/55.js +0 -1
  914. package/dist/619.js +0 -1
  915. package/dist/619.js.map +0 -1
  916. package/dist/65.js +0 -1
  917. package/dist/65.js.map +0 -1
  918. package/dist/709.js +0 -1
  919. package/dist/709.js.map +0 -1
  920. package/dist/710.js +0 -2
  921. package/dist/710.js.LICENSE.txt +0 -14
  922. package/dist/710.js.map +0 -1
  923. package/dist/729.js +0 -1
  924. package/dist/729.js.map +0 -1
  925. package/dist/752.js +0 -1
  926. package/dist/752.js.map +0 -1
  927. package/dist/833.js +0 -1
  928. package/dist/833.js.map +0 -1
  929. package/dist/93.js +0 -1
  930. package/dist/93.js.map +0 -1
  931. package/dist/99.js +0 -1
  932. /package/dist/{104.js.LICENSE.txt → 2272.js.LICENSE.txt} +0 -0
  933. /package/dist/{184.js.LICENSE.txt → 3184.js.LICENSE.txt} +0 -0
  934. /package/dist/{540.js.LICENSE.txt → 6540.js.LICENSE.txt} +0 -0
  935. /package/src/{pharmacy-dashboard.meta.ts → dashboard-meta/pharmacy-dashboard.meta.ts} +0 -0
  936. /package/src/{queue-dashboard.meta.ts → dashboard-meta/queue-dashboard.meta.ts} +0 -0
  937. /package/src/{service-queues/service-queue/stats → shared/ui}/stat-card/stat-card.component.scss +0 -0
@@ -0,0 +1,1542 @@
1
+ import React, { useEffect, useRef, useState } from 'react';
2
+ import {
3
+ Button,
4
+ ComboBox,
5
+ Dropdown,
6
+ FileUploaderItem,
7
+ FormLabel,
8
+ InlineLoading,
9
+ Modal,
10
+ ProgressIndicator,
11
+ ProgressStep,
12
+ RadioButton,
13
+ RadioButtonGroup,
14
+ Table,
15
+ TableBody,
16
+ TableCell,
17
+ TableHead,
18
+ TableHeader,
19
+ TableRow,
20
+ Tag,
21
+ } from '@carbon/react';
22
+ import {
23
+ ArrowRight,
24
+ CheckboxCheckedFilled,
25
+ CheckmarkOutline,
26
+ CloudUpload,
27
+ Close,
28
+ // FingerprintRecognition,
29
+ Information,
30
+ PendingFilled,
31
+ Renew,
32
+ // ScanDisabled,
33
+ WarningAltFilled,
34
+ } from '@carbon/react/icons';
35
+ import { type Patient, showSnackbar } from '@openmrs/esm-framework';
36
+ import styles from './workflow-drawer.component.scss';
37
+ import { type HieClient, type RequestCustomOtpDto, type Scheme } from '../types';
38
+ import { getClientEligibityStatus } from '../../shared/services/eligibility.resource';
39
+ import { maskCrNumber, maskExceptFirstAndLast } from '../utils/mask-data';
40
+ import OtpVerificationStep from './otp-verification-step.component';
41
+ import EmrCompare from './emr-compare.component';
42
+ import EmrCreatePreview from './emr-create-preview.component';
43
+ import {
44
+ // getBiometricCaptureUrl,
45
+ getOtpWhitelistStatus,
46
+ // isBiometricConfigured,
47
+ requestOtpWhitelist,
48
+ } from './verification.resource';
49
+ import { fetchServiceQueuesByLocationUuid } from '../../resources/queue.resource';
50
+ import { fetchCashPoints, fetchPaymentModes } from '../../shared/services/billing.resource';
51
+ import { getReadableErrorMessage } from '../utils/error-handler';
52
+ import { fetchPomsfBalance } from '../../claims/claims.resource';
53
+ import { type Intervention, type ClaimResult, type PomsfBalance } from '../../claims';
54
+ import { formatKes, getAllPomsfBenefitBalances, getPomsfDisplayBalance, isPomsfActive } from './pomsf-balance.util';
55
+ import EmergencySlotComponent from '../emergency/emergency-extension.component';
56
+ import { generateReferenceNumber, type EmergencyFormData } from '../emergency/type';
57
+ import { sendEmergencyClaimIdentified } from '../emergency/emergency.resource';
58
+
59
+ type Phase =
60
+ // | 'biometric'
61
+ // | 'biometric-not-setup'
62
+ 'otp-gate' | 'whitelist-request' | 'whitelist-pending' | 'otp' | 'consent' | 'visit';
63
+
64
+ type Method = 'cash' | 'insurance';
65
+
66
+ type RequiredField = 'visitType' | 'room' | 'insurance';
67
+
68
+ const STEPS = ['Verify & consent', 'Start visit'];
69
+ // Retained for the commented biometric/OTP whitelist workflow below.
70
+ const BIOMETRIC_MAX_ATTEMPTS = 3;
71
+
72
+ // Decode HTML entities in backend-provided names (e.g. "Accident & Emergency").
73
+ function decodeHtmlEntities(value: string): string {
74
+ if (!value || typeof document === 'undefined') {
75
+ return value;
76
+ }
77
+ const el = document.createElement('textarea');
78
+ el.innerHTML = value;
79
+ return el.value;
80
+ }
81
+ const OTP_EXPIRY_SECONDS = 300; // 5 minutes
82
+
83
+ // Where the patient is sent first, and the rooms available for each category.
84
+ const PATIENT_CATEGORIES = ['Triage', 'Walk-in', 'CCC'];
85
+ const WALK_IN_ROOMS = [];
86
+
87
+ // Payment modes that are direct payment (not insurance schemes) — excluded from
88
+ // the insurance-scheme list.
89
+ const NON_INSURANCE_PAYMENT_MODES = /cash|mpesa|m-pesa|waiver/i;
90
+
91
+ // OpenMRS visit types (searchable).
92
+ const VISIT_TYPE_OPTIONS = ['Outpatient', 'Inpatient', 'Emergency'];
93
+
94
+ // Keys that still have to work while an option is selected: menu navigation, commit
95
+ // and dismiss. Everything else that would mutate the text is blocked below.
96
+ const SELECTION_NAV_KEYS = new Set([
97
+ 'Tab',
98
+ 'Enter',
99
+ 'Escape',
100
+ 'ArrowUp',
101
+ 'ArrowDown',
102
+ 'ArrowLeft',
103
+ 'ArrowRight',
104
+ 'Home',
105
+ 'End',
106
+ 'Shift',
107
+ 'Control',
108
+ 'Alt',
109
+ 'Meta',
110
+ ]);
111
+
112
+ // A picked option behaves as a single locked token: while one is selected the field
113
+ // can't be typed into, pasted into, or erased from the keyboard, so it can never hold
114
+ // a half-edited label that still reads as a valid selection. Clearing is deliberate —
115
+ // only the combo box's ✕ button removes a selection. Bound on the wrapper in the
116
+ // capture phase so these run before Carbon's own handlers.
117
+ function lockSelection(hasSelection: boolean) {
118
+ const block = (event: React.SyntheticEvent) => {
119
+ event.preventDefault();
120
+ event.stopPropagation();
121
+ };
122
+ return {
123
+ onKeyDownCapture: (event: React.KeyboardEvent) => {
124
+ if (!hasSelection) {
125
+ return;
126
+ }
127
+ // Backspace/Delete included: use the ✕ button to change a selection.
128
+ if (event.key === 'Backspace' || event.key === 'Delete') {
129
+ block(event);
130
+ return;
131
+ }
132
+ // Let shortcuts through — an actual paste is stopped by onPasteCapture.
133
+ if (SELECTION_NAV_KEYS.has(event.key) || event.ctrlKey || event.metaKey) {
134
+ return;
135
+ }
136
+ // Any single-character key would append to the locked label.
137
+ if (event.key.length === 1) {
138
+ block(event);
139
+ }
140
+ },
141
+ onPasteCapture: (event: React.ClipboardEvent) => {
142
+ if (hasSelection) {
143
+ block(event);
144
+ }
145
+ },
146
+ };
147
+ }
148
+
149
+ // Carbon's ComboBox shows every item unless it's given a shouldFilterItem, so each
150
+ // searchable dropdown gets one of these. Once an item is picked Carbon puts its label
151
+ // in the input, which would otherwise filter the reopened menu down to that one item —
152
+ // hence treating "input equals the current selection" as an empty query.
153
+ function filterByLabel<T>(toLabel: (item: T) => string, selectedLabel: string) {
154
+ return ({ item, inputValue }: { item: T; inputValue: string | null }) => {
155
+ const query = (inputValue ?? '').trim().toLowerCase();
156
+ if (!query || query === (selectedLabel ?? '').trim().toLowerCase()) {
157
+ return true;
158
+ }
159
+ return toLabel(item).toLowerCase().includes(query);
160
+ };
161
+ }
162
+
163
+ // Reasons biometric identification could not be used (option set for the request).
164
+ const WHITELIST_REASONS = [
165
+ 'Biometric device not working',
166
+ 'Patient fingerprints not readable',
167
+ 'Patient has no usable fingerprints',
168
+ 'Fingerprint repeatedly not matching',
169
+ 'Other',
170
+ ];
171
+
172
+ const phaseToIndex: Record<Phase, number> = {
173
+ // biometric: 0,
174
+ // 'biometric-not-setup': 0,
175
+ 'otp-gate': 0,
176
+ 'whitelist-request': 0,
177
+ 'whitelist-pending': 0,
178
+ otp: 0,
179
+ consent: 0,
180
+ visit: 1,
181
+ };
182
+
183
+ interface WorkflowDrawerProps {
184
+ open: boolean;
185
+ client?: HieClient;
186
+ clientType?: string;
187
+ locationUuid?: string;
188
+ requestCustomOtpDto?: RequestCustomOtpDto;
189
+ phoneNumber?: string;
190
+ // EMR lookup result for the client, so the user can create or sync the record.
191
+ amrsPatient?: Patient | null;
192
+ amrsChecked?: boolean;
193
+ syncingAmrs?: boolean;
194
+ onCreatePatient?: () => void;
195
+ onSyncPatient?: () => void;
196
+ onClose: () => void;
197
+ onStartVisit: (details: {
198
+ patientCategory: string;
199
+ room: string;
200
+ roomUuid: string;
201
+ visitType: string;
202
+ method?: Method;
203
+ insurance?: string;
204
+ emergencyResponse?: ClaimResult;
205
+ emergencyCashPointUuid?: string;
206
+ emergencyServicePriceUuid?: string;
207
+ emergencyIntervention?: Intervention;
208
+ protocolCode?: string;
209
+ }) => Promise<void>;
210
+ }
211
+
212
+ const WorkflowDrawer: React.FC<WorkflowDrawerProps> = ({
213
+ open,
214
+ client,
215
+ clientType,
216
+ locationUuid,
217
+ requestCustomOtpDto,
218
+ phoneNumber,
219
+ amrsPatient,
220
+ amrsChecked,
221
+ syncingAmrs,
222
+ onCreatePatient,
223
+ onSyncPatient,
224
+ onClose,
225
+ onStartVisit,
226
+ }) => {
227
+ const [phase, setPhase] = useState<Phase>('otp');
228
+ const [pendingEmrAction, setPendingEmrAction] = useState<'create' | 'sync' | null>(null);
229
+ const [isOtpWhitelisted, setIsOtpWhitelisted] = useState(false);
230
+ const [consent, setConsent] = useState(false);
231
+ // const [launchingBiometric, setLaunchingBiometric] = useState(false);
232
+ // const [biometricUrl, setBiometricUrl] = useState<string | null>(null);
233
+ // Retained for the commented biometric/OTP whitelist workflow below.
234
+ const [failCount, setFailCount] = useState(0);
235
+ const [checkingWhitelist, setCheckingWhitelist] = useState(false);
236
+ const [submittingWhitelist, setSubmittingWhitelist] = useState(false);
237
+ const [showWhitelistForm, setShowWhitelistForm] = useState(false);
238
+ const [reason, setReason] = useState('');
239
+ const [failedImage, setFailedImage] = useState<File | null>(null);
240
+ const [reasonError, setReasonError] = useState('');
241
+ const [imageError, setImageError] = useState('');
242
+ const [dragOver, setDragOver] = useState(false);
243
+ const fileInputRef = useRef<HTMLInputElement>(null);
244
+ const [method, setMethod] = useState<Method>('insurance');
245
+ const [patientCategory, setPatientCategory] = useState<string>(PATIENT_CATEGORIES[0]);
246
+ const [room, setRoom] = useState<string>('');
247
+ const [insurance, setInsurance] = useState<string>('');
248
+ const [visitType, setVisitType] = useState<string>('');
249
+ const [triageRooms, setTriageRooms] = useState<string[]>([]);
250
+ // Maps each triage room label to its service-queue uuid, needed to enqueue the patient.
251
+ const [triageQueueByRoom, setTriageQueueByRoom] = useState<Record<string, string>>({});
252
+ const [loadingRooms, setLoadingRooms] = useState(false);
253
+ const [insuranceSchemes, setInsuranceSchemes] = useState<string[]>([]);
254
+ const [loadingSchemes, setLoadingSchemes] = useState(false);
255
+ const [hasCashPoint, setHasCashPoint] = useState<boolean | null>(null);
256
+ const [hasCashMode, setHasCashMode] = useState<boolean | null>(null);
257
+ const [schemes, setSchemes] = useState<Scheme[]>([]);
258
+ const [loadingEligibility, setLoadingEligibility] = useState(false);
259
+ const [eligibilityChecked, setEligibilityChecked] = useState(false);
260
+ const [pomsfBalance, setPomsfBalance] = useState<PomsfBalance | null>(null);
261
+ const [insuranceError, setInsuranceError] = useState('');
262
+ // Required fields only flag once the user has actually been in them, so the step
263
+ // doesn't open pre-painted red. Each clears the moment its field has a value.
264
+ const [touched, setTouched] = useState<Record<RequiredField, boolean>>({
265
+ visitType: false,
266
+ room: false,
267
+ insurance: false,
268
+ });
269
+ const [emergencyForm, setEmergencyForm] = useState<EmergencyFormData>();
270
+ const [emergencyFormValid, setEmergencyFormValid] = useState(false);
271
+ const [startingVisit, setStartingVisit] = useState(false);
272
+ const markTouched = (field: RequiredField) => () =>
273
+ setTouched((prev) => (prev[field] ? prev : { ...prev, [field]: true }));
274
+
275
+ useEffect(() => {
276
+ if (open) {
277
+ setPhase('otp');
278
+ setPendingEmrAction(null);
279
+ setIsOtpWhitelisted(false);
280
+ setConsent(false);
281
+ // setLaunchingBiometric(false);
282
+ // setBiometricUrl(null);
283
+ // setFailCount(0);
284
+ setReason('');
285
+ setFailedImage(null);
286
+ setReasonError('');
287
+ setImageError('');
288
+ setShowWhitelistForm(false);
289
+ setMethod('insurance');
290
+ setPatientCategory(PATIENT_CATEGORIES[0]);
291
+ setRoom('');
292
+ setInsurance('');
293
+ setVisitType('');
294
+ setInsuranceError('');
295
+ setTriageRooms([]);
296
+ setTriageQueueByRoom({});
297
+ setInsuranceSchemes([]);
298
+ setHasCashPoint(null);
299
+ setHasCashMode(null);
300
+ setEligibilityChecked(false);
301
+ setTouched({ visitType: false, room: false, insurance: false });
302
+ setStartingVisit(false);
303
+ }
304
+ }, [open]);
305
+
306
+ // Load the patient's eligibility schemes up front so the eligible schemes and
307
+ // SHA eligibility can be shown on the consent summary and appended to the SHA
308
+ // payment option.
309
+ useEffect(() => {
310
+ if (!open || !client?.id || !locationUuid) {
311
+ return;
312
+ }
313
+ let active = true;
314
+ setLoadingEligibility(true);
315
+ setSchemes([]);
316
+ setEligibilityChecked(false);
317
+ getClientEligibityStatus({ requestIdNumber: client.id, requestIdType: '3', locationUuid })
318
+ .then((resp) => {
319
+ if (!active) {
320
+ return;
321
+ }
322
+ setSchemes(resp?.schemes ?? []);
323
+ setEligibilityChecked(true);
324
+ })
325
+ .catch(() => {
326
+ if (active) {
327
+ setSchemes([]);
328
+ setEligibilityChecked(false);
329
+ }
330
+ })
331
+ .finally(() => {
332
+ if (active) {
333
+ setLoadingEligibility(false);
334
+ }
335
+ });
336
+ return () => {
337
+ active = false;
338
+ };
339
+ }, [open, client?.id, locationUuid]);
340
+
341
+ // POMSF's balance lives behind a separate HIE endpoint (/pomsf-balance) from
342
+ // the /eligibility call above, so it's fetched independently — gated only on
343
+ // POMSF being Active (regardless of which scheme is selected in the dropdown,
344
+ // since the Eligibility row below lists every active scheme unconditionally),
345
+ // and never on Visit type. That means switching Visit type afterwards just
346
+ // re-picks a benefit line out of the response already in state (see
347
+ // pomsf-balance.util.ts) rather than re-fetching. Uses a plain fetch rather
348
+ // than the usePomsfBalance hook, which pulls in useConfig({ externalModuleName
349
+ // }) and has been observed to throw here.
350
+ const pomsfActive = isPomsfActive(schemes);
351
+ useEffect(() => {
352
+ if (!open || !pomsfActive || !client?.id || !locationUuid) {
353
+ setPomsfBalance(null);
354
+ return;
355
+ }
356
+ let active = true;
357
+ fetchPomsfBalance(client.id, locationUuid)
358
+ .then((balance) => {
359
+ if (active) {
360
+ setPomsfBalance(balance);
361
+ }
362
+ })
363
+ .catch(() => {
364
+ if (active) {
365
+ setPomsfBalance(null);
366
+ }
367
+ });
368
+ return () => {
369
+ active = false;
370
+ };
371
+ }, [open, pomsfActive, client?.id, locationUuid]);
372
+
373
+ // Load triage service queues for the LOGGED-IN location only (queues whose
374
+ // name contains "triage"), so rooms from other locations aren't shown.
375
+ useEffect(() => {
376
+ if (!open || !locationUuid) {
377
+ return;
378
+ }
379
+ let active = true;
380
+ setLoadingRooms(true);
381
+ fetchServiceQueuesByLocationUuid(locationUuid)
382
+ .then((resp) => {
383
+ if (!active) {
384
+ return;
385
+ }
386
+ const triageQueues = (resp?.results ?? [])
387
+ // Strictly this location — never queues from sibling/child locations.
388
+ .filter((q) => q.location?.uuid === locationUuid)
389
+ .filter((q) => /triage/i.test(q.name ?? q.display ?? ''))
390
+ .map((q) => ({ label: decodeHtmlEntities(q.display || q.name), uuid: q.uuid }))
391
+ .filter((q) => q.label && q.uuid);
392
+ const byRoom: Record<string, string> = {};
393
+ for (const q of triageQueues) {
394
+ // First queue wins for a given label (deduped below for the dropdown).
395
+ if (!byRoom[q.label]) {
396
+ byRoom[q.label] = q.uuid;
397
+ }
398
+ }
399
+ setTriageQueueByRoom(byRoom);
400
+ setTriageRooms(Array.from(new Set(triageQueues.map((q) => q.label))));
401
+ })
402
+ .catch((err) => {
403
+ if (active) {
404
+ showSnackbar({
405
+ kind: 'error',
406
+ title: 'Couldn’t load triage rooms',
407
+ subtitle: getReadableErrorMessage(err, 'Please try again.'),
408
+ });
409
+ }
410
+ })
411
+ .finally(() => {
412
+ if (active) {
413
+ setLoadingRooms(false);
414
+ }
415
+ });
416
+ return () => {
417
+ active = false;
418
+ };
419
+ }, [open, locationUuid]);
420
+
421
+ // Payment modes are global; cash points are what's tied to a location. So we
422
+ // (1) check the logged-in location has a cash point (can it collect payment),
423
+ // and (2) load the global insurance schemes for the dropdown.
424
+ useEffect(() => {
425
+ if (!open || !locationUuid) {
426
+ return;
427
+ }
428
+ let active = true;
429
+ setLoadingSchemes(true);
430
+ Promise.all([fetchCashPoints(), fetchPaymentModes()])
431
+ .then(([cashPoints, modes]) => {
432
+ if (!active) {
433
+ return;
434
+ }
435
+ const facilityCashPoints = (cashPoints ?? []).filter((cp) => !cp.retired && cp.location?.uuid === locationUuid);
436
+ setHasCashPoint(facilityCashPoints.length > 0);
437
+
438
+ // Whether a "cash" payment mode is configured on the backend.
439
+ setHasCashMode((modes ?? []).some((m) => !m.retired && /cash/i.test(m.name ?? '')));
440
+
441
+ const schemes = (modes ?? [])
442
+ .filter((m) => !m.retired && m.name && !NON_INSURANCE_PAYMENT_MODES.test(m.name))
443
+ .map((m) => decodeHtmlEntities(m.name));
444
+ setInsuranceSchemes(Array.from(new Set(schemes)));
445
+ })
446
+ .catch((err) => {
447
+ if (active) {
448
+ showSnackbar({
449
+ kind: 'error',
450
+ title: 'Couldn’t load payment options',
451
+ subtitle: getReadableErrorMessage(err, 'Please try again.'),
452
+ });
453
+ }
454
+ })
455
+ .finally(() => {
456
+ if (active) {
457
+ setLoadingSchemes(false);
458
+ }
459
+ });
460
+ return () => {
461
+ active = false;
462
+ };
463
+ }, [open, locationUuid]);
464
+
465
+ // Check upfront whether OTP is already whitelisted for this client, so that
466
+ // when biometrics fail we can go straight to sending the OTP.
467
+ useEffect(() => {
468
+ if (!open || !client) {
469
+ return;
470
+ }
471
+ let active = true;
472
+ getOtpWhitelistStatus(client.id).then((status) => {
473
+ if (active) {
474
+ setIsOtpWhitelisted(status === 'approved');
475
+ }
476
+ });
477
+ return () => {
478
+ active = false;
479
+ };
480
+ // eslint-disable-next-line react-hooks/exhaustive-deps
481
+ }, [open]);
482
+
483
+ // When we reach the OTP gate, resolve the whitelist status and route accordingly.
484
+ useEffect(() => {
485
+ if (phase !== 'otp-gate' || !client) {
486
+ return;
487
+ }
488
+ let active = true;
489
+ setCheckingWhitelist(true);
490
+ getOtpWhitelistStatus(client.id)
491
+ .then((status) => {
492
+ if (!active) return;
493
+ if (status === 'approved') {
494
+ setPhase('otp');
495
+ } else if (status === 'pending') {
496
+ setPhase('whitelist-pending');
497
+ } else {
498
+ setPhase('whitelist-request');
499
+ }
500
+ })
501
+ .finally(() => active && setCheckingWhitelist(false));
502
+ return () => {
503
+ active = false;
504
+ };
505
+ // eslint-disable-next-line react-hooks/exhaustive-deps
506
+ }, [phase]);
507
+
508
+ if (!open || !client) {
509
+ return null;
510
+ }
511
+
512
+ const fullName = `${client.first_name} ${maskExceptFirstAndLast(client.middle_name)} ${maskExceptFirstAndLast(
513
+ client.last_name,
514
+ )}`;
515
+
516
+ // Selected person shown as a patient header: initials avatar (colour-coded by
517
+ // type) + name and type on one line, CR number on a subtle second line.
518
+ const isPrincipal = clientType === 'Principal';
519
+ const initials = `${client.first_name?.[0] ?? ''}${client.last_name?.[0] ?? ''}`.toUpperCase();
520
+ const clientStrip = (
521
+ <div className={styles.patientStrip}>
522
+ <span className={`${styles.patientAvatar} ${isPrincipal ? styles.avatarPrincipal : styles.avatarDependant}`}>
523
+ {initials}
524
+ </span>
525
+ <div className={styles.patientInfo}>
526
+ <div className={styles.patientLine1}>
527
+ <span className={styles.patientName}>{fullName}</span>
528
+ {clientType ? (
529
+ <Tag type={isPrincipal ? 'blue' : 'teal'} size="sm">
530
+ {clientType}
531
+ </Tag>
532
+ ) : null}
533
+ </div>
534
+ <span className={styles.patientCr}>CR · {maskCrNumber(client.id)}</span>
535
+ </div>
536
+ </div>
537
+ );
538
+
539
+ // The single action button on the EMR status card. Clicking it opens a focused
540
+ // confirmation dialog (emrConfirmModal) rather than expanding the card inline.
541
+ const emrActionArea = (kind: 'create' | 'sync') => {
542
+ const handler = kind === 'create' ? onCreatePatient : onSyncPatient;
543
+ if (!handler) {
544
+ return null;
545
+ }
546
+ return kind === 'create' ? (
547
+ <Button kind="primary" size="sm" onClick={() => setPendingEmrAction('create')}>
548
+ Create in EMR
549
+ </Button>
550
+ ) : (
551
+ <Button
552
+ kind="tertiary"
553
+ size="sm"
554
+ renderIcon={Renew}
555
+ disabled={syncingAmrs}
556
+ onClick={() => setPendingEmrAction('sync')}
557
+ >
558
+ {syncingAmrs ? 'Syncing…' : 'Sync'}
559
+ </Button>
560
+ );
561
+ };
562
+
563
+ // Focused confirmation dialog for the create / sync EMR actions.
564
+ const emrConfirmModal = (
565
+ <Modal
566
+ open={pendingEmrAction !== null}
567
+ size="sm"
568
+ modalHeading={pendingEmrAction === 'create' ? 'Create patient in the EMR?' : 'Sync EMR record?'}
569
+ primaryButtonText={pendingEmrAction === 'create' ? 'Yes, create' : 'Yes, sync'}
570
+ secondaryButtonText="Cancel"
571
+ primaryButtonDisabled={syncingAmrs}
572
+ onRequestClose={() => setPendingEmrAction(null)}
573
+ onSecondarySubmit={() => setPendingEmrAction(null)}
574
+ onRequestSubmit={() => {
575
+ const action = pendingEmrAction;
576
+ setPendingEmrAction(null);
577
+ if (action === 'create') {
578
+ onCreatePatient?.();
579
+ } else if (action === 'sync') {
580
+ onSyncPatient?.();
581
+ }
582
+ }}
583
+ >
584
+ <p className={styles.emrConfirmText}>
585
+ {pendingEmrAction === 'create'
586
+ ? `This patient does not yet exist in our records. A new EMR record will be created for CR ${maskCrNumber(
587
+ client.id,
588
+ )} so they can be registered and attended to.`
589
+ : `This patient already exists in our records. Their EMR record for CR ${maskCrNumber(
590
+ client.id,
591
+ )} will be updated with the latest registry details so their information is current before they are attended to.`}
592
+ </p>
593
+ </Modal>
594
+ );
595
+
596
+ // Shows the EMR lookup result for the client and lets the user act on it:
597
+ // create the patient in the EMR (not found) or sync an existing record (found).
598
+ const emrStatusCard = !amrsChecked ? null : amrsPatient ? (
599
+ <div>
600
+ {/* <div className={`${styles.emrStatus} ${styles.emrStatusFound}`}> */}
601
+ {/* <span className={styles.emrStatusIcon}>
602
+ <CheckmarkOutline size={20} />
603
+ </span>
604
+ <div className={styles.emrStatusBody}>
605
+ <span className={styles.emrStatusTitle}>Patient found in the EMR</span>
606
+ <span className={styles.emrStatusText}>
607
+ CR {maskCrNumber(client.id)} already has a record. Review the differences below and update the EMR with the
608
+ details you choose.
609
+ </span>
610
+ {amrsPatient.uuid ? (
611
+ <EmrCompare client={client} patientUuid={amrsPatient.uuid} onUpdated={onSyncPatient} />
612
+ ) : null}
613
+ </div> */}
614
+ </div>
615
+ ) : (
616
+ <div className={`${styles.emrStatus} ${styles.emrStatusMissing}`}>
617
+ <span className={styles.emrStatusIcon}>
618
+ <WarningAltFilled size={20} />
619
+ </span>
620
+ <div className={styles.emrStatusBody}>
621
+ <span className={styles.emrStatusTitle}>Patient not found in the system</span>
622
+ <span className={styles.emrStatusText}>
623
+ No EMR record matches CR {maskCrNumber(client.id)}. Review the details below and create the record to
624
+ continue.
625
+ </span>
626
+ <EmrCreatePreview client={client} onCreate={() => onCreatePatient?.()} />
627
+ </div>
628
+ </div>
629
+ );
630
+
631
+ /*
632
+ const launchBiometric = async () => {
633
+ setLaunchingBiometric(true);
634
+ try {
635
+ const url = await getBiometricCaptureUrl(client.id);
636
+ if (url) {
637
+ setBiometricUrl(url);
638
+ } else {
639
+ showSnackbar({ kind: 'error', title: 'Could not start biometric capture', subtitle: 'Please try again.' });
640
+ }
641
+ } finally {
642
+ setLaunchingBiometric(false);
643
+ }
644
+ };
645
+
646
+ const handleBiometricFailed = () => {
647
+ const attempts = failCount + 1;
648
+ setFailCount(attempts);
649
+ setBiometricUrl(null);
650
+ // Messaging is shown in-page (fail count on the scanner, fallback note on the
651
+ // OTP screen) rather than as toasts.
652
+ if (attempts >= BIOMETRIC_MAX_ATTEMPTS) {
653
+ // If OTP is already whitelisted, go straight to sending it (with the
654
+ // override option); otherwise route through the whitelist gate.
655
+ setPhase(isOtpWhitelisted ? 'otp' : 'otp-gate');
656
+ }
657
+ };
658
+ */
659
+
660
+ // `stay` keeps the current screen (both buttons) instead of moving to the
661
+ // pending screen when the status is not yet approved.
662
+ const checkWhitelistStatus = async (stay = false) => {
663
+ setCheckingWhitelist(true);
664
+ try {
665
+ const status = await getOtpWhitelistStatus(client.id);
666
+ if (status === 'approved') {
667
+ setIsOtpWhitelisted(true);
668
+ showSnackbar({ kind: 'success', title: 'Whitelisted', subtitle: 'You can now use OTP verification.' });
669
+ setPhase('otp');
670
+ } else {
671
+ showSnackbar({ kind: 'info', title: 'Awaiting approval', subtitle: 'The SHA team has not approved this yet.' });
672
+ if (!stay) {
673
+ setPhase('whitelist-pending');
674
+ }
675
+ }
676
+ } finally {
677
+ setCheckingWhitelist(false);
678
+ }
679
+ };
680
+
681
+ const submitWhitelistRequest = async () => {
682
+ // Inline validation
683
+ let valid = true;
684
+ if (!reason.trim()) {
685
+ setReasonError('Select a reason for OTP');
686
+ valid = false;
687
+ } else {
688
+ setReasonError('');
689
+ }
690
+ if (!failedImage) {
691
+ setImageError('Attach an image of the failed biometric');
692
+ valid = false;
693
+ } else {
694
+ setImageError('');
695
+ }
696
+ if (!valid) {
697
+ return;
698
+ }
699
+ setSubmittingWhitelist(true);
700
+ try {
701
+ await requestOtpWhitelist({
702
+ crId: client.id,
703
+ reason,
704
+ failureCount: failCount,
705
+ failedBiometricImage: failedImage,
706
+ });
707
+ showSnackbar({ kind: 'success', title: 'Request submitted', subtitle: 'Awaiting approval from the SHA team.' });
708
+ setPhase('whitelist-pending');
709
+ } finally {
710
+ setSubmittingWhitelist(false);
711
+ }
712
+ };
713
+
714
+ const handleStartVisit = async () => {
715
+ const usingInsurance = method === 'insurance';
716
+
717
+ if (!room || !visitType || (usingInsurance && !insurance)) {
718
+ return;
719
+ }
720
+ setStartingVisit(true);
721
+ try {
722
+ let emergencyResponse: ClaimResult = {} as ClaimResult;
723
+ if (visitType === 'Emergency') {
724
+ const res = await sendEmergencyClaimIdentified(
725
+ emergencyForm?.modeOfArrival,
726
+ emergencyForm?.broughtBy,
727
+ locationUuid,
728
+ emergencyForm?.interventionCode,
729
+ generateReferenceNumber(),
730
+ client?.id,
731
+ emergencyForm?.providerNationalId,
732
+ emergencyForm?.identificationType,
733
+ emergencyForm?.licensingBody,
734
+ emergencyForm?.notes,
735
+ emergencyForm?.otp,
736
+ );
737
+
738
+ if (res && 'error' in res && 'message' in res) {
739
+ const message = res.message ?? '';
740
+ showSnackbar({
741
+ kind: 'error',
742
+ title: 'An error occured while starting the visit',
743
+ subtitle: message,
744
+ });
745
+ return;
746
+ }
747
+ emergencyResponse = res;
748
+ }
749
+
750
+ await onStartVisit({
751
+ patientCategory,
752
+ room,
753
+ roomUuid: triageQueueByRoom[room] ?? '',
754
+ visitType,
755
+ method,
756
+ insurance: usingInsurance ? insurance : undefined,
757
+ emergencyResponse,
758
+ emergencyCashPointUuid: visitType === 'Emergency' ? emergencyForm?.cashpointUuid : undefined,
759
+ emergencyServicePriceUuid: visitType === 'Emergency' ? emergencyForm?.servicePriceUuid : undefined,
760
+ emergencyIntervention: visitType === 'Emergency' ? emergencyForm?.intervention : undefined,
761
+ protocolCode: visitType === 'Emergency' ? emergencyForm?.protocolCode : undefined,
762
+ });
763
+ } finally {
764
+ setStartingVisit(false);
765
+ }
766
+ };
767
+
768
+ // Required-field validation. A field flags only once the user has been in it and
769
+ // left it empty, so the step doesn't open pre-painted red; each message then clears
770
+ // reactively the moment its field is filled.
771
+ const roomInvalidText =
772
+ touched.room && !room ? `Select a ${patientCategory === 'Walk-in' ? 'walk-in' : 'triage'} room` : '';
773
+ const visitTypeInvalidText = touched.visitType && !visitType ? 'Select a visit type' : '';
774
+ // The SHA-ineligibility message (set on selecting an ineligible scheme) takes
775
+ // precedence over the "select a scheme" prompt, and is shown regardless of touch
776
+ // state because it's a response to something the user just did.
777
+ const isCccPatient = patientCategory === 'CCC';
778
+
779
+ const insuranceInvalidText =
780
+ insuranceError || (method === 'insurance' && touched.insurance && !insurance ? 'Select an insurance scheme' : '');
781
+
782
+ // A scheme is active/eligible when its coverage status is '1'.
783
+ const isActiveScheme = (s: Scheme) => s.coverage?.status === '1';
784
+
785
+ // Balance for the benefit line matching the current Visit type, picked from
786
+ // the POMSF balance response fetched above — see pomsf-balance.util.ts for the
787
+ // PMF-07/PMF-12 mapping and the rest of the gating rules.
788
+ const pomsfDisplayBalance = getPomsfDisplayBalance(schemes, visitType, pomsfBalance);
789
+ // The full breakdown (every benefit line, not just the one for the current
790
+ // Visit type) — shown underneath so staff can see all of a patient's POMSF
791
+ // benefits at a glance, not just the auto-picked one.
792
+ const pomsfAllBenefits = pomsfActive ? getAllPomsfBenefitBalances(pomsfBalance) : [];
793
+
794
+ // Every eligible scheme the registry returns for the patient (all active
795
+ // schemes) — shown in full on the consent summary.
796
+ const eligibleSchemes = schemes.filter(isActiveScheme);
797
+
798
+ // SHA eligibility indicator, shown on the consent summary and beside the SHA
799
+ // payment option. Derived from the eligible schemes: eligible when the patient
800
+ // has at least one active scheme.
801
+ const shaActive = eligibleSchemes.length > 0;
802
+
803
+ // Insurance dropdown items. SHA carries its eligibility in the name and is not
804
+ // selectable unless the patient is eligible (has an active eligible scheme).
805
+ const insuranceItems = insuranceSchemes.map((name) => {
806
+ const isSha = /sha|shif|phc/i.test(name);
807
+ if (!isSha) {
808
+ return { id: name, label: name, isSha: false, eligible: true, disabled: false };
809
+ }
810
+ const suffix = loadingEligibility
811
+ ? ' · checking eligibility…'
812
+ : shaActive
813
+ ? ' · eligible'
814
+ : eligibilityChecked
815
+ ? ' · not eligible'
816
+ : ' · eligibility unknown';
817
+ return { id: name, label: `${name}${suffix}`, isSha: true, eligible: shaActive, disabled: !shaActive };
818
+ });
819
+
820
+ const shaEligibilityTag = loadingEligibility ? (
821
+ <InlineLoading className={styles.eligibilityLoading} description="Checking SHA eligibility…" />
822
+ ) : (
823
+ <Tag size="sm" type={shaActive ? 'green' : 'red'}>
824
+ {shaActive ? 'SHA · Eligible' : eligibilityChecked ? 'SHA · Not eligible' : 'SHA · Unknown'}
825
+ </Tag>
826
+ );
827
+
828
+ // The full list of the patient's eligible schemes — shared by the consent
829
+ // summary and the insurance payment section so both show the same detail.
830
+ const eligibleSchemesList =
831
+ eligibleSchemes.length > 0 ? (
832
+ <div className={styles.schemes}>
833
+ <div className={styles.schemesHead}>Eligible scheme{eligibleSchemes.length === 1 ? '' : 's'}</div>
834
+ <ul className={styles.schemeList}>
835
+ {eligibleSchemes.map((s, i) => (
836
+ <li key={`${s.schemeName}-${i}`} className={styles.schemeItem}>
837
+ <div className={styles.schemeTop}>
838
+ <span className={styles.schemeName}>{s.schemeName}</span>
839
+ <Tag size="sm" type="green">
840
+ Active
841
+ </Tag>
842
+ </div>
843
+ <div className={styles.schemeMeta}>
844
+ {s.memberType ? (
845
+ <span>{s.memberType.charAt(0).toUpperCase() + s.memberType.slice(1).toLowerCase()}</span>
846
+ ) : null}
847
+ {s.coverage?.endDate ? <span>Valid to {String(s.coverage.endDate).slice(0, 10)}</span> : null}
848
+ </div>
849
+ </li>
850
+ ))}
851
+ </ul>
852
+ </div>
853
+ ) : null;
854
+
855
+ return (
856
+ <>
857
+ {/* Overlay does NOT close on click — the user must use Close or Cancel */}
858
+ <div className={styles.overlay} />
859
+ <aside className={styles.drawer} role="dialog" aria-label="Registration workflow">
860
+ <header className={styles.header}>
861
+ <h4 className={styles.title}>Patient registration</h4>
862
+ <Button kind="ghost" size="sm" hasIconOnly iconDescription="Close" renderIcon={Close} onClick={onClose} />
863
+ </header>
864
+
865
+ <div className={styles.body}>
866
+ {/* The stepper scrolls with the content */}
867
+ <div className={styles.stepper}>
868
+ <div className={styles.stepperCard}>
869
+ <ProgressIndicator currentIndex={phaseToIndex[phase]} spaceEqually>
870
+ {STEPS.map((label) => (
871
+ <ProgressStep key={label} label={label} />
872
+ ))}
873
+ </ProgressIndicator>
874
+ <p className={styles.stepCaption}>
875
+ Step {phaseToIndex[phase] + 1} of {STEPS.length}: <strong>{STEPS[phaseToIndex[phase]]}</strong>
876
+ </p>
877
+ </div>
878
+ </div>
879
+
880
+ <div className={styles.bodyInner}>
881
+ {/*
882
+ ---- Step 1: Verify — biometric ----
883
+ {phase === 'biometric' ? (
884
+ <div className={styles.verifyContent}>
885
+ {!biometricUrl && clientStrip}
886
+ {!biometricUrl ? (
887
+ <>
888
+ <div className={styles.biometricArea}>
889
+ <button
890
+ type="button"
891
+ className={styles.biometricLaunch}
892
+ onClick={launchBiometric}
893
+ disabled={launchingBiometric}
894
+ >
895
+ <span className={styles.biometricIcon}>
896
+ <FingerprintRecognition size={48} />
897
+ </span>
898
+ <span className={styles.biometricLaunchText}>
899
+ {launchingBiometric ? 'Starting scanner…' : 'Tap to scan fingerprint'}
900
+ </span>
901
+ <span className={styles.biometricLaunchHint}>Confirm the patient&apos;s identity</span>
902
+ </button>
903
+ {failCount > 0 ? (
904
+ <p className={styles.failNote}>
905
+ Attempt {failCount} of {BIOMETRIC_MAX_ATTEMPTS} failed. Please try again.
906
+ </p>
907
+ ) : (
908
+ <></>
909
+ )}
910
+ </div>
911
+ <div className={styles.guidePanel}>
912
+ <div className={styles.guideHead}>
913
+ <Information size={18} className={styles.guideHeadIcon} />
914
+ How verification works
915
+ </div>
916
+ <ol className={styles.guideSteps}>
917
+ <li>Scan the patient&apos;s fingerprint to confirm their identity.</li>
918
+ <li>If the fingerprint fails {BIOMETRIC_MAX_ATTEMPTS} times, switch to an OTP code.</li>
919
+ <li>If OTP isn&apos;t allowed for this patient yet, request OTP whitelisting.</li>
920
+ <li>Once approved (or if already allowed), verify with the OTP sent to their phone.</li>
921
+ </ol>
922
+ </div>
923
+ </>
924
+ ) : (
925
+ <div className={styles.biometricFrameWrap}>
926
+ <iframe title="Fingerprint capture" src={biometricUrl} className={styles.biometricFrame} />
927
+ <div className={styles.capturePrompt}>
928
+ <span className={styles.capturePromptText}>Did the fingerprint match the patient?</span>
929
+ <span className={styles.capturePromptHint}>
930
+ {failCount > 0
931
+ ? `Attempt ${failCount + 1} of ${BIOMETRIC_MAX_ATTEMPTS}. After ${BIOMETRIC_MAX_ATTEMPTS} tries you'll switch to OTP.`
932
+ : `You have ${BIOMETRIC_MAX_ATTEMPTS} tries before switching to OTP.`}
933
+ </span>
934
+ <div className={styles.captureActions}>
935
+ <Button kind="secondary" size="sm" renderIcon={Renew} onClick={handleBiometricFailed}>
936
+ No, try again
937
+ </Button>
938
+ <Button
939
+ kind="primary"
940
+ size="sm"
941
+ renderIcon={CheckmarkOutline}
942
+ onClick={() => {
943
+ setConsent(true);
944
+ setPhase('consent');
945
+ }}
946
+ >
947
+ Yes, identified
948
+ </Button>
949
+ </div>
950
+ </div>
951
+ </div>
952
+ )}
953
+ </div>
954
+ ) : (
955
+ <></>
956
+ )}
957
+ */}
958
+
959
+ {/*
960
+ ---- Step 1: Verify — biometric not configured ----
961
+ {phase === 'biometric-not-setup' ? (
962
+ <div className={styles.verifyContent}>
963
+ {clientStrip}
964
+ <div className={`${styles.statusCard} ${styles.statusCardDanger}`}>
965
+ <span className={`${styles.statusBadge} ${styles.statusBadgeDanger}`}>
966
+ <ScanDisabled size={20} />
967
+ </span>
968
+ <h5 className={styles.statusTitle}>Biometric not detected</h5>
969
+ <p className={styles.statusText}>
970
+ We couldn&apos;t detect a fingerprint scanner on this workstation. You can proceed by verifying the
971
+ patient with a one-time PIN (OTP) sent to their phone.
972
+ </p>
973
+ <Button
974
+ kind="primary"
975
+ size="sm"
976
+ renderIcon={ArrowRight}
977
+ onClick={() => setPhase(isOtpWhitelisted ? 'otp' : 'otp-gate')}
978
+ >
979
+ Use OTP instead
980
+ </Button>
981
+ </div>
982
+ </div>
983
+ ) : (
984
+ <></>
985
+ )}
986
+ */}
987
+
988
+ {/* ---- Step 1: Verify — checking whitelist ---- */}
989
+ {phase === 'otp-gate' ? (
990
+ <div className={styles.verifyContent}>
991
+ <div className={styles.loadingCard}>
992
+ <InlineLoading description="Checking OTP whitelist status…" />
993
+ </div>
994
+ </div>
995
+ ) : (
996
+ <></>
997
+ )}
998
+
999
+ {/* ---- Step 1: Verify — whitelist request ---- */}
1000
+ {phase === 'whitelist-request' ? (
1001
+ <div className={styles.verifyContent}>
1002
+ {!showWhitelistForm ? (
1003
+ <div className={styles.statusCard}>
1004
+ <span className={styles.statusBadge}>
1005
+ <WarningAltFilled size={24} />
1006
+ </span>
1007
+ <h5 className={styles.statusTitle}>Not whitelisted for OTP</h5>
1008
+ <p className={styles.statusText}>
1009
+ This patient isn&apos;t whitelisted to receive a One-Time Password. Request whitelisting from the
1010
+ SHA team to continue verifying by OTP.
1011
+ </p>
1012
+ <div className={styles.statusActions}>
1013
+ <Button
1014
+ kind="tertiary"
1015
+ size="sm"
1016
+ disabled={checkingWhitelist}
1017
+ onClick={() => checkWhitelistStatus(true)}
1018
+ >
1019
+ {checkingWhitelist ? 'Checking…' : 'Check whitelist status'}
1020
+ </Button>
1021
+ <Button
1022
+ kind="primary"
1023
+ size="sm"
1024
+ renderIcon={ArrowRight}
1025
+ onClick={() => setShowWhitelistForm(true)}
1026
+ >
1027
+ Request whitelisting
1028
+ </Button>
1029
+ </div>
1030
+ </div>
1031
+ ) : (
1032
+ <div className={styles.panel}>
1033
+ <div className={styles.panelHead}>Request OTP whitelisting</div>
1034
+ <div className={styles.panelBody}>
1035
+ <div className={styles.infoNote}>
1036
+ <Information size={20} className={styles.infoNoteIcon} />
1037
+ <p className={styles.infoNoteText}>
1038
+ OTP is not yet approved for this patient. Submit the details below to request whitelisting
1039
+ from the SHA team.
1040
+ </p>
1041
+ </div>
1042
+ <div className={styles.readonlyField}>
1043
+ <span className={styles.readonlyLabel}>Biometric attempts failed</span>
1044
+ <span className={styles.readonlyValue}>
1045
+ {failCount} of {BIOMETRIC_MAX_ATTEMPTS}
1046
+ </span>
1047
+ </div>
1048
+ <Dropdown
1049
+ id="whitelist-reason"
1050
+ titleText={
1051
+ <span>
1052
+ Reason for OTP <span className={styles.required}>*</span>
1053
+ </span>
1054
+ }
1055
+ label="Select a reason"
1056
+ items={WHITELIST_REASONS}
1057
+ selectedItem={reason || null}
1058
+ invalid={!!reasonError}
1059
+ invalidText={reasonError}
1060
+ onChange={({ selectedItem }) => {
1061
+ setReason((selectedItem as string) ?? '');
1062
+ setReasonError('');
1063
+ }}
1064
+ />
1065
+ <div className={styles.uploadField}>
1066
+ <FormLabel>
1067
+ Image of failed biometric <span className={styles.required}>*</span>
1068
+ </FormLabel>
1069
+ <p className={styles.uploadHint}>
1070
+ Screenshot or photo of the failed attempt · PNG or JPG · one file
1071
+ </p>
1072
+ <div
1073
+ className={`${styles.dropZone} ${dragOver ? styles.dropZoneActive : ''} ${
1074
+ imageError ? styles.dropZoneInvalid : ''
1075
+ }`}
1076
+ role="button"
1077
+ tabIndex={0}
1078
+ onClick={() => fileInputRef.current?.click()}
1079
+ onKeyDown={(e) => {
1080
+ if (e.key === 'Enter' || e.key === ' ') {
1081
+ e.preventDefault();
1082
+ fileInputRef.current?.click();
1083
+ }
1084
+ }}
1085
+ onDragOver={(e) => {
1086
+ e.preventDefault();
1087
+ setDragOver(true);
1088
+ }}
1089
+ onDragLeave={() => setDragOver(false)}
1090
+ onDrop={(e) => {
1091
+ e.preventDefault();
1092
+ setDragOver(false);
1093
+ const file = e.dataTransfer.files?.[0];
1094
+ if (file) {
1095
+ setFailedImage(file);
1096
+ setImageError('');
1097
+ }
1098
+ }}
1099
+ >
1100
+ <span className={styles.dropIcon}>
1101
+ <CloudUpload size={24} />
1102
+ </span>
1103
+ <span className={styles.dropTitle}>Drag and drop an image here</span>
1104
+ <span className={styles.dropSubtitle}>or click to browse</span>
1105
+ <input
1106
+ ref={fileInputRef}
1107
+ type="file"
1108
+ accept=".png,.jpg,.jpeg"
1109
+ className={styles.hiddenInput}
1110
+ onChange={(e) => {
1111
+ const file = e.target.files?.[0] ?? null;
1112
+ setFailedImage(file);
1113
+ if (file) {
1114
+ setImageError('');
1115
+ }
1116
+ }}
1117
+ />
1118
+ </div>
1119
+ {failedImage ? (
1120
+ <FileUploaderItem
1121
+ name={failedImage.name}
1122
+ status="edit"
1123
+ iconDescription="Remove file"
1124
+ onDelete={() => setFailedImage(null)}
1125
+ />
1126
+ ) : null}
1127
+ {imageError ? <p className={styles.fieldError}>{imageError}</p> : null}
1128
+ </div>
1129
+ <Button
1130
+ className={styles.submitBtn}
1131
+ kind="primary"
1132
+ size="sm"
1133
+ disabled={submittingWhitelist || !reason.trim() || !failedImage}
1134
+ onClick={submitWhitelistRequest}
1135
+ >
1136
+ {submittingWhitelist ? 'Submitting…' : 'Submit request'}
1137
+ </Button>
1138
+ </div>
1139
+ </div>
1140
+ )}
1141
+ </div>
1142
+ ) : (
1143
+ <></>
1144
+ )}
1145
+
1146
+ {/* ---- Step 1: Verify — whitelist pending ---- */}
1147
+ {phase === 'whitelist-pending' ? (
1148
+ <div className={styles.verifyContent}>
1149
+ <div className={styles.statusCard}>
1150
+ <span className={styles.statusBadge}>
1151
+ <PendingFilled size={24} />
1152
+ </span>
1153
+ <h5 className={styles.statusTitle}>Awaiting approval</h5>
1154
+ <p className={styles.statusText}>
1155
+ Your OTP whitelisting request is pending approval. Check back to see if it has been approved.
1156
+ </p>
1157
+ <Button kind="primary" size="sm" disabled={checkingWhitelist} onClick={() => checkWhitelistStatus()}>
1158
+ {checkingWhitelist ? 'Checking…' : 'Check whitelist status'}
1159
+ </Button>
1160
+ </div>
1161
+ </div>
1162
+ ) : (
1163
+ <></>
1164
+ )}
1165
+
1166
+ {/* ---- Step 1: Verify — OTP ---- */}
1167
+ {phase === 'otp' && requestCustomOtpDto ? (
1168
+ <div className={styles.verifyContent}>
1169
+ <OtpVerificationStep
1170
+ requestCustomOtpDto={requestCustomOtpDto}
1171
+ phoneNumber={phoneNumber ?? ''}
1172
+ timerSeconds={OTP_EXPIRY_SECONDS}
1173
+ biometricFailedCount={failCount}
1174
+ onVerified={() => {
1175
+ setConsent(true);
1176
+ setPhase('consent');
1177
+ }}
1178
+ />
1179
+ </div>
1180
+ ) : (
1181
+ <></>
1182
+ )}
1183
+
1184
+ {/* ---- Step 2: Consent ---- */}
1185
+ {phase === 'consent' ? (
1186
+ <div className={styles.verifyContent}>
1187
+ <div className={styles.consentConfirmed}>
1188
+ <CheckboxCheckedFilled size={20} className={styles.consentConfirmedIcon} />
1189
+ <span className={styles.consentConfirmedText}>
1190
+ The patient has consented to you accessing their details. You can now proceed.
1191
+ </span>
1192
+ </div>
1193
+
1194
+ {consent ? (
1195
+ <>
1196
+ <div className={styles.panel}>
1197
+ <div className={styles.panelHead}>Patient details</div>
1198
+ <div className={styles.panelBody}>
1199
+ <dl className={styles.detailGrid}>
1200
+ <div className={`${styles.detailRow} ${styles.detailFull}`}>
1201
+ <dt>Full name</dt>
1202
+ <dd>
1203
+ {[client.first_name, client.middle_name, client.last_name].filter(Boolean).join(' ')}
1204
+ </dd>
1205
+ </div>
1206
+ <div className={styles.detailRow}>
1207
+ <dt>CR number</dt>
1208
+ <dd>{client.id}</dd>
1209
+ </div>
1210
+ <div className={styles.detailRow}>
1211
+ <dt>Phone number</dt>
1212
+ <dd>{client.phone || '—'}</dd>
1213
+ </div>
1214
+ <div className={styles.detailRow}>
1215
+ <dt>ID number</dt>
1216
+ <dd>{client.identification_number || '—'}</dd>
1217
+ </div>
1218
+ <div className={styles.detailRow}>
1219
+ <dt>SHA eligibility</dt>
1220
+ <dd>{shaEligibilityTag}</dd>
1221
+ </div>
1222
+ </dl>
1223
+
1224
+ {eligibleSchemesList}
1225
+ </div>
1226
+ </div>
1227
+ {emrStatusCard}
1228
+ {emrConfirmModal}
1229
+ </>
1230
+ ) : (
1231
+ <></>
1232
+ )}
1233
+ </div>
1234
+ ) : (
1235
+ <></>
1236
+ )}
1237
+
1238
+ {/* ---- Step 3: Start visit ---- */}
1239
+ {phase === 'visit' ? (
1240
+ <div className={styles.verifyContent}>
1241
+ <div className={`${styles.panelBody} ${styles.scrollBody}`}>
1242
+ <div {...lockSelection(!!visitType)} onBlurCapture={markTouched('visitType')}>
1243
+ <ComboBox
1244
+ id="visit-type"
1245
+ titleText={
1246
+ <span>
1247
+ Visit type<span className={styles.required}>*</span>
1248
+ </span>
1249
+ }
1250
+ placeholder="Search or select a visit type"
1251
+ items={VISIT_TYPE_OPTIONS}
1252
+ itemToString={(item) => item ?? ''}
1253
+ shouldFilterItem={filterByLabel<string>((item) => item ?? '', visitType)}
1254
+ selectedItem={visitType || null}
1255
+ invalid={!!visitTypeInvalidText}
1256
+ invalidText={visitTypeInvalidText}
1257
+ onChange={({ selectedItem }) => {
1258
+ setVisitType((selectedItem as string) ?? '');
1259
+ }}
1260
+ />
1261
+ </div>
1262
+ <div className={styles.formSection}>
1263
+ <h6 className={styles.sectionLabel}>Patient category</h6>
1264
+ <RadioButtonGroup
1265
+ legendText="Patient destination"
1266
+ name="patient-category-group"
1267
+ orientation="horizontal"
1268
+ valueSelected={patientCategory}
1269
+ onChange={(v) => {
1270
+ setPatientCategory(v as string);
1271
+ setRoom('');
1272
+ }}
1273
+ >
1274
+ {PATIENT_CATEGORIES.map((cat) => (
1275
+ <RadioButton key={cat} id={`cat-${cat.toLowerCase()}`} labelText={cat} value={cat} />
1276
+ ))}
1277
+ </RadioButtonGroup>
1278
+
1279
+ <div {...lockSelection(!!room)} onBlurCapture={markTouched('room')}>
1280
+ <ComboBox
1281
+ id="visit-room"
1282
+ titleText={
1283
+ <span>
1284
+ {patientCategory === 'Walk-in' ? 'Walk-in room' : 'Triage room'}
1285
+ <span className={styles.required}>*</span>
1286
+ </span>
1287
+ }
1288
+ placeholder={
1289
+ patientCategory === 'Walk-in'
1290
+ ? 'Search or select a walk-in room'
1291
+ : loadingRooms
1292
+ ? 'Loading triage rooms…'
1293
+ : triageRooms.length === 0
1294
+ ? 'No triage rooms for this location'
1295
+ : 'Search or select a triage room'
1296
+ }
1297
+ items={patientCategory === 'Walk-in' ? WALK_IN_ROOMS : triageRooms}
1298
+ itemToString={(item) => item ?? ''}
1299
+ shouldFilterItem={filterByLabel<string>((item) => item ?? '', room)}
1300
+ disabled={patientCategory === 'Triage' && (loadingRooms || triageRooms.length === 0)}
1301
+ selectedItem={room || null}
1302
+ invalid={!!roomInvalidText}
1303
+ invalidText={roomInvalidText}
1304
+ onChange={({ selectedItem }) => {
1305
+ setRoom((selectedItem as string) ?? '');
1306
+ }}
1307
+ />
1308
+ </div>
1309
+ </div>
1310
+
1311
+ <div className={styles.formSection}>
1312
+ {!isCccPatient ? <h6 className={styles.sectionLabel}>Payment</h6> : <></>}
1313
+ {hasCashPoint === false ? (
1314
+ <div className={styles.errorNote}>
1315
+ <WarningAltFilled size={20} className={styles.errorNoteIcon} />
1316
+ <p className={styles.errorNoteText}>
1317
+ Payment modes have not been configured. Contact your system administrator.
1318
+ </p>
1319
+ </div>
1320
+ ) : null}
1321
+
1322
+ <RadioButtonGroup
1323
+ legendText="Payment method"
1324
+ name="method-group"
1325
+ orientation="horizontal"
1326
+ valueSelected={method}
1327
+ disabled={isCccPatient || hasCashPoint === false}
1328
+ onChange={(v) => {
1329
+ // Switching payment method clears any preselected
1330
+ // insurance so it can't carry into the payer mapping —
1331
+ // insurance→cash and cash→insurance both start fresh.
1332
+ setMethod(v as Method);
1333
+ setInsurance('');
1334
+ setInsuranceError('');
1335
+ }}
1336
+ >
1337
+ <RadioButton id="method-insurance" labelText="Insurance" value="insurance" />
1338
+ <RadioButton id="method-cash" labelText="Cash" value="cash" />
1339
+ </RadioButtonGroup>
1340
+
1341
+ {method === 'cash' && hasCashMode === false ? (
1342
+ <div className={styles.errorNote}>
1343
+ <WarningAltFilled size={20} className={styles.errorNoteIcon} />
1344
+ <p className={styles.errorNoteText}>
1345
+ Cash payment mode is not set. Contact your system administrator.
1346
+ </p>
1347
+ </div>
1348
+ ) : null}
1349
+
1350
+ {method === 'insurance' && !isCccPatient ? (
1351
+ <div {...lockSelection(!!insurance)} onBlurCapture={markTouched('insurance')}>
1352
+ <ComboBox
1353
+ id="insurance-scheme"
1354
+ titleText={
1355
+ <span>
1356
+ Insurance scheme<span className={styles.required}>*</span>
1357
+ </span>
1358
+ }
1359
+ placeholder={
1360
+ loadingSchemes
1361
+ ? 'Loading insurance schemes…'
1362
+ : insuranceSchemes.length === 0
1363
+ ? 'No insurance schemes available'
1364
+ : 'Search or select insurance scheme'
1365
+ }
1366
+ items={insuranceItems}
1367
+ itemToString={(item) => (item ? item.label : '')}
1368
+ shouldFilterItem={filterByLabel(
1369
+ (item: (typeof insuranceItems)[number]) => item?.label ?? '',
1370
+ insuranceItems.find((i) => i.id === insurance)?.label ?? '',
1371
+ )}
1372
+ itemToElement={(item) =>
1373
+ item ? (
1374
+ item.isSha ? (
1375
+ <span
1376
+ className={`${styles.schemePill} ${
1377
+ item.eligible ? styles.schemePillEligible : styles.schemePillIneligible
1378
+ }`}
1379
+ >
1380
+ {item.label}
1381
+ </span>
1382
+ ) : (
1383
+ <span>{item.label}</span>
1384
+ )
1385
+ ) : null
1386
+ }
1387
+ disabled={loadingSchemes || insuranceSchemes.length === 0}
1388
+ selectedItem={insuranceItems.find((i) => i.id === insurance) ?? null}
1389
+ invalid={!!insuranceInvalidText}
1390
+ invalidText={insuranceInvalidText}
1391
+ onChange={({ selectedItem }) => {
1392
+ if (!selectedItem) {
1393
+ // The combo box's clear button hands back null — drop the selection.
1394
+ setInsurance('');
1395
+ setInsuranceError('');
1396
+ return;
1397
+ }
1398
+ if (selectedItem.disabled) {
1399
+ // Patient isn't SHA-eligible — block the selection.
1400
+ setInsurance('');
1401
+ setInsuranceError('Patient is not eligible for SHA. Choose another scheme.');
1402
+ return;
1403
+ }
1404
+ setInsurance(selectedItem.id);
1405
+ setInsuranceError('');
1406
+ }}
1407
+ />
1408
+ </div>
1409
+ ) : (
1410
+ <></>
1411
+ )}
1412
+
1413
+ {method === 'insurance' &&
1414
+ !isCccPatient &&
1415
+ /pomsf/i.test(insurance) &&
1416
+ pomsfDisplayBalance !== null ? (
1417
+ <div className={styles.eligibilityRow}>
1418
+ <span className={styles.eligibilityRowLabel}>Eligibility</span>
1419
+ <Tag size="sm" type="green">
1420
+ {`POMSF · Active · ${formatKes(pomsfDisplayBalance)}`}
1421
+ </Tag>
1422
+ </div>
1423
+ ) : null}
1424
+
1425
+ {method === 'insurance' && !isCccPatient && /sha|shif/i.test(insurance) ? (
1426
+ <div className={styles.eligibilityRow}>
1427
+ <span className={styles.eligibilityRowLabel}>Eligibility</span>
1428
+ {shaEligibilityTag}
1429
+ {eligibleSchemes.map((s, i) => (
1430
+ <Tag key={`${s.schemeName}-${i}`} size="sm" type="green">
1431
+ {/* POMSF's tag additionally carries its balance for the current Visit
1432
+ type (see pomsf-balance.util.ts), once one is picked — this row
1433
+ lists every active scheme regardless of which one is selected above. */}
1434
+ {/pomsf/i.test(s.schemeName) && pomsfDisplayBalance !== null
1435
+ ? `${s.schemeName} · Active · ${formatKes(pomsfDisplayBalance)}`
1436
+ : `${s.schemeName} · Active`}
1437
+ </Tag>
1438
+ ))}
1439
+ </div>
1440
+ ) : null}
1441
+
1442
+ {method === 'insurance' && !isCccPatient && pomsfAllBenefits.length > 0 ? (
1443
+ <div className={styles.pomsfBenefitsSection}>
1444
+ <span className={styles.eligibilityRowLabel}>POMSF benefits</span>
1445
+ <div className={styles.tableWrapper}>
1446
+ <Table size="sm" aria-label="POMSF benefits">
1447
+ <TableHead>
1448
+ <TableRow>
1449
+ <TableHeader>Benefit</TableHeader>
1450
+ <TableHeader>Balance</TableHeader>
1451
+ </TableRow>
1452
+ </TableHead>
1453
+ <TableBody>
1454
+ {pomsfAllBenefits.map((benefit) => (
1455
+ <TableRow key={benefit.code}>
1456
+ <TableCell>{benefit.name}</TableCell>
1457
+ <TableCell>{benefit.balance !== null ? formatKes(benefit.balance) : '—'}</TableCell>
1458
+ </TableRow>
1459
+ ))}
1460
+ </TableBody>
1461
+ </Table>
1462
+ </div>
1463
+ </div>
1464
+ ) : null}
1465
+ </div>
1466
+ </div>
1467
+ </div>
1468
+ ) : (
1469
+ <></>
1470
+ )}
1471
+ <div className={styles.formSection}>
1472
+ {visitType === 'Emergency' && (
1473
+ <EmergencySlotComponent
1474
+ client={client}
1475
+ onFormChange={setEmergencyForm}
1476
+ onValidationChange={setEmergencyFormValid}
1477
+ />
1478
+ )}
1479
+ </div>
1480
+ </div>
1481
+ </div>
1482
+
1483
+ <footer className={styles.footer}>
1484
+ {phase === 'consent' && amrsChecked && !amrsPatient ? (
1485
+ <span className={styles.footerHint}>
1486
+ <WarningAltFilled size={16} className={styles.footerHintIcon} />
1487
+ Create the patient in the EMR to continue.
1488
+ </span>
1489
+ ) : (
1490
+ <div />
1491
+ )}
1492
+ <div className={styles.footerRight}>
1493
+ <Button kind="secondary" size="sm" onClick={onClose} disabled={startingVisit}>
1494
+ Cancel
1495
+ </Button>
1496
+ {phase === 'consent' ? (
1497
+ <Button
1498
+ kind="primary"
1499
+ size="sm"
1500
+ renderIcon={ArrowRight}
1501
+ // Block continuing until the patient exists in the EMR (found or created).
1502
+ disabled={!consent || !amrsPatient}
1503
+ onClick={() => setPhase('visit')}
1504
+ >
1505
+ Continue
1506
+ </Button>
1507
+ ) : (
1508
+ <></>
1509
+ )}
1510
+ {phase === 'visit' ? (
1511
+ <Button
1512
+ kind="primary"
1513
+ size="sm"
1514
+ renderIcon={ArrowRight}
1515
+ disabled={
1516
+ startingVisit ||
1517
+ !room ||
1518
+ !visitType ||
1519
+ hasCashPoint === false ||
1520
+ (method === 'cash' && hasCashMode === false) ||
1521
+ (method === 'insurance' && !insurance) ||
1522
+ (visitType === 'Emergency' && !emergencyFormValid)
1523
+ }
1524
+ onClick={handleStartVisit}
1525
+ >
1526
+ {startingVisit ? (
1527
+ <InlineLoading description="Starting visit and sending to triage..." />
1528
+ ) : (
1529
+ `Start visit & send to ${patientCategory === 'Walk-in' ? 'walk-in' : 'triage'}`
1530
+ )}
1531
+ </Button>
1532
+ ) : (
1533
+ <></>
1534
+ )}
1535
+ </div>
1536
+ </footer>
1537
+ </aside>
1538
+ </>
1539
+ );
1540
+ };
1541
+
1542
+ export default WorkflowDrawer;