@spaceinvoices/react-ui 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (352) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +340 -0
  3. package/cli/dist/index.js +922 -0
  4. package/package.json +87 -0
  5. package/registry.json +600 -0
  6. package/spaceinvoices.schema.json +47 -0
  7. package/src/app.tsx +25 -0
  8. package/src/common/autocomplete.tsx +135 -0
  9. package/src/components/activities/activity-timeline.tsx +160 -0
  10. package/src/components/activities/index.ts +1 -0
  11. package/src/components/activities/locales/de.ts +30 -0
  12. package/src/components/activities/locales/sl.ts +30 -0
  13. package/src/components/advance-invoices/advance-invoices.hooks.ts +75 -0
  14. package/src/components/advance-invoices/create/create-advance-invoice-form.tsx +702 -0
  15. package/src/components/advance-invoices/create/locales/de.ts +29 -0
  16. package/src/components/advance-invoices/create/locales/sl.ts +25 -0
  17. package/src/components/advance-invoices/create/prepare-advance-invoice-submission.ts +74 -0
  18. package/src/components/advance-invoices/index.ts +5 -0
  19. package/src/components/advance-invoices/list/index.ts +3 -0
  20. package/src/components/advance-invoices/list/list-row-actions.tsx +119 -0
  21. package/src/components/advance-invoices/list/list-table.tsx +178 -0
  22. package/src/components/advance-invoices/list/locales/de.ts +32 -0
  23. package/src/components/advance-invoices/list/locales/sl.ts +32 -0
  24. package/src/components/advance-invoices/list/use-advance-invoice-download.ts +63 -0
  25. package/src/components/button-loader.tsx +11 -0
  26. package/src/components/combobox.tsx +96 -0
  27. package/src/components/company-registry/company-registry-autocomplete.tsx +151 -0
  28. package/src/components/company-registry/company-registry.hooks.ts +67 -0
  29. package/src/components/company-registry/index.ts +7 -0
  30. package/src/components/credit-notes/create/create-credit-note-form.tsx +332 -0
  31. package/src/components/credit-notes/create/index.ts +1 -0
  32. package/src/components/credit-notes/create/locales/de.ts +69 -0
  33. package/src/components/credit-notes/create/locales/sl.ts +67 -0
  34. package/src/components/credit-notes/credit-notes.hooks.ts +22 -0
  35. package/src/components/credit-notes/index.ts +10 -0
  36. package/src/components/credit-notes/list/index.ts +3 -0
  37. package/src/components/credit-notes/list/list-row-actions.tsx +116 -0
  38. package/src/components/credit-notes/list/list-table.tsx +183 -0
  39. package/src/components/credit-notes/list/locales/de.ts +33 -0
  40. package/src/components/credit-notes/list/locales/sl.ts +33 -0
  41. package/src/components/credit-notes/list/use-credit-note-download.ts +65 -0
  42. package/src/components/customers/create-customer-form/create-customer-form.tsx +134 -0
  43. package/src/components/customers/create-customer-form/locales/de.ts +20 -0
  44. package/src/components/customers/create-customer-form/locales/sl.ts +20 -0
  45. package/src/components/customers/customer-autocomplete.tsx +173 -0
  46. package/src/components/customers/customer-combobox.tsx +130 -0
  47. package/src/components/customers/customer-list-table/customer-list-row-actions.tsx +48 -0
  48. package/src/components/customers/customer-list-table/customer-list-table.tsx +124 -0
  49. package/src/components/customers/customer-list-table/index.ts +2 -0
  50. package/src/components/customers/customer-list-table/locales/de.ts +16 -0
  51. package/src/components/customers/customer-list-table/locales/sl.ts +16 -0
  52. package/src/components/customers/customers.hooks.test.ts +348 -0
  53. package/src/components/customers/customers.hooks.ts +57 -0
  54. package/src/components/customers/index.ts +5 -0
  55. package/src/components/dashboard/chart-empty-state.tsx +29 -0
  56. package/src/components/dashboard/collection-rate-card/collection-rate-card.tsx +80 -0
  57. package/src/components/dashboard/collection-rate-card/index.ts +4 -0
  58. package/src/components/dashboard/collection-rate-card/locales/sl.ts +3 -0
  59. package/src/components/dashboard/collection-rate-card/use-collection-rate.ts +74 -0
  60. package/src/components/dashboard/index.ts +54 -0
  61. package/src/components/dashboard/invoice-status-chart/index.ts +4 -0
  62. package/src/components/dashboard/invoice-status-chart/invoice-status-chart.tsx +130 -0
  63. package/src/components/dashboard/invoice-status-chart/locales/sl.ts +9 -0
  64. package/src/components/dashboard/invoice-status-chart/use-invoice-status.ts +105 -0
  65. package/src/components/dashboard/loading-card.tsx +19 -0
  66. package/src/components/dashboard/payment-methods-chart/index.ts +4 -0
  67. package/src/components/dashboard/payment-methods-chart/locales/sl.ts +12 -0
  68. package/src/components/dashboard/payment-methods-chart/payment-methods-chart.tsx +152 -0
  69. package/src/components/dashboard/payment-methods-chart/use-payment-methods.ts +50 -0
  70. package/src/components/dashboard/payment-trend-chart/index.ts +4 -0
  71. package/src/components/dashboard/payment-trend-chart/locales/sl.ts +5 -0
  72. package/src/components/dashboard/payment-trend-chart/payment-trend-chart.tsx +137 -0
  73. package/src/components/dashboard/payment-trend-chart/use-payment-trend.ts +92 -0
  74. package/src/components/dashboard/revenue-card.tsx +49 -0
  75. package/src/components/dashboard/revenue-trend-chart/index.ts +4 -0
  76. package/src/components/dashboard/revenue-trend-chart/locales/sl.ts +5 -0
  77. package/src/components/dashboard/revenue-trend-chart/revenue-trend-chart.tsx +137 -0
  78. package/src/components/dashboard/revenue-trend-chart/use-revenue-trend.ts +93 -0
  79. package/src/components/dashboard/shared/index.ts +5 -0
  80. package/src/components/dashboard/shared/use-revenue-data.ts +160 -0
  81. package/src/components/dashboard/shared/use-stats-counts.ts +89 -0
  82. package/src/components/dashboard/shared/use-stats-query.ts +38 -0
  83. package/src/components/dashboard/stat-card.tsx +41 -0
  84. package/src/components/dashboard/tax-collected-card/index.ts +2 -0
  85. package/src/components/dashboard/tax-collected-card/tax-collected-card.tsx +77 -0
  86. package/src/components/dashboard/tax-collected-card/use-tax-collected.ts +145 -0
  87. package/src/components/dashboard/top-customers-chart/index.ts +4 -0
  88. package/src/components/dashboard/top-customers-chart/locales/sl.ts +5 -0
  89. package/src/components/dashboard/top-customers-chart/top-customers-chart.tsx +130 -0
  90. package/src/components/dashboard/top-customers-chart/use-top-customers.ts +72 -0
  91. package/src/components/documents/create/document-add-item-form.tsx +379 -0
  92. package/src/components/documents/create/document-add-item-tax-rate-field.tsx +120 -0
  93. package/src/components/documents/create/document-details-section.tsx +597 -0
  94. package/src/components/documents/create/document-items-section.tsx +133 -0
  95. package/src/components/documents/create/document-recipient-section.tsx +101 -0
  96. package/src/components/documents/create/form-types.ts +36 -0
  97. package/src/components/documents/create/index.ts +9 -0
  98. package/src/components/documents/create/live-preview.tsx +235 -0
  99. package/src/components/documents/create/mark-as-paid-section.tsx +82 -0
  100. package/src/components/documents/create/prepare-document-submission.test.ts +132 -0
  101. package/src/components/documents/create/prepare-document-submission.ts +187 -0
  102. package/src/components/documents/create/prepare-preview-data.test.ts +155 -0
  103. package/src/components/documents/create/prepare-preview-data.ts +16 -0
  104. package/src/components/documents/create/smart-code-insert-button.tsx +139 -0
  105. package/src/components/documents/create/use-document-customer-form.ts +161 -0
  106. package/src/components/documents/document-preview.tsx +13 -0
  107. package/src/components/documents/documents.hooks.ts +146 -0
  108. package/src/components/documents/index.ts +23 -0
  109. package/src/components/documents/shared/document-preview-display.tsx +172 -0
  110. package/src/components/documents/shared/index.ts +3 -0
  111. package/src/components/documents/shared/scaled-document-preview.tsx +70 -0
  112. package/src/components/documents/shared/use-a4-scaling.ts +62 -0
  113. package/src/components/documents/types.ts +61 -0
  114. package/src/components/documents/view/document-actions-bar.tsx +328 -0
  115. package/src/components/documents/view/document-details-card.tsx +179 -0
  116. package/src/components/documents/view/document-payments-list.tsx +256 -0
  117. package/src/components/documents/view/index.ts +4 -0
  118. package/src/components/documents/view/locales/de.ts +85 -0
  119. package/src/components/documents/view/locales/sl.ts +84 -0
  120. package/src/components/documents/view/use-document-download.ts +125 -0
  121. package/src/components/entities/create-entity-form.tsx +105 -0
  122. package/src/components/entities/entities.hooks.ts +50 -0
  123. package/src/components/entities/entity-settings-form/email-template-variables-info.tsx +103 -0
  124. package/src/components/entities/entity-settings-form/entity-settings-form.tsx +1326 -0
  125. package/src/components/entities/entity-settings-form/image-upload-with-crop.tsx +222 -0
  126. package/src/components/entities/entity-settings-form/index.ts +2 -0
  127. package/src/components/entities/entity-settings-form/input-with-preview.tsx +190 -0
  128. package/src/components/entities/entity-settings-form/locales/de.ts +192 -0
  129. package/src/components/entities/entity-settings-form/locales/sl.ts +188 -0
  130. package/src/components/entities/furs-settings-form/furs-settings-form.tsx +410 -0
  131. package/src/components/entities/furs-settings-form/furs-settings.hooks.ts +320 -0
  132. package/src/components/entities/furs-settings-form/index.ts +3 -0
  133. package/src/components/entities/furs-settings-form/locales/de.ts +233 -0
  134. package/src/components/entities/furs-settings-form/locales/en.ts +194 -0
  135. package/src/components/entities/furs-settings-form/locales/sl.ts +196 -0
  136. package/src/components/entities/furs-settings-form/sections/certificate-settings-section.tsx +242 -0
  137. package/src/components/entities/furs-settings-form/sections/enable-fiscalization-section.tsx +139 -0
  138. package/src/components/entities/furs-settings-form/sections/general-settings-section.tsx +252 -0
  139. package/src/components/entities/furs-settings-form/sections/premises-management-section.tsx +370 -0
  140. package/src/components/entities/furs-settings-form/sections/register-premise-dialog.tsx +420 -0
  141. package/src/components/entities/keys.ts +2 -0
  142. package/src/components/entities/settings/branding-settings-form.tsx +274 -0
  143. package/src/components/entities/settings/company-settings-form.tsx +256 -0
  144. package/src/components/entities/settings/defaults-settings-form.tsx +501 -0
  145. package/src/components/entities/settings/email-settings-form.tsx +288 -0
  146. package/src/components/entities/settings/eslog-settings-form.tsx +113 -0
  147. package/src/components/entities/settings/index.ts +8 -0
  148. package/src/components/entities/settings/number-format-settings-form.tsx +244 -0
  149. package/src/components/entities/settings/pdf-template-selector/demo-invoice-data.ts +164 -0
  150. package/src/components/entities/settings/pdf-template-selector/index.ts +2 -0
  151. package/src/components/entities/settings/pdf-template-selector/locales/de.ts +18 -0
  152. package/src/components/entities/settings/pdf-template-selector/locales/sl.ts +18 -0
  153. package/src/components/entities/settings/pdf-template-selector/pdf-template-cards.tsx +49 -0
  154. package/src/components/entities/settings/settings-footer.tsx +16 -0
  155. package/src/components/entities/settings/tax-rules-settings-form.tsx +346 -0
  156. package/src/components/estimates/create/create-estimate-form.tsx +384 -0
  157. package/src/components/estimates/create/locales/de.ts +64 -0
  158. package/src/components/estimates/create/locales/sl.ts +63 -0
  159. package/src/components/estimates/create/prepare-estimate-submission.ts +39 -0
  160. package/src/components/estimates/create/use-estimate-customer-form.ts +5 -0
  161. package/src/components/estimates/estimates.hooks.ts +15 -0
  162. package/src/components/estimates/index.ts +6 -0
  163. package/src/components/estimates/list/index.ts +3 -0
  164. package/src/components/estimates/list/list-row-actions.tsx +103 -0
  165. package/src/components/estimates/list/list-table.tsx +171 -0
  166. package/src/components/estimates/list/locales/de.ts +26 -0
  167. package/src/components/estimates/list/locales/sl.ts +26 -0
  168. package/src/components/estimates/list/use-estimate-download.ts +63 -0
  169. package/src/components/export/document-export-form.tsx +288 -0
  170. package/src/components/export/index.ts +2 -0
  171. package/src/components/form/form-input.tsx +89 -0
  172. package/src/components/form/index.ts +1 -0
  173. package/src/components/invoices/create/create-invoice-form.tsx +852 -0
  174. package/src/components/invoices/create/eslog-validation.test.ts +242 -0
  175. package/src/components/invoices/create/eslog-validation.ts +208 -0
  176. package/src/components/invoices/create/locales/de.ts +118 -0
  177. package/src/components/invoices/create/locales/sl.ts +114 -0
  178. package/src/components/invoices/create/prepare-invoice-submission.test.ts +777 -0
  179. package/src/components/invoices/create/prepare-invoice-submission.ts +79 -0
  180. package/src/components/invoices/create/use-invoice-customer-form.ts +5 -0
  181. package/src/components/invoices/index.ts +9 -0
  182. package/src/components/invoices/invoices-furs.hooks.ts +28 -0
  183. package/src/components/invoices/invoices.hooks.ts +110 -0
  184. package/src/components/invoices/list/index.ts +3 -0
  185. package/src/components/invoices/list/list-row-actions.tsx +132 -0
  186. package/src/components/invoices/list/list-table.tsx +165 -0
  187. package/src/components/invoices/list/locales/de.ts +33 -0
  188. package/src/components/invoices/list/locales/sl.ts +33 -0
  189. package/src/components/invoices/list/use-invoice-download.ts +62 -0
  190. package/src/components/invoices/send-email-dialog/index.ts +1 -0
  191. package/src/components/invoices/send-email-dialog/locales/de.ts +18 -0
  192. package/src/components/invoices/send-email-dialog/locales/sl.ts +17 -0
  193. package/src/components/invoices/send-email-dialog/send-email-dialog.tsx +289 -0
  194. package/src/components/invoices/send-email-dialog.tsx +2 -0
  195. package/src/components/invoices/shared/index.ts +2 -0
  196. package/src/components/invoices/shared/scaled-document-preview.tsx +32 -0
  197. package/src/components/invoices/shared/use-a4-scaling.tsx +39 -0
  198. package/src/components/invoices/view/eslog-info-display.tsx +160 -0
  199. package/src/components/invoices/view/furs-info-display.tsx +213 -0
  200. package/src/components/items/create-item-form/create-item-form.tsx +155 -0
  201. package/src/components/items/create-item-form/locales/de.ts +14 -0
  202. package/src/components/items/create-item-form/locales/en.ts +9 -0
  203. package/src/components/items/create-item-form/locales/sl.ts +14 -0
  204. package/src/components/items/item-combobox.tsx +147 -0
  205. package/src/components/items/item-list-table/item-list-header.tsx +33 -0
  206. package/src/components/items/item-list-table/item-list-row-actions.tsx +48 -0
  207. package/src/components/items/item-list-table/item-list-row.tsx +32 -0
  208. package/src/components/items/item-list-table/item-list-table.tsx +76 -0
  209. package/src/components/items/item-list-table/locales/de.ts +10 -0
  210. package/src/components/items/item-list-table/locales/en.ts +10 -0
  211. package/src/components/items/item-list-table/locales/sl.ts +10 -0
  212. package/src/components/items/items.hooks.ts +63 -0
  213. package/src/components/loading-spinner.tsx +24 -0
  214. package/src/components/payments/create-payment-form/create-payment-form.tsx +222 -0
  215. package/src/components/payments/create-payment-form/locales/de.ts +20 -0
  216. package/src/components/payments/create-payment-form/locales/sl.ts +20 -0
  217. package/src/components/payments/edit-payment-form/edit-payment-form.tsx +230 -0
  218. package/src/components/payments/edit-payment-form/index.ts +1 -0
  219. package/src/components/payments/edit-payment-form/locales/de.ts +20 -0
  220. package/src/components/payments/edit-payment-form/locales/sl.ts +20 -0
  221. package/src/components/payments/index.ts +4 -0
  222. package/src/components/payments/list/index.ts +2 -0
  223. package/src/components/payments/list/list-row-actions.tsx +98 -0
  224. package/src/components/payments/list/list-table.tsx +186 -0
  225. package/src/components/payments/list/locales/de.ts +19 -0
  226. package/src/components/payments/list/locales/sl.ts +19 -0
  227. package/src/components/payments/payments.hooks.ts +15 -0
  228. package/src/components/request-logs/index.ts +3 -0
  229. package/src/components/request-logs/request-log-detail.tsx +242 -0
  230. package/src/components/request-logs/request-log-list-table.tsx +266 -0
  231. package/src/components/request-logs/request-logs-page.tsx +10 -0
  232. package/src/components/table/README.md +410 -0
  233. package/src/components/table/data-table.tsx +251 -0
  234. package/src/components/table/date-cell.tsx +35 -0
  235. package/src/components/table/filter-bar.tsx +114 -0
  236. package/src/components/table/filter-panel.tsx +407 -0
  237. package/src/components/table/hooks/use-table-fetch.ts +17 -0
  238. package/src/components/table/hooks/use-table-query.ts +36 -0
  239. package/src/components/table/hooks/use-table-state.ts +293 -0
  240. package/src/components/table/index.ts +35 -0
  241. package/src/components/table/search-input.tsx +85 -0
  242. package/src/components/table/sortable-header.tsx +56 -0
  243. package/src/components/table/table-empty-state.tsx +40 -0
  244. package/src/components/table/table-no-results.tsx +41 -0
  245. package/src/components/table/table-pagination.tsx +42 -0
  246. package/src/components/table/table-skeleton.tsx +54 -0
  247. package/src/components/table/types.ts +136 -0
  248. package/src/components/tax-reports/index.ts +1 -0
  249. package/src/components/tax-reports/kir-export-form.tsx +172 -0
  250. package/src/components/taxes/create-tax-form/create-tax-form.tsx +112 -0
  251. package/src/components/taxes/create-tax-form/locales/de.ts +8 -0
  252. package/src/components/taxes/create-tax-form/locales/en.ts +7 -0
  253. package/src/components/taxes/create-tax-form/locales/sl.ts +8 -0
  254. package/src/components/taxes/tax-list-table/locales/de.ts +11 -0
  255. package/src/components/taxes/tax-list-table/locales/en.ts +10 -0
  256. package/src/components/taxes/tax-list-table/locales/sl.ts +11 -0
  257. package/src/components/taxes/tax-list-table/tax-list-header.tsx +29 -0
  258. package/src/components/taxes/tax-list-table/tax-list-row-actions.tsx +43 -0
  259. package/src/components/taxes/tax-list-table/tax-list-row.tsx +46 -0
  260. package/src/components/taxes/tax-list-table/tax-list-table.tsx +59 -0
  261. package/src/components/taxes/taxes.hooks.ts +35 -0
  262. package/src/components/ui/alert-dialog.tsx +61 -0
  263. package/src/components/ui/alert.tsx +72 -0
  264. package/src/components/ui/badge.tsx +48 -0
  265. package/src/components/ui/breadcrumb.tsx +132 -0
  266. package/src/components/ui/button.tsx +61 -0
  267. package/src/components/ui/calendar.tsx +213 -0
  268. package/src/components/ui/card.tsx +94 -0
  269. package/src/components/ui/chart.tsx +380 -0
  270. package/src/components/ui/checkbox.tsx +27 -0
  271. package/src/components/ui/collapsible.tsx +56 -0
  272. package/src/components/ui/command.tsx +187 -0
  273. package/src/components/ui/dialog.tsx +187 -0
  274. package/src/components/ui/drawer.tsx +123 -0
  275. package/src/components/ui/dropdown-menu.tsx +291 -0
  276. package/src/components/ui/form.tsx +166 -0
  277. package/src/components/ui/input-group.tsx +149 -0
  278. package/src/components/ui/input.tsx +20 -0
  279. package/src/components/ui/label.tsx +18 -0
  280. package/src/components/ui/loading-spinner.tsx +16 -0
  281. package/src/components/ui/popover.tsx +108 -0
  282. package/src/components/ui/radio-group.tsx +37 -0
  283. package/src/components/ui/select.tsx +200 -0
  284. package/src/components/ui/separator.tsx +23 -0
  285. package/src/components/ui/sheet.tsx +145 -0
  286. package/src/components/ui/sidebar.tsx +771 -0
  287. package/src/components/ui/skeleton.tsx +13 -0
  288. package/src/components/ui/sonner.tsx +60 -0
  289. package/src/components/ui/spinner.tsx +10 -0
  290. package/src/components/ui/sticky-form-footer.tsx +55 -0
  291. package/src/components/ui/switch.tsx +30 -0
  292. package/src/components/ui/table.tsx +101 -0
  293. package/src/components/ui/tabs.tsx +80 -0
  294. package/src/components/ui/textarea.tsx +18 -0
  295. package/src/components/ui/tooltip.tsx +89 -0
  296. package/src/components/wl-subscription/index.ts +2 -0
  297. package/src/components/wl-subscription/locked-feature.tsx +173 -0
  298. package/src/components/wl-subscription/upgrade-modal.tsx +209 -0
  299. package/src/frontend.tsx +28 -0
  300. package/src/generate-schemas.ts +265 -0
  301. package/src/generated/schemas/advanceinvoice.ts +177 -0
  302. package/src/generated/schemas/creditnote.ts +187 -0
  303. package/src/generated/schemas/customer.ts +29 -0
  304. package/src/generated/schemas/entity.ts +252 -0
  305. package/src/generated/schemas/estimate.ts +159 -0
  306. package/src/generated/schemas/furssettings.ts +25 -0
  307. package/src/generated/schemas/index.ts +24 -0
  308. package/src/generated/schemas/invoice.ts +167 -0
  309. package/src/generated/schemas/item.ts +38 -0
  310. package/src/generated/schemas/payment.ts +44 -0
  311. package/src/generated/schemas/previewadvanceinvoice_body.ts +354 -0
  312. package/src/generated/schemas/previewestimate_body.ts +309 -0
  313. package/src/generated/schemas/registerfursmovablepremise_body.ts +22 -0
  314. package/src/generated/schemas/registerfursrealestatepremise_body.ts +32 -0
  315. package/src/generated/schemas/renderdocument_body.ts +594 -0
  316. package/src/generated/schemas/sendemail_body.ts +26 -0
  317. package/src/generated/schemas/startpdfexport_body.ts +20 -0
  318. package/src/generated/schemas/tax.ts +48 -0
  319. package/src/generated/schemas/uploadfile_body.ts +23 -0
  320. package/src/generated/schemas/uploadfurscertificate_body.ts +20 -0
  321. package/src/generated/schemas/userfurssettings.ts +19 -0
  322. package/src/hooks/create-resource-hooks.test.ts +483 -0
  323. package/src/hooks/create-resource-hooks.ts +300 -0
  324. package/src/hooks/use-debounce.ts +12 -0
  325. package/src/hooks/use-duplicate-document.ts +185 -0
  326. package/src/hooks/use-media-query.tsx +19 -0
  327. package/src/hooks/use-mobile.ts +39 -0
  328. package/src/hooks/use-next-document-number.ts +57 -0
  329. package/src/hooks/use-resource-mutation.ts +118 -0
  330. package/src/hooks/use-vies-check.ts +130 -0
  331. package/src/index.css +11 -0
  332. package/src/index.html +13 -0
  333. package/src/index.tsx +12 -0
  334. package/src/lib/auth.ts +4 -0
  335. package/src/lib/browser-cookies.ts +70 -0
  336. package/src/lib/constants.ts +287 -0
  337. package/src/lib/cookies.ts +36 -0
  338. package/src/lib/schemas/advance-invoice.ts +43 -0
  339. package/src/lib/schemas/credit-note.ts +32 -0
  340. package/src/lib/schemas/estimate.ts +31 -0
  341. package/src/lib/schemas/index.ts +18 -0
  342. package/src/lib/schemas/invoice.ts +43 -0
  343. package/src/lib/schemas/shared.ts +79 -0
  344. package/src/lib/translation.ts +38 -0
  345. package/src/lib/utils.ts +6 -0
  346. package/src/providers/entities-context.tsx +41 -0
  347. package/src/providers/entities-provider.tsx +201 -0
  348. package/src/providers/form-footer-context.tsx +72 -0
  349. package/src/providers/sdk-provider.tsx +164 -0
  350. package/src/providers/white-label-provider.tsx +91 -0
  351. package/src/providers/wl-subscription-provider.tsx +277 -0
  352. package/src/utils/string-helpers.ts +111 -0
