@hub-kit/core 0.3.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 (499) hide show
  1. package/README.md +125 -0
  2. package/cli/hub-kit.mjs +112 -0
  3. package/dist/adapters/bank-reconciliation.d.ts +100 -0
  4. package/dist/adapters/bank-reconciliation.js +1 -0
  5. package/dist/adapters/bank-sync-log.d.ts +46 -0
  6. package/dist/adapters/bank-sync-log.js +1 -0
  7. package/dist/adapters/category-rules.d.ts +94 -0
  8. package/dist/adapters/category-rules.js +1 -0
  9. package/dist/adapters/companies.d.ts +85 -0
  10. package/dist/adapters/companies.js +3 -0
  11. package/dist/adapters/customers.d.ts +71 -0
  12. package/dist/adapters/customers.js +1 -0
  13. package/dist/adapters/exclusion-rules.d.ts +34 -0
  14. package/dist/adapters/exclusion-rules.js +15 -0
  15. package/dist/adapters/file-naming.d.ts +36 -0
  16. package/dist/adapters/file-naming.js +1 -0
  17. package/dist/adapters/index.d.ts +24 -0
  18. package/dist/adapters/index.js +1 -0
  19. package/dist/adapters/invoice-detail.d.ts +126 -0
  20. package/dist/adapters/invoice-detail.js +1 -0
  21. package/dist/adapters/invoice-list.d.ts +63 -0
  22. package/dist/adapters/invoice-list.js +1 -0
  23. package/dist/adapters/invoice-upload.d.ts +26 -0
  24. package/dist/adapters/invoice-upload.js +1 -0
  25. package/dist/adapters/manual-bookings.d.ts +56 -0
  26. package/dist/adapters/manual-bookings.js +1 -0
  27. package/dist/adapters/notifications.d.ts +31 -0
  28. package/dist/adapters/notifications.js +1 -0
  29. package/dist/adapters/open-items.d.ts +42 -0
  30. package/dist/adapters/open-items.js +1 -0
  31. package/dist/adapters/opos-whitelist.d.ts +38 -0
  32. package/dist/adapters/opos-whitelist.js +1 -0
  33. package/dist/adapters/outgoing-invoices.d.ts +32 -0
  34. package/dist/adapters/outgoing-invoices.js +1 -0
  35. package/dist/adapters/overview.d.ts +68 -0
  36. package/dist/adapters/overview.js +1 -0
  37. package/dist/adapters/processing-log.d.ts +48 -0
  38. package/dist/adapters/processing-log.js +1 -0
  39. package/dist/adapters/properties.d.ts +87 -0
  40. package/dist/adapters/properties.js +1 -0
  41. package/dist/adapters/supplier-detail.d.ts +64 -0
  42. package/dist/adapters/supplier-detail.js +1 -0
  43. package/dist/adapters/supplier-list.d.ts +21 -0
  44. package/dist/adapters/supplier-list.js +1 -0
  45. package/dist/adapters/team.d.ts +79 -0
  46. package/dist/adapters/team.js +1 -0
  47. package/dist/adapters/trash.d.ts +26 -0
  48. package/dist/adapters/trash.js +1 -0
  49. package/dist/adapters/vat-rules.d.ts +83 -0
  50. package/dist/adapters/vat-rules.js +1 -0
  51. package/dist/components/access/index.d.ts +3 -0
  52. package/dist/components/access/index.js +3 -0
  53. package/dist/components/access/permission-checklist.d.ts +13 -0
  54. package/dist/components/access/permission-checklist.js +19 -0
  55. package/dist/components/access/permission-matrix.d.ts +12 -0
  56. package/dist/components/access/permission-matrix.js +18 -0
  57. package/dist/components/access/types.d.ts +15 -0
  58. package/dist/components/access/types.js +1 -0
  59. package/dist/components/dashboard/date-range-calendar.d.ts +19 -0
  60. package/dist/components/dashboard/date-range-calendar.js +97 -0
  61. package/dist/components/dashboard/index.d.ts +23 -0
  62. package/dist/components/dashboard/index.js +14 -0
  63. package/dist/components/dashboard/kpi-card.d.ts +13 -0
  64. package/dist/components/dashboard/kpi-card.js +7 -0
  65. package/dist/components/dashboard/money-cards-row.d.ts +29 -0
  66. package/dist/components/dashboard/money-cards-row.js +28 -0
  67. package/dist/components/dashboard/money-trend-chart.d.ts +13 -0
  68. package/dist/components/dashboard/money-trend-chart.js +16 -0
  69. package/dist/components/dashboard/panel.d.ts +9 -0
  70. package/dist/components/dashboard/panel.js +5 -0
  71. package/dist/components/dashboard/period-picker.d.ts +25 -0
  72. package/dist/components/dashboard/period-picker.js +82 -0
  73. package/dist/components/dashboard/periods.d.ts +13 -0
  74. package/dist/components/dashboard/periods.js +63 -0
  75. package/dist/components/dashboard/pipeline-stages-panel.d.ts +14 -0
  76. package/dist/components/dashboard/pipeline-stages-panel.js +12 -0
  77. package/dist/components/dashboard/processing-summary-panel.d.ts +34 -0
  78. package/dist/components/dashboard/processing-summary-panel.js +11 -0
  79. package/dist/components/dashboard/ranked-bars.d.ts +15 -0
  80. package/dist/components/dashboard/ranked-bars.js +16 -0
  81. package/dist/components/dashboard/ranked-list-panel.d.ts +14 -0
  82. package/dist/components/dashboard/ranked-list-panel.js +9 -0
  83. package/dist/components/dashboard/stage-tiles.d.ts +15 -0
  84. package/dist/components/dashboard/stage-tiles.js +6 -0
  85. package/dist/components/dashboard/stat-rows-panel.d.ts +25 -0
  86. package/dist/components/dashboard/stat-rows-panel.js +7 -0
  87. package/dist/components/dashboard/stat-tile.d.ts +20 -0
  88. package/dist/components/dashboard/stat-tile.js +9 -0
  89. package/dist/components/feedback/index.d.ts +4 -0
  90. package/dist/components/feedback/index.js +2 -0
  91. package/dist/components/feedback/query-states.d.ts +27 -0
  92. package/dist/components/feedback/query-states.js +38 -0
  93. package/dist/components/feedback/table-pagination.d.ts +20 -0
  94. package/dist/components/feedback/table-pagination.js +15 -0
  95. package/dist/components/invoice-queue/index.d.ts +5 -0
  96. package/dist/components/invoice-queue/index.js +3 -0
  97. package/dist/components/invoice-queue/next-action-cell.d.ts +5 -0
  98. package/dist/components/invoice-queue/next-action-cell.js +9 -0
  99. package/dist/components/invoice-queue/queue-kpi-card.d.ts +19 -0
  100. package/dist/components/invoice-queue/queue-kpi-card.js +31 -0
  101. package/dist/components/invoice-queue/queue-kpi-row.d.ts +22 -0
  102. package/dist/components/invoice-queue/queue-kpi-row.js +12 -0
  103. package/dist/components/notifications/alerts.d.ts +25 -0
  104. package/dist/components/notifications/alerts.js +66 -0
  105. package/dist/components/notifications/bell.d.ts +14 -0
  106. package/dist/components/notifications/bell.js +17 -0
  107. package/dist/components/notifications/highlight.d.ts +4 -0
  108. package/dist/components/notifications/highlight.js +7 -0
  109. package/dist/components/notifications/index.d.ts +7 -0
  110. package/dist/components/notifications/index.js +6 -0
  111. package/dist/components/notifications/reminder-dialog.d.ts +24 -0
  112. package/dist/components/notifications/reminder-dialog.js +54 -0
  113. package/dist/components/notifications/types.d.ts +27 -0
  114. package/dist/components/notifications/types.js +1 -0
  115. package/dist/components/notifications/use-notification-acks.d.ts +7 -0
  116. package/dist/components/notifications/use-notification-acks.js +37 -0
  117. package/dist/components/shell/breadcrumbs.d.ts +7 -0
  118. package/dist/components/shell/breadcrumbs.js +38 -0
  119. package/dist/components/shell/index.d.ts +3 -0
  120. package/dist/components/shell/index.js +3 -0
  121. package/dist/components/shell/shell.d.ts +30 -0
  122. package/dist/components/shell/shell.js +110 -0
  123. package/dist/components/shell/types.d.ts +23 -0
  124. package/dist/components/shell/types.js +3 -0
  125. package/dist/components/tour/find-target.d.ts +1 -0
  126. package/dist/components/tour/find-target.js +3 -0
  127. package/dist/components/tour/index.d.ts +14 -0
  128. package/dist/components/tour/index.js +8 -0
  129. package/dist/components/tour/labels.d.ts +10 -0
  130. package/dist/components/tour/labels.js +9 -0
  131. package/dist/components/tour/seen-store.d.ts +3 -0
  132. package/dist/components/tour/seen-store.js +34 -0
  133. package/dist/components/tour/tour-blocks.d.ts +4 -0
  134. package/dist/components/tour/tour-blocks.js +27 -0
  135. package/dist/components/tour/tour-button.d.ts +4 -0
  136. package/dist/components/tour/tour-button.js +12 -0
  137. package/dist/components/tour/tour-card.d.ts +11 -0
  138. package/dist/components/tour/tour-card.js +7 -0
  139. package/dist/components/tour/tour-context.d.ts +16 -0
  140. package/dist/components/tour/tour-context.js +2 -0
  141. package/dist/components/tour/tour-overlay.d.ts +1 -0
  142. package/dist/components/tour/tour-overlay.js +165 -0
  143. package/dist/components/tour/tour-provider.d.ts +9 -0
  144. package/dist/components/tour/tour-provider.js +80 -0
  145. package/dist/components/tour/types.d.ts +44 -0
  146. package/dist/components/tour/types.js +1 -0
  147. package/dist/components/tour/use-tour.d.ts +3 -0
  148. package/dist/components/tour/use-tour.js +9 -0
  149. package/dist/hooks/use-mobile.d.ts +1 -0
  150. package/dist/hooks/use-mobile.js +15 -0
  151. package/dist/i18n/index.d.ts +15 -0
  152. package/dist/i18n/index.js +15 -0
  153. package/dist/lib/bank-import/classify.d.ts +8 -0
  154. package/dist/lib/bank-import/classify.js +89 -0
  155. package/dist/lib/bank-import/column-guess.d.ts +2 -0
  156. package/dist/lib/bank-import/column-guess.js +40 -0
  157. package/dist/lib/bank-import/csv.d.ts +3 -0
  158. package/dist/lib/bank-import/csv.js +20 -0
  159. package/dist/lib/bank-import/duplicates.d.ts +2 -0
  160. package/dist/lib/bank-import/duplicates.js +21 -0
  161. package/dist/lib/bank-import/index.d.ts +12 -0
  162. package/dist/lib/bank-import/index.js +9 -0
  163. package/dist/lib/bank-import/mapping-storage.d.ts +3 -0
  164. package/dist/lib/bank-import/mapping-storage.js +29 -0
  165. package/dist/lib/bank-import/normalize.d.ts +4 -0
  166. package/dist/lib/bank-import/normalize.js +82 -0
  167. package/dist/lib/bank-import/parse-file.d.ts +7 -0
  168. package/dist/lib/bank-import/parse-file.js +23 -0
  169. package/dist/lib/bank-import/types.d.ts +31 -0
  170. package/dist/lib/bank-import/types.js +1 -0
  171. package/dist/lib/bank-import/xlsx.d.ts +2 -0
  172. package/dist/lib/bank-import/xlsx.js +25 -0
  173. package/dist/lib/class-names.d.ts +2 -0
  174. package/dist/lib/class-names.js +5 -0
  175. package/dist/lib/download.d.ts +2 -0
  176. package/dist/lib/download.js +14 -0
  177. package/dist/lib/formatters.d.ts +6 -0
  178. package/dist/lib/formatters.js +24 -0
  179. package/dist/lib/index.d.ts +9 -0
  180. package/dist/lib/index.js +6 -0
  181. package/dist/lib/opos-whitelist/index.d.ts +2 -0
  182. package/dist/lib/opos-whitelist/index.js +1 -0
  183. package/dist/lib/opos-whitelist/opos.d.ts +14 -0
  184. package/dist/lib/opos-whitelist/opos.js +49 -0
  185. package/dist/lib/query-result.d.ts +12 -0
  186. package/dist/lib/query-result.js +1 -0
  187. package/dist/lib/tour-placeholders/index.d.ts +2 -0
  188. package/dist/lib/tour-placeholders/index.js +1 -0
  189. package/dist/lib/tour-placeholders/overview.d.ts +12 -0
  190. package/dist/lib/tour-placeholders/overview.js +139 -0
  191. package/dist/pages/bank-accounts/BankAccountsPage.d.ts +7 -0
  192. package/dist/pages/bank-accounts/BankAccountsPage.js +21 -0
  193. package/dist/pages/bank-accounts/index.d.ts +4 -0
  194. package/dist/pages/bank-accounts/index.js +2 -0
  195. package/dist/pages/bank-accounts/labels.d.ts +15 -0
  196. package/dist/pages/bank-accounts/labels.js +14 -0
  197. package/dist/pages/bank-import/BankImportWizard.d.ts +9 -0
  198. package/dist/pages/bank-import/BankImportWizard.js +158 -0
  199. package/dist/pages/bank-import/index.d.ts +4 -0
  200. package/dist/pages/bank-import/index.js +2 -0
  201. package/dist/pages/bank-import/labels.d.ts +44 -0
  202. package/dist/pages/bank-import/labels.js +43 -0
  203. package/dist/pages/bank-sync-log/BankSyncLogPage.d.ts +7 -0
  204. package/dist/pages/bank-sync-log/BankSyncLogPage.js +77 -0
  205. package/dist/pages/bank-sync-log/index.d.ts +4 -0
  206. package/dist/pages/bank-sync-log/index.js +2 -0
  207. package/dist/pages/bank-sync-log/labels.d.ts +21 -0
  208. package/dist/pages/bank-sync-log/labels.js +20 -0
  209. package/dist/pages/bank-transactions/BankMatchPanel.d.ts +8 -0
  210. package/dist/pages/bank-transactions/BankMatchPanel.js +75 -0
  211. package/dist/pages/bank-transactions/BankTransactionsPage.d.ts +7 -0
  212. package/dist/pages/bank-transactions/BankTransactionsPage.js +59 -0
  213. package/dist/pages/bank-transactions/badges.d.ts +8 -0
  214. package/dist/pages/bank-transactions/badges.js +24 -0
  215. package/dist/pages/bank-transactions/index.d.ts +6 -0
  216. package/dist/pages/bank-transactions/index.js +4 -0
  217. package/dist/pages/bank-transactions/labels.d.ts +41 -0
  218. package/dist/pages/bank-transactions/labels.js +40 -0
  219. package/dist/pages/bank-transactions/sort-control.d.ts +17 -0
  220. package/dist/pages/bank-transactions/sort-control.js +8 -0
  221. package/dist/pages/bank-transactions/use-table-view.d.ts +23 -0
  222. package/dist/pages/bank-transactions/use-table-view.js +54 -0
  223. package/dist/pages/category-rules/CategoryRulesPage.d.ts +7 -0
  224. package/dist/pages/category-rules/CategoryRulesPage.js +160 -0
  225. package/dist/pages/category-rules/index.d.ts +4 -0
  226. package/dist/pages/category-rules/index.js +2 -0
  227. package/dist/pages/category-rules/labels.d.ts +66 -0
  228. package/dist/pages/category-rules/labels.js +72 -0
  229. package/dist/pages/companies/company-detail-page.d.ts +10 -0
  230. package/dist/pages/companies/company-detail-page.js +184 -0
  231. package/dist/pages/companies/company-form.d.ts +20 -0
  232. package/dist/pages/companies/company-form.js +23 -0
  233. package/dist/pages/companies/company-list-page.d.ts +9 -0
  234. package/dist/pages/companies/company-list-page.js +109 -0
  235. package/dist/pages/companies/known-spellings-card.d.ts +8 -0
  236. package/dist/pages/companies/known-spellings-card.js +65 -0
  237. package/dist/pages/companies/labels.d.ts +105 -0
  238. package/dist/pages/companies/labels.js +104 -0
  239. package/dist/pages/companies/sort-control.d.ts +17 -0
  240. package/dist/pages/companies/sort-control.js +8 -0
  241. package/dist/pages/companies/use-infinite-rows.d.ts +6 -0
  242. package/dist/pages/companies/use-infinite-rows.js +24 -0
  243. package/dist/pages/companies/use-table-view.d.ts +23 -0
  244. package/dist/pages/companies/use-table-view.js +56 -0
  245. package/dist/pages/customers/company-chip.d.ts +6 -0
  246. package/dist/pages/customers/company-chip.js +9 -0
  247. package/dist/pages/customers/copy-button.d.ts +6 -0
  248. package/dist/pages/customers/copy-button.js +31 -0
  249. package/dist/pages/customers/customer-detail-page.d.ts +10 -0
  250. package/dist/pages/customers/customer-detail-page.js +83 -0
  251. package/dist/pages/customers/customer-list-page.d.ts +9 -0
  252. package/dist/pages/customers/customer-list-page.js +65 -0
  253. package/dist/pages/customers/edit-customer-dialog.d.ts +9 -0
  254. package/dist/pages/customers/edit-customer-dialog.js +72 -0
  255. package/dist/pages/customers/form-hints.d.ts +6 -0
  256. package/dist/pages/customers/form-hints.js +9 -0
  257. package/dist/pages/customers/invoice-status-badge.d.ts +10 -0
  258. package/dist/pages/customers/invoice-status-badge.js +22 -0
  259. package/dist/pages/customers/labels.d.ts +116 -0
  260. package/dist/pages/customers/labels.js +117 -0
  261. package/dist/pages/customers/new-customer-dialog.d.ts +6 -0
  262. package/dist/pages/customers/new-customer-dialog.js +93 -0
  263. package/dist/pages/customers/sort-control.d.ts +14 -0
  264. package/dist/pages/customers/sort-control.js +9 -0
  265. package/dist/pages/customers/use-table-view.d.ts +23 -0
  266. package/dist/pages/customers/use-table-view.js +56 -0
  267. package/dist/pages/exclusion-rules/exclusion-rules-page.d.ts +7 -0
  268. package/dist/pages/exclusion-rules/exclusion-rules-page.js +114 -0
  269. package/dist/pages/exclusion-rules/labels.d.ts +53 -0
  270. package/dist/pages/exclusion-rules/labels.js +61 -0
  271. package/dist/pages/file-naming/build-filename.d.ts +3 -0
  272. package/dist/pages/file-naming/build-filename.js +82 -0
  273. package/dist/pages/file-naming/file-naming-page.d.ts +10 -0
  274. package/dist/pages/file-naming/file-naming-page.js +120 -0
  275. package/dist/pages/file-naming/labels.d.ts +44 -0
  276. package/dist/pages/file-naming/labels.js +44 -0
  277. package/dist/pages/index.d.ts +63 -0
  278. package/dist/pages/index.js +48 -0
  279. package/dist/pages/invoice-detail/InvoiceDetailPage.d.ts +11 -0
  280. package/dist/pages/invoice-detail/InvoiceDetailPage.js +292 -0
  281. package/dist/pages/invoice-detail/OutgoingInvoiceFlag.d.ts +26 -0
  282. package/dist/pages/invoice-detail/OutgoingInvoiceFlag.js +16 -0
  283. package/dist/pages/invoice-detail/ReviewBadge.d.ts +15 -0
  284. package/dist/pages/invoice-detail/ReviewBadge.js +23 -0
  285. package/dist/pages/invoice-detail/ReviewCard.d.ts +17 -0
  286. package/dist/pages/invoice-detail/ReviewCard.js +12 -0
  287. package/dist/pages/invoice-detail/SideBySide.d.ts +5 -0
  288. package/dist/pages/invoice-detail/SideBySide.js +5 -0
  289. package/dist/pages/invoice-detail/WorkflowHistoryList.d.ts +23 -0
  290. package/dist/pages/invoice-detail/WorkflowHistoryList.js +32 -0
  291. package/dist/pages/invoice-detail/WorkflowLadder.d.ts +20 -0
  292. package/dist/pages/invoice-detail/WorkflowLadder.js +16 -0
  293. package/dist/pages/invoice-detail/history.d.ts +23 -0
  294. package/dist/pages/invoice-detail/history.js +76 -0
  295. package/dist/pages/invoice-detail/index.d.ts +21 -0
  296. package/dist/pages/invoice-detail/index.js +11 -0
  297. package/dist/pages/invoice-detail/labels.d.ts +79 -0
  298. package/dist/pages/invoice-detail/labels.js +139 -0
  299. package/dist/pages/invoice-detail/pipeline-types.d.ts +58 -0
  300. package/dist/pages/invoice-detail/pipeline-types.js +1 -0
  301. package/dist/pages/invoice-detail/review-recheck.d.ts +8 -0
  302. package/dist/pages/invoice-detail/review-recheck.js +103 -0
  303. package/dist/pages/invoice-detail/review.d.ts +91 -0
  304. package/dist/pages/invoice-detail/review.js +310 -0
  305. package/dist/pages/invoice-list/badges.d.ts +23 -0
  306. package/dist/pages/invoice-list/badges.js +26 -0
  307. package/dist/pages/invoice-list/index.d.ts +5 -0
  308. package/dist/pages/invoice-list/index.js +3 -0
  309. package/dist/pages/invoice-list/invoice-list-page.d.ts +13 -0
  310. package/dist/pages/invoice-list/invoice-list-page.js +114 -0
  311. package/dist/pages/invoice-list/labels.d.ts +36 -0
  312. package/dist/pages/invoice-list/labels.js +29 -0
  313. package/dist/pages/invoice-list/sort-control.d.ts +17 -0
  314. package/dist/pages/invoice-list/sort-control.js +8 -0
  315. package/dist/pages/invoice-list/use-table-view.d.ts +23 -0
  316. package/dist/pages/invoice-list/use-table-view.js +54 -0
  317. package/dist/pages/invoice-upload/InvoiceUploadPage.d.ts +7 -0
  318. package/dist/pages/invoice-upload/InvoiceUploadPage.js +115 -0
  319. package/dist/pages/invoice-upload/index.d.ts +4 -0
  320. package/dist/pages/invoice-upload/index.js +2 -0
  321. package/dist/pages/invoice-upload/labels.d.ts +29 -0
  322. package/dist/pages/invoice-upload/labels.js +28 -0
  323. package/dist/pages/manual-bookings/ManualBookingsPage.d.ts +7 -0
  324. package/dist/pages/manual-bookings/ManualBookingsPage.js +161 -0
  325. package/dist/pages/manual-bookings/index.d.ts +4 -0
  326. package/dist/pages/manual-bookings/index.js +2 -0
  327. package/dist/pages/manual-bookings/labels.d.ts +53 -0
  328. package/dist/pages/manual-bookings/labels.js +52 -0
  329. package/dist/pages/notifications/labels.d.ts +22 -0
  330. package/dist/pages/notifications/labels.js +21 -0
  331. package/dist/pages/notifications/notifications-page.d.ts +14 -0
  332. package/dist/pages/notifications/notifications-page.js +81 -0
  333. package/dist/pages/open-items/OpenItemsPage.d.ts +11 -0
  334. package/dist/pages/open-items/OpenItemsPage.js +110 -0
  335. package/dist/pages/open-items/index.d.ts +6 -0
  336. package/dist/pages/open-items/index.js +3 -0
  337. package/dist/pages/open-items/labels.d.ts +37 -0
  338. package/dist/pages/open-items/labels.js +36 -0
  339. package/dist/pages/open-items/urgency.d.ts +8 -0
  340. package/dist/pages/open-items/urgency.js +27 -0
  341. package/dist/pages/opos-whitelist/OposWhitelistPage.d.ts +7 -0
  342. package/dist/pages/opos-whitelist/OposWhitelistPage.js +165 -0
  343. package/dist/pages/opos-whitelist/index.d.ts +4 -0
  344. package/dist/pages/opos-whitelist/index.js +2 -0
  345. package/dist/pages/opos-whitelist/labels.d.ts +56 -0
  346. package/dist/pages/opos-whitelist/labels.js +70 -0
  347. package/dist/pages/outgoing-invoices/OutgoingInvoicesPage.d.ts +7 -0
  348. package/dist/pages/outgoing-invoices/OutgoingInvoicesPage.js +169 -0
  349. package/dist/pages/outgoing-invoices/index.d.ts +4 -0
  350. package/dist/pages/outgoing-invoices/index.js +2 -0
  351. package/dist/pages/outgoing-invoices/labels.d.ts +43 -0
  352. package/dist/pages/outgoing-invoices/labels.js +42 -0
  353. package/dist/pages/outgoing-invoices/sort-control.d.ts +17 -0
  354. package/dist/pages/outgoing-invoices/sort-control.js +8 -0
  355. package/dist/pages/outgoing-invoices/use-table-view.d.ts +23 -0
  356. package/dist/pages/outgoing-invoices/use-table-view.js +54 -0
  357. package/dist/pages/overview/labels.d.ts +35 -0
  358. package/dist/pages/overview/labels.js +34 -0
  359. package/dist/pages/overview/overview-page.d.ts +22 -0
  360. package/dist/pages/overview/overview-page.js +127 -0
  361. package/dist/pages/processing-log/labels.d.ts +54 -0
  362. package/dist/pages/processing-log/labels.js +53 -0
  363. package/dist/pages/processing-log/mail-parsing.d.ts +21 -0
  364. package/dist/pages/processing-log/mail-parsing.js +52 -0
  365. package/dist/pages/processing-log/processing-log-page.d.ts +9 -0
  366. package/dist/pages/processing-log/processing-log-page.js +206 -0
  367. package/dist/pages/properties/badges.d.ts +20 -0
  368. package/dist/pages/properties/badges.js +45 -0
  369. package/dist/pages/properties/company-assignment-field.d.ts +11 -0
  370. package/dist/pages/properties/company-assignment-field.js +13 -0
  371. package/dist/pages/properties/form-field.d.ts +6 -0
  372. package/dist/pages/properties/form-field.js +9 -0
  373. package/dist/pages/properties/labels.d.ts +124 -0
  374. package/dist/pages/properties/labels.js +128 -0
  375. package/dist/pages/properties/name-variants-card.d.ts +7 -0
  376. package/dist/pages/properties/name-variants-card.js +60 -0
  377. package/dist/pages/properties/property-detail-page.d.ts +10 -0
  378. package/dist/pages/properties/property-detail-page.js +150 -0
  379. package/dist/pages/properties/property-list-page.d.ts +13 -0
  380. package/dist/pages/properties/property-list-page.js +201 -0
  381. package/dist/pages/properties/sort-control.d.ts +14 -0
  382. package/dist/pages/properties/sort-control.js +9 -0
  383. package/dist/pages/properties/use-infinite-rows.d.ts +6 -0
  384. package/dist/pages/properties/use-infinite-rows.js +26 -0
  385. package/dist/pages/properties/use-table-view.d.ts +23 -0
  386. package/dist/pages/properties/use-table-view.js +56 -0
  387. package/dist/pages/supplier-detail/SupplierDetailPage.d.ts +10 -0
  388. package/dist/pages/supplier-detail/SupplierDetailPage.js +157 -0
  389. package/dist/pages/supplier-detail/index.d.ts +4 -0
  390. package/dist/pages/supplier-detail/index.js +2 -0
  391. package/dist/pages/supplier-detail/labels.d.ts +46 -0
  392. package/dist/pages/supplier-detail/labels.js +45 -0
  393. package/dist/pages/supplier-list/SupplierListPage.d.ts +9 -0
  394. package/dist/pages/supplier-list/SupplierListPage.js +102 -0
  395. package/dist/pages/supplier-list/index.d.ts +4 -0
  396. package/dist/pages/supplier-list/index.js +2 -0
  397. package/dist/pages/supplier-list/labels.d.ts +33 -0
  398. package/dist/pages/supplier-list/labels.js +32 -0
  399. package/dist/pages/supplier-list/sort-control.d.ts +17 -0
  400. package/dist/pages/supplier-list/sort-control.js +8 -0
  401. package/dist/pages/supplier-list/use-table-view.d.ts +23 -0
  402. package/dist/pages/supplier-list/use-table-view.js +54 -0
  403. package/dist/pages/team/account-dialogs.d.ts +12 -0
  404. package/dist/pages/team/account-dialogs.js +49 -0
  405. package/dist/pages/team/employee-editor.d.ts +19 -0
  406. package/dist/pages/team/employee-editor.js +124 -0
  407. package/dist/pages/team/labels.d.ts +99 -0
  408. package/dist/pages/team/labels.js +98 -0
  409. package/dist/pages/team/new-employee.d.ts +8 -0
  410. package/dist/pages/team/new-employee.js +103 -0
  411. package/dist/pages/team/roles-tab.d.ts +6 -0
  412. package/dist/pages/team/roles-tab.js +46 -0
  413. package/dist/pages/team/team-page.d.ts +7 -0
  414. package/dist/pages/team/team-page.js +81 -0
  415. package/dist/pages/team/temp-password-dialog.d.ts +11 -0
  416. package/dist/pages/team/temp-password-dialog.js +23 -0
  417. package/dist/pages/trash/labels.d.ts +68 -0
  418. package/dist/pages/trash/labels.js +69 -0
  419. package/dist/pages/trash/trash-page.d.ts +9 -0
  420. package/dist/pages/trash/trash-page.js +259 -0
  421. package/dist/pages/vat-rules/labels.d.ts +110 -0
  422. package/dist/pages/vat-rules/labels.js +109 -0
  423. package/dist/pages/vat-rules/new-rule-dialog.d.ts +7 -0
  424. package/dist/pages/vat-rules/new-rule-dialog.js +134 -0
  425. package/dist/pages/vat-rules/rule-row.d.ts +20 -0
  426. package/dist/pages/vat-rules/rule-row.js +120 -0
  427. package/dist/pages/vat-rules/vat-rules-page.d.ts +9 -0
  428. package/dist/pages/vat-rules/vat-rules-page.js +61 -0
  429. package/dist/ui/alert-dialog.d.ts +20 -0
  430. package/dist/ui/alert-dialog.js +41 -0
  431. package/dist/ui/badge.d.ts +9 -0
  432. package/dist/ui/badge.js +20 -0
  433. package/dist/ui/breadcrumb.d.ts +19 -0
  434. package/dist/ui/breadcrumb.js +23 -0
  435. package/dist/ui/button.d.ts +11 -0
  436. package/dist/ui/button.js +33 -0
  437. package/dist/ui/calendar.d.ts +8 -0
  438. package/dist/ui/calendar.js +75 -0
  439. package/dist/ui/card.d.ts +8 -0
  440. package/dist/ui/card.js +16 -0
  441. package/dist/ui/chart.d.ts +62 -0
  442. package/dist/ui/chart.js +118 -0
  443. package/dist/ui/checkbox.d.ts +4 -0
  444. package/dist/ui/checkbox.js +11 -0
  445. package/dist/ui/collapsible.d.ts +5 -0
  446. package/dist/ui/collapsible.js +5 -0
  447. package/dist/ui/combobox.d.ts +24 -0
  448. package/dist/ui/combobox.js +55 -0
  449. package/dist/ui/command.d.ts +80 -0
  450. package/dist/ui/command.js +29 -0
  451. package/dist/ui/dialog.d.ts +19 -0
  452. package/dist/ui/dialog.js +58 -0
  453. package/dist/ui/dropdown-menu.d.ts +27 -0
  454. package/dist/ui/dropdown-menu.js +33 -0
  455. package/dist/ui/field-context.d.ts +4 -0
  456. package/dist/ui/field-context.js +6 -0
  457. package/dist/ui/field.d.ts +3 -0
  458. package/dist/ui/field.js +8 -0
  459. package/dist/ui/icon-action.d.ts +3 -0
  460. package/dist/ui/icon-action.js +8 -0
  461. package/dist/ui/index.d.ts +32 -0
  462. package/dist/ui/index.js +32 -0
  463. package/dist/ui/input.d.ts +3 -0
  464. package/dist/ui/input.js +11 -0
  465. package/dist/ui/label.d.ts +5 -0
  466. package/dist/ui/label.js +15 -0
  467. package/dist/ui/multi-combobox.d.ts +18 -0
  468. package/dist/ui/multi-combobox.js +40 -0
  469. package/dist/ui/popover.d.ts +9 -0
  470. package/dist/ui/popover.js +12 -0
  471. package/dist/ui/scroll-area.d.ts +5 -0
  472. package/dist/ui/scroll-area.js +9 -0
  473. package/dist/ui/scroll-shadow.d.ts +8 -0
  474. package/dist/ui/scroll-shadow.js +57 -0
  475. package/dist/ui/select.d.ts +13 -0
  476. package/dist/ui/select.js +31 -0
  477. package/dist/ui/separator.d.ts +4 -0
  478. package/dist/ui/separator.js +7 -0
  479. package/dist/ui/sheet.d.ts +25 -0
  480. package/dist/ui/sheet.js +40 -0
  481. package/dist/ui/sidebar.d.ts +65 -0
  482. package/dist/ui/sidebar.js +207 -0
  483. package/dist/ui/skeleton.d.ts +2 -0
  484. package/dist/ui/skeleton.js +6 -0
  485. package/dist/ui/sonner.d.ts +5 -0
  486. package/dist/ui/sonner.js +13 -0
  487. package/dist/ui/switch.d.ts +4 -0
  488. package/dist/ui/switch.js +7 -0
  489. package/dist/ui/table.d.ts +12 -0
  490. package/dist/ui/table.js +24 -0
  491. package/dist/ui/tabs.d.ts +7 -0
  492. package/dist/ui/tabs.js +12 -0
  493. package/dist/ui/textarea.d.ts +3 -0
  494. package/dist/ui/textarea.js +11 -0
  495. package/dist/ui/tooltip.d.ts +7 -0
  496. package/dist/ui/tooltip.js +11 -0
  497. package/package.json +80 -0
  498. package/themes/TOKENS.md +57 -0
  499. package/themes/default.css +60 -0
