@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,61 @@
1
+ /**
2
+ * Shared document types for invoices, estimates, credit notes, and advance invoices
3
+ */
4
+
5
+ export type DocumentTypes = "invoice" | "estimate" | "credit_note" | "advance_invoice";
6
+
7
+ export interface DocumentConfig {
8
+ type: DocumentTypes;
9
+ apiEndpoint: string;
10
+ cacheKey: string;
11
+ dateFieldName: "date_due" | "date_valid_till" | null;
12
+ dateFieldLabel: string | null;
13
+ singularName: string;
14
+ pluralName: string;
15
+ }
16
+
17
+ export const DOCUMENT_CONFIGS: Record<DocumentTypes, DocumentConfig> = {
18
+ invoice: {
19
+ type: "invoice",
20
+ apiEndpoint: "invoices",
21
+ cacheKey: "invoices",
22
+ dateFieldName: "date_due",
23
+ dateFieldLabel: "Due Date",
24
+ singularName: "Invoice",
25
+ pluralName: "Invoices",
26
+ },
27
+ estimate: {
28
+ type: "estimate",
29
+ apiEndpoint: "estimates",
30
+ cacheKey: "estimates",
31
+ dateFieldName: "date_valid_till",
32
+ dateFieldLabel: "Valid Until",
33
+ singularName: "Estimate",
34
+ pluralName: "Estimates",
35
+ },
36
+ credit_note: {
37
+ type: "credit_note",
38
+ apiEndpoint: "credit-notes",
39
+ cacheKey: "credit-notes",
40
+ dateFieldName: null, // Credit notes don't have a due date
41
+ dateFieldLabel: null,
42
+ singularName: "Credit Note",
43
+ pluralName: "Credit Notes",
44
+ },
45
+ advance_invoice: {
46
+ type: "advance_invoice",
47
+ apiEndpoint: "advance-invoices",
48
+ cacheKey: "advance-invoices",
49
+ dateFieldName: "date_due",
50
+ dateFieldLabel: "Due Date",
51
+ singularName: "Advance Invoice",
52
+ pluralName: "Advance Invoices",
53
+ },
54
+ } as const;
55
+
56
+ /**
57
+ * Get document configuration by type
58
+ */
59
+ export function getDocumentConfig(type: DocumentTypes): DocumentConfig {
60
+ return DOCUMENT_CONFIGS[type];
61
+ }
@@ -0,0 +1,328 @@
1
+ import type { AdvanceInvoice, CreditNote, Estimate, Invoice } from "@spaceinvoices/js-sdk";
2
+ import {
3
+ Check,
4
+ CheckCircle,
5
+ ChevronDown,
6
+ Copy,
7
+ Download,
8
+ FileCode2,
9
+ Link2Off,
10
+ Loader2,
11
+ Mail,
12
+ Pencil,
13
+ Plus,
14
+ Share2,
15
+ Trash2,
16
+ } from "lucide-react";
17
+ import { useState } from "react";
18
+ import { Button } from "@/ui/components/ui/button";
19
+ import {
20
+ DropdownMenu,
21
+ DropdownMenuContent,
22
+ DropdownMenuItem,
23
+ DropdownMenuTrigger,
24
+ } from "@/ui/components/ui/dropdown-menu";
25
+ import { Tooltip, TooltipContent, TooltipTrigger } from "@/ui/components/ui/tooltip";
26
+ import { type DocumentType, getAllowedDuplicateTargets } from "@/ui/hooks/use-duplicate-document";
27
+ import type { ComponentTranslationProps } from "@/ui/lib/translation";
28
+ import { createTranslation } from "@/ui/lib/translation";
29
+ import type { Entity } from "@/ui/providers/entities-context";
30
+ import de from "./locales/de";
31
+ import sl from "./locales/sl";
32
+ import { useDocumentDownload } from "./use-document-download";
33
+
34
+ const translations = { de, sl } as const;
35
+
36
+ type Document = Invoice | Estimate | CreditNote | AdvanceInvoice;
37
+
38
+ const PDF_LOCALES = [
39
+ { code: "en-US", label: "English" },
40
+ { code: "de-DE", label: "Deutsch" },
41
+ { code: "es-ES", label: "Español" },
42
+ { code: "fr-FR", label: "Français" },
43
+ { code: "it-IT", label: "Italiano" },
44
+ { code: "sl-SI", label: "Slovenščina" },
45
+ ] as const;
46
+
47
+ interface DocumentActionsBarProps extends ComponentTranslationProps {
48
+ document: Document;
49
+ documentType: DocumentType;
50
+ entity: Entity;
51
+ currentLocale: string;
52
+ onAddPayment?: () => void;
53
+ onSendEmail?: () => void;
54
+ onDownloadStart?: () => void;
55
+ onDownloadSuccess?: (fileName: string) => void;
56
+ onDownloadError?: (error: string) => void;
57
+ onShareLinkCopied?: () => void;
58
+ /** Called when user wants to share the document (generate shareable link) */
59
+ onShare?: () => Promise<void>;
60
+ /** Called when user wants to unshare the document (remove shareable link) */
61
+ onUnshare?: () => Promise<void>;
62
+ /** Whether sharing is in progress */
63
+ isSharing?: boolean;
64
+ /** Whether unsharing is in progress */
65
+ isUnsharing?: boolean;
66
+ /** Called when user wants to duplicate/convert document */
67
+ onDuplicate?: (targetType: DocumentType) => void;
68
+ /** Called when user wants to edit the document */
69
+ onEdit?: () => void;
70
+ /** Whether the document is editable (not voided, not FURS fiscalized) */
71
+ isEditable?: boolean;
72
+ /** Called when user wants to finalize a draft document */
73
+ onFinalize?: () => void;
74
+ /** Whether finalization is in progress */
75
+ isFinalizing?: boolean;
76
+ /** Called when user wants to delete a draft document */
77
+ onDeleteDraft?: () => void;
78
+ /** Whether draft deletion is in progress */
79
+ isDeletingDraft?: boolean;
80
+ }
81
+
82
+ function getApiLocale(uiLanguage: string): string {
83
+ const localeMap: Record<string, string> = {
84
+ en: "en-US",
85
+ sl: "sl-SI",
86
+ de: "de-DE",
87
+ es: "es-ES",
88
+ fr: "fr-FR",
89
+ it: "it-IT",
90
+ };
91
+ return localeMap[uiLanguage] || "en-US";
92
+ }
93
+
94
+ export function DocumentActionsBar({
95
+ document,
96
+ documentType,
97
+ entity,
98
+ currentLocale,
99
+ onAddPayment,
100
+ onSendEmail,
101
+ onDownloadStart,
102
+ onDownloadSuccess,
103
+ onDownloadError,
104
+ onShareLinkCopied,
105
+ onShare,
106
+ onUnshare,
107
+ isSharing,
108
+ isUnsharing,
109
+ onDuplicate,
110
+ onEdit,
111
+ isEditable,
112
+ onFinalize,
113
+ isFinalizing,
114
+ onDeleteDraft,
115
+ isDeletingDraft,
116
+ ...i18nProps
117
+ }: DocumentActionsBarProps) {
118
+ const t = createTranslation({ translations, locale: currentLocale, ...i18nProps });
119
+ const [linkCopied, setLinkCopied] = useState(false);
120
+
121
+ const { isDownloadingPdf, isDownloadingEslog, downloadPdf, downloadEslog } = useDocumentDownload({
122
+ onDownloadStart,
123
+ onDownloadSuccess,
124
+ onDownloadError,
125
+ });
126
+
127
+ const supportsPayments =
128
+ documentType === "invoice" || documentType === "advance_invoice" || documentType === "credit_note";
129
+
130
+ const eslogFeatureAvailable = entity.country_rules?.features?.includes("eslog") ?? false;
131
+ const eslogValid = (document as Invoice).eslog?.validation_status === "valid";
132
+ const showEslogDownload = eslogFeatureAvailable && eslogValid;
133
+
134
+ const shareableId = (document as Invoice).shareable_id;
135
+ const shareUrl = shareableId ? `${window.location.origin}/public/invoices/${shareableId}` : null;
136
+
137
+ const handleDownloadPdf = (locale: string) => downloadPdf(document, documentType, locale);
138
+ const handleDownloadEslog = () => downloadEslog(document, documentType);
139
+
140
+ const handleCopyShareLink = async () => {
141
+ if (!shareUrl) return;
142
+ try {
143
+ await navigator.clipboard.writeText(shareUrl);
144
+ setLinkCopied(true);
145
+ onShareLinkCopied?.();
146
+ setTimeout(() => setLinkCopied(false), 2000);
147
+ } catch (error) {
148
+ console.error("Failed to copy link:", error);
149
+ }
150
+ };
151
+
152
+ const apiLocale = getApiLocale(currentLocale);
153
+ const isDraft = (document as any).is_draft === true;
154
+
155
+ return (
156
+ <div className="flex flex-wrap items-center gap-2">
157
+ {/* PDF Download */}
158
+ <div className="flex">
159
+ <Button
160
+ variant="outline"
161
+ size="sm"
162
+ disabled={isDownloadingPdf}
163
+ onClick={() => handleDownloadPdf(apiLocale)}
164
+ className="cursor-pointer rounded-r-none"
165
+ >
166
+ {isDownloadingPdf ? <Loader2 className="mr-2 h-4 w-4 animate-spin" /> : <Download className="mr-2 h-4 w-4" />}
167
+ {t("PDF")}
168
+ </Button>
169
+ <DropdownMenu>
170
+ <DropdownMenuTrigger asChild>
171
+ <Button
172
+ variant="outline"
173
+ size="sm"
174
+ disabled={isDownloadingPdf}
175
+ className="cursor-pointer rounded-l-none border-l-0 px-2"
176
+ >
177
+ <ChevronDown className="h-4 w-4" />
178
+ </Button>
179
+ </DropdownMenuTrigger>
180
+ <DropdownMenuContent align="end">
181
+ {PDF_LOCALES.map((locale) => (
182
+ <DropdownMenuItem
183
+ key={locale.code}
184
+ onClick={() => handleDownloadPdf(locale.code)}
185
+ className="cursor-pointer"
186
+ >
187
+ {locale.label}
188
+ </DropdownMenuItem>
189
+ ))}
190
+ </DropdownMenuContent>
191
+ </DropdownMenu>
192
+ </div>
193
+
194
+ {/* e-SLOG Download */}
195
+ {showEslogDownload && (
196
+ <Button
197
+ variant="outline"
198
+ size="sm"
199
+ disabled={isDownloadingEslog}
200
+ onClick={handleDownloadEslog}
201
+ className="cursor-pointer"
202
+ >
203
+ {isDownloadingEslog ? (
204
+ <Loader2 className="mr-2 h-4 w-4 animate-spin" />
205
+ ) : (
206
+ <FileCode2 className="mr-2 h-4 w-4" />
207
+ )}
208
+ e-SLOG
209
+ </Button>
210
+ )}
211
+
212
+ {/* Send Email */}
213
+ <Button variant="outline" size="sm" onClick={onSendEmail} className="cursor-pointer">
214
+ <Mail className="mr-2 h-4 w-4" />
215
+ {t("Send")}
216
+ </Button>
217
+
218
+ {/* Add Payment */}
219
+ {supportsPayments && (
220
+ <Button variant="outline" size="sm" onClick={onAddPayment} className="cursor-pointer">
221
+ <Plus className="mr-2 h-4 w-4" />
222
+ {t("Payment")}
223
+ </Button>
224
+ )}
225
+
226
+ {/* Edit */}
227
+ {onEdit && isEditable && (
228
+ <Button variant="outline" size="sm" onClick={onEdit} className="cursor-pointer">
229
+ <Pencil className="mr-2 h-4 w-4" />
230
+ {t("Edit")}
231
+ </Button>
232
+ )}
233
+
234
+ {/* Share Link */}
235
+ {shareUrl ? (
236
+ <div className="flex">
237
+ <Tooltip>
238
+ <TooltipTrigger asChild>
239
+ <Button
240
+ variant="outline"
241
+ size="sm"
242
+ onClick={handleCopyShareLink}
243
+ className="cursor-pointer rounded-r-none"
244
+ >
245
+ {linkCopied ? <Check className="mr-2 h-4 w-4 text-green-600" /> : <Share2 className="mr-2 h-4 w-4" />}
246
+ {linkCopied ? t("Copied") : t("Share")}
247
+ </Button>
248
+ </TooltipTrigger>
249
+ <TooltipContent>
250
+ <p>{t("Copy shareable link")}</p>
251
+ </TooltipContent>
252
+ </Tooltip>
253
+ <DropdownMenu>
254
+ <DropdownMenuTrigger asChild>
255
+ <Button variant="outline" size="sm" className="cursor-pointer rounded-l-none border-l-0 px-2">
256
+ <ChevronDown className="h-4 w-4" />
257
+ </Button>
258
+ </DropdownMenuTrigger>
259
+ <DropdownMenuContent align="end">
260
+ <DropdownMenuItem onClick={handleCopyShareLink} className="cursor-pointer">
261
+ <Share2 className="mr-2 h-4 w-4" />
262
+ {t("Copy shareable link")}
263
+ </DropdownMenuItem>
264
+ <DropdownMenuItem
265
+ onClick={onUnshare}
266
+ disabled={isUnsharing}
267
+ className="hover:!bg-destructive hover:!text-destructive-foreground focus:!bg-destructive focus:!text-destructive-foreground cursor-pointer text-destructive"
268
+ >
269
+ {isUnsharing ? (
270
+ <Loader2 className="mr-2 h-4 w-4 animate-spin" />
271
+ ) : (
272
+ <Link2Off className="mr-2 h-4 w-4" />
273
+ )}
274
+ {t("Unshare")}
275
+ </DropdownMenuItem>
276
+ </DropdownMenuContent>
277
+ </DropdownMenu>
278
+ </div>
279
+ ) : onShare ? (
280
+ <Button variant="outline" size="sm" onClick={onShare} disabled={isSharing} className="cursor-pointer">
281
+ {isSharing ? <Loader2 className="mr-2 h-4 w-4 animate-spin" /> : <Share2 className="mr-2 h-4 w-4" />}
282
+ {t("Share")}
283
+ </Button>
284
+ ) : null}
285
+
286
+ {/* Duplicate/Convert */}
287
+ {onDuplicate && (
288
+ <DropdownMenu>
289
+ <DropdownMenuTrigger asChild>
290
+ <Button variant="outline" size="sm" className="cursor-pointer">
291
+ <Copy className="mr-2 h-4 w-4" />
292
+ {t("Duplicate")}
293
+ <ChevronDown className="ml-1 h-4 w-4" />
294
+ </Button>
295
+ </DropdownMenuTrigger>
296
+ <DropdownMenuContent align="end">
297
+ {getAllowedDuplicateTargets(documentType).map((targetType) => (
298
+ <DropdownMenuItem key={targetType} onClick={() => onDuplicate(targetType)} className="cursor-pointer">
299
+ {targetType === documentType ? t(`Duplicate ${documentType}`) : t(`Create ${targetType}`)}
300
+ </DropdownMenuItem>
301
+ ))}
302
+ </DropdownMenuContent>
303
+ </DropdownMenu>
304
+ )}
305
+
306
+ {/* Draft Actions */}
307
+ {isDraft && onFinalize && (
308
+ <Button variant="default" size="sm" onClick={onFinalize} disabled={isFinalizing} className="cursor-pointer">
309
+ {isFinalizing ? <Loader2 className="mr-2 h-4 w-4 animate-spin" /> : <CheckCircle className="mr-2 h-4 w-4" />}
310
+ {t("Finalize")}
311
+ </Button>
312
+ )}
313
+
314
+ {isDraft && onDeleteDraft && (
315
+ <Button
316
+ variant="destructive"
317
+ size="sm"
318
+ onClick={onDeleteDraft}
319
+ disabled={isDeletingDraft}
320
+ className="cursor-pointer"
321
+ >
322
+ {isDeletingDraft ? <Loader2 className="mr-2 h-4 w-4 animate-spin" /> : <Trash2 className="mr-2 h-4 w-4" />}
323
+ {t("Delete Draft")}
324
+ </Button>
325
+ )}
326
+ </div>
327
+ );
328
+ }
@@ -0,0 +1,179 @@
1
+ import type { AdvanceInvoice, CreditNote, Estimate, Invoice } from "@spaceinvoices/js-sdk";
2
+ import { Badge } from "@/ui/components/ui/badge";
3
+ import { Card, CardContent, CardHeader, CardTitle } from "@/ui/components/ui/card";
4
+ import { Separator } from "@/ui/components/ui/separator";
5
+ import type { ComponentTranslationProps } from "@/ui/lib/translation";
6
+ import { createTranslation } from "@/ui/lib/translation";
7
+ import de from "./locales/de";
8
+ import sl from "./locales/sl";
9
+
10
+ const translations = { de, sl } as const;
11
+
12
+ // Document type union
13
+ type Document = Invoice | Estimate | CreditNote | AdvanceInvoice;
14
+ type DocumentType = "invoice" | "estimate" | "credit_note" | "advance_invoice";
15
+
16
+ interface DocumentDetailsCardProps extends ComponentTranslationProps {
17
+ document: Document;
18
+ documentType: DocumentType;
19
+ /** Locale for date formatting */
20
+ locale?: string;
21
+ }
22
+
23
+ /**
24
+ * Format currency value
25
+ */
26
+ function formatCurrency(amount: number, currencyCode: string, locale: string): string {
27
+ return new Intl.NumberFormat(locale, {
28
+ style: "currency",
29
+ currency: currencyCode,
30
+ }).format(amount);
31
+ }
32
+
33
+ /**
34
+ * Format date
35
+ */
36
+ function formatDate(date: Date | string | null | undefined, locale: string): string {
37
+ if (!date) return "-";
38
+ const d = typeof date === "string" ? new Date(date) : date;
39
+ return new Intl.DateTimeFormat(locale, {
40
+ year: "numeric",
41
+ month: "short",
42
+ day: "numeric",
43
+ }).format(d);
44
+ }
45
+
46
+ /**
47
+ * Get payment status for invoice/advance invoice
48
+ */
49
+ function getPaymentStatus(
50
+ document: Invoice | AdvanceInvoice,
51
+ t: (key: string) => string,
52
+ ): { label: string; variant: "default" | "secondary" | "destructive" | "outline" } {
53
+ // Check voided_at - ensure it's a valid date, not just truthy
54
+ if (document.voided_at && new Date(document.voided_at).getTime() > 0) {
55
+ return { label: t("Voided"), variant: "secondary" };
56
+ }
57
+ if (document.paid_in_full) {
58
+ return { label: t("Paid in full"), variant: "default" };
59
+ }
60
+ if (document.total_paid > 0) {
61
+ return { label: t("Partially paid"), variant: "outline" };
62
+ }
63
+ return { label: t("Unpaid"), variant: "destructive" };
64
+ }
65
+
66
+ /**
67
+ * Document Details Card Component
68
+ *
69
+ * Displays document metadata including:
70
+ * - Document number and dates
71
+ * - Customer information
72
+ * - Totals breakdown
73
+ * - Payment status (for invoices/advance invoices)
74
+ */
75
+ export function DocumentDetailsCard({ document, documentType, locale = "en", ...i18nProps }: DocumentDetailsCardProps) {
76
+ const t = createTranslation({ translations, locale, ...i18nProps });
77
+
78
+ const currencyCode = document.currency_code;
79
+ const fmt = (amount: number) => formatCurrency(amount, currencyCode, locale);
80
+ const fmtDate = (date: Date | string | null | undefined) => formatDate(date, locale);
81
+
82
+ // Type guards for document-specific fields
83
+ const isInvoiceOrAdvance = documentType === "invoice" || documentType === "advance_invoice";
84
+ const isEstimate = documentType === "estimate";
85
+ const invoiceDoc = document as Invoice | AdvanceInvoice;
86
+ const estimateDoc = document as Estimate;
87
+
88
+ // Get customer name
89
+ const customerName = document.customer?.name || "-";
90
+
91
+ // Calculate tax total
92
+ const taxTotal = document.total_with_tax - document.total;
93
+
94
+ return (
95
+ <Card>
96
+ <CardHeader className="pb-3">
97
+ <CardTitle className="flex items-center justify-between text-lg">
98
+ {t("Details")}
99
+ {isInvoiceOrAdvance && (
100
+ <Badge variant={getPaymentStatus(invoiceDoc, t).variant}>{getPaymentStatus(invoiceDoc, t).label}</Badge>
101
+ )}
102
+ </CardTitle>
103
+ </CardHeader>
104
+ <CardContent className="space-y-4">
105
+ {/* Document info */}
106
+ <div className="grid grid-cols-2 gap-x-4 gap-y-2 text-sm">
107
+ <div className="text-muted-foreground">{t("Number")}</div>
108
+ <div className="font-medium">{document.number}</div>
109
+
110
+ <div className="text-muted-foreground">{t("Date")}</div>
111
+ <div>{fmtDate(document.date)}</div>
112
+
113
+ {isInvoiceOrAdvance && (
114
+ <>
115
+ <div className="text-muted-foreground">{t("Due date")}</div>
116
+ <div>{fmtDate(invoiceDoc.date_due)}</div>
117
+ </>
118
+ )}
119
+
120
+ {isInvoiceOrAdvance && (invoiceDoc as any).date_service && (
121
+ <>
122
+ <div className="text-muted-foreground">
123
+ {(invoiceDoc as any).date_service_to ? t("Service period") : t("Service date")}
124
+ </div>
125
+ <div>
126
+ {(invoiceDoc as any).date_service_to
127
+ ? `${fmtDate((invoiceDoc as any).date_service)} - ${fmtDate((invoiceDoc as any).date_service_to)}`
128
+ : fmtDate((invoiceDoc as any).date_service)}
129
+ </div>
130
+ </>
131
+ )}
132
+
133
+ {isEstimate && estimateDoc.date_valid_till && (
134
+ <>
135
+ <div className="text-muted-foreground">{t("Valid until")}</div>
136
+ <div>{fmtDate(estimateDoc.date_valid_till)}</div>
137
+ </>
138
+ )}
139
+
140
+ <div className="text-muted-foreground">{t("Customer")}</div>
141
+ <div>{customerName}</div>
142
+ </div>
143
+
144
+ <Separator />
145
+
146
+ {/* Totals */}
147
+ <div className="space-y-2 text-sm">
148
+ <div className="flex justify-between">
149
+ <span className="text-muted-foreground">{t("Subtotal")}</span>
150
+ <span>{fmt(document.total)}</span>
151
+ </div>
152
+ <div className="flex justify-between">
153
+ <span className="text-muted-foreground">{t("Tax")}</span>
154
+ <span>{fmt(taxTotal)}</span>
155
+ </div>
156
+ <div className="flex justify-between font-semibold">
157
+ <span>{t("Total")}</span>
158
+ <span>{fmt(document.total_with_tax)}</span>
159
+ </div>
160
+
161
+ {/* Payment info for invoices/advance invoices */}
162
+ {isInvoiceOrAdvance && invoiceDoc.total_paid > 0 && (
163
+ <>
164
+ <Separator />
165
+ <div className="flex justify-between text-green-600">
166
+ <span>{t("Paid")}</span>
167
+ <span>-{fmt(invoiceDoc.total_paid)}</span>
168
+ </div>
169
+ <div className="flex justify-between font-semibold">
170
+ <span>{t("Due")}</span>
171
+ <span>{fmt(invoiceDoc.total_due)}</span>
172
+ </div>
173
+ </>
174
+ )}
175
+ </div>
176
+ </CardContent>
177
+ </Card>
178
+ );
179
+ }