@@ -0,0 +1,118 @@
1
+ import type SDK from "@spaceinvoices/js-sdk";
2
+ import type { SDKMethodOptions } from "@spaceinvoices/js-sdk";
3
+ import type { UseMutationOptions } from "@tanstack/react-query";
4
+
5
+ import { useMutation, useQueryClient } from "@tanstack/react-query";
6
+
7
+ import { useSDK } from "@/ui/providers/sdk-provider";
8
+
9
+ type ResourceMutationOptions<TData, TError, TVariables, TContext> = {
10
+ /** The resource name in the SDK (e.g., 'customers', 'invoices') */
11
+ resourceName: keyof SDK;
12
+ /** The method name to call on the resource (e.g., 'create', 'update', 'delete') */
13
+ methodName: string;
14
+ /** The cache key(s) to invalidate after successful mutation */
15
+ cacheKey: string | string[];
16
+ /** Entity ID for multi-tenant filtering */
17
+ entityId?: string | null;
18
+ /** Account ID for account-specific requests */
19
+ accountId?: string | null;
20
+ /** Additional mutation options from React Query */
21
+ mutationOptions?: Omit<
22
+ UseMutationOptions<TData, TError, TVariables, TContext>,
23
+ "mutationFn" | "onSuccess" | "onError"
24
+ > & {
25
+ /** Custom success callback - receives data, variables, and context */
26
+ onSuccess?: (data: TData, variables: TVariables, context: TContext | undefined) => void;
27
+ /** Custom error callback - receives error, variables, and context */
28
+ onError?: (error: TError, variables: TVariables, context: TContext | undefined) => void;
29
+ };
30
+ };
31
+
32
+ /**
33
+ * Generic hook for creating mutations for any resource in the SDK
34
+ * Automatically handles cache invalidation and error handling
35
+ */
36
+ export function useResourceMutation<TData, TError = Error, TVariables = unknown, TContext = unknown>({
37
+ resourceName,
38
+ methodName,
39
+ cacheKey,
40
+ entityId,
41
+ accountId,
42
+ mutationOptions,
43
+ }: ResourceMutationOptions<TData, TError, TVariables, TContext>) {
44
+ const { sdk } = useSDK();
45
+ const queryClient = useQueryClient();
46
+
47
+ // Destructure to separate onSuccess/onError from other options
48
+ const { onSuccess: customOnSuccess, onError: customOnError, ...otherOptions } = mutationOptions || {};
49
+
50
+ return useMutation<TData, TError, TVariables, TContext>({
51
+ ...otherOptions,
52
+ mutationFn: async (variables: TVariables) => {
53
+ // SDK is guaranteed non-null by provider - no need to check
54
+ const resource = sdk[resourceName] as Record<string, (...args: unknown[]) => Promise<unknown>>;
55
+
56
+ if (!resource || typeof resource[methodName] !== "function") {
57
+ throw new Error(`Method ${methodName} not found on resource ${String(resourceName)}`);
58
+ }
59
+
60
+ // Build SDK options (entity_id, etc.)
61
+ const options: SDKMethodOptions | undefined = entityId ? { entity_id: entityId } : undefined;
62
+
63
+ // SDK API: method(data, options) or method(id, data, options)
64
+ const isUpdateMethod = methodName === "update";
65
+ const isDeleteMethod = methodName === "delete";
66
+
67
+ if (isUpdateMethod) {
68
+ // Update: method(id, data, options)
69
+ const { id, data } = variables as { id: string; data: unknown };
70
+ return (await resource[methodName](id, data, options)) as TData;
71
+ }
72
+
73
+ if (isDeleteMethod) {
74
+ // Delete: method(id, options)
75
+ const { id } = variables as { id: string };
76
+ return (await resource[methodName](id, options)) as TData;
77
+ }
78
+
79
+ // Create: method(data, options)
80
+ return (await resource[methodName](variables, options)) as TData;
81
+ },
82
+
83
+ onSuccess: (data, variables, context) => {
84
+ // Invalidate all relevant cache keys
85
+ invalidateCacheKeys(queryClient, cacheKey, entityId, accountId);
86
+
87
+ // Call custom onSuccess if provided
88
+ customOnSuccess?.(data, variables, context);
89
+ },
90
+
91
+ onError: (error, variables, context) => {
92
+ // Call custom onError if provided
93
+ customOnError?.(error, variables, context);
94
+ },
95
+ });
96
+ }
97
+
98
+ /**
99
+ * Invalidate cache keys - marks queries as stale and refetches active ones
100
+ */
101
+ function invalidateCacheKeys(
102
+ queryClient: ReturnType<typeof useQueryClient>,
103
+ cacheKey: string | string[],
104
+ _entityId?: string | null,
105
+ _accountId?: string | null,
106
+ ): void {
107
+ const cacheKeys = Array.isArray(cacheKey) ? cacheKey : [cacheKey];
108
+
109
+ cacheKeys.forEach((key) => {
110
+ // Invalidate all queries that start with this cache key
111
+ // This marks them as stale (ignoring staleTime) and refetches active queries
112
+ queryClient.invalidateQueries({
113
+ queryKey: [key],
114
+ exact: false, // Match all queries starting with this key
115
+ refetchType: "active", // Refetch queries that are currently active
116
+ });
117
+ });
118
+ }
@@ -0,0 +1,130 @@
1
+ import type { ViesCheckRequest, ViesCheckResponse } from "@spaceinvoices/js-sdk";
2
+ import { useQuery } from "@tanstack/react-query";
3
+ import { useMemo } from "react";
4
+ import { useSDK } from "../providers/sdk-provider";
5
+ import { useDebounce } from "./use-debounce";
6
+
7
+ export const VIES_CHECK_CACHE_KEY = "vies-check";
8
+
9
+ /** Debounce delay for VIES checks (ms) */
10
+ const VIES_DEBOUNCE_DELAY = 500;
11
+
12
+ /** Cache time for VIES results - 5 minutes */
13
+ const VIES_STALE_TIME = 5 * 60 * 1000;
14
+
15
+ export interface UseViesCheckParams {
16
+ /** Issuer country name or code */
17
+ issuerCountry?: string | null;
18
+ /** Issuer country code (takes precedence over country name) */
19
+ issuerCountryCode?: string | null;
20
+ /** Whether the issuer is a tax subject (default: true) */
21
+ isTaxSubject?: boolean;
22
+ /** Customer country name or code */
23
+ customerCountry?: string | null;
24
+ /** Customer country code (takes precedence over country name) */
25
+ customerCountryCode?: string | null;
26
+ /** Customer VAT/tax number */
27
+ customerTaxNumber?: string | null;
28
+ /** Whether to enable the query (default: true) */
29
+ enabled?: boolean;
30
+ }
31
+
32
+ export interface UseViesCheckResult {
33
+ /** The VIES check result */
34
+ data: ViesCheckResponse | undefined;
35
+ /** Whether the query is loading */
36
+ isLoading: boolean;
37
+ /** Whether the query is fetching (includes background refetches) */
38
+ isFetching: boolean;
39
+ /** Error if the query failed */
40
+ error: Error | null;
41
+ /** Whether reverse charge should be applied */
42
+ reverseChargeApplies: boolean;
43
+ /** Transaction type determined by VIES check */
44
+ transactionType: ViesCheckResponse["transaction_type"] | undefined;
45
+ /** Warning message from VIES validation */
46
+ warning: string | null;
47
+ /** Whether VIES validation was successful */
48
+ viesValid: boolean | null;
49
+ }
50
+
51
+ /**
52
+ * Hook to check VIES status for a given issuer/customer combination.
53
+ * Uses debouncing to avoid excessive API calls during typing.
54
+ *
55
+ * @example
56
+ * ```tsx
57
+ * const { reverseChargeApplies, transactionType, warning } = useViesCheck({
58
+ * issuerCountryCode: entity.country_code,
59
+ * isTaxSubject: entity.is_tax_subject,
60
+ * customerCountry: customer.country,
61
+ * customerTaxNumber: customer.tax_number,
62
+ * });
63
+ *
64
+ * // Disable taxes when reverse charge applies
65
+ * if (reverseChargeApplies) {
66
+ * // Show reverse charge message and disable tax controls
67
+ * }
68
+ * ```
69
+ */
70
+ export function useViesCheck({
71
+ issuerCountry,
72
+ issuerCountryCode,
73
+ isTaxSubject = true,
74
+ customerCountry,
75
+ customerCountryCode,
76
+ customerTaxNumber,
77
+ enabled = true,
78
+ }: UseViesCheckParams): UseViesCheckResult {
79
+ const { sdk } = useSDK();
80
+
81
+ // Build the request object
82
+ const requestData = useMemo((): ViesCheckRequest | null => {
83
+ // Need at least issuer info to make a check
84
+ if (!issuerCountry && !issuerCountryCode) return null;
85
+
86
+ // Need at least some customer info to make a meaningful check
87
+ if (!customerCountry && !customerCountryCode && !customerTaxNumber) return null;
88
+
89
+ return {
90
+ issuer: {
91
+ country: issuerCountry || undefined,
92
+ country_code: issuerCountryCode || undefined,
93
+ is_tax_subject: isTaxSubject,
94
+ },
95
+ customer: {
96
+ country: customerCountry || undefined,
97
+ country_code: customerCountryCode || undefined,
98
+ tax_number: customerTaxNumber || undefined,
99
+ },
100
+ };
101
+ }, [issuerCountry, issuerCountryCode, isTaxSubject, customerCountry, customerCountryCode, customerTaxNumber]);
102
+
103
+ // Debounce the request data to avoid excessive API calls
104
+ const debouncedRequest = useDebounce(requestData, VIES_DEBOUNCE_DELAY);
105
+
106
+ // Create a stable query key
107
+ const queryKey = useMemo(() => [VIES_CHECK_CACHE_KEY, debouncedRequest], [debouncedRequest]);
108
+
109
+ const query = useQuery({
110
+ queryKey,
111
+ queryFn: async () => {
112
+ if (!debouncedRequest) throw new Error("No request data");
113
+ return sdk.vies.checkVies(debouncedRequest);
114
+ },
115
+ enabled: enabled && !!sdk && !!debouncedRequest,
116
+ staleTime: VIES_STALE_TIME,
117
+ refetchOnWindowFocus: false,
118
+ });
119
+
120
+ return {
121
+ data: query.data,
122
+ isLoading: query.isLoading,
123
+ isFetching: query.isFetching,
124
+ error: query.error,
125
+ reverseChargeApplies: query.data?.reverse_charge_applies ?? false,
126
+ transactionType: query.data?.transaction_type,
127
+ warning: query.data?.warning ?? null,
128
+ viesValid: query.data?.vies_valid ?? null,
129
+ };
130
+ }
package/src/index.css ADDED
@@ -0,0 +1,11 @@
1
+ @import "../styles/globals.css";
2
+
3
+ @layer base {
4
+ :root {
5
+ @apply font-sans;
6
+ }
7
+
8
+ body {
9
+ @apply grid place-items-center min-w-[320px] min-h-screen relative m-0 bg-background text-foreground;
10
+ }
11
+ }
package/src/index.html ADDED
@@ -0,0 +1,13 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <!-- <link rel="icon" type="image/svg+xml" href="./logo.svg" /> -->
7
+ <title>Space Invoices React UI kit</title>
8
+ <script type="module" src="./frontend.tsx" async></script>
9
+ </head>
10
+ <body>
11
+ <div id="root"></div>
12
+ </body>
13
+ </html>
package/src/index.tsx ADDED
@@ -0,0 +1,12 @@
1
+ import { serve } from "bun";
2
+ import index from "./index.html";
3
+
4
+ // can set server to const
5
+ serve({
6
+ routes: {
7
+ // Serve index.html for all unmatched routes.
8
+ "/*": index,
9
+ },
10
+
11
+ development: process.env.NODE_ENV !== "production",
12
+ });
@@ -0,0 +1,4 @@
1
+ export const AUTH_COOKIES = {
2
+ TOKEN: "l.token",
3
+ USER: "l.user",
4
+ } as const;
@@ -0,0 +1,70 @@
1
+ import { ACTIVE_ENTITY_COOKIE } from "@/ui/components/entities/keys";
2
+
3
+ import { AUTH_COOKIES } from "./auth";
4
+ import { getCookie as _getCookie } from "./cookies";
5
+
6
+ type CookieOptions = {
7
+ path?: string;
8
+ expires?: Date;
9
+ maxAge?: number;
10
+ domain?: string;
11
+ secure?: boolean;
12
+ sameSite?: "Strict" | "Lax" | "None";
13
+ };
14
+
15
+ /**
16
+ * Sets a cookie with the given name, value, and options
17
+ */
18
+ export function setCookie(name: string, value: string, options: CookieOptions = {}) {
19
+ if (typeof window === "undefined") {
20
+ console.warn("setCookie called on server");
21
+ return;
22
+ }
23
+
24
+ const { path = "/", expires, maxAge, domain, secure, sameSite = "Lax" } = options;
25
+
26
+ let cookie = `${encodeURIComponent(name)}=${encodeURIComponent(value)}`;
27
+
28
+ cookie += `; path=${path}`;
29
+
30
+ if (expires) cookie += `; expires=${expires.toUTCString()}`;
31
+ if (maxAge) cookie += `; max-age=${maxAge}`;
32
+ if (domain) cookie += `; domain=${domain}`;
33
+ if (secure) cookie += "; secure";
34
+ if (sameSite) cookie += `; samesite=${sameSite}`;
35
+
36
+ // biome-ignore lint/suspicious/noDocumentCookie: required for cookie helper
37
+ document.cookie = cookie;
38
+ }
39
+
40
+ /**
41
+ * Gets a cookie value by name
42
+ */
43
+ export function getCookie(name: string): string | undefined {
44
+ if (typeof window === "undefined") {
45
+ return undefined;
46
+ }
47
+
48
+ return _getCookie(document.cookie, name);
49
+ }
50
+
51
+ /**
52
+ * Removes a cookie by name
53
+ */
54
+ export function deleteCookie(name: string, path = "/") {
55
+ if (typeof window === "undefined") {
56
+ console.warn("deleteCookie called on server");
57
+ return;
58
+ }
59
+
60
+ setCookie(name, "", {
61
+ path,
62
+ expires: new Date(0),
63
+ });
64
+ }
65
+
66
+ export function flushCookies() {
67
+ deleteCookie(AUTH_COOKIES.TOKEN);
68
+ deleteCookie(AUTH_COOKIES.USER);
69
+ deleteCookie(ACTIVE_ENTITY_COOKIE);
70
+ }
@@ -0,0 +1,287 @@
1
+ /**
2
+ * Shared constants for the UI library
3
+ */
4
+
5
+ /**
6
+ * Supported currencies - comprehensive list of world currencies
7
+ * Includes: Major world currencies, G20 currencies, European currencies, and common trading currencies
8
+ * Sorted alphabetically by code (ISO 4217)
9
+ */
10
+ export const CURRENCY_CODES = [
11
+ // Middle East
12
+ { value: "AED", label: "AED - UAE Dirham" },
13
+ // Africa
14
+ { value: "AFN", label: "AFN - Afghan Afghani" },
15
+ // Europe
16
+ { value: "ALL", label: "ALL - Albanian Lek" },
17
+ // Middle East
18
+ { value: "AMD", label: "AMD - Armenian Dram" },
19
+ // Caribbean
20
+ { value: "ANG", label: "ANG - Netherlands Antillean Guilder" },
21
+ // Africa
22
+ { value: "AOA", label: "AOA - Angolan Kwanza" },
23
+ // South America
24
+ { value: "ARS", label: "ARS - Argentine Peso" },
25
+ // Oceania
26
+ { value: "AUD", label: "AUD - Australian Dollar" },
27
+ // Caribbean
28
+ { value: "AWG", label: "AWG - Aruban Florin" },
29
+ // Europe
30
+ { value: "AZN", label: "AZN - Azerbaijani Manat" },
31
+ { value: "BAM", label: "BAM - Bosnia-Herzegovina Mark" },
32
+ // Caribbean
33
+ { value: "BBD", label: "BBD - Barbadian Dollar" },
34
+ // Asia
35
+ { value: "BDT", label: "BDT - Bangladeshi Taka" },
36
+ // Europe
37
+ { value: "BGN", label: "BGN - Bulgarian Lev" },
38
+ // Middle East
39
+ { value: "BHD", label: "BHD - Bahraini Dinar" },
40
+ // Africa
41
+ { value: "BIF", label: "BIF - Burundian Franc" },
42
+ // Caribbean
43
+ { value: "BMD", label: "BMD - Bermudian Dollar" },
44
+ // Asia
45
+ { value: "BND", label: "BND - Brunei Dollar" },
46
+ // South America
47
+ { value: "BOB", label: "BOB - Bolivian Boliviano" },
48
+ { value: "BRL", label: "BRL - Brazilian Real" },
49
+ // Caribbean
50
+ { value: "BSD", label: "BSD - Bahamian Dollar" },
51
+ // Asia
52
+ { value: "BTN", label: "BTN - Bhutanese Ngultrum" },
53
+ // Africa
54
+ { value: "BWP", label: "BWP - Botswanan Pula" },
55
+ // Europe
56
+ { value: "BYN", label: "BYN - Belarusian Ruble" },
57
+ // Central America
58
+ { value: "BZD", label: "BZD - Belize Dollar" },
59
+ // North America
60
+ { value: "CAD", label: "CAD - Canadian Dollar" },
61
+ // Africa
62
+ { value: "CDF", label: "CDF - Congolese Franc" },
63
+ // Europe
64
+ { value: "CHF", label: "CHF - Swiss Franc" },
65
+ // South America
66
+ { value: "CLP", label: "CLP - Chilean Peso" },
67
+ // Asia
68
+ { value: "CNY", label: "CNY - Chinese Yuan" },
69
+ // South America
70
+ { value: "COP", label: "COP - Colombian Peso" },
71
+ // Central America
72
+ { value: "CRC", label: "CRC - Costa Rican Colon" },
73
+ // Caribbean
74
+ { value: "CUP", label: "CUP - Cuban Peso" },
75
+ // Africa
76
+ { value: "CVE", label: "CVE - Cape Verdean Escudo" },
77
+ // Europe
78
+ { value: "CZK", label: "CZK - Czech Koruna" },
79
+ // Africa
80
+ { value: "DJF", label: "DJF - Djiboutian Franc" },
81
+ // Europe
82
+ { value: "DKK", label: "DKK - Danish Krone" },
83
+ // Caribbean
84
+ { value: "DOP", label: "DOP - Dominican Peso" },
85
+ // Africa
86
+ { value: "DZD", label: "DZD - Algerian Dinar" },
87
+ // Africa
88
+ { value: "EGP", label: "EGP - Egyptian Pound" },
89
+ // Africa
90
+ { value: "ERN", label: "ERN - Eritrean Nakfa" },
91
+ // Africa
92
+ { value: "ETB", label: "ETB - Ethiopian Birr" },
93
+ // Europe
94
+ { value: "EUR", label: "EUR - Euro" },
95
+ // Oceania
96
+ { value: "FJD", label: "FJD - Fijian Dollar" },
97
+ // Europe
98
+ { value: "GBP", label: "GBP - British Pound" },
99
+ { value: "GEL", label: "GEL - Georgian Lari" },
100
+ // Africa
101
+ { value: "GHS", label: "GHS - Ghanaian Cedi" },
102
+ // Europe
103
+ { value: "GIP", label: "GIP - Gibraltar Pound" },
104
+ // Africa
105
+ { value: "GMD", label: "GMD - Gambian Dalasi" },
106
+ { value: "GNF", label: "GNF - Guinean Franc" },
107
+ // Central America
108
+ { value: "GTQ", label: "GTQ - Guatemalan Quetzal" },
109
+ // South America
110
+ { value: "GYD", label: "GYD - Guyanese Dollar" },
111
+ // Asia
112
+ { value: "HKD", label: "HKD - Hong Kong Dollar" },
113
+ // Central America
114
+ { value: "HNL", label: "HNL - Honduran Lempira" },
115
+ // Europe
116
+ { value: "HRK", label: "HRK - Croatian Kuna" },
117
+ // Caribbean
118
+ { value: "HTG", label: "HTG - Haitian Gourde" },
119
+ // Europe
120
+ { value: "HUF", label: "HUF - Hungarian Forint" },
121
+ // Asia
122
+ { value: "IDR", label: "IDR - Indonesian Rupiah" },
123
+ { value: "ILS", label: "ILS - Israeli Shekel" },
124
+ { value: "INR", label: "INR - Indian Rupee" },
125
+ // Middle East
126
+ { value: "IQD", label: "IQD - Iraqi Dinar" },
127
+ { value: "IRR", label: "IRR - Iranian Rial" },
128
+ // Europe
129
+ { value: "ISK", label: "ISK - Icelandic Krona" },
130
+ // Caribbean
131
+ { value: "JMD", label: "JMD - Jamaican Dollar" },
132
+ // Middle East
133
+ { value: "JOD", label: "JOD - Jordanian Dinar" },
134
+ // Asia
135
+ { value: "JPY", label: "JPY - Japanese Yen" },
136
+ // Africa
137
+ { value: "KES", label: "KES - Kenyan Shilling" },
138
+ // Asia
139
+ { value: "KGS", label: "KGS - Kyrgystani Som" },
140
+ { value: "KHR", label: "KHR - Cambodian Riel" },
141
+ // Africa
142
+ { value: "KMF", label: "KMF - Comorian Franc" },
143
+ // Asia
144
+ { value: "KRW", label: "KRW - South Korean Won" },
145
+ // Middle East
146
+ { value: "KWD", label: "KWD - Kuwaiti Dinar" },
147
+ // Caribbean
148
+ { value: "KYD", label: "KYD - Cayman Islands Dollar" },
149
+ // Asia
150
+ { value: "KZT", label: "KZT - Kazakhstani Tenge" },
151
+ { value: "LAK", label: "LAK - Laotian Kip" },
152
+ // Middle East
153
+ { value: "LBP", label: "LBP - Lebanese Pound" },
154
+ // Asia
155
+ { value: "LKR", label: "LKR - Sri Lankan Rupee" },
156
+ // Africa
157
+ { value: "LRD", label: "LRD - Liberian Dollar" },
158
+ { value: "LSL", label: "LSL - Lesotho Loti" },
159
+ // Africa
160
+ { value: "LYD", label: "LYD - Libyan Dinar" },
161
+ { value: "MAD", label: "MAD - Moroccan Dirham" },
162
+ // Europe
163
+ { value: "MDL", label: "MDL - Moldovan Leu" },
164
+ // Africa
165
+ { value: "MGA", label: "MGA - Malagasy Ariary" },
166
+ // Europe
167
+ { value: "MKD", label: "MKD - Macedonian Denar" },
168
+ // Asia
169
+ { value: "MMK", label: "MMK - Myanmar Kyat" },
170
+ { value: "MNT", label: "MNT - Mongolian Tugrik" },
171
+ { value: "MOP", label: "MOP - Macanese Pataca" },
172
+ // Africa
173
+ { value: "MRU", label: "MRU - Mauritanian Ouguiya" },
174
+ { value: "MUR", label: "MUR - Mauritian Rupee" },
175
+ // Asia
176
+ { value: "MVR", label: "MVR - Maldivian Rufiyaa" },
177
+ // Africa
178
+ { value: "MWK", label: "MWK - Malawian Kwacha" },
179
+ // North America
180
+ { value: "MXN", label: "MXN - Mexican Peso" },
181
+ // Asia
182
+ { value: "MYR", label: "MYR - Malaysian Ringgit" },
183
+ // Africa
184
+ { value: "MZN", label: "MZN - Mozambican Metical" },
185
+ { value: "NAD", label: "NAD - Namibian Dollar" },
186
+ { value: "NGN", label: "NGN - Nigerian Naira" },
187
+ // Central America
188
+ { value: "NIO", label: "NIO - Nicaraguan Cordoba" },
189
+ // Europe
190
+ { value: "NOK", label: "NOK - Norwegian Krone" },
191
+ // Asia
192
+ { value: "NPR", label: "NPR - Nepalese Rupee" },
193
+ // Oceania
194
+ { value: "NZD", label: "NZD - New Zealand Dollar" },
195
+ // Middle East
196
+ { value: "OMR", label: "OMR - Omani Rial" },
197
+ // Central America
198
+ { value: "PAB", label: "PAB - Panamanian Balboa" },
199
+ // South America
200
+ { value: "PEN", label: "PEN - Peruvian Sol" },
201
+ // Oceania
202
+ { value: "PGK", label: "PGK - Papua New Guinean Kina" },
203
+ // Asia
204
+ { value: "PHP", label: "PHP - Philippine Peso" },
205
+ { value: "PKR", label: "PKR - Pakistani Rupee" },
206
+ // Europe
207
+ { value: "PLN", label: "PLN - Polish Zloty" },
208
+ // South America
209
+ { value: "PYG", label: "PYG - Paraguayan Guarani" },
210
+ // Middle East
211
+ { value: "QAR", label: "QAR - Qatari Rial" },
212
+ // Europe
213
+ { value: "RON", label: "RON - Romanian Leu" },
214
+ { value: "RSD", label: "RSD - Serbian Dinar" },
215
+ { value: "RUB", label: "RUB - Russian Ruble" },
216
+ // Africa
217
+ { value: "RWF", label: "RWF - Rwandan Franc" },
218
+ // Middle East
219
+ { value: "SAR", label: "SAR - Saudi Riyal" },
220
+ // Oceania
221
+ { value: "SBD", label: "SBD - Solomon Islands Dollar" },
222
+ // Africa
223
+ { value: "SCR", label: "SCR - Seychellois Rupee" },
224
+ { value: "SDG", label: "SDG - Sudanese Pound" },
225
+ // Europe
226
+ { value: "SEK", label: "SEK - Swedish Krona" },
227
+ // Asia
228
+ { value: "SGD", label: "SGD - Singapore Dollar" },
229
+ // Africa
230
+ { value: "SLL", label: "SLL - Sierra Leonean Leone" },
231
+ { value: "SOS", label: "SOS - Somali Shilling" },
232
+ // South America
233
+ { value: "SRD", label: "SRD - Surinamese Dollar" },
234
+ // Africa
235
+ { value: "SSP", label: "SSP - South Sudanese Pound" },
236
+ { value: "STN", label: "STN - Sao Tome and Principe Dobra" },
237
+ // Central America
238
+ { value: "SVC", label: "SVC - Salvadoran Colon" },
239
+ // Middle East
240
+ { value: "SYP", label: "SYP - Syrian Pound" },
241
+ // Africa
242
+ { value: "SZL", label: "SZL - Swazi Lilangeni" },
243
+ // Asia
244
+ { value: "THB", label: "THB - Thai Baht" },
245
+ { value: "TJS", label: "TJS - Tajikistani Somoni" },
246
+ { value: "TMT", label: "TMT - Turkmenistani Manat" },
247
+ // Africa
248
+ { value: "TND", label: "TND - Tunisian Dinar" },
249
+ // Oceania
250
+ { value: "TOP", label: "TOP - Tongan Pa'anga" },
251
+ // Europe
252
+ { value: "TRY", label: "TRY - Turkish Lira" },
253
+ // Caribbean
254
+ { value: "TTD", label: "TTD - Trinidad and Tobago Dollar" },
255
+ // Asia
256
+ { value: "TWD", label: "TWD - New Taiwan Dollar" },
257
+ // Africa
258
+ { value: "TZS", label: "TZS - Tanzanian Shilling" },
259
+ // Europe
260
+ { value: "UAH", label: "UAH - Ukrainian Hryvnia" },
261
+ // Africa
262
+ { value: "UGX", label: "UGX - Ugandan Shilling" },
263
+ // North America
264
+ { value: "USD", label: "USD - US Dollar" },
265
+ // South America
266
+ { value: "UYU", label: "UYU - Uruguayan Peso" },
267
+ // Asia
268
+ { value: "UZS", label: "UZS - Uzbekistan Som" },
269
+ // South America
270
+ { value: "VES", label: "VES - Venezuelan Bolivar" },
271
+ // Asia
272
+ { value: "VND", label: "VND - Vietnamese Dong" },
273
+ // Oceania
274
+ { value: "VUV", label: "VUV - Vanuatu Vatu" },
275
+ { value: "WST", label: "WST - Samoan Tala" },
276
+ // Africa
277
+ { value: "XAF", label: "XAF - Central African CFA Franc" },
278
+ { value: "XOF", label: "XOF - West African CFA Franc" },
279
+ // Middle East
280
+ { value: "YER", label: "YER - Yemeni Rial" },
281
+ // Africa
282
+ { value: "ZAR", label: "ZAR - South African Rand" },
283
+ { value: "ZMW", label: "ZMW - Zambian Kwacha" },
284
+ { value: "ZWL", label: "ZWL - Zimbabwean Dollar" },
285
+ ] as const;
286
+
287
+ export type CurrencyCode = (typeof CURRENCY_CODES)[number]["value"];
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Cookie helper functions that work on both client and server
3
+ * provided a cookie string from the server or client headers
4
+ */
5
+
6
+ export function getCookie(cookiesString: string, name: string) {
7
+ const value = `; ${cookiesString}`;
8
+ const parts = value.split(`; ${name}=`);
9
+ if (parts.length === 2) {
10
+ return decodeURIComponent(parts.pop()?.split(";").shift() ?? "");
11
+ }
12
+ return undefined;
13
+ }
14
+
15
+ export function removeCookie(cookiesString: string, cookieName: string): string {
16
+ if (!cookiesString) return "";
17
+
18
+ // Split cookies string into individual cookies
19
+ const cookies = cookiesString
20
+ .split(";")
21
+ .map((cookie) => cookie.trim())
22
+ .filter((cookie) => !cookie.startsWith(`${cookieName}=`));
23
+
24
+ // Join remaining cookies back together
25
+ return cookies.join("; ");
26
+ }
27
+
28
+ export function serializeCookie(
29
+ cookiesString: string,
30
+ name: string,
31
+ value: string,
32
+ options: { path?: string; maxAge?: number } = {},
33
+ ) {
34
+ const cookie = `${name}=${value}; path=${options.path || "/"}; max-age=${options.maxAge || 31536000}`;
35
+ return `${cookiesString}; ${cookie}`;
36
+ }