@handled-ai/design-system 0.8.0 → 0.9.0

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 (336) hide show
  1. package/README.md +14 -4
  2. package/dist/charts/bar-chart-component.d.ts +24 -0
  3. package/dist/charts/bar-chart-component.js +123 -0
  4. package/dist/charts/bar-chart-component.js.map +1 -0
  5. package/dist/charts/chart-tooltip.d.ts +26 -0
  6. package/dist/charts/chart-tooltip.js +69 -0
  7. package/dist/charts/chart-tooltip.js.map +1 -0
  8. package/dist/charts/chart.d.ts +64 -0
  9. package/dist/charts/chart.js +285 -0
  10. package/dist/charts/chart.js.map +1 -0
  11. package/dist/charts/donut-chart.d.ts +21 -0
  12. package/dist/charts/donut-chart.js +96 -0
  13. package/dist/charts/donut-chart.js.map +1 -0
  14. package/dist/charts/index.d.ts +11 -0
  15. package/dist/charts/index.js +10 -0
  16. package/dist/charts/index.js.map +1 -0
  17. package/dist/charts/pipeline-overview.d.ts +76 -0
  18. package/dist/charts/pipeline-overview.js +372 -0
  19. package/dist/charts/pipeline-overview.js.map +1 -0
  20. package/dist/charts/sankey-chart.d.ts +52 -0
  21. package/dist/charts/sankey-chart.js +219 -0
  22. package/dist/charts/sankey-chart.js.map +1 -0
  23. package/dist/charts/top-line-metrics.d.ts +26 -0
  24. package/dist/charts/top-line-metrics.js +224 -0
  25. package/dist/charts/top-line-metrics.js.map +1 -0
  26. package/dist/charts/trend-area-chart.d.ts +21 -0
  27. package/dist/charts/trend-area-chart.js +150 -0
  28. package/dist/charts/trend-area-chart.js.map +1 -0
  29. package/dist/charts/volume-analysis-chart.d.ts +19 -0
  30. package/dist/charts/volume-analysis-chart.js +121 -0
  31. package/dist/charts/volume-analysis-chart.js.map +1 -0
  32. package/dist/components/activity-detail.d.ts +38 -0
  33. package/dist/components/activity-detail.js +163 -0
  34. package/dist/components/activity-detail.js.map +1 -0
  35. package/dist/components/activity-log.d.ts +21 -0
  36. package/dist/components/activity-log.js +61 -0
  37. package/dist/components/activity-log.js.map +1 -0
  38. package/dist/components/agent-popover.d.ts +71 -0
  39. package/dist/components/agent-popover.js +282 -0
  40. package/dist/components/agent-popover.js.map +1 -0
  41. package/dist/components/agent-widget.d.ts +24 -0
  42. package/dist/components/agent-widget.js +117 -0
  43. package/dist/components/agent-widget.js.map +1 -0
  44. package/dist/components/avatar.d.ts +13 -0
  45. package/dist/components/avatar.js +140 -0
  46. package/dist/components/avatar.js.map +1 -0
  47. package/dist/components/badge.d.ts +12 -0
  48. package/dist/components/badge.js +75 -0
  49. package/dist/components/badge.js.map +1 -0
  50. package/dist/components/button.d.ts +13 -0
  51. package/dist/components/button.js +83 -0
  52. package/dist/components/button.js.map +1 -0
  53. package/dist/components/card.d.ts +11 -0
  54. package/dist/components/card.js +119 -0
  55. package/dist/components/card.js.map +1 -0
  56. package/dist/components/contact-list.d.ts +34 -0
  57. package/dist/components/contact-list.js +84 -0
  58. package/dist/components/contact-list.js.map +1 -0
  59. package/dist/components/dashboard-cards.d.ts +10 -0
  60. package/dist/components/dashboard-cards.js +164 -0
  61. package/dist/components/dashboard-cards.js.map +1 -0
  62. package/dist/components/data-table-display.d.ts +19 -0
  63. package/dist/components/data-table-display.js +109 -0
  64. package/dist/components/data-table-display.js.map +1 -0
  65. package/dist/components/data-table-filter.d.ts +18 -0
  66. package/dist/components/data-table-filter.js +107 -0
  67. package/dist/components/data-table-filter.js.map +1 -0
  68. package/dist/components/data-table-quick-views.d.ts +13 -0
  69. package/dist/components/data-table-quick-views.js +90 -0
  70. package/dist/components/data-table-quick-views.js.map +1 -0
  71. package/dist/components/data-table-toolbar.d.ts +18 -0
  72. package/dist/components/data-table-toolbar.js +45 -0
  73. package/dist/components/data-table-toolbar.js.map +1 -0
  74. package/dist/components/data-table.d.ts +39 -0
  75. package/dist/components/data-table.js +821 -0
  76. package/dist/components/data-table.js.map +1 -0
  77. package/dist/components/detail-view.d.ts +44 -0
  78. package/dist/components/detail-view.js +165 -0
  79. package/dist/components/detail-view.js.map +1 -0
  80. package/dist/components/dialog.d.ts +19 -0
  81. package/dist/components/dialog.js +188 -0
  82. package/dist/components/dialog.js.map +1 -0
  83. package/dist/components/dropdown-menu.d.ts +27 -0
  84. package/dist/components/dropdown-menu.js +279 -0
  85. package/dist/components/dropdown-menu.js.map +1 -0
  86. package/dist/components/entity-panel.d.ts +69 -0
  87. package/dist/components/entity-panel.js +584 -0
  88. package/dist/components/entity-panel.js.map +1 -0
  89. package/dist/components/inbox-row.d.ts +27 -0
  90. package/dist/components/inbox-row.js +139 -0
  91. package/dist/components/inbox-row.js.map +1 -0
  92. package/dist/components/inbox-toolbar.d.ts +21 -0
  93. package/dist/components/inbox-toolbar.js +203 -0
  94. package/dist/components/inbox-toolbar.js.map +1 -0
  95. package/dist/components/input.d.ts +5 -0
  96. package/dist/components/input.js +50 -0
  97. package/dist/components/input.js.map +1 -0
  98. package/dist/components/insights-filter-bar.d.ts +21 -0
  99. package/dist/components/insights-filter-bar.js +99 -0
  100. package/dist/components/insights-filter-bar.js.map +1 -0
  101. package/dist/components/item-list-display.d.ts +22 -0
  102. package/dist/components/item-list-display.js +240 -0
  103. package/dist/components/item-list-display.js.map +1 -0
  104. package/dist/components/item-list-filter.d.ts +16 -0
  105. package/dist/components/item-list-filter.js +87 -0
  106. package/dist/components/item-list-filter.js.map +1 -0
  107. package/dist/components/item-list-toolbar.d.ts +25 -0
  108. package/dist/components/item-list-toolbar.js +79 -0
  109. package/dist/components/item-list-toolbar.js.map +1 -0
  110. package/dist/components/item-list.d.ts +20 -0
  111. package/dist/components/item-list.js +702 -0
  112. package/dist/components/item-list.js.map +1 -0
  113. package/dist/components/label.d.ts +6 -0
  114. package/dist/components/label.js +55 -0
  115. package/dist/components/label.js.map +1 -0
  116. package/dist/components/message.d.ts +23 -0
  117. package/dist/components/message.js +117 -0
  118. package/dist/components/message.js.map +1 -0
  119. package/dist/components/metric-card.d.ts +25 -0
  120. package/dist/components/metric-card.js +107 -0
  121. package/dist/components/metric-card.js.map +1 -0
  122. package/dist/components/performance-metrics-table.d.ts +38 -0
  123. package/dist/components/performance-metrics-table.js +342 -0
  124. package/dist/components/performance-metrics-table.js.map +1 -0
  125. package/dist/components/preview-list.d.ts +14 -0
  126. package/dist/components/preview-list.js +83 -0
  127. package/dist/components/preview-list.js.map +1 -0
  128. package/dist/components/progress.d.ts +6 -0
  129. package/dist/components/progress.js +69 -0
  130. package/dist/components/progress.js.map +1 -0
  131. package/dist/components/quick-action-chat-area.d.ts +24 -0
  132. package/dist/components/quick-action-chat-area.js +178 -0
  133. package/dist/components/quick-action-chat-area.js.map +1 -0
  134. package/dist/components/quick-action-modal.d.ts +30 -0
  135. package/dist/components/quick-action-modal.js +288 -0
  136. package/dist/components/quick-action-modal.js.map +1 -0
  137. package/dist/components/quick-action-sidebar-nav.d.ts +51 -0
  138. package/dist/components/quick-action-sidebar-nav.js +528 -0
  139. package/dist/components/quick-action-sidebar-nav.js.map +1 -0
  140. package/dist/components/recommended-actions-section.d.ts +23 -0
  141. package/dist/components/recommended-actions-section.js +215 -0
  142. package/dist/components/recommended-actions-section.js.map +1 -0
  143. package/dist/components/report-card.d.ts +26 -0
  144. package/dist/components/report-card.js +69 -0
  145. package/dist/components/report-card.js.map +1 -0
  146. package/dist/components/score-analysis-modal.d.ts +26 -0
  147. package/dist/components/score-analysis-modal.js +141 -0
  148. package/dist/components/score-analysis-modal.js.map +1 -0
  149. package/dist/components/score-breakdown.d.ts +17 -0
  150. package/dist/components/score-breakdown.js +162 -0
  151. package/dist/components/score-breakdown.js.map +1 -0
  152. package/dist/components/score-feedback.d.ts +40 -0
  153. package/dist/components/score-feedback.js +209 -0
  154. package/dist/components/score-feedback.js.map +1 -0
  155. package/dist/components/score-ring.d.ts +14 -0
  156. package/dist/components/score-ring.js +79 -0
  157. package/dist/components/score-ring.js.map +1 -0
  158. package/dist/components/scroll-area.d.ts +7 -0
  159. package/dist/components/scroll-area.js +101 -0
  160. package/dist/components/scroll-area.js.map +1 -0
  161. package/dist/components/select.d.ts +17 -0
  162. package/dist/components/select.js +228 -0
  163. package/dist/components/select.js.map +1 -0
  164. package/dist/components/separator.d.ts +6 -0
  165. package/dist/components/separator.js +61 -0
  166. package/dist/components/separator.js.map +1 -0
  167. package/dist/components/sheet.d.ts +16 -0
  168. package/dist/components/sheet.js +168 -0
  169. package/dist/components/sheet.js.map +1 -0
  170. package/dist/components/sidebar.d.ts +73 -0
  171. package/dist/components/sidebar.js +723 -0
  172. package/dist/components/sidebar.js.map +1 -0
  173. package/dist/components/signal-feedback-inline.d.ts +51 -0
  174. package/dist/components/signal-feedback-inline.js +548 -0
  175. package/dist/components/signal-feedback-inline.js.map +1 -0
  176. package/dist/components/simple-data-table.d.ts +15 -0
  177. package/dist/components/simple-data-table.js +91 -0
  178. package/dist/components/simple-data-table.js.map +1 -0
  179. package/dist/components/skeleton.d.ts +5 -0
  180. package/dist/components/skeleton.js +44 -0
  181. package/dist/components/skeleton.js.map +1 -0
  182. package/dist/components/status-badge.d.ts +10 -0
  183. package/dist/components/status-badge.js +82 -0
  184. package/dist/components/status-badge.js.map +1 -0
  185. package/dist/components/styled-bar-list.d.ts +20 -0
  186. package/dist/components/styled-bar-list.js +59 -0
  187. package/dist/components/styled-bar-list.js.map +1 -0
  188. package/dist/components/suggested-actions.d.ts +110 -0
  189. package/dist/components/suggested-actions.js +1538 -0
  190. package/dist/components/suggested-actions.js.map +1 -0
  191. package/dist/components/table.d.ts +12 -0
  192. package/dist/components/table.js +147 -0
  193. package/dist/components/table.js.map +1 -0
  194. package/dist/components/tabs.d.ts +14 -0
  195. package/dist/components/tabs.js +129 -0
  196. package/dist/components/tabs.js.map +1 -0
  197. package/dist/components/textarea.d.ts +5 -0
  198. package/dist/components/textarea.js +47 -0
  199. package/dist/components/textarea.js.map +1 -0
  200. package/dist/components/timeline-activity.d.ts +34 -0
  201. package/dist/components/timeline-activity.js +181 -0
  202. package/dist/components/timeline-activity.js.map +1 -0
  203. package/dist/components/tooltip.d.ts +9 -0
  204. package/dist/components/tooltip.js +93 -0
  205. package/dist/components/tooltip.js.map +1 -0
  206. package/dist/components/view-mode-toggle.d.ts +16 -0
  207. package/dist/components/view-mode-toggle.js +24 -0
  208. package/dist/components/view-mode-toggle.js.map +1 -0
  209. package/dist/hooks/use-mobile.d.ts +3 -0
  210. package/dist/hooks/use-mobile.js +21 -0
  211. package/dist/hooks/use-mobile.js.map +1 -0
  212. package/dist/index.d.ts +68 -1878
  213. package/dist/index.js +69 -10918
  214. package/dist/index.js.map +1 -1
  215. package/dist/lib/icons.d.ts +18 -0
  216. package/dist/lib/icons.js +21 -0
  217. package/dist/lib/icons.js.map +1 -0
  218. package/dist/lib/utils.d.ts +5 -0
  219. package/dist/lib/utils.js +9 -0
  220. package/dist/lib/utils.js.map +1 -0
  221. package/dist/prototype/index.d.ts +20 -0
  222. package/dist/prototype/index.js +8 -0
  223. package/dist/prototype/index.js.map +1 -0
  224. package/dist/prototype/prototype-accounts-view.d.ts +22 -0
  225. package/dist/prototype/prototype-accounts-view.js +70 -0
  226. package/dist/prototype/prototype-accounts-view.js.map +1 -0
  227. package/dist/prototype/prototype-admin-view.d.ts +21 -0
  228. package/dist/prototype/prototype-admin-view.js +53 -0
  229. package/dist/prototype/prototype-admin-view.js.map +1 -0
  230. package/dist/prototype/prototype-config.d.ts +226 -0
  231. package/dist/prototype/prototype-config.js +1 -0
  232. package/dist/prototype/prototype-config.js.map +1 -0
  233. package/dist/prototype/prototype-inbox-view.d.ts +48 -0
  234. package/dist/prototype/prototype-inbox-view.js +701 -0
  235. package/dist/prototype/prototype-inbox-view.js.map +1 -0
  236. package/dist/prototype/prototype-insights-view.d.ts +23 -0
  237. package/dist/prototype/prototype-insights-view.js +335 -0
  238. package/dist/prototype/prototype-insights-view.js.map +1 -0
  239. package/dist/prototype/prototype-shell.d.ts +40 -0
  240. package/dist/prototype/prototype-shell.js +190 -0
  241. package/dist/prototype/prototype-shell.js.map +1 -0
  242. package/dist/prototype/prototype-work-queue-view.d.ts +8 -0
  243. package/dist/prototype/prototype-work-queue-view.js +17 -0
  244. package/dist/prototype/prototype-work-queue-view.js.map +1 -0
  245. package/dist/three/agent-orb.d.ts +39 -0
  246. package/dist/three/agent-orb.js +500 -0
  247. package/dist/three/agent-orb.js.map +1 -0
  248. package/dist/three/index.d.ts +2 -0
  249. package/dist/three/index.js +2 -0
  250. package/dist/three/index.js.map +1 -0
  251. package/package.json +98 -17
  252. package/src/charts/bar-chart-component.tsx +150 -0
  253. package/src/charts/chart-tooltip.tsx +86 -0
  254. package/src/charts/chart.tsx +371 -0
  255. package/src/charts/donut-chart.tsx +112 -0
  256. package/src/charts/index.ts +13 -0
  257. package/src/charts/pipeline-overview.tsx +476 -0
  258. package/src/charts/sankey-chart.tsx +290 -0
  259. package/src/charts/top-line-metrics.tsx +261 -0
  260. package/src/charts/trend-area-chart.tsx +150 -0
  261. package/src/charts/volume-analysis-chart.tsx +124 -0
  262. package/src/components/activity-detail.tsx +233 -0
  263. package/src/components/activity-log.tsx +89 -0
  264. package/src/components/agent-popover.tsx +373 -0
  265. package/src/components/agent-widget.tsx +163 -0
  266. package/src/components/avatar.tsx +109 -0
  267. package/src/components/badge.tsx +48 -0
  268. package/src/components/button.tsx +59 -0
  269. package/src/components/card.tsx +92 -0
  270. package/src/components/contact-list.tsx +121 -0
  271. package/src/components/dashboard-cards.tsx +170 -0
  272. package/src/components/data-table-display.tsx +139 -0
  273. package/src/components/data-table-filter.tsx +138 -0
  274. package/src/components/data-table-quick-views.tsx +103 -0
  275. package/src/components/data-table-toolbar.tsx +56 -0
  276. package/src/components/data-table.tsx +915 -0
  277. package/src/components/detail-view.tsx +237 -0
  278. package/src/components/dialog.tsx +158 -0
  279. package/src/components/dropdown-menu.tsx +257 -0
  280. package/src/components/entity-panel.tsx +767 -0
  281. package/src/components/inbox-row.tsx +132 -0
  282. package/src/components/inbox-toolbar.tsx +213 -0
  283. package/src/components/input.tsx +21 -0
  284. package/src/components/insights-filter-bar.tsx +132 -0
  285. package/src/components/item-list-display.tsx +278 -0
  286. package/src/components/item-list-filter.tsx +118 -0
  287. package/src/components/item-list-toolbar.tsx +97 -0
  288. package/src/components/item-list.tsx +843 -0
  289. package/src/components/label.tsx +24 -0
  290. package/src/components/message.tsx +83 -0
  291. package/src/components/metric-card.tsx +178 -0
  292. package/src/components/performance-metrics-table.tsx +442 -0
  293. package/src/components/preview-list.tsx +62 -0
  294. package/src/components/progress.tsx +31 -0
  295. package/src/components/quick-action-chat-area.tsx +156 -0
  296. package/src/components/quick-action-modal.tsx +331 -0
  297. package/src/components/quick-action-sidebar-nav.tsx +592 -0
  298. package/src/components/recommended-actions-section.tsx +258 -0
  299. package/src/components/report-card.tsx +106 -0
  300. package/src/components/score-analysis-modal.tsx +172 -0
  301. package/src/components/score-breakdown.tsx +179 -0
  302. package/src/components/score-feedback.tsx +288 -0
  303. package/src/components/score-ring.tsx +87 -0
  304. package/src/components/scroll-area.tsx +58 -0
  305. package/src/components/select.tsx +190 -0
  306. package/src/components/separator.tsx +28 -0
  307. package/src/components/sheet.tsx +143 -0
  308. package/src/components/sidebar.tsx +726 -0
  309. package/src/components/signal-feedback-inline.tsx +591 -0
  310. package/src/components/simple-data-table.tsx +124 -0
  311. package/src/components/skeleton.tsx +15 -0
  312. package/src/components/status-badge.tsx +63 -0
  313. package/src/components/styled-bar-list.tsx +70 -0
  314. package/src/components/suggested-actions.tsx +1985 -0
  315. package/src/components/table.tsx +116 -0
  316. package/src/components/tabs.tsx +91 -0
  317. package/src/components/textarea.tsx +18 -0
  318. package/src/components/timeline-activity.tsx +234 -0
  319. package/src/components/tooltip.tsx +57 -0
  320. package/src/components/view-mode-toggle.tsx +39 -0
  321. package/src/hooks/use-mobile.ts +21 -0
  322. package/src/index.ts +77 -0
  323. package/src/lib/icons.ts +18 -0
  324. package/src/lib/utils.ts +6 -0
  325. package/src/prototype/index.ts +11 -0
  326. package/src/prototype/prototype-accounts-view.tsx +112 -0
  327. package/src/prototype/prototype-admin-view.tsx +67 -0
  328. package/src/prototype/prototype-config.ts +243 -0
  329. package/src/prototype/prototype-inbox-view.tsx +810 -0
  330. package/src/prototype/prototype-insights-view.tsx +379 -0
  331. package/src/prototype/prototype-shell.tsx +219 -0
  332. package/src/prototype/prototype-work-queue-view.tsx +30 -0
  333. package/src/styles/globals.css +299 -0
  334. package/src/three/agent-orb.tsx +557 -0
  335. package/src/three/index.ts +5 -0
  336. package/src/types/r3f.d.ts +8 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/components/item-list.tsx"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport {\n AlertCircle,\n ChevronDown,\n Mail,\n MessageSquare,\n Phone,\n SearchX,\n} from \"lucide-react\"\n\nimport { cn } from \"../lib/utils\"\nimport { Badge } from \"./badge\"\nimport {\n ItemListToolbar,\n type ItemListQuickView,\n} from \"./item-list-toolbar\"\nimport { type ItemListDisplayState } from \"./item-list-display\"\nimport { type ItemListFilterCategory } from \"./item-list-filter\"\n\ntype QueueStage =\n | \"Referrals\"\n | \"E&B Verified\"\n | \"Contacted\"\n | \"Pending Intake\"\n | \"Pending Scheduling\"\n\ntype QueueRisk = \"At Risk\" | \"Watch\" | \"Stable\"\n\ninterface QueueItem {\n id: string\n patient: string\n source: string\n specialty: string\n stage: QueueStage\n risk: QueueRisk\n attempts: number\n owner: string\n aging: string\n contactSignals: {\n phone: boolean\n email: boolean\n message: boolean\n }\n}\n\nconst QUEUE_ITEMS: QueueItem[] = [\n {\n id: \"REF-1894\",\n patient: \"James Liu\",\n source: \"Cedars\",\n specialty: \"Oncology\",\n stage: \"E&B Verified\",\n risk: \"At Risk\",\n attempts: 2,\n owner: \"Jessica Wong\",\n aging: \"Aging 18h\",\n contactSignals: { phone: true, email: false, message: false },\n },\n {\n id: \"REF-1903\",\n patient: \"Michael Brown\",\n source: \"Providence\",\n specialty: \"Orthopedics\",\n stage: \"E&B Verified\",\n risk: \"Stable\",\n attempts: 1,\n owner: \"Sarah Johnson\",\n aging: \"New today\",\n contactSignals: { phone: false, email: true, message: false },\n },\n {\n id: \"REF-1910\",\n patient: \"Samantha Rodriguez\",\n source: \"Kaiser\",\n specialty: \"Rheumatology\",\n stage: \"E&B Verified\",\n risk: \"At Risk\",\n attempts: 4,\n owner: \"Michael Chen\",\n aging: \"Aging 36h\",\n contactSignals: { phone: true, email: true, message: true },\n },\n {\n id: \"REF-1916\",\n patient: \"Christopher Davis\",\n source: \"USC\",\n specialty: \"Gastroenterology\",\n stage: \"E&B Verified\",\n risk: \"Stable\",\n attempts: 1,\n owner: \"Daniel Kim\",\n aging: \"New 6h ago\",\n contactSignals: { phone: false, email: true, message: true },\n },\n {\n id: \"REF-1924\",\n patient: \"Lisa Anderson\",\n source: \"CHLA\",\n specialty: \"Pediatric Surgery\",\n stage: \"E&B Verified\",\n risk: \"Watch\",\n attempts: 1,\n owner: \"Jennifer Davis\",\n aging: \"New 8h ago\",\n contactSignals: { phone: true, email: false, message: true },\n },\n {\n id: \"REF-1901\",\n patient: \"Sarah Chen\",\n source: \"CHLA\",\n specialty: \"Pediatrics\",\n stage: \"Contacted\",\n risk: \"Stable\",\n attempts: 1,\n owner: \"Daniel Kim\",\n aging: \"New today\",\n contactSignals: { phone: true, email: false, message: false },\n },\n {\n id: \"REF-1908\",\n patient: \"David Smith\",\n source: \"USC\",\n specialty: \"Dermatology\",\n stage: \"Contacted\",\n risk: \"Stable\",\n attempts: 2,\n owner: \"Jennifer Davis\",\n aging: \"New 3h ago\",\n contactSignals: { phone: false, email: true, message: true },\n },\n {\n id: \"REF-1913\",\n patient: \"Olivia Martinez\",\n source: \"Providence\",\n specialty: \"Cardiology\",\n stage: \"Contacted\",\n risk: \"At Risk\",\n attempts: 3,\n owner: \"Jessica Wong\",\n aging: \"Aging 24h\",\n contactSignals: { phone: true, email: true, message: false },\n },\n {\n id: \"REF-1919\",\n patient: \"Kevin Nguyen\",\n source: \"Kaiser\",\n specialty: \"Nephrology\",\n stage: \"Contacted\",\n risk: \"Stable\",\n attempts: 1,\n owner: \"Sarah Johnson\",\n aging: \"New 5h ago\",\n contactSignals: { phone: true, email: false, message: true },\n },\n {\n id: \"REF-1923\",\n patient: \"Rachel Kim\",\n source: \"UCLA Health\",\n specialty: \"Hematology\",\n stage: \"Contacted\",\n risk: \"Watch\",\n attempts: 2,\n owner: \"Michael Chen\",\n aging: \"New 7h ago\",\n contactSignals: { phone: false, email: true, message: true },\n },\n {\n id: \"REF-1926\",\n patient: \"Brian Foster\",\n source: \"Cedars\",\n specialty: \"Vascular Surgery\",\n stage: \"Contacted\",\n risk: \"Stable\",\n attempts: 1,\n owner: \"Daniel Kim\",\n aging: \"New today\",\n contactSignals: { phone: false, email: false, message: true },\n },\n {\n id: \"REF-1931\",\n patient: \"Jasmine Patel\",\n source: \"Dignity Health\",\n specialty: \"Pulmonology\",\n stage: \"Pending Intake\",\n risk: \"Watch\",\n attempts: 2,\n owner: \"Sarah Johnson\",\n aging: \"Aging 14h\",\n contactSignals: { phone: true, email: true, message: false },\n },\n {\n id: \"REF-1933\",\n patient: \"Evan Torres\",\n source: \"Sutter\",\n specialty: \"Neurology\",\n stage: \"Pending Intake\",\n risk: \"Stable\",\n attempts: 1,\n owner: \"Jessica Wong\",\n aging: \"New 2h ago\",\n contactSignals: { phone: false, email: true, message: true },\n },\n {\n id: \"REF-1940\",\n patient: \"Natalie Brooks\",\n source: \"MemorialCare\",\n specialty: \"Pain Management\",\n stage: \"Pending Scheduling\",\n risk: \"Watch\",\n attempts: 2,\n owner: \"Jennifer Davis\",\n aging: \"Aging 20h\",\n contactSignals: { phone: true, email: false, message: true },\n },\n {\n id: \"REF-1942\",\n patient: \"Carlos Rivera\",\n source: \"Providence\",\n specialty: \"Urology\",\n stage: \"Pending Scheduling\",\n risk: \"Stable\",\n attempts: 1,\n owner: \"Daniel Kim\",\n aging: \"New 5h ago\",\n contactSignals: { phone: false, email: true, message: false },\n },\n {\n id: \"REF-1946\",\n patient: \"Alyssa Wright\",\n source: \"UCLA Health\",\n specialty: \"Referrals\",\n stage: \"Referrals\",\n risk: \"Stable\",\n attempts: 1,\n owner: \"Michael Chen\",\n aging: \"New today\",\n contactSignals: { phone: false, email: true, message: true },\n },\n {\n id: \"REF-1948\",\n patient: \"Marcus Lopez\",\n source: \"Cedars\",\n specialty: \"Referrals\",\n stage: \"Referrals\",\n risk: \"At Risk\",\n attempts: 4,\n owner: \"Jessica Wong\",\n aging: \"Aging 30h\",\n contactSignals: { phone: true, email: true, message: false },\n },\n]\n\nconst STAGE_ORDER: QueueStage[] = [\n \"Referrals\",\n \"E&B Verified\",\n \"Contacted\",\n \"Pending Intake\",\n \"Pending Scheduling\",\n]\n\nconst RISK_ORDER: QueueRisk[] = [\"At Risk\", \"Watch\", \"Stable\"]\n\nconst FILTER_CATEGORIES: ItemListFilterCategory[] = [\n {\n id: \"stage\",\n label: \"Queue stage\",\n options: STAGE_ORDER,\n },\n {\n id: \"risk\",\n label: \"Risk level\",\n options: RISK_ORDER,\n },\n {\n id: \"owner\",\n label: \"Assignee\",\n options: [...new Set(QUEUE_ITEMS.map((item) => item.owner))],\n },\n]\n\ninterface QuickViewDefinition {\n id: string\n label: string\n matches: (item: QueueItem) => boolean\n}\n\nconst QUICK_VIEW_DEFINITIONS: QuickViewDefinition[] = [\n {\n id: \"referrals\",\n label: \"Referrals\",\n matches: (item) => item.stage === \"Referrals\",\n },\n {\n id: \"contact-attempted\",\n label: \"Contact Attempted\",\n matches: (item) =>\n item.stage === \"E&B Verified\" || item.stage === \"Contacted\",\n },\n {\n id: \"pending-intake\",\n label: \"Pending Intake\",\n matches: (item) => item.stage === \"Pending Intake\",\n },\n {\n id: \"pending-scheduling\",\n label: \"Pending Scheduling\",\n matches: (item) => item.stage === \"Pending Scheduling\",\n },\n {\n id: \"needs-escalation\",\n label: \"Needs Escalation\",\n matches: (item) => item.attempts >= 4 || item.risk === \"At Risk\",\n },\n]\n\nconst DEFAULT_DISPLAY_STATE: ItemListDisplayState = {\n viewMode: \"list\",\n grouping: \"stage\",\n subGrouping: \"none\",\n ordering: \"priority\",\n orderingDirection: \"desc\",\n showContactSignals: true,\n showOwner: true,\n showStatus: true,\n}\n\nfunction toggleFilterValue(\n current: Record<string, string[]>,\n categoryId: string,\n option: string,\n) {\n const selected = current[categoryId] ?? []\n const hasOption = selected.includes(option)\n\n return {\n ...current,\n [categoryId]: hasOption\n ? selected.filter((value) => value !== option)\n : [...selected, option],\n }\n}\n\nfunction matchesCategoryFilter(\n item: QueueItem,\n categoryId: string,\n selectedOptions: string[],\n) {\n if (selectedOptions.length === 0) {\n return true\n }\n\n switch (categoryId) {\n case \"stage\":\n return selectedOptions.includes(item.stage)\n case \"risk\":\n return selectedOptions.includes(item.risk)\n case \"owner\":\n return selectedOptions.includes(item.owner)\n default:\n return true\n }\n}\n\nfunction getRiskDotColor(risk: QueueRisk) {\n switch (risk) {\n case \"At Risk\":\n return \"bg-red-500\"\n case \"Watch\":\n return \"bg-orange-400\"\n case \"Stable\":\n default:\n return \"bg-muted-foreground/30\"\n }\n}\n\nconst AVATAR_COLORS = [\n \"bg-blue-100 text-blue-700\",\n \"bg-emerald-100 text-emerald-700\",\n \"bg-purple-100 text-purple-700\",\n \"bg-amber-100 text-amber-700\",\n \"bg-rose-100 text-rose-700\",\n \"bg-cyan-100 text-cyan-700\",\n]\n\nfunction getAvatarColor(name: string) {\n return AVATAR_COLORS[name.charCodeAt(0) % AVATAR_COLORS.length]\n}\n\nfunction WorkItemCard({ item, display }: { item: QueueItem; display: ItemListDisplayState }) {\n return (\n <div className=\"rounded-lg border border-border bg-card p-3 shadow-sm transition-shadow hover:shadow-md\">\n <div className=\"mb-2 flex items-center justify-between\">\n <span className=\"font-mono text-[10px] text-muted-foreground\">{item.id}</span>\n <div\n className={cn(\n \"h-2 w-2 rounded-full\",\n getRiskDotColor(item.risk),\n )}\n />\n </div>\n <div className=\"mb-1 text-sm font-medium text-foreground\">\n {item.patient}\n </div>\n <div className=\"mb-2 text-xs text-muted-foreground\">\n via {item.source} &rarr; {item.specialty}\n </div>\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-1.5\">\n {item.risk === \"At Risk\" ? (\n <Badge\n variant=\"outline\"\n className=\"h-5 gap-1 rounded-full border-red-200 bg-red-50 px-1.5 text-[10px] font-medium text-red-700 shadow-none\"\n >\n <AlertCircle className=\"h-3 w-3\" />\n At Risk\n </Badge>\n ) : null}\n <span\n className={cn(\n \"inline-flex h-5 items-center rounded border px-1.5 text-[10px] font-semibold\",\n item.attempts >= 4\n ? \"border-red-200 bg-red-50 text-red-700\"\n : item.attempts === 3\n ? \"border-amber-200 bg-amber-50 text-amber-700\"\n : \"border-border bg-muted text-muted-foreground\",\n )}\n >\n {item.attempts >= 4 ? \"4+\" : item.attempts}\n </span>\n </div>\n <span className=\"text-[11px] text-muted-foreground\">{item.aging}</span>\n </div>\n {display.showOwner ? (\n <div className=\"mt-2 flex items-center gap-1.5 border-t border-border/60 pt-2\">\n <div\n className={cn(\n \"flex h-5 w-5 items-center justify-center rounded text-[9px] font-semibold\",\n getAvatarColor(item.owner),\n )}\n >\n {item.owner.charAt(0)}\n </div>\n <span className=\"text-xs text-muted-foreground\">{item.owner}</span>\n </div>\n ) : null}\n </div>\n )\n}\n\nexport function ItemList() {\n const [selectedFilters, setSelectedFilters] = React.useState<\n Record<string, string[]>\n >({})\n const [activeQuickView, setActiveQuickView] = React.useState<string | null>(\n \"contact-attempted\",\n )\n const [display, setDisplay] =\n React.useState<ItemListDisplayState>(DEFAULT_DISPLAY_STATE)\n const [expandedGroups, setExpandedGroups] = React.useState<\n Record<string, boolean>\n >({})\n\n const quickViews = React.useMemo<ItemListQuickView[]>(\n () =>\n QUICK_VIEW_DEFINITIONS.map((definition) => ({\n id: definition.id,\n label: definition.label,\n count: QUEUE_ITEMS.filter(definition.matches).length,\n })),\n [],\n )\n\n const filteredItems = React.useMemo(() => {\n const quickViewFilter = QUICK_VIEW_DEFINITIONS.find(\n (definition) => definition.id === activeQuickView,\n )\n\n return QUEUE_ITEMS.filter((item) => {\n if (quickViewFilter && !quickViewFilter.matches(item)) {\n return false\n }\n\n return Object.entries(selectedFilters).every(([categoryId, options]) =>\n matchesCategoryFilter(item, categoryId, options),\n )\n })\n }, [activeQuickView, selectedFilters])\n\n const groupedItems = React.useMemo(() => {\n const groups = new Map<string, QueueItem[]>()\n\n for (const item of filteredItems) {\n const key =\n display.grouping === \"stage\"\n ? item.stage\n : display.grouping === \"owner\"\n ? item.owner\n : item.risk\n const current = groups.get(key) ?? []\n current.push(item)\n groups.set(key, current)\n }\n\n const entries = Array.from(groups.entries())\n\n entries.sort(([groupA], [groupB]) => {\n if (display.grouping === \"stage\") {\n return (\n STAGE_ORDER.indexOf(groupA as QueueStage) -\n STAGE_ORDER.indexOf(groupB as QueueStage)\n )\n }\n\n if (display.grouping === \"risk\") {\n return (\n RISK_ORDER.indexOf(groupA as QueueRisk) -\n RISK_ORDER.indexOf(groupB as QueueRisk)\n )\n }\n\n return groupA.localeCompare(groupB)\n })\n\n return entries.map(([group, items]) => ({\n key: group.toLowerCase().replace(/\\s+/g, \"-\"),\n label: group,\n items,\n }))\n }, [display.grouping, filteredItems])\n\n React.useEffect(() => {\n setExpandedGroups((previous) => {\n const next: Record<string, boolean> = {}\n groupedItems.forEach((group) => {\n next[group.key] = previous[group.key] ?? true\n })\n return next\n })\n }, [groupedItems])\n\n return (\n <div className=\"overflow-hidden bg-background\">\n <div className=\"border-b border-border px-6 py-4\">\n <h3 className=\"text-xl font-semibold tracking-tight text-foreground\">\n Patient Inventory\n </h3>\n </div>\n\n <ItemListToolbar\n quickViews={quickViews}\n activeQuickView={activeQuickView}\n onQuickViewChange={setActiveQuickView}\n filterCategories={FILTER_CATEGORIES}\n selectedFilters={selectedFilters}\n onToggleFilter={(categoryId, option) =>\n setSelectedFilters((previous) =>\n toggleFilterValue(previous, categoryId, option),\n )\n }\n onClearFilters={() => setSelectedFilters({})}\n display={display}\n onDisplayChange={setDisplay}\n onResetDisplay={() => setDisplay(DEFAULT_DISPLAY_STATE)}\n />\n\n <div className=\"flex-1 overflow-auto\">\n {groupedItems.length > 0 ? (\n display.viewMode === \"board\" ? (\n /* Board View */\n <div className=\"flex gap-4 overflow-x-auto p-4\">\n {groupedItems.map((group) => (\n <div\n key={group.key}\n className=\"flex w-[280px] shrink-0 flex-col\"\n >\n <div className=\"mb-3 flex items-center justify-between px-1\">\n <h4 className=\"truncate text-sm font-semibold uppercase text-muted-foreground\">\n {group.label}\n </h4>\n <span className=\"rounded-full bg-muted px-2 py-0.5 text-xs font-medium text-muted-foreground\">\n {group.items.length}\n </span>\n </div>\n <div className=\"flex flex-col gap-3\">\n {group.items.map((item) => (\n <WorkItemCard\n key={item.id}\n item={item}\n display={display}\n />\n ))}\n {group.items.length === 0 ? (\n <div className=\"flex h-24 items-center justify-center rounded-lg border-2 border-dashed border-border bg-muted/30\">\n <span className=\"text-xs text-muted-foreground/50\">\n No items\n </span>\n </div>\n ) : null}\n </div>\n </div>\n ))}\n </div>\n ) : (\n /* List View */\n groupedItems.map((group) => {\n const isExpanded = expandedGroups[group.key]\n\n return (\n <div\n key={group.key}\n className=\"last:border-b-0\"\n >\n <button\n type=\"button\"\n onClick={() =>\n setExpandedGroups((previous) => ({\n ...previous,\n [group.key]: !previous[group.key],\n }))\n }\n className=\"flex w-full cursor-pointer select-none items-center gap-2 border-b border-border bg-muted/30 px-4 py-2 text-left transition-colors hover:bg-muted/50\"\n >\n <ChevronDown\n className={cn(\n \"h-3.5 w-3.5 text-muted-foreground transition-transform\",\n !isExpanded && \"-rotate-90\",\n )}\n />\n <span className=\"text-[11px] font-bold uppercase tracking-wider text-muted-foreground\">\n {group.label}\n </span>\n <span className=\"rounded border border-border bg-background px-1.5 py-0 text-[10px] font-medium text-muted-foreground\">\n {group.items.length}\n </span>\n </button>\n\n {isExpanded ? (\n <div>\n {group.items.map((item) => (\n <div\n key={item.id}\n className=\"group flex cursor-pointer items-center gap-3 border-b border-border/50 px-4 py-2.5 text-sm transition-colors hover:bg-muted/40\"\n >\n <span className=\"w-[80px] shrink-0 font-mono text-xs text-muted-foreground/80\">\n {item.id}\n </span>\n\n <div className=\"shrink-0\">\n <div\n className={cn(\n \"h-2 w-2 rounded-full\",\n getRiskDotColor(item.risk),\n )}\n />\n </div>\n\n <div className=\"min-w-0 flex-1 truncate font-semibold text-sm text-foreground\">\n {item.patient}{\" \"}\n <span className=\"font-normal text-muted-foreground\">\n via {item.source} &rarr; {item.specialty}\n </span>\n </div>\n\n <div className=\"hidden w-[80px] shrink-0 items-center md:flex\">\n {item.risk === \"At Risk\" ? (\n <Badge\n variant=\"outline\"\n className=\"h-5 gap-1 rounded-full border-red-200 bg-red-50 px-1.5 text-[10px] font-medium text-red-700 shadow-none\"\n >\n <AlertCircle className=\"h-3 w-3\" />\n At Risk\n </Badge>\n ) : null}\n </div>\n\n {display.showContactSignals ? (\n <div className=\"hidden items-center gap-3 text-muted-foreground/40 md:flex\">\n <Phone className=\"h-3.5 w-3.5 cursor-pointer transition-colors hover:text-foreground\" />\n <Mail className=\"h-3.5 w-3.5 cursor-pointer transition-colors hover:text-foreground\" />\n <MessageSquare className=\"h-3.5 w-3.5 cursor-pointer transition-colors hover:text-foreground\" />\n </div>\n ) : null}\n\n <div className=\"hidden w-[60px] shrink-0 items-center justify-center md:flex\">\n <span\n className={cn(\n \"inline-flex h-5 items-center justify-center rounded border px-2 text-xs font-semibold\",\n item.attempts >= 4\n ? \"border-red-300 bg-red-100 text-red-700\"\n : item.attempts === 3\n ? \"border-amber-300 bg-amber-100 text-amber-700\"\n : \"border-border bg-muted text-muted-foreground\",\n )}\n >\n {item.attempts >= 4 ? \"4+\" : item.attempts}\n </span>\n </div>\n\n {display.showOwner ? (\n <div className=\"hidden w-[120px] shrink-0 items-center gap-2 lg:flex\">\n <span className=\"truncate text-xs font-medium text-foreground\">\n {item.owner}\n </span>\n </div>\n ) : null}\n\n {display.showStatus ? (\n <div className=\"hidden w-[140px] shrink-0 items-center justify-end gap-2 sm:flex\">\n <span className=\"truncate rounded bg-muted px-2 py-0.5 text-xs text-muted-foreground\">\n {item.stage}\n </span>\n </div>\n ) : null}\n\n <div className=\"w-[80px] shrink-0 text-right text-xs text-muted-foreground\">\n {item.aging}\n </div>\n </div>\n ))}\n </div>\n ) : null}\n </div>\n )\n })\n )\n ) : (\n <div className=\"flex h-56 flex-col items-center justify-center gap-1 text-muted-foreground\">\n <SearchX className=\"h-7 w-7 opacity-40\" />\n <p className=\"text-sm font-medium\">No queue items found</p>\n <p className=\"text-xs\">\n Try a different quick view or clear your filters.\n </p>\n </div>\n )}\n </div>\n </div>\n )\n}\n\n// ---------------------------------------------------------------------------\n// GroupedListView -- shared grouped row list used by ItemList and Inbox\n// ---------------------------------------------------------------------------\n\nexport interface GroupedListGroup<T> {\n key: string\n label: string\n items: T[]\n}\n\nexport interface GroupedListViewProps<T> {\n groups: GroupedListGroup<T>[]\n renderRow: (item: T, index: number) => React.ReactNode\n getItemKey: (item: T) => string\n selectedKey?: string\n onItemClick?: (item: T) => void\n emptyMessage?: string\n className?: string\n}\n\nexport function GroupedListView<T>({\n groups,\n renderRow,\n getItemKey,\n selectedKey,\n onItemClick,\n emptyMessage = \"No items found\",\n className,\n}: GroupedListViewProps<T>) {\n const [expandedGroups, setExpandedGroups] = React.useState<Record<string, boolean>>(() => {\n const init: Record<string, boolean> = {}\n groups.forEach((g) => { init[g.key] = true })\n return init\n })\n\n React.useEffect(() => {\n setExpandedGroups((prev) => {\n const next: Record<string, boolean> = {}\n groups.forEach((g) => { next[g.key] = prev[g.key] ?? true })\n return next\n })\n }, [groups])\n\n if (groups.length === 0 || groups.every((g) => g.items.length === 0)) {\n return (\n <div className={cn(\"flex h-56 flex-col items-center justify-center gap-1 text-muted-foreground\", className)}>\n <SearchX className=\"h-7 w-7 opacity-40\" />\n <p className=\"text-sm font-medium\">{emptyMessage}</p>\n </div>\n )\n }\n\n return (\n <div className={className}>\n {groups.map((group) => {\n const isExpanded = expandedGroups[group.key] ?? true\n return (\n <div key={group.key}>\n <button\n type=\"button\"\n onClick={() =>\n setExpandedGroups((prev) => ({ ...prev, [group.key]: !prev[group.key] }))\n }\n className=\"flex w-full cursor-pointer select-none items-center gap-2 border-b border-border bg-muted/30 px-4 py-2 text-left transition-colors hover:bg-muted/50\"\n >\n <ChevronDown\n className={cn(\n \"h-3.5 w-3.5 text-muted-foreground transition-transform\",\n !isExpanded && \"-rotate-90\",\n )}\n />\n <span className=\"text-[11px] font-bold uppercase tracking-wider text-muted-foreground\">\n {group.label}\n </span>\n <span className=\"rounded border border-border bg-background px-1.5 py-0 text-[10px] font-medium text-muted-foreground\">\n {group.items.length}\n </span>\n </button>\n {isExpanded &&\n group.items.map((item, idx) => {\n const key = getItemKey(item)\n return (\n <div\n key={key}\n onClick={() => onItemClick?.(item)}\n className={cn(\n \"flex items-center gap-3 px-4 py-2.5 border-b border-border/50 text-[13px] cursor-pointer transition-colors\",\n selectedKey === key\n ? \"bg-muted/30 border-l-2 border-l-primary\"\n : \"border-l-2 border-l-transparent hover:bg-muted/40\",\n )}\n >\n {renderRow(item, idx)}\n </div>\n )\n })}\n </div>\n )\n })}\n </div>\n )\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,6 @@