@@ -0,0 +1,7 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { Link } from "@tanstack/react-router";
3
+ import { Skeleton } from "../../ui/skeleton.js";
4
+ import { cn } from "../../lib/class-names.js";
5
+ export function KpiCard({ icon: Icon, iconTint, label, to, loading, value, delta, headerRight, className, }) {
6
+ return (_jsxs("div", { className: cn("relative flex flex-col rounded-xl bg-card p-3 shadow-xs transition-shadow hover:shadow-md", className), children: [_jsx(Link, { to: to, "aria-label": label, className: "absolute inset-0 rounded-xl focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring" }), _jsxs("div", { className: "flex items-center justify-between gap-2", children: [_jsxs("span", { className: "flex min-w-0 items-center gap-2", children: [_jsx("span", { className: cn("inline-flex size-6 shrink-0 items-center justify-center rounded-md text-white", iconTint), children: _jsx(Icon, { className: "size-3.5" }) }), _jsx("span", { className: "truncate text-[15px] font-medium text-muted-foreground", children: label })] }), headerRight && _jsx("span", { className: "relative z-10 shrink-0", children: headerRight })] }), _jsx("div", { className: "flex flex-1 flex-col justify-center gap-1 py-2", children: loading ? (_jsx(Skeleton, { className: "h-8 w-28" })) : (_jsxs(_Fragment, { children: [_jsx("span", { className: "text-2xl font-semibold tracking-tight tabular-nums text-foreground", children: value }), delta] })) })] }));
7
+ }
@@ -0,0 +1,29 @@
1
+ import type { LucideIcon } from "lucide-react";
2
+ import type { OverviewPeriod } from "./periods";
3
+ import { type PeriodLabels, type PeriodValue } from "./period-picker";
4
+ export interface MoneyFigure {
5
+ value: number;
6
+ count?: number;
7
+ previousValue?: number;
8
+ loading: boolean;
9
+ }
10
+ export interface MoneyCardSpec {
11
+ key: string;
12
+ icon: LucideIcon;
13
+ to: string;
14
+ iconTint: string;
15
+ higherIsBetter: boolean;
16
+ label: string;
17
+ countLabel?: (count: number) => string;
18
+ deltaLabel: (period: OverviewPeriod, percent: string) => string;
19
+ }
20
+ export declare function MoneyCardsRow({ cards, figures, periods, onPeriodChange, periodLabels, formatMoney, formatDay, className, }: {
21
+ cards: MoneyCardSpec[];
22
+ figures: Record<string, MoneyFigure>;
23
+ periods: Record<string, PeriodValue>;
24
+ onPeriodChange: (cardKey: string, value: PeriodValue) => void;
25
+ periodLabels?: PeriodLabels;
26
+ formatMoney: (value: number) => string;
27
+ formatDay: (iso: string) => string;
28
+ className?: string;
29
+ }): import("react").JSX.Element;
@@ -0,0 +1,28 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useMemo } from "react";
3
+ import { ArrowDownRight, ArrowUpRight } from "lucide-react";
4
+ import { KpiCard } from "./kpi-card.js";
5
+ import { PeriodPicker } from "./period-picker.js";
6
+ import { cn } from "../../lib/class-names.js";
7
+ export function MoneyCardsRow({ cards, figures, periods, onPeriodChange, periodLabels, formatMoney, formatDay, className, }) {
8
+ return (_jsx("div", { className: cn("grid h-full gap-3 sm:grid-cols-2 xl:grid-cols-3", className), children: cards.map((card) => (_jsx(MoneyCard, { card: card, figure: figures[card.key], period: periods[card.key], onPeriodChange: (value) => onPeriodChange(card.key, value), periodLabels: periodLabels, formatMoney: formatMoney, formatDay: formatDay }, card.key))) }));
9
+ }
10
+ function MoneyCard({ card, figure, period, onPeriodChange, periodLabels, formatMoney, formatDay, }) {
11
+ const value = figure?.value ?? 0;
12
+ const loading = figure?.loading ?? true;
13
+ return (_jsx(KpiCard, { icon: card.icon, iconTint: card.iconTint, label: card.label, to: card.to, loading: loading, value: formatMoney(value), delta: _jsxs("span", { className: "flex flex-wrap items-center gap-x-2 gap-y-0.5", children: [figure?.count !== undefined && card.countLabel && (_jsx("span", { className: "text-[13px] font-medium tabular-nums text-muted-foreground", children: card.countLabel(figure.count) })), _jsx(MoneyDelta, { value: value, previousValue: figure?.previousValue, higherIsBetter: card.higherIsBetter, period: period.period, deltaLabel: card.deltaLabel })] }), headerRight: _jsx(PeriodPicker, { value: period, onChange: onPeriodChange, labels: periodLabels, formatDay: formatDay }) }));
14
+ }
15
+ function MoneyDelta({ value, previousValue, higherIsBetter, period, deltaLabel, }) {
16
+ const percent = useMemo(() => {
17
+ if (previousValue === undefined || previousValue === 0)
18
+ return null;
19
+ const raw = ((value - previousValue) / Math.abs(previousValue)) * 100;
20
+ return Number.isFinite(raw) ? raw : null;
21
+ }, [value, previousValue]);
22
+ if (percent === null)
23
+ return null;
24
+ const up = percent >= 0;
25
+ const good = up === higherIsBetter;
26
+ const Icon = up ? ArrowUpRight : ArrowDownRight;
27
+ return (_jsxs("span", { className: cn("flex items-center gap-1 text-[13px] font-medium", good ? "text-success" : "text-danger"), children: [_jsx(Icon, { className: "size-3.5 shrink-0", "aria-hidden": true }), deltaLabel(period, `${up ? "+" : ""}${percent.toFixed(1)}`)] }));
28
+ }
@@ -0,0 +1,13 @@
1
+ export interface MoneyTrendPoint {
2
+ label: string;
3
+ incoming: number;
4
+ outgoing: number;
5
+ }
6
+ export declare function MoneyTrendChart({ data, loading, incomingLabel, outgoingLabel, formatMoney, formatMoneyCompact, }: {
7
+ data: MoneyTrendPoint[];
8
+ loading: boolean;
9
+ incomingLabel: string;
10
+ outgoingLabel: string;
11
+ formatMoney: (value: number) => string;
12
+ formatMoneyCompact: (value: number) => string;
13
+ }): import("react").JSX.Element | null;
@@ -0,0 +1,16 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useMemo } from "react";
3
+ import { CartesianGrid, Line, LineChart, XAxis, YAxis } from "recharts";
4
+ import { Skeleton } from "../../ui/skeleton.js";
5
+ import { ChartContainer, ChartLegend, ChartLegendContent, ChartTooltip, ChartTooltipContent, } from "../../ui/chart.js";
6
+ export function MoneyTrendChart({ data, loading, incomingLabel, outgoingLabel, formatMoney, formatMoneyCompact, }) {
7
+ const config = useMemo(() => ({
8
+ incoming: { label: incomingLabel, color: "var(--color-chart-1)" },
9
+ outgoing: { label: outgoingLabel, color: "var(--color-chart-2)" },
10
+ }), [incomingLabel, outgoingLabel]);
11
+ if (loading)
12
+ return _jsx(Skeleton, { className: "h-[190px] w-full rounded-xl" });
13
+ if (data.length === 0)
14
+ return null;
15
+ return (_jsx(ChartContainer, { config: config, className: "h-[190px] w-full", children: _jsxs(LineChart, { data: data, margin: { left: 0, right: 8, top: 4, bottom: 0 }, children: [_jsx(CartesianGrid, { vertical: false, strokeDasharray: "3 3", className: "stroke-border" }), _jsx(XAxis, { dataKey: "label", tickLine: false, axisLine: false, tickMargin: 6, tick: { fontSize: 11, fill: "var(--color-muted-foreground)" } }), _jsx(YAxis, { tickLine: false, axisLine: false, width: 46, tick: { fontSize: 11, fill: "var(--color-muted-foreground)" }, tickFormatter: (value) => formatMoneyCompact(value) }), _jsx(ChartTooltip, { content: _jsx(ChartTooltipContent, { formatter: (value) => formatMoney(Number(value)) }) }), _jsx(ChartLegend, { content: _jsx(ChartLegendContent, {}) }), _jsx(Line, { dataKey: "incoming", name: incomingLabel, type: "monotone", stroke: "var(--color-incoming)", strokeWidth: 2, dot: false }), _jsx(Line, { dataKey: "outgoing", name: outgoingLabel, type: "monotone", stroke: "var(--color-outgoing)", strokeWidth: 2, dot: false })] }) }));
16
+ }
@@ -0,0 +1,9 @@
1
+ import type { ReactNode } from "react";
2
+ export declare function DashboardPanel({ title, titleExtra, headerRight, className, dataTour, children, }: {
3
+ title: string;
4
+ titleExtra?: ReactNode;
5
+ headerRight?: ReactNode;
6
+ className?: string;
7
+ dataTour?: string;
8
+ children: ReactNode;
9
+ }): import("react").JSX.Element;
@@ -0,0 +1,5 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { cn } from "../../lib/class-names.js";
3
+ export function DashboardPanel({ title, titleExtra, headerRight, className, dataTour, children, }) {
4
+ return (_jsxs("section", { "data-tour": dataTour, className: cn("flex min-w-0 flex-col rounded-2xl bg-brand-wash p-4", className), children: [_jsxs("div", { className: "flex items-start justify-between gap-2", children: [_jsxs("h2", { className: "flex min-w-0 flex-wrap items-baseline gap-x-2 text-[15px] font-semibold tracking-tight text-foreground", children: [_jsx("span", { className: "truncate", children: title }), titleExtra && (_jsx("span", { className: "text-[13px] font-medium tabular-nums text-muted-foreground", children: titleExtra }))] }), headerRight && _jsx("span", { className: "flex shrink-0 items-center gap-2", children: headerRight })] }), children] }));
5
+ }
@@ -0,0 +1,25 @@
1
+ import { type DateRangeCalendarLabels } from "./date-range-calendar";
2
+ import { type OverviewPeriod } from "./periods";
3
+ export interface PeriodValue {
4
+ period: OverviewPeriod;
5
+ from?: string;
6
+ to?: string;
7
+ }
8
+ export interface PeriodLabels {
9
+ period: Record<OverviewPeriod, string>;
10
+ back: string;
11
+ reset: string;
12
+ calendar: DateRangeCalendarLabels;
13
+ }
14
+ export declare const englishPeriodLabels: PeriodLabels;
15
+ export declare function readStoredPeriod(key: string): PeriodValue;
16
+ export declare function writeStoredPeriod(key: string, value: PeriodValue): void;
17
+ export declare function useStoredPeriod(key: string): [PeriodValue, (value: PeriodValue) => void];
18
+ export declare function PeriodPicker({ value, onChange, className, labels, formatDay, locale, }: {
19
+ value: PeriodValue;
20
+ onChange: (value: PeriodValue) => void;
21
+ className?: string;
22
+ labels?: PeriodLabels;
23
+ formatDay: (iso: string) => string;
24
+ locale?: string;
25
+ }): import("react").JSX.Element;
@@ -0,0 +1,82 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState } from "react";
3
+ import { Check, ChevronDown, ChevronLeft } from "lucide-react";
4
+ import { Button } from "../../ui/button.js";
5
+ import { DateRangeCalendar, englishDateRangeCalendarLabels, } from "./date-range-calendar.js";
6
+ import { Popover, PopoverContent, PopoverTrigger } from "../../ui/popover.js";
7
+ import { isOverviewPeriod, OVERVIEW_PERIOD_DEFAULT, OVERVIEW_PERIODS, } from "./periods.js";
8
+ import { cn } from "../../lib/class-names.js";
9
+ export const englishPeriodLabels = {
10
+ period: {
11
+ all: "All time",
12
+ custom: "Custom range",
13
+ last30Days: "Last 30 days",
14
+ currentMonth: "This month",
15
+ lastMonth: "Last month",
16
+ last6Months: "Last 6 months",
17
+ last12Months: "Last 12 months",
18
+ currentYear: "This year",
19
+ lastYear: "Last year",
20
+ },
21
+ back: "Back",
22
+ reset: "Reset",
23
+ calendar: englishDateRangeCalendarLabels,
24
+ };
25
+ const PRESETS = OVERVIEW_PERIODS.filter((period) => period !== "custom");
26
+ const STORAGE_PREFIX = "hub-kit.overview-period.";
27
+ export function readStoredPeriod(key) {
28
+ if (typeof window === "undefined")
29
+ return { period: OVERVIEW_PERIOD_DEFAULT };
30
+ try {
31
+ const raw = window.localStorage.getItem(STORAGE_PREFIX + key);
32
+ if (raw) {
33
+ const parsed = JSON.parse(raw);
34
+ if (isOverviewPeriod(parsed?.period)) {
35
+ return { period: parsed.period, from: parsed.from, to: parsed.to };
36
+ }
37
+ }
38
+ }
39
+ catch {
40
+ }
41
+ return { period: OVERVIEW_PERIOD_DEFAULT };
42
+ }
43
+ export function writeStoredPeriod(key, value) {
44
+ try {
45
+ window.localStorage.setItem(STORAGE_PREFIX + key, JSON.stringify(value));
46
+ }
47
+ catch {
48
+ }
49
+ }
50
+ export function useStoredPeriod(key) {
51
+ const [value, setValue] = useState(() => readStoredPeriod(key));
52
+ const set = (next) => {
53
+ setValue(next);
54
+ writeStoredPeriod(key, next);
55
+ };
56
+ return [value, set];
57
+ }
58
+ export function PeriodPicker({ value, onChange, className, labels = englishPeriodLabels, formatDay, locale = "en", }) {
59
+ const [open, setOpen] = useState(false);
60
+ const [customOpen, setCustomOpen] = useState(false);
61
+ const isCustom = value.period === "custom";
62
+ const label = isCustom && value.from && value.to
63
+ ? `${formatDay(value.from)} – ${formatDay(value.to)}`
64
+ : labels.period[value.period];
65
+ return (_jsxs(Popover, { open: open, onOpenChange: (nextOpen) => {
66
+ setOpen(nextOpen);
67
+ if (nextOpen) {
68
+ setCustomOpen(isCustom);
69
+ }
70
+ }, children: [_jsx(PopoverTrigger, { asChild: true, children: _jsxs(Button, { type: "button", variant: "ghost", className: cn("h-6 gap-1 px-1.5 text-[0.7rem] font-normal text-muted-foreground hover:text-foreground", className), children: [label, _jsx(ChevronDown, { className: "size-3 opacity-60" })] }) }), _jsx(PopoverContent, { align: "end", className: "w-auto p-1", children: customOpen ? (_jsx("div", { className: "p-2", children: _jsx(DateRangeCalendar, { open: open, from: value.from ?? "", to: value.to ?? "", locale: locale, labels: labels.calendar, footerExtra: _jsxs("button", { type: "button", onClick: () => setCustomOpen(false), className: "flex cursor-pointer items-center gap-1 rounded-md px-2 py-1.5 text-xs text-muted-foreground transition-colors hover:bg-muted hover:text-foreground", children: [_jsx(ChevronLeft, { className: "size-3" }), labels.back] }), onApply: (from, to) => {
71
+ if (!from || !to) {
72
+ onChange({ period: OVERVIEW_PERIOD_DEFAULT, from: undefined, to: undefined });
73
+ }
74
+ else {
75
+ onChange({ period: "custom", from, to });
76
+ }
77
+ setOpen(false);
78
+ } }) })) : (_jsxs("div", { className: "flex flex-col", children: [PRESETS.map((period) => (_jsxs("button", { type: "button", onClick: () => {
79
+ onChange({ period, from: undefined, to: undefined });
80
+ setOpen(false);
81
+ }, className: cn("flex cursor-pointer items-center justify-between gap-4 rounded-md px-2 py-1.5 text-left text-xs whitespace-nowrap transition-colors hover:bg-muted", period === value.period && "font-medium"), children: [labels.period[period], period === value.period && _jsx(Check, { className: "size-3" })] }, period))), _jsx("div", { className: "my-1 h-px bg-border" }), _jsxs("button", { type: "button", onClick: () => setCustomOpen(true), className: cn("flex cursor-pointer items-center justify-between gap-4 rounded-md px-2 py-1.5 text-left text-xs whitespace-nowrap transition-colors hover:bg-muted", isCustom && "font-medium"), children: [labels.period.custom, isCustom && _jsx(Check, { className: "size-3" })] })] })) })] }));
82
+ }
@@ -0,0 +1,13 @@
1
+ export declare const OVERVIEW_PERIODS: readonly ["all", "custom", "last30Days", "currentMonth", "lastMonth", "last6Months", "last12Months", "currentYear", "lastYear"];
2
+ export type OverviewPeriod = (typeof OVERVIEW_PERIODS)[number];
3
+ export declare const OVERVIEW_PERIOD_DEFAULT: OverviewPeriod;
4
+ export declare function isOverviewPeriod(value: unknown): value is OverviewPeriod;
5
+ export interface PeriodRange {
6
+ from: string | null;
7
+ to: string | null;
8
+ }
9
+ export declare function overviewPeriodRange(period: OverviewPeriod, today?: Date, custom?: {
10
+ from?: string | null;
11
+ to?: string | null;
12
+ }): PeriodRange;
13
+ export declare function previousPeriodRange(range: PeriodRange): PeriodRange;
@@ -0,0 +1,63 @@
1
+ export const OVERVIEW_PERIODS = [
2
+ "all",
3
+ "custom",
4
+ "last30Days",
5
+ "currentMonth",
6
+ "lastMonth",
7
+ "last6Months",
8
+ "last12Months",
9
+ "currentYear",
10
+ "lastYear",
11
+ ];
12
+ export const OVERVIEW_PERIOD_DEFAULT = "last30Days";
13
+ export function isOverviewPeriod(value) {
14
+ return OVERVIEW_PERIODS.includes(value);
15
+ }
16
+ const toIsoDate = (date) => `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, "0")}-${String(date.getDate()).padStart(2, "0")}`;
17
+ export function overviewPeriodRange(period, today = new Date(), custom) {
18
+ const year = today.getFullYear();
19
+ const month = today.getMonth();
20
+ switch (period) {
21
+ case "all":
22
+ return { from: null, to: null };
23
+ case "custom":
24
+ return { from: custom?.from || null, to: custom?.to || null };
25
+ case "last30Days": {
26
+ const to = new Date(year, month, today.getDate());
27
+ const from = new Date(to);
28
+ from.setDate(from.getDate() - 29);
29
+ return { from: toIsoDate(from), to: toIsoDate(to) };
30
+ }
31
+ case "currentMonth":
32
+ return { from: toIsoDate(new Date(year, month, 1)), to: toIsoDate(new Date(year, month + 1, 0)) };
33
+ case "lastMonth":
34
+ return { from: toIsoDate(new Date(year, month - 1, 1)), to: toIsoDate(new Date(year, month, 0)) };
35
+ case "last6Months":
36
+ return {
37
+ from: toIsoDate(new Date(year, month - 5, 1)),
38
+ to: toIsoDate(new Date(year, month + 1, 0)),
39
+ };
40
+ case "last12Months":
41
+ return {
42
+ from: toIsoDate(new Date(year, month - 11, 1)),
43
+ to: toIsoDate(new Date(year, month + 1, 0)),
44
+ };
45
+ case "currentYear":
46
+ return { from: `${year}-01-01`, to: `${year}-12-31` };
47
+ case "lastYear":
48
+ return { from: `${year - 1}-01-01`, to: `${year - 1}-12-31` };
49
+ }
50
+ }
51
+ export function previousPeriodRange(range) {
52
+ if (!range.from || !range.to)
53
+ return { from: null, to: null };
54
+ const from = new Date(`${range.from}T00:00:00Z`);
55
+ const to = new Date(`${range.to}T00:00:00Z`);
56
+ if (Number.isNaN(from.getTime()) || Number.isNaN(to.getTime()))
57
+ return { from: null, to: null };
58
+ const days = Math.round((to.getTime() - from.getTime()) / 86_400_000) + 1;
59
+ const previousTo = new Date(from.getTime() - 86_400_000);
60
+ const previousFrom = new Date(previousTo.getTime() - (days - 1) * 86_400_000);
61
+ const toUtcIso = (date) => date.toISOString().slice(0, 10);
62
+ return { from: toUtcIso(previousFrom), to: toUtcIso(previousTo) };
63
+ }
@@ -0,0 +1,14 @@
1
+ import { type StageTile } from "./stage-tiles";
2
+ import { type PeriodLabels, type PeriodValue } from "./period-picker";
3
+ export declare function PipelineStagesPanel({ title, stages, loading, error, period, onPeriodChange, periodLabels, formatDay, className, dataTour, }: {
4
+ title: string;
5
+ stages: StageTile[];
6
+ loading: boolean;
7
+ error?: boolean;
8
+ period: PeriodValue;
9
+ onPeriodChange: (value: PeriodValue) => void;
10
+ periodLabels?: PeriodLabels;
11
+ formatDay: (iso: string) => string;
12
+ className?: string;
13
+ dataTour?: string;
14
+ }): import("react").JSX.Element | null;
@@ -0,0 +1,12 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { DashboardPanel } from "./panel.js";
3
+ import { StageTiles } from "./stage-tiles.js";
4
+ import { PeriodPicker } from "./period-picker.js";
5
+ export function PipelineStagesPanel({ title, stages, loading, error, period, onPeriodChange, periodLabels, formatDay, className, dataTour, }) {
6
+ if (error)
7
+ return null;
8
+ const total = stages.reduce((sum, stage) => sum + stage.count, 0);
9
+ if (!loading && total === 0)
10
+ return null;
11
+ return (_jsx(DashboardPanel, { title: title, headerRight: _jsx(PeriodPicker, { value: period, onChange: onPeriodChange, labels: periodLabels, formatDay: formatDay }), className: className, dataTour: dataTour, children: _jsx(StageTiles, { stages: stages, loading: loading }) }));
12
+ }
@@ -0,0 +1,34 @@
1
+ import type { ReactNode } from "react";
2
+ import { type PeriodLabels, type PeriodValue } from "./period-picker";
3
+ export interface ProcessingSummary {
4
+ processed: number;
5
+ recognized: number;
6
+ needsReview: number;
7
+ errors: number;
8
+ channels: {
9
+ label: string;
10
+ count: number;
11
+ }[];
12
+ lastRunLabel: string | null;
13
+ }
14
+ export declare function ProcessingSummaryPanel({ title, seeAllLabel, seeAllTo, summary, loading, error, labels, period, onPeriodChange, periodLabels, formatDay, className, dataTour, }: {
15
+ title: string;
16
+ seeAllLabel: string;
17
+ seeAllTo: string;
18
+ summary: ProcessingSummary | undefined;
19
+ loading: boolean;
20
+ error?: boolean;
21
+ labels: {
22
+ processed: string;
23
+ recognized: string;
24
+ needsReview: string;
25
+ errors: string;
26
+ channelsPrefix: string;
27
+ };
28
+ period: PeriodValue;
29
+ onPeriodChange: (value: PeriodValue) => void;
30
+ periodLabels?: PeriodLabels;
31
+ formatDay: (iso: string) => string;
32
+ className?: string;
33
+ dataTour?: string;
34
+ }): ReactNode;
@@ -0,0 +1,11 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { Link } from "@tanstack/react-router";
3
+ import { DashboardPanel } from "./panel.js";
4
+ import { StatTile } from "./stat-tile.js";
5
+ import { PeriodPicker } from "./period-picker.js";
6
+ export function ProcessingSummaryPanel({ title, seeAllLabel, seeAllTo, summary, loading, error, labels, period, onPeriodChange, periodLabels, formatDay, className, dataTour, }) {
7
+ if (error)
8
+ return null;
9
+ const value = (n) => (loading || n === undefined ? "—" : String(n));
10
+ return (_jsxs(DashboardPanel, { title: title, headerRight: _jsxs(_Fragment, { children: [_jsx(Link, { to: seeAllTo, className: "text-xs font-medium text-brand-dark hover:underline", children: seeAllLabel }), _jsx(PeriodPicker, { value: period, onChange: onPeriodChange, labels: periodLabels, formatDay: formatDay })] }), className: className, dataTour: dataTour, children: [_jsxs("div", { className: "mt-3 grid flex-1 grid-cols-2 gap-2", children: [_jsx(StatTile, { to: seeAllTo, label: labels.processed, value: value(summary?.processed) }), _jsx(StatTile, { to: seeAllTo, label: labels.recognized, value: value(summary?.recognized) }), _jsx(StatTile, { to: seeAllTo, label: labels.needsReview, value: value(summary?.needsReview), valueCls: summary && summary.needsReview > 0 ? "text-warning" : undefined }), _jsx(StatTile, { to: seeAllTo, label: labels.errors, value: value(summary?.errors), valueCls: summary && summary.errors > 0 ? "text-danger" : undefined })] }), _jsxs("div", { className: "mt-auto flex flex-wrap items-center justify-between gap-x-3 gap-y-0.5 pt-2", children: [summary && summary.channels.length > 0 && (_jsxs("p", { className: "text-xs text-muted-foreground", children: [labels.channelsPrefix, " ", summary.channels.map((c) => `${c.label} ${c.count}`).join(" · ")] })), summary?.lastRunLabel && (_jsx("p", { className: "text-xs text-muted-foreground", children: summary.lastRunLabel }))] })] }));
11
+ }
@@ -0,0 +1,15 @@
1
+ export interface RankedBarRow {
2
+ key: string;
3
+ label: string;
4
+ valueText: string;
5
+ sharePct: number;
6
+ link?: {
7
+ to: string;
8
+ params?: Record<string, string>;
9
+ search?: Record<string, unknown>;
10
+ };
11
+ }
12
+ export declare function RankedBars({ rows }: {
13
+ rows: RankedBarRow[];
14
+ }): import("react").JSX.Element | null;
15
+ export declare function RankedBarsSkeleton(): import("react").JSX.Element;
@@ -0,0 +1,16 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { Link } from "@tanstack/react-router";
3
+ import { Skeleton } from "../../ui/skeleton.js";
4
+ import { cn } from "../../lib/class-names.js";
5
+ const BAR_TINTS = ["bg-chart-1", "bg-chart-2", "bg-chart-3", "bg-chart-4", "bg-chart-5"];
6
+ export function RankedBars({ rows }) {
7
+ if (rows.length === 0)
8
+ return null;
9
+ return (_jsx("ol", { className: "mt-3 space-y-1.5", children: rows.map((row, index) => {
10
+ const body = (_jsxs(_Fragment, { children: [_jsx("span", { className: "w-5 shrink-0 text-xs tabular-nums text-muted-foreground", children: String(index + 1).padStart(2, "0") }), _jsxs("span", { className: "min-w-0 flex-1", children: [_jsxs("span", { className: "flex items-baseline justify-between gap-2", children: [_jsx("span", { className: "truncate text-sm text-foreground", children: row.label }), _jsx("span", { className: "shrink-0 text-sm font-medium tabular-nums text-foreground", children: row.valueText })] }), _jsx("span", { className: "mt-1 block h-1.5 w-full overflow-hidden rounded-full bg-brand-tint", children: _jsx("span", { className: cn("block h-full rounded-full", BAR_TINTS[index % BAR_TINTS.length]), style: { width: `${Math.min(Math.max(row.sharePct, 2), 100)}%` } }) })] }), _jsxs("span", { className: "w-12 shrink-0 rounded-md border border-border px-1.5 py-0.5 text-center text-[0.7rem] font-medium tabular-nums text-muted-foreground", children: [row.sharePct.toFixed(0), " %"] })] }));
11
+ return (_jsx("li", { children: row.link ? (_jsx(Link, { to: row.link.to, params: row.link.params, search: row.link.search, className: "flex items-center gap-3 rounded-lg px-1 py-0.5 transition-colors hover:bg-brand-tint/50", children: body })) : (_jsx("span", { className: "flex items-center gap-3 px-1 py-0.5", children: body })) }, row.key));
12
+ }) }));
13
+ }
14
+ export function RankedBarsSkeleton() {
15
+ return (_jsx("div", { className: "mt-3 space-y-2", children: Array.from({ length: 5 }, (_, index) => (_jsxs("div", { className: "flex items-center gap-3 px-1 py-0.5", children: [_jsx(Skeleton, { className: "h-4 w-5" }), _jsxs("div", { className: "min-w-0 flex-1 space-y-1.5", children: [_jsx(Skeleton, { className: "h-4 w-3/4" }), _jsx(Skeleton, { className: "h-1.5 w-full rounded-full" })] }), _jsx(Skeleton, { className: "h-5 w-12 rounded-md" })] }, index))) }));
16
+ }
@@ -0,0 +1,14 @@
1
+ import { type RankedBarRow } from "./ranked-bars";
2
+ import { type PeriodLabels, type PeriodValue } from "./period-picker";
3
+ export declare function RankedListPanel({ title, totalLabel, rows, loading, period, onPeriodChange, periodLabels, formatDay, className, dataTour, }: {
4
+ title: string;
5
+ totalLabel?: string;
6
+ rows: RankedBarRow[];
7
+ loading: boolean;
8
+ period: PeriodValue;
9
+ onPeriodChange: (value: PeriodValue) => void;
10
+ periodLabels?: PeriodLabels;
11
+ formatDay: (iso: string) => string;
12
+ className?: string;
13
+ dataTour?: string;
14
+ }): import("react").JSX.Element | null;
@@ -0,0 +1,9 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { DashboardPanel } from "./panel.js";
3
+ import { RankedBars, RankedBarsSkeleton } from "./ranked-bars.js";
4
+ import { PeriodPicker } from "./period-picker.js";
5
+ export function RankedListPanel({ title, totalLabel, rows, loading, period, onPeriodChange, periodLabels, formatDay, className, dataTour, }) {
6
+ if (!loading && rows.length === 0)
7
+ return null;
8
+ return (_jsx(DashboardPanel, { title: title, titleExtra: totalLabel, headerRight: _jsx(PeriodPicker, { value: period, onChange: onPeriodChange, labels: periodLabels, formatDay: formatDay }), className: className, dataTour: dataTour, children: loading ? _jsx(RankedBarsSkeleton, {}) : _jsx(RankedBars, { rows: rows }) }));
9
+ }
@@ -0,0 +1,15 @@
1
+ export interface StageTile {
2
+ key: string;
3
+ label: string;
4
+ count: number;
5
+ tileClassName?: string;
6
+ labelClassName?: string;
7
+ link: {
8
+ to: string;
9
+ search?: Record<string, unknown>;
10
+ };
11
+ }
12
+ export declare function StageTiles({ stages, loading }: {
13
+ stages: StageTile[];
14
+ loading: boolean;
15
+ }): import("react").JSX.Element;
@@ -0,0 +1,6 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Link } from "@tanstack/react-router";
3
+ import { cn } from "../../lib/class-names.js";
4
+ export function StageTiles({ stages, loading }) {
5
+ return (_jsx("div", { className: "mt-3 grid flex-1 auto-rows-fr grid-cols-2 gap-2 sm:grid-cols-3", children: stages.map((stage) => (_jsxs(Link, { to: stage.link.to, search: stage.link.search, className: cn("flex flex-col justify-center rounded-xl p-2.5 transition-opacity hover:opacity-80 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", stage.tileClassName), children: [_jsx("div", { className: cn("truncate text-sm font-medium", stage.labelClassName), children: stage.label }), _jsx("div", { className: "mt-0.5 text-2xl font-semibold tracking-tight tabular-nums text-foreground", children: loading ? "—" : stage.count })] }, stage.key))) }));
6
+ }
@@ -0,0 +1,25 @@
1
+ import type { ReactNode } from "react";
2
+ import type { LucideIcon } from "lucide-react";
3
+ export interface StatRowConfig {
4
+ key: string;
5
+ to: string;
6
+ search?: Record<string, unknown>;
7
+ icon: LucideIcon;
8
+ iconClassName: string;
9
+ label: string;
10
+ value: string;
11
+ valueClassName?: string;
12
+ }
13
+ export declare function StatRowsPanel({ title, rows, loading, emptyText, footerLink, headerRight, className, dataTour, }: {
14
+ title: string;
15
+ rows: StatRowConfig[];
16
+ loading?: boolean;
17
+ emptyText?: string;
18
+ footerLink?: {
19
+ to: string;
20
+ label: string;
21
+ };
22
+ headerRight?: ReactNode;
23
+ className?: string;
24
+ dataTour?: string;
25
+ }): import("react").JSX.Element;
@@ -0,0 +1,7 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Link } from "@tanstack/react-router";
3
+ import { DashboardPanel } from "./panel.js";
4
+ import { StatRow } from "./stat-tile.js";
5
+ export function StatRowsPanel({ title, rows, loading, emptyText, footerLink, headerRight, className, dataTour, }) {
6
+ return (_jsxs(DashboardPanel, { title: title, headerRight: headerRight, className: className, dataTour: dataTour, children: [!loading && rows.length === 0 && emptyText ? (_jsx("p", { className: "mt-3 text-sm text-muted-foreground", children: emptyText })) : (_jsx("div", { className: "mt-3 flex flex-1 flex-col gap-1.5", children: rows.map((row) => (_jsx(StatRow, { to: row.to, search: row.search, icon: row.icon, iconCls: row.iconClassName, label: row.label, value: loading ? "—" : row.value, valueCls: row.valueClassName }, row.key))) })), footerLink && (_jsx(Link, { to: footerLink.to, className: "mt-auto pt-2 text-sm font-medium text-brand-dark hover:underline", children: footerLink.label }))] }));
7
+ }
@@ -0,0 +1,20 @@
1
+ import type { LucideIcon } from "lucide-react";
2
+ export declare function StatTile({ to, search, icon: Icon, iconCls, label, value, valueCls, className, }: {
3
+ to: string;
4
+ search?: Record<string, unknown>;
5
+ icon?: LucideIcon;
6
+ iconCls?: string;
7
+ label: string;
8
+ value: string;
9
+ valueCls?: string;
10
+ className?: string;
11
+ }): import("react").JSX.Element;
12
+ export declare function StatRow({ to, search, icon: Icon, iconCls, label, value, valueCls, }: {
13
+ to: string;
14
+ search?: Record<string, unknown>;
15
+ icon: LucideIcon;
16
+ iconCls: string;
17
+ label: string;
18
+ value: string;
19
+ valueCls?: string;
20
+ }): import("react").JSX.Element;
@@ -0,0 +1,9 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Link } from "@tanstack/react-router";
3
+ import { cn } from "../../lib/class-names.js";
4
+ export function StatTile({ to, search, icon: Icon, iconCls, label, value, valueCls, className, }) {
5
+ return (_jsxs(Link, { to: to, search: search, className: cn("flex min-w-0 flex-col justify-center gap-1 rounded-lg px-2 py-1.5 transition-colors hover:bg-card/70", className), children: [_jsxs("span", { className: "flex min-w-0 items-center gap-1.5", title: label, children: [Icon && (_jsx("span", { className: cn("inline-flex size-5 shrink-0 items-center justify-center rounded-md text-white", iconCls), children: _jsx(Icon, { className: "size-3" }) })), _jsx("span", { className: "truncate text-sm font-medium text-muted-foreground", children: label })] }), _jsx("span", { className: cn("text-2xl font-semibold tracking-tight tabular-nums text-foreground", valueCls), children: value })] }));
6
+ }
7
+ export function StatRow({ to, search, icon: Icon, iconCls, label, value, valueCls, }) {
8
+ return (_jsxs(Link, { to: to, search: search, className: "flex items-center gap-2.5 rounded-lg px-2 py-1.5 transition-colors hover:bg-card/70", children: [_jsx("span", { className: cn("inline-flex size-6 shrink-0 items-center justify-center rounded-md text-white", iconCls), children: _jsx(Icon, { className: "size-3.5" }) }), _jsx("span", { className: "min-w-0 flex-1 truncate text-sm text-muted-foreground", title: label, children: label }), _jsx("span", { className: cn("shrink-0 text-base font-semibold tabular-nums text-foreground", valueCls), children: value })] }));
9
+ }
@@ -0,0 +1,4 @@
1
+ export { ErrorState, EmptyState, TableSkeleton, CardsSkeleton, readableErrorMessage, englishErrorStateLabels, } from "./query-states";
2
+ export type { ErrorStateLabels } from "./query-states";
3
+ export { TablePagination, PAGE_SIZES, englishPaginationLabels } from "./table-pagination";
4
+ export type { PaginationLabels } from "./table-pagination";
@@ -0,0 +1,2 @@
1
+ export { ErrorState, EmptyState, TableSkeleton, CardsSkeleton, readableErrorMessage, englishErrorStateLabels, } from "./query-states.js";
2
+ export { TablePagination, PAGE_SIZES, englishPaginationLabels } from "./table-pagination.js";
@@ -0,0 +1,27 @@
1
+ import type { ReactNode } from "react";
2
+ export interface ErrorStateLabels {
3
+ title: string;
4
+ unknownError: string;
5
+ retry: string;
6
+ }
7
+ export declare const englishErrorStateLabels: ErrorStateLabels;
8
+ export declare function readableErrorMessage(error: unknown, fallback: string): string;
9
+ export declare function ErrorState({ error, onRetry, labels, className, }: {
10
+ error: unknown;
11
+ onRetry?: () => void;
12
+ labels?: ErrorStateLabels;
13
+ className?: string;
14
+ }): import("react").JSX.Element;
15
+ export declare function EmptyState({ title, hint, action, className, }: {
16
+ title: string;
17
+ hint?: string;
18
+ action?: ReactNode;
19
+ className?: string;
20
+ }): import("react").JSX.Element;
21
+ export declare function TableSkeleton({ rows, columns }: {
22
+ rows?: number;
23
+ columns?: number;
24
+ }): import("react").JSX.Element;
25
+ export declare function CardsSkeleton({ count }: {
26
+ count?: number;
27
+ }): import("react").JSX.Element;
@@ -0,0 +1,38 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { AlertTriangle, Inbox } from "lucide-react";
3
+ import { Skeleton } from "../../ui/skeleton.js";
4
+ import { Button } from "../../ui/button.js";
5
+ import { cn } from "../../lib/class-names.js";
6
+ export const englishErrorStateLabels = {
7
+ title: "Something went wrong.",
8
+ unknownError: "Unknown error.",
9
+ retry: "Try again",
10
+ };
11
+ // Supabase rejects with a plain object, not an Error, so read its message field too.
12
+ export function readableErrorMessage(error, fallback) {
13
+ if (error instanceof Error && error.message)
14
+ return error.message;
15
+ if (typeof error === "string" && error)
16
+ return error;
17
+ if (error && typeof error === "object") {
18
+ const errorObject = error;
19
+ const message = typeof errorObject.message === "string" ? errorObject.message : null;
20
+ if (message) {
21
+ const code = typeof errorObject.code === "string" ? errorObject.code : null;
22
+ return code ? `${message} (${code})` : message;
23
+ }
24
+ }
25
+ return fallback;
26
+ }
27
+ export function ErrorState({ error, onRetry, labels = englishErrorStateLabels, className, }) {
28
+ return (_jsxs("div", { className: cn("flex flex-col items-center justify-center rounded-xl border border-destructive/30 bg-destructive/5 px-6 py-12 text-center", className), children: [_jsx("span", { className: "grid size-12 place-items-center rounded-full bg-destructive/10 text-destructive", children: _jsx(AlertTriangle, { className: "size-6" }) }), _jsx("h2", { className: "mt-4 text-base font-semibold text-foreground", children: labels.title }), _jsx("p", { className: "mt-1 max-w-md text-sm text-muted-foreground", children: readableErrorMessage(error, labels.unknownError) }), onRetry && (_jsx(Button, { variant: "outline", className: "mt-4", onClick: onRetry, children: labels.retry }))] }));
29
+ }
30
+ export function EmptyState({ title, hint, action, className, }) {
31
+ return (_jsxs("div", { className: cn("flex flex-col items-center justify-center rounded-xl border border-dashed border-border bg-card px-6 py-12 text-center", className), children: [_jsx("span", { className: "grid size-12 place-items-center rounded-full bg-muted text-muted-foreground", children: _jsx(Inbox, { className: "size-6" }) }), _jsx("h2", { className: "mt-4 text-base font-semibold text-foreground", children: title }), hint && _jsx("p", { className: "mt-1 max-w-md text-sm text-muted-foreground", children: hint }), action && _jsx("div", { className: "mt-4", children: action })] }));
32
+ }
33
+ export function TableSkeleton({ rows = 6, columns = 5 }) {
34
+ return (_jsx("div", { className: "overflow-hidden rounded-xl border border-border bg-card", children: _jsx("div", { className: "divide-y divide-border", children: Array.from({ length: rows }).map((_, rowIndex) => (_jsx("div", { className: "flex items-center gap-4 px-4 py-3", children: Array.from({ length: columns }).map((_, columnIndex) => (_jsx(Skeleton, { className: cn("h-4", columnIndex === 0 ? "w-40" : "flex-1") }, columnIndex))) }, rowIndex))) }) }));
35
+ }
36
+ export function CardsSkeleton({ count = 4 }) {
37
+ return (_jsx("div", { className: "grid grid-cols-2 gap-3 lg:grid-cols-4", children: Array.from({ length: count }).map((_, index) => (_jsx(Skeleton, { className: "h-24 rounded-xl" }, index))) }));
38
+ }