1
+ import * as React from 'react';
2
+ import { Label as Label$1 } from 'radix-ui';
3
+
4
+ declare function Label({ className, ...props }: React.ComponentProps<typeof Label$1.Root>): React.JSX.Element;
5
+
6
+ export { Label };
@@ -0,0 +1,55 @@
1
+ "use client"
2
+
3
+ "use client";
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
8
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
9
+ var __spreadValues = (a, b) => {
10
+ for (var prop in b || (b = {}))
11
+ if (__hasOwnProp.call(b, prop))
12
+ __defNormalProp(a, prop, b[prop]);
13
+ if (__getOwnPropSymbols)
14
+ for (var prop of __getOwnPropSymbols(b)) {
15
+ if (__propIsEnum.call(b, prop))
16
+ __defNormalProp(a, prop, b[prop]);
17
+ }
18
+ return a;
19
+ };
20
+ var __objRest = (source, exclude) => {
21
+ var target = {};
22
+ for (var prop in source)
23
+ if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
24
+ target[prop] = source[prop];
25
+ if (source != null && __getOwnPropSymbols)
26
+ for (var prop of __getOwnPropSymbols(source)) {
27
+ if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
28
+ target[prop] = source[prop];
29
+ }
30
+ return target;
31
+ };
32
+ import { jsx } from "react/jsx-runtime";
33
+ import { Label as LabelPrimitive } from "radix-ui";
34
+ import { cn } from "../lib/utils.js";
35
+ function Label(_a) {
36
+ var _b = _a, {
37
+ className
38
+ } = _b, props = __objRest(_b, [
39
+ "className"
40
+ ]);
41
+ return /* @__PURE__ */ jsx(
42
+ LabelPrimitive.Root,
43
+ __spreadValues({
44
+ "data-slot": "label",
45
+ className: cn(
46
+ "flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50",
47
+ className
48
+ )
49
+ }, props)
50
+ );
51
+ }
52
+ export {
53
+ Label
54
+ };
55
+ //# sourceMappingURL=label.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/components/label.tsx"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport { Label as LabelPrimitive } from \"radix-ui\"\n\nimport { cn } from \"../lib/utils\"\n\nfunction Label({\n className,\n ...props\n}: React.ComponentProps<typeof LabelPrimitive.Root>) {\n return (\n <LabelPrimitive.Root\n data-slot=\"label\"\n className={cn(\n \"flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50\",\n className\n )}\n {...props}\n />\n )\n}\n\nexport { Label }\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAYI;AATJ,SAAS,SAAS,sBAAsB;AAExC,SAAS,UAAU;AAEnB,SAAS,MAAM,IAGsC;AAHtC,eACb;AAAA;AAAA,EARF,IAOe,IAEV,kBAFU,IAEV;AAAA,IADH;AAAA;AAGA,SACE;AAAA,IAAC,eAAe;AAAA,IAAf;AAAA,MACC,aAAU;AAAA,MACV,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,OACI;AAAA,EACN;AAEJ;","names":[]}
@@ -0,0 +1,23 @@
1
+ import * as class_variance_authority_types from 'class-variance-authority/types';
2
+ import * as React from 'react';
3
+ import { HTMLAttributes, ComponentProps } from 'react';
4
+ import { VariantProps } from 'class-variance-authority';
5
+ import { Avatar } from './avatar.js';
6
+ import 'radix-ui';
7
+
8
+ type MessageProps = HTMLAttributes<HTMLDivElement> & {
9
+ from: "user" | "assistant";
10
+ };
11
+ declare const Message: ({ className, from, ...props }: MessageProps) => React.JSX.Element;
12
+ declare const messageContentVariants: (props?: ({
13
+ variant?: "flat" | "contained" | null | undefined;
14
+ } & class_variance_authority_types.ClassProp) | undefined) => string;
15
+ type MessageContentProps = HTMLAttributes<HTMLDivElement> & VariantProps<typeof messageContentVariants>;
16
+ declare const MessageContent: ({ children, className, variant, ...props }: MessageContentProps) => React.JSX.Element;
17
+ type MessageAvatarProps = ComponentProps<typeof Avatar> & {
18
+ src?: string;
19
+ name?: string;
20
+ };
21
+ declare const MessageAvatar: ({ src, name, className, children, ...props }: MessageAvatarProps) => React.JSX.Element;
22
+
23
+ export { Message, MessageAvatar, type MessageAvatarProps, MessageContent, type MessageContentProps, type MessageProps };
@@ -0,0 +1,117 @@
1
+ "use client"
2
+
3
+ "use client";
4
+ var __defProp = Object.defineProperty;
5
+ var __defProps = Object.defineProperties;
6
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
7
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
10
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
11
+ var __spreadValues = (a, b) => {
12
+ for (var prop in b || (b = {}))
13
+ if (__hasOwnProp.call(b, prop))
14
+ __defNormalProp(a, prop, b[prop]);
15
+ if (__getOwnPropSymbols)
16
+ for (var prop of __getOwnPropSymbols(b)) {
17
+ if (__propIsEnum.call(b, prop))
18
+ __defNormalProp(a, prop, b[prop]);
19
+ }
20
+ return a;
21
+ };
22
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
23
+ var __objRest = (source, exclude) => {
24
+ var target = {};
25
+ for (var prop in source)
26
+ if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
27
+ target[prop] = source[prop];
28
+ if (source != null && __getOwnPropSymbols)
29
+ for (var prop of __getOwnPropSymbols(source)) {
30
+ if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
31
+ target[prop] = source[prop];
32
+ }
33
+ return target;
34
+ };
35
+ import { jsx, jsxs } from "react/jsx-runtime";
36
+ import { cva } from "class-variance-authority";
37
+ import { cn } from "../lib/utils.js";
38
+ import { Avatar, AvatarFallback, AvatarImage } from "./avatar.js";
39
+ const Message = (_a) => {
40
+ var _b = _a, { className, from } = _b, props = __objRest(_b, ["className", "from"]);
41
+ return /* @__PURE__ */ jsx(
42
+ "div",
43
+ __spreadValues({
44
+ "data-slot": "message",
45
+ className: cn(
46
+ "group flex w-full items-end gap-3 py-2",
47
+ from === "user" ? "is-user justify-end" : "is-assistant justify-start",
48
+ className
49
+ )
50
+ }, props)
51
+ );
52
+ };
53
+ const messageContentVariants = cva(
54
+ "flex flex-col gap-2 overflow-hidden text-sm leading-relaxed shadow-sm whitespace-pre-wrap",
55
+ {
56
+ variants: {
57
+ variant: {
58
+ contained: [
59
+ "max-w-[85%] px-6 py-4 rounded-[24px]",
60
+ "group-[.is-user]:bg-primary group-[.is-user]:text-primary-foreground group-[.is-user]:rounded-br-sm",
61
+ "group-[.is-assistant]:bg-muted group-[.is-assistant]:text-foreground group-[.is-assistant]:rounded-bl-sm"
62
+ ],
63
+ flat: [
64
+ "group-[.is-user]:max-w-[85%] group-[.is-user]:bg-secondary group-[.is-user]:px-4 group-[.is-user]:py-3 group-[.is-user]:text-foreground",
65
+ "group-[.is-assistant]:text-foreground"
66
+ ]
67
+ }
68
+ },
69
+ defaultVariants: {
70
+ variant: "contained"
71
+ }
72
+ }
73
+ );
74
+ const MessageContent = (_c) => {
75
+ var _d = _c, {
76
+ children,
77
+ className,
78
+ variant
79
+ } = _d, props = __objRest(_d, [
80
+ "children",
81
+ "className",
82
+ "variant"
83
+ ]);
84
+ return /* @__PURE__ */ jsx(
85
+ "div",
86
+ __spreadProps(__spreadValues({
87
+ "data-slot": "message-content",
88
+ className: cn(messageContentVariants({ variant, className }))
89
+ }, props), {
90
+ children
91
+ })
92
+ );
93
+ };
94
+ const MessageAvatar = (_e) => {
95
+ var _f = _e, {
96
+ src,
97
+ name,
98
+ className,
99
+ children
100
+ } = _f, props = __objRest(_f, [
101
+ "src",
102
+ "name",
103
+ "className",
104
+ "children"
105
+ ]);
106
+ return /* @__PURE__ */ jsxs(Avatar, __spreadProps(__spreadValues({ className: cn("ring-border size-8 ring-1 shrink-0", className) }, props), { children: [
107
+ children,
108
+ src && /* @__PURE__ */ jsx(AvatarImage, { alt: "", className: "mt-0 mb-0", src }),
109
+ !children && !src && /* @__PURE__ */ jsx(AvatarFallback, { children: (name == null ? void 0 : name.slice(0, 2)) || "ME" })
110
+ ] }));
111
+ };
112
+ export {
113
+ Message,
114
+ MessageAvatar,
115
+ MessageContent
116
+ };
117
+ //# sourceMappingURL=message.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/components/message.tsx"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport type { ComponentProps, HTMLAttributes } from \"react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"../lib/utils\"\nimport { Avatar, AvatarFallback, AvatarImage } from \"./avatar\"\n\nexport type MessageProps = HTMLAttributes<HTMLDivElement> & {\n from: \"user\" | \"assistant\"\n}\n\nexport const Message = ({ className, from, ...props }: MessageProps) => (\n <div\n data-slot=\"message\"\n className={cn(\n \"group flex w-full items-end gap-3 py-2\",\n from === \"user\" ? \"is-user justify-end\" : \"is-assistant justify-start\",\n className\n )}\n {...props}\n />\n)\n\nconst messageContentVariants = cva(\n \"flex flex-col gap-2 overflow-hidden text-sm leading-relaxed shadow-sm whitespace-pre-wrap\",\n {\n variants: {\n variant: {\n contained: [\n \"max-w-[85%] px-6 py-4 rounded-[24px]\",\n \"group-[.is-user]:bg-primary group-[.is-user]:text-primary-foreground group-[.is-user]:rounded-br-sm\",\n \"group-[.is-assistant]:bg-muted group-[.is-assistant]:text-foreground group-[.is-assistant]:rounded-bl-sm\",\n ],\n flat: [\n \"group-[.is-user]:max-w-[85%] group-[.is-user]:bg-secondary group-[.is-user]:px-4 group-[.is-user]:py-3 group-[.is-user]:text-foreground\",\n \"group-[.is-assistant]:text-foreground\",\n ],\n },\n },\n defaultVariants: {\n variant: \"contained\",\n },\n }\n)\n\nexport type MessageContentProps = HTMLAttributes<HTMLDivElement> &\n VariantProps<typeof messageContentVariants>\n\nexport const MessageContent = ({\n children,\n className,\n variant,\n ...props\n}: MessageContentProps) => (\n <div\n data-slot=\"message-content\"\n className={cn(messageContentVariants({ variant, className }))}\n {...props}\n >\n {children}\n </div>\n)\n\nexport type MessageAvatarProps = ComponentProps<typeof Avatar> & {\n src?: string\n name?: string\n}\n\nexport const MessageAvatar = ({\n src,\n name,\n className,\n children,\n ...props\n}: MessageAvatarProps) => (\n <Avatar className={cn(\"ring-border size-8 ring-1 shrink-0\", className)} {...props}>\n {children}\n {src && <AvatarImage alt=\"\" className=\"mt-0 mb-0\" src={src} />}\n {!children && !src && <AvatarFallback>{name?.slice(0, 2) || \"ME\"}</AvatarFallback>}\n </Avatar>\n)\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAcE,cA+DA,YA/DA;AAVF,SAAS,WAA8B;AAEvC,SAAS,UAAU;AACnB,SAAS,QAAQ,gBAAgB,mBAAmB;AAM7C,MAAM,UAAU,CAAC,OAA6C;AAA7C,eAAE,aAAW,KAbrC,IAawB,IAAsB,kBAAtB,IAAsB,CAApB,aAAW;AACnC;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW;AAAA,QACT;AAAA,QACA,SAAS,SAAS,wBAAwB;AAAA,QAC1C;AAAA,MACF;AAAA,OACI;AAAA,EACN;AAAA;AAGF,MAAM,yBAAyB;AAAA,EAC7B;AAAA,EACA;AAAA,IACE,UAAU;AAAA,MACR,SAAS;AAAA,QACP,WAAW;AAAA,UACT;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,QACA,MAAM;AAAA,UACJ;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,IACA,iBAAiB;AAAA,MACf,SAAS;AAAA,IACX;AAAA,EACF;AACF;AAKO,MAAM,iBAAiB,CAAC,OAKP;AALO,eAC7B;AAAA;AAAA,IACA;AAAA,IACA;AAAA,EArDF,IAkD+B,IAI1B,kBAJ0B,IAI1B;AAAA,IAHH;AAAA,IACA;AAAA,IACA;AAAA;AAGA;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW,GAAG,uBAAuB,EAAE,SAAS,UAAU,CAAC,CAAC;AAAA,OACxD,QAHL;AAAA,MAKE;AAAA;AAAA,EACH;AAAA;AAQK,MAAM,gBAAgB,CAAC,OAMP;AANO,eAC5B;AAAA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EA1EF,IAsE8B,IAKzB,kBALyB,IAKzB;AAAA,IAJH;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAGA,8BAAC,uCAAO,WAAW,GAAG,sCAAsC,SAAS,KAAO,QAA3E,EACE;AAAA;AAAA,IACA,OAAO,oBAAC,eAAY,KAAI,IAAG,WAAU,aAAY,KAAU;AAAA,IAC3D,CAAC,YAAY,CAAC,OAAO,oBAAC,kBAAgB,wCAAM,MAAM,GAAG,OAAM,MAAK;AAAA,MACnE;AAAA;","names":[]}
@@ -0,0 +1,25 @@
1
+ import * as React from 'react';
2
+
3
+ interface MetricDataPoint {
4
+ label: string;
5
+ value: number | string;
6
+ color?: string;
7
+ }
8
+ interface MetricCardProps {
9
+ title: string;
10
+ value?: string | number;
11
+ unit?: string;
12
+ subtitle?: string;
13
+ change?: {
14
+ value: string;
15
+ direction: "up" | "down" | "neutral";
16
+ isGood?: boolean;
17
+ };
18
+ footerText?: string;
19
+ dataPoints?: MetricDataPoint[];
20
+ showExternalLink?: boolean;
21
+ showInfo?: boolean;
22
+ }
23
+ declare function MetricCard({ title, value, unit, subtitle, change, footerText, dataPoints, showExternalLink, showInfo, }: MetricCardProps): React.JSX.Element;
24
+
25
+ export { MetricCard, type MetricCardProps, type MetricDataPoint };
@@ -0,0 +1,107 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { ArrowUp, ArrowDown, Info, ExternalLink } from "lucide-react";
3
+ import { cn } from "../lib/utils.js";
4
+ function MetricCard({
5
+ title,
6
+ value,
7
+ unit,
8
+ subtitle,
9
+ change,
10
+ footerText,
11
+ dataPoints,
12
+ showExternalLink,
13
+ showInfo = true
14
+ }) {
15
+ const renderDonut = () => {
16
+ if (!dataPoints || dataPoints.length === 0 || value === void 0) return null;
17
+ const size = 80;
18
+ const strokeWidth = 12;
19
+ const radius = (size - strokeWidth) / 2;
20
+ const circumference = 2 * Math.PI * radius;
21
+ const total = dataPoints.reduce((sum, dp) => sum + (typeof dp.value === "number" ? dp.value : 0), 0);
22
+ let currentOffset = 0;
23
+ return /* @__PURE__ */ jsxs("div", { className: "relative", style: { width: size, height: size }, children: [
24
+ /* @__PURE__ */ jsx("svg", { width: size, height: size, className: "transform -rotate-90", children: dataPoints.map((dp, i) => {
25
+ const val = typeof dp.value === "number" ? dp.value : 0;
26
+ const percentage = val / total;
27
+ const strokeLength = percentage * circumference;
28
+ const offset = currentOffset;
29
+ currentOffset += strokeLength;
30
+ const colors = ["#166534", "#22c55e", "#6ee7b7", "#ccfbf1", "#f1f5f9"];
31
+ const color = dp.color || colors[i % colors.length];
32
+ return /* @__PURE__ */ jsx(
33
+ "circle",
34
+ {
35
+ cx: size / 2,
36
+ cy: size / 2,
37
+ r: radius,
38
+ fill: "none",
39
+ stroke: color,
40
+ strokeWidth,
41
+ strokeDasharray: `${Math.max(strokeLength - 2, 0)} ${circumference}`,
42
+ strokeDashoffset: -offset,
43
+ className: "transition-all duration-300"
44
+ },
45
+ dp.label
46
+ );
47
+ }) }),
48
+ /* @__PURE__ */ jsx("div", { className: "absolute inset-0 flex items-center justify-center flex-col", children: /* @__PURE__ */ jsx("span", { className: "text-xl font-bold text-foreground leading-none", children: value }) })
49
+ ] });
50
+ };
51
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-col rounded-xl border border-border bg-card p-5 shadow-sm h-full w-full", children: [
52
+ /* @__PURE__ */ jsxs("div", { className: cn("flex justify-between items-start", title ? "mb-4" : "mb-4"), children: [
53
+ title ? /* @__PURE__ */ jsx("h3", { className: "font-semibold text-sm text-foreground/80", children: title }) : /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
54
+ /* @__PURE__ */ jsxs("div", { className: "flex items-baseline gap-1", children: [
55
+ /* @__PURE__ */ jsx("span", { className: "text-3xl font-bold tracking-tight text-foreground", children: value }),
56
+ unit && /* @__PURE__ */ jsx("span", { className: "text-2xl font-bold tracking-tight text-foreground", children: unit })
57
+ ] }),
58
+ subtitle && /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-muted-foreground mt-2", children: subtitle })
59
+ ] }),
60
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 text-muted-foreground shrink-0 mt-0.5", children: [
61
+ showExternalLink && /* @__PURE__ */ jsx(ExternalLink, { className: "w-3.5 h-3.5 cursor-pointer hover:text-foreground transition-colors" }),
62
+ showInfo && /* @__PURE__ */ jsx(Info, { className: "w-3.5 h-3.5 cursor-pointer hover:text-foreground transition-colors" })
63
+ ] })
64
+ ] }),
65
+ /* @__PURE__ */ jsxs("div", { className: "flex-1 flex flex-col min-w-0", children: [
66
+ dataPoints && dataPoints.length > 0 ? (
67
+ // Donut Chart Variant
68
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-4 mt-2 mb-6", children: [
69
+ /* @__PURE__ */ jsx("div", { className: "shrink-0", children: renderDonut() }),
70
+ /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-2 flex-1 min-w-0", children: dataPoints.slice(0, 5).map((dp, i) => {
71
+ const colors = ["bg-[#166534]", "bg-[#22c55e]", "bg-[#6ee7b7]", "bg-[#ccfbf1]", "bg-[#f1f5f9]"];
72
+ return /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2 text-[11px] font-medium min-w-0", children: [
73
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 text-muted-foreground min-w-0", children: [
74
+ /* @__PURE__ */ jsx("div", { className: cn("w-1.5 h-1.5 rounded-full shrink-0", dp.color ? "" : colors[i % colors.length]), style: dp.color ? { backgroundColor: dp.color } : {} }),
75
+ /* @__PURE__ */ jsx("span", { className: "whitespace-nowrap", children: dp.label })
76
+ ] }),
77
+ /* @__PURE__ */ jsx("span", { className: "text-foreground font-semibold shrink-0", children: dp.value })
78
+ ] }, dp.label);
79
+ }) })
80
+ ] })
81
+ ) : title && // Standard Big Number Variant (only if title exists)
82
+ /* @__PURE__ */ jsxs("div", { className: "mb-6", children: [
83
+ /* @__PURE__ */ jsxs("div", { className: "flex items-baseline gap-1", children: [
84
+ /* @__PURE__ */ jsx("span", { className: "text-4xl font-bold tracking-tight text-foreground", children: value }),
85
+ unit && /* @__PURE__ */ jsx("span", { className: "text-2xl font-bold tracking-tight text-foreground", children: unit })
86
+ ] }),
87
+ subtitle && /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-muted-foreground mt-1", children: subtitle })
88
+ ] }),
89
+ /* @__PURE__ */ jsxs("div", { className: "mt-auto flex flex-col gap-1.5", children: [
90
+ change && /* @__PURE__ */ jsx("div", { className: "flex items-center gap-1", children: (() => {
91
+ const isGoodDirection = change.isGood !== void 0 ? change.isGood : change.direction === "up";
92
+ const colorClass = isGoodDirection ? "text-emerald-600" : "text-red-600";
93
+ const Icon = change.direction === "down" ? ArrowDown : ArrowUp;
94
+ return /* @__PURE__ */ jsxs("span", { className: cn("text-xs font-semibold flex items-center gap-0.5", colorClass), children: [
95
+ /* @__PURE__ */ jsx(Icon, { className: "w-3 h-3 stroke-[3]" }),
96
+ change.value
97
+ ] });
98
+ })() }),
99
+ footerText && /* @__PURE__ */ jsx("span", { className: "text-[11px] text-muted-foreground font-medium", children: footerText })
100
+ ] })
101
+ ] })
102
+ ] });
103
+ }
104
+ export {
105
+ MetricCard
106
+ };
107
+ //# sourceMappingURL=metric-card.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/components/metric-card.tsx"],"sourcesContent":["import * as React from \"react\"\nimport { ArrowUp, ArrowDown, Info, ExternalLink } from \"lucide-react\"\nimport { cn } from \"../lib/utils\"\n\nexport interface MetricDataPoint {\n label: string\n value: number | string\n color?: string\n}\n\nexport interface MetricCardProps {\n title: string\n value?: string | number\n unit?: string\n subtitle?: string\n change?: { \n value: string\n direction: \"up\" | \"down\" | \"neutral\"\n isGood?: boolean // if true, up is green. if false, up is red (e.g. churn).\n }\n footerText?: string\n dataPoints?: MetricDataPoint[]\n showExternalLink?: boolean\n showInfo?: boolean\n}\n\nexport function MetricCard({\n title,\n value,\n unit,\n subtitle,\n change,\n footerText,\n dataPoints,\n showExternalLink,\n showInfo = true,\n}: MetricCardProps) {\n // SVG Donut Chart logic for variants with dataPoints\n const renderDonut = () => {\n if (!dataPoints || dataPoints.length === 0 || value === undefined) return null\n\n // Simple pseudo-donut chart logic assuming specific colors from the image\n // In a real prod environment we'd use recharts/visx, but for this standalone component\n // we can draw an SVG circle with stroke-dasharray based on the data\n const size = 80\n const strokeWidth = 12\n const radius = (size - strokeWidth) / 2\n const circumference = 2 * Math.PI * radius\n \n // Calculate total to distribute the circle\n const total = dataPoints.reduce((sum, dp) => sum + (typeof dp.value === 'number' ? dp.value : 0), 0)\n let currentOffset = 0\n\n return (\n <div className=\"relative\" style={{ width: size, height: size }}>\n <svg width={size} height={size} className=\"transform -rotate-90\">\n {dataPoints.map((dp, i) => {\n const val = typeof dp.value === 'number' ? dp.value : 0\n const percentage = val / total\n const strokeLength = percentage * circumference\n const offset = currentOffset\n currentOffset += strokeLength\n\n // Fallback colors matching the image's teal/green palette\n const colors = [\"#166534\", \"#22c55e\", \"#6ee7b7\", \"#ccfbf1\", \"#f1f5f9\"]\n const color = dp.color || colors[i % colors.length]\n\n return (\n <circle\n key={dp.label}\n cx={size / 2}\n cy={size / 2}\n r={radius}\n fill=\"none\"\n stroke={color}\n strokeWidth={strokeWidth}\n strokeDasharray={`${Math.max(strokeLength - 2, 0)} ${circumference}`}\n strokeDashoffset={-offset}\n className=\"transition-all duration-300\"\n />\n )\n })}\n </svg>\n <div className=\"absolute inset-0 flex items-center justify-center flex-col\">\n <span className=\"text-xl font-bold text-foreground leading-none\">{value}</span>\n </div>\n </div>\n )\n }\n\n return (\n <div className=\"flex flex-col rounded-xl border border-border bg-card p-5 shadow-sm h-full w-full\">\n <div className={cn(\"flex justify-between items-start\", title ? \"mb-4\" : \"mb-4\")}>\n {title ? (\n <h3 className=\"font-semibold text-sm text-foreground/80\">{title}</h3>\n ) : (\n <div className=\"flex flex-col\">\n <div className=\"flex items-baseline gap-1\">\n <span className=\"text-3xl font-bold tracking-tight text-foreground\">{value}</span>\n {unit && <span className=\"text-2xl font-bold tracking-tight text-foreground\">{unit}</span>}\n </div>\n {subtitle && (\n <p className=\"text-sm font-medium text-muted-foreground mt-2\">{subtitle}</p>\n )}\n </div>\n )}\n <div className=\"flex items-center gap-1.5 text-muted-foreground shrink-0 mt-0.5\">\n {showExternalLink && <ExternalLink className=\"w-3.5 h-3.5 cursor-pointer hover:text-foreground transition-colors\" />}\n {showInfo && <Info className=\"w-3.5 h-3.5 cursor-pointer hover:text-foreground transition-colors\" />}\n </div>\n </div>\n\n <div className=\"flex-1 flex flex-col min-w-0\">\n {dataPoints && dataPoints.length > 0 ? (\n // Donut Chart Variant\n <div className=\"flex items-center gap-4 mt-2 mb-6\">\n <div className=\"shrink-0\">\n {renderDonut()}\n </div>\n <div className=\"flex flex-col gap-2 flex-1 min-w-0\">\n {dataPoints.slice(0, 5).map((dp, i) => {\n const colors = [\"bg-[#166534]\", \"bg-[#22c55e]\", \"bg-[#6ee7b7]\", \"bg-[#ccfbf1]\", \"bg-[#f1f5f9]\"]\n return (\n <div key={dp.label} className=\"flex items-center justify-between gap-2 text-[11px] font-medium min-w-0\">\n <div className=\"flex items-center gap-1.5 text-muted-foreground min-w-0\">\n <div className={cn(\"w-1.5 h-1.5 rounded-full shrink-0\", dp.color ? \"\" : colors[i % colors.length])} style={dp.color ? { backgroundColor: dp.color } : {}} />\n <span className=\"whitespace-nowrap\">{dp.label}</span>\n </div>\n <span className=\"text-foreground font-semibold shrink-0\">{dp.value}</span>\n </div>\n )\n })}\n </div>\n </div>\n ) : title && (\n // Standard Big Number Variant (only if title exists)\n <div className=\"mb-6\">\n <div className=\"flex items-baseline gap-1\">\n <span className=\"text-4xl font-bold tracking-tight text-foreground\">{value}</span>\n {unit && <span className=\"text-2xl font-bold tracking-tight text-foreground\">{unit}</span>}\n </div>\n {subtitle && (\n <p className=\"text-sm font-medium text-muted-foreground mt-1\">{subtitle}</p>\n )}\n </div>\n )}\n\n {/* Footer section (Change indicator & extra text) */}\n <div className=\"mt-auto flex flex-col gap-1.5\">\n {change && (\n <div className=\"flex items-center gap-1\">\n {(() => {\n // Determine color based on isGood property\n // By default, up is green (good), down is red (bad)\n const isGoodDirection = change.isGood !== undefined \n ? change.isGood \n : change.direction === \"up\";\n \n const colorClass = isGoodDirection ? \"text-emerald-600\" : \"text-red-600\";\n const Icon = change.direction === \"down\" ? ArrowDown : ArrowUp;\n \n return (\n <span className={cn(\"text-xs font-semibold flex items-center gap-0.5\", colorClass)}>\n <Icon className=\"w-3 h-3 stroke-[3]\" />\n {change.value}\n </span>\n )\n })()}\n </div>\n )}\n {footerText && (\n <span className=\"text-[11px] text-muted-foreground font-medium\">{footerText}</span>\n )}\n </div>\n </div>\n </div>\n )\n}\n"],"mappings":"AAsDM,SAcQ,KAdR;AArDN,SAAS,SAAS,WAAW,MAAM,oBAAoB;AACvD,SAAS,UAAU;AAwBZ,SAAS,WAAW;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,WAAW;AACb,GAAoB;AAElB,QAAM,cAAc,MAAM;AACxB,QAAI,CAAC,cAAc,WAAW,WAAW,KAAK,UAAU,OAAW,QAAO;AAK1E,UAAM,OAAO;AACb,UAAM,cAAc;AACpB,UAAM,UAAU,OAAO,eAAe;AACtC,UAAM,gBAAgB,IAAI,KAAK,KAAK;AAGpC,UAAM,QAAQ,WAAW,OAAO,CAAC,KAAK,OAAO,OAAO,OAAO,GAAG,UAAU,WAAW,GAAG,QAAQ,IAAI,CAAC;AACnG,QAAI,gBAAgB;AAEpB,WACE,qBAAC,SAAI,WAAU,YAAW,OAAO,EAAE,OAAO,MAAM,QAAQ,KAAK,GAC3D;AAAA,0BAAC,SAAI,OAAO,MAAM,QAAQ,MAAM,WAAU,wBACvC,qBAAW,IAAI,CAAC,IAAI,MAAM;AACzB,cAAM,MAAM,OAAO,GAAG,UAAU,WAAW,GAAG,QAAQ;AACtD,cAAM,aAAa,MAAM;AACzB,cAAM,eAAe,aAAa;AAClC,cAAM,SAAS;AACf,yBAAiB;AAGjB,cAAM,SAAS,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AACrE,cAAM,QAAQ,GAAG,SAAS,OAAO,IAAI,OAAO,MAAM;AAElD,eACE;AAAA,UAAC;AAAA;AAAA,YAEC,IAAI,OAAO;AAAA,YACX,IAAI,OAAO;AAAA,YACX,GAAG;AAAA,YACH,MAAK;AAAA,YACL,QAAQ;AAAA,YACR;AAAA,YACA,iBAAiB,GAAG,KAAK,IAAI,eAAe,GAAG,CAAC,CAAC,IAAI,aAAa;AAAA,YAClE,kBAAkB,CAAC;AAAA,YACnB,WAAU;AAAA;AAAA,UATL,GAAG;AAAA,QAUV;AAAA,MAEJ,CAAC,GACH;AAAA,MACA,oBAAC,SAAI,WAAU,8DACb,8BAAC,UAAK,WAAU,kDAAkD,iBAAM,GAC1E;AAAA,OACF;AAAA,EAEJ;AAEA,SACE,qBAAC,SAAI,WAAU,qFACb;AAAA,yBAAC,SAAI,WAAW,GAAG,oCAAoC,QAAQ,SAAS,MAAM,GAC3E;AAAA,cACC,oBAAC,QAAG,WAAU,4CAA4C,iBAAM,IAEhE,qBAAC,SAAI,WAAU,iBACb;AAAA,6BAAC,SAAI,WAAU,6BACb;AAAA,8BAAC,UAAK,WAAU,qDAAqD,iBAAM;AAAA,UAC1E,QAAQ,oBAAC,UAAK,WAAU,qDAAqD,gBAAK;AAAA,WACrF;AAAA,QACC,YACC,oBAAC,OAAE,WAAU,kDAAkD,oBAAS;AAAA,SAE5E;AAAA,MAEF,qBAAC,SAAI,WAAU,mEACZ;AAAA,4BAAoB,oBAAC,gBAAa,WAAU,sEAAqE;AAAA,QACjH,YAAY,oBAAC,QAAK,WAAU,sEAAqE;AAAA,SACpG;AAAA,OACF;AAAA,IAEA,qBAAC,SAAI,WAAU,gCACZ;AAAA,oBAAc,WAAW,SAAS;AAAA;AAAA,QAEjC,qBAAC,SAAI,WAAU,qCACb;AAAA,8BAAC,SAAI,WAAU,YACZ,sBAAY,GACf;AAAA,UACA,oBAAC,SAAI,WAAU,sCACZ,qBAAW,MAAM,GAAG,CAAC,EAAE,IAAI,CAAC,IAAI,MAAM;AACrC,kBAAM,SAAS,CAAC,gBAAgB,gBAAgB,gBAAgB,gBAAgB,cAAc;AAC9F,mBACE,qBAAC,SAAmB,WAAU,2EAC5B;AAAA,mCAAC,SAAI,WAAU,2DACb;AAAA,oCAAC,SAAI,WAAW,GAAG,qCAAqC,GAAG,QAAQ,KAAK,OAAO,IAAI,OAAO,MAAM,CAAC,GAAG,OAAO,GAAG,QAAQ,EAAE,iBAAiB,GAAG,MAAM,IAAI,CAAC,GAAG;AAAA,gBAC1J,oBAAC,UAAK,WAAU,qBAAqB,aAAG,OAAM;AAAA,iBAChD;AAAA,cACA,oBAAC,UAAK,WAAU,0CAA0C,aAAG,OAAM;AAAA,iBAL3D,GAAG,KAMb;AAAA,UAEJ,CAAC,GACH;AAAA,WACF;AAAA,UACE;AAAA,MAEF,qBAAC,SAAI,WAAU,QACb;AAAA,6BAAC,SAAI,WAAU,6BACb;AAAA,8BAAC,UAAK,WAAU,qDAAqD,iBAAM;AAAA,UAC1E,QAAQ,oBAAC,UAAK,WAAU,qDAAqD,gBAAK;AAAA,WACrF;AAAA,QACC,YACC,oBAAC,OAAE,WAAU,kDAAkD,oBAAS;AAAA,SAE5E;AAAA,MAIF,qBAAC,SAAI,WAAU,iCACZ;AAAA,kBACC,oBAAC,SAAI,WAAU,2BACX,iBAAM;AAGN,gBAAM,kBAAkB,OAAO,WAAW,SACtC,OAAO,SACP,OAAO,cAAc;AAEzB,gBAAM,aAAa,kBAAkB,qBAAqB;AAC1D,gBAAM,OAAO,OAAO,cAAc,SAAS,YAAY;AAEvD,iBACE,qBAAC,UAAK,WAAW,GAAG,mDAAmD,UAAU,GAC/E;AAAA,gCAAC,QAAK,WAAU,sBAAqB;AAAA,YACpC,OAAO;AAAA,aACV;AAAA,QAEJ,GAAG,GACL;AAAA,QAED,cACC,oBAAC,UAAK,WAAU,iDAAiD,sBAAW;AAAA,SAEhF;AAAA,OACF;AAAA,KACF;AAEJ;","names":[]}
@@ -0,0 +1,38 @@
1
+ import * as React from 'react';
2
+
3
+ interface PerformanceMetricsTableRow {
4
+ id: string;
5
+ label: string;
6
+ avatarFallback: string;
7
+ role?: string;
8
+ primaryValue: number;
9
+ primaryTarget: number;
10
+ ratePercent: number;
11
+ metricOne: number;
12
+ metricTwo: string;
13
+ metricThree: number;
14
+ metricFour: number;
15
+ }
16
+ interface PerformanceMetricsTableSortOption {
17
+ id: "primary-desc" | "primary-asc" | "rate-desc" | "metric-four-desc";
18
+ label: string;
19
+ }
20
+ interface PerformanceMetricsTableProps {
21
+ title?: string;
22
+ entityColumnLabel?: string;
23
+ primaryMetricColumnLabel?: string;
24
+ rateColumnLabel?: string;
25
+ metricOneColumnLabel?: string;
26
+ metricTwoColumnLabel?: string;
27
+ metricThreeColumnLabel?: string;
28
+ metricFourColumnLabel?: string;
29
+ viewOptions?: string[];
30
+ roleOptions?: string[];
31
+ sortOptions?: PerformanceMetricsTableSortOption[];
32
+ rows?: PerformanceMetricsTableRow[];
33
+ pageSize?: number;
34
+ searchPlaceholder?: string;
35
+ }
36
+ declare function PerformanceMetricsTable({ title, entityColumnLabel, primaryMetricColumnLabel, rateColumnLabel, metricOneColumnLabel, metricTwoColumnLabel, metricThreeColumnLabel, metricFourColumnLabel, viewOptions, roleOptions, sortOptions, rows, pageSize, searchPlaceholder, }: PerformanceMetricsTableProps): React.JSX.Element;
37
+
38
+ export { PerformanceMetricsTable, type PerformanceMetricsTableRow, type PerformanceMetricsTableSortOption };