@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,501 @@
1
+ import { zodResolver } from "@hookform/resolvers/zod";
2
+ import type { Entity } from "@spaceinvoices/js-sdk";
3
+ import { Sparkles } from "lucide-react";
4
+ import type { ReactNode } from "react";
5
+ import { useRef } from "react";
6
+ import { useForm } from "react-hook-form";
7
+ import { z } from "zod";
8
+ import { SmartCodeInsertButton } from "@/ui/components/documents/create/smart-code-insert-button";
9
+ import {
10
+ Form,
11
+ FormControl,
12
+ FormDescription,
13
+ FormField,
14
+ FormItem,
15
+ FormLabel,
16
+ FormMessage,
17
+ } from "@/ui/components/ui/form";
18
+ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/ui/components/ui/select";
19
+ import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/ui/components/ui/tabs";
20
+ import { CURRENCY_CODES } from "@/ui/lib/constants";
21
+ import type { ComponentTranslationProps } from "@/ui/lib/translation";
22
+ import { createTranslation } from "@/ui/lib/translation";
23
+ import { useFormFooterRegistration } from "@/ui/providers/form-footer-context";
24
+ import { useUpdateEntity } from "../entities.hooks";
25
+ import { InputWithPreview } from "../entity-settings-form/input-with-preview";
26
+ import de from "../entity-settings-form/locales/de";
27
+ import sl from "../entity-settings-form/locales/sl";
28
+
29
+ const translations = { sl, de } as const;
30
+
31
+ const SUPPORTED_LOCALES = [
32
+ { value: "en-US", label: "English (US)" },
33
+ { value: "de-DE", label: "Deutsch (DE)" },
34
+ { value: "it-IT", label: "Italiano (IT)" },
35
+ { value: "fr-FR", label: "Français (FR)" },
36
+ { value: "es-ES", label: "Español (ES)" },
37
+ { value: "sl-SI", label: "Slovenščina (SI)" },
38
+ ] as const;
39
+
40
+ const defaultsSettingsSchema = z.object({
41
+ currency_code: z.union([z.string(), z.null()]).optional(),
42
+ locale: z.union([z.string(), z.null()]).optional(),
43
+ // Invoice defaults
44
+ default_invoice_note: z.union([z.string(), z.null()]).optional(),
45
+ default_invoice_payment_terms: z.union([z.string(), z.null()]).optional(),
46
+ // Estimate defaults
47
+ default_estimate_note: z.union([z.string(), z.null()]).optional(),
48
+ default_estimate_payment_terms: z.union([z.string(), z.null()]).optional(),
49
+ // Credit note defaults
50
+ default_credit_note_note: z.union([z.string(), z.null()]).optional(),
51
+ default_credit_note_payment_terms: z.union([z.string(), z.null()]).optional(),
52
+ // Shared
53
+ document_footer: z.union([z.string(), z.null()]).optional(),
54
+ });
55
+
56
+ type DefaultsSettingsSchema = z.infer<typeof defaultsSettingsSchema>;
57
+
58
+ type SectionType = "localization" | "documents" | "footer";
59
+
60
+ export type DefaultsSettingsFormProps = {
61
+ entity: Entity;
62
+ onSuccess?: (data: Entity) => void;
63
+ onError?: (error: unknown) => void;
64
+ /** Optional render prop to wrap each section with help content */
65
+ renderSection?: (section: SectionType, content: ReactNode) => ReactNode;
66
+ } & ComponentTranslationProps;
67
+
68
+ export function DefaultsSettingsForm({
69
+ entity,
70
+ t: translateProp,
71
+ namespace,
72
+ locale,
73
+ onSuccess,
74
+ onError,
75
+ renderSection,
76
+ }: DefaultsSettingsFormProps) {
77
+ const t = createTranslation({ t: translateProp, namespace, locale, translations });
78
+
79
+ const currentSettings = (entity.settings as any) || {};
80
+
81
+ // Refs for smart code insert buttons - Invoice
82
+ const invoiceNoteRef = useRef<HTMLTextAreaElement>(null);
83
+ const invoicePaymentTermsRef = useRef<HTMLTextAreaElement>(null);
84
+ // Refs for smart code insert buttons - Estimate
85
+ const estimateNoteRef = useRef<HTMLTextAreaElement>(null);
86
+ const estimatePaymentTermsRef = useRef<HTMLTextAreaElement>(null);
87
+ // Refs for smart code insert buttons - Credit Note
88
+ const creditNoteNoteRef = useRef<HTMLTextAreaElement>(null);
89
+ const creditNotePaymentTermsRef = useRef<HTMLTextAreaElement>(null);
90
+ // Ref for document footer (shared)
91
+ const documentFooterRef = useRef<HTMLTextAreaElement>(null);
92
+
93
+ const form = useForm<DefaultsSettingsSchema>({
94
+ resolver: zodResolver(defaultsSettingsSchema),
95
+ defaultValues: {
96
+ currency_code: entity.currency_code || null,
97
+ locale: entity.locale || "en-US",
98
+ // Invoice
99
+ default_invoice_note: currentSettings.default_invoice_note || null,
100
+ default_invoice_payment_terms: currentSettings.default_invoice_payment_terms || null,
101
+ // Estimate
102
+ default_estimate_note: currentSettings.default_estimate_note || null,
103
+ default_estimate_payment_terms: currentSettings.default_estimate_payment_terms || null,
104
+ // Credit Note
105
+ default_credit_note_note: currentSettings.default_credit_note_note || null,
106
+ default_credit_note_payment_terms: currentSettings.default_credit_note_payment_terms || null,
107
+ // Shared
108
+ document_footer: currentSettings.document_footer || null,
109
+ },
110
+ });
111
+
112
+ const { mutate: updateEntity, isPending } = useUpdateEntity({
113
+ entityId: entity.id,
114
+ onSuccess: (data) => {
115
+ form.reset(form.getValues());
116
+ onSuccess?.(data);
117
+ },
118
+ onError,
119
+ });
120
+
121
+ useFormFooterRegistration({
122
+ formId: "defaults-settings-form",
123
+ isPending,
124
+ isDirty: form.formState.isDirty,
125
+ label: t("Save Settings"),
126
+ });
127
+
128
+ const onSubmit = (values: DefaultsSettingsSchema) => {
129
+ const updatePayload: any = {
130
+ settings: {
131
+ ...currentSettings,
132
+ // Invoice
133
+ default_invoice_note: values.default_invoice_note || null,
134
+ default_invoice_payment_terms: values.default_invoice_payment_terms || null,
135
+ // Estimate
136
+ default_estimate_note: values.default_estimate_note || null,
137
+ default_estimate_payment_terms: values.default_estimate_payment_terms || null,
138
+ // Credit Note
139
+ default_credit_note_note: values.default_credit_note_note || null,
140
+ default_credit_note_payment_terms: values.default_credit_note_payment_terms || null,
141
+ // Shared
142
+ document_footer: values.document_footer || null,
143
+ },
144
+ };
145
+
146
+ if (values.currency_code && values.currency_code !== entity.currency_code) {
147
+ updatePayload.currency_code = values.currency_code;
148
+ }
149
+ if (values.locale && values.locale !== entity.locale) {
150
+ updatePayload.locale = values.locale;
151
+ }
152
+
153
+ updateEntity({ id: entity.id, data: updatePayload });
154
+ };
155
+
156
+ // Helper to wrap section content with render prop if provided
157
+ const wrapSection = (section: SectionType, content: ReactNode) => {
158
+ return renderSection ? renderSection(section, content) : content;
159
+ };
160
+
161
+ // Localization section content
162
+ const localizationContent = (
163
+ <div className="grid gap-6 md:grid-cols-2">
164
+ <FormField
165
+ control={form.control}
166
+ name="currency_code"
167
+ render={({ field }) => (
168
+ <FormItem>
169
+ <FormLabel className="font-medium text-sm">{t("Currency")}</FormLabel>
170
+ <Select onValueChange={field.onChange} value={field.value || ""}>
171
+ <FormControl>
172
+ <SelectTrigger className="h-10">
173
+ <SelectValue placeholder={t("Select currency")} />
174
+ </SelectTrigger>
175
+ </FormControl>
176
+ <SelectContent>
177
+ {CURRENCY_CODES.map((currency) => (
178
+ <SelectItem key={currency.value} value={currency.value}>
179
+ {currency.label}
180
+ </SelectItem>
181
+ ))}
182
+ </SelectContent>
183
+ </Select>
184
+ <FormMessage />
185
+ </FormItem>
186
+ )}
187
+ />
188
+
189
+ <FormField
190
+ control={form.control}
191
+ name="locale"
192
+ render={({ field }) => (
193
+ <FormItem>
194
+ <FormLabel className="font-medium text-sm">{t("Locale")}</FormLabel>
195
+ <Select onValueChange={field.onChange} value={field.value || ""}>
196
+ <FormControl>
197
+ <SelectTrigger className="h-10">
198
+ <SelectValue placeholder={t("Select locale")} />
199
+ </SelectTrigger>
200
+ </FormControl>
201
+ <SelectContent>
202
+ {SUPPORTED_LOCALES.map((loc) => (
203
+ <SelectItem key={loc.value} value={loc.value}>
204
+ {loc.label}
205
+ </SelectItem>
206
+ ))}
207
+ </SelectContent>
208
+ </Select>
209
+ <FormMessage />
210
+ </FormItem>
211
+ )}
212
+ />
213
+ </div>
214
+ );
215
+
216
+ // Documents section content (tabs)
217
+ const documentsContent = (
218
+ <div className="border-t pt-6">
219
+ <div className="mb-4 flex items-center gap-2">
220
+ <Sparkles className="h-4 w-4 text-muted-foreground" />
221
+ <p className="font-medium text-muted-foreground text-xs">{t("Document Defaults")}</p>
222
+ </div>
223
+
224
+ <Tabs defaultValue="invoice" className="w-full">
225
+ <TabsList className="w-full">
226
+ <TabsTrigger value="invoice" className="cursor-pointer">
227
+ {t("Invoice")}
228
+ </TabsTrigger>
229
+ <TabsTrigger value="estimate" className="cursor-pointer">
230
+ {t("Estimate")}
231
+ </TabsTrigger>
232
+ <TabsTrigger value="credit_note" className="cursor-pointer">
233
+ {t("Credit Note")}
234
+ </TabsTrigger>
235
+ </TabsList>
236
+
237
+ {/* Invoice Tab */}
238
+ <TabsContent value="invoice" className="mt-4 space-y-4">
239
+ <FormField
240
+ control={form.control}
241
+ name="default_invoice_note"
242
+ render={({ field }) => (
243
+ <FormItem>
244
+ <div className="flex items-center justify-between">
245
+ <FormLabel className="font-medium text-sm">{t("Default Note")}</FormLabel>
246
+ <SmartCodeInsertButton
247
+ textareaRef={invoiceNoteRef}
248
+ value={field.value || ""}
249
+ onInsert={(newValue) => field.onChange(newValue)}
250
+ t={t}
251
+ />
252
+ </div>
253
+ <FormControl>
254
+ <InputWithPreview
255
+ ref={invoiceNoteRef}
256
+ value={field.value || ""}
257
+ onChange={field.onChange}
258
+ placeholder={t("Payment due by {document_due_date}. Please reference invoice {document_number}.")}
259
+ entity={entity}
260
+ multiline
261
+ rows={3}
262
+ className="resize-y"
263
+ />
264
+ </FormControl>
265
+ <FormDescription className="text-xs">
266
+ {t("This note will be pre-filled when creating new invoices")}
267
+ </FormDescription>
268
+ <FormMessage />
269
+ </FormItem>
270
+ )}
271
+ />
272
+
273
+ <FormField
274
+ control={form.control}
275
+ name="default_invoice_payment_terms"
276
+ render={({ field }) => (
277
+ <FormItem>
278
+ <div className="flex items-center justify-between">
279
+ <FormLabel className="font-medium text-sm">{t("Default Payment Terms")}</FormLabel>
280
+ <SmartCodeInsertButton
281
+ textareaRef={invoicePaymentTermsRef}
282
+ value={field.value || ""}
283
+ onInsert={(newValue) => field.onChange(newValue)}
284
+ t={t}
285
+ />
286
+ </div>
287
+ <FormControl>
288
+ <InputWithPreview
289
+ ref={invoicePaymentTermsRef}
290
+ value={field.value || ""}
291
+ onChange={field.onChange}
292
+ placeholder={t("Net 30 days. Payment due by {document_due_date}.")}
293
+ entity={entity}
294
+ multiline
295
+ rows={3}
296
+ className="resize-y"
297
+ />
298
+ </FormControl>
299
+ <FormDescription className="text-xs">
300
+ {t("Payment terms pre-filled when creating new invoices")}
301
+ </FormDescription>
302
+ <FormMessage />
303
+ </FormItem>
304
+ )}
305
+ />
306
+ </TabsContent>
307
+
308
+ {/* Estimate Tab */}
309
+ <TabsContent value="estimate" className="mt-4 space-y-4">
310
+ <FormField
311
+ control={form.control}
312
+ name="default_estimate_note"
313
+ render={({ field }) => (
314
+ <FormItem>
315
+ <div className="flex items-center justify-between">
316
+ <FormLabel className="font-medium text-sm">{t("Default Note")}</FormLabel>
317
+ <SmartCodeInsertButton
318
+ textareaRef={estimateNoteRef}
319
+ value={field.value || ""}
320
+ onInsert={(newValue) => field.onChange(newValue)}
321
+ t={t}
322
+ />
323
+ </div>
324
+ <FormControl>
325
+ <InputWithPreview
326
+ ref={estimateNoteRef}
327
+ value={field.value || ""}
328
+ onChange={field.onChange}
329
+ placeholder={t("This estimate is valid until {document_valid_until}.")}
330
+ entity={entity}
331
+ multiline
332
+ rows={3}
333
+ className="resize-y"
334
+ />
335
+ </FormControl>
336
+ <FormDescription className="text-xs">
337
+ {t("This note will be pre-filled when creating new estimates")}
338
+ </FormDescription>
339
+ <FormMessage />
340
+ </FormItem>
341
+ )}
342
+ />
343
+
344
+ <FormField
345
+ control={form.control}
346
+ name="default_estimate_payment_terms"
347
+ render={({ field }) => (
348
+ <FormItem>
349
+ <div className="flex items-center justify-between">
350
+ <FormLabel className="font-medium text-sm">{t("Default Payment Terms")}</FormLabel>
351
+ <SmartCodeInsertButton
352
+ textareaRef={estimatePaymentTermsRef}
353
+ value={field.value || ""}
354
+ onInsert={(newValue) => field.onChange(newValue)}
355
+ t={t}
356
+ />
357
+ </div>
358
+ <FormControl>
359
+ <InputWithPreview
360
+ ref={estimatePaymentTermsRef}
361
+ value={field.value || ""}
362
+ onChange={field.onChange}
363
+ placeholder={t("Payment due upon acceptance.")}
364
+ entity={entity}
365
+ multiline
366
+ rows={3}
367
+ className="resize-y"
368
+ />
369
+ </FormControl>
370
+ <FormDescription className="text-xs">
371
+ {t("Payment terms pre-filled when creating new estimates")}
372
+ </FormDescription>
373
+ <FormMessage />
374
+ </FormItem>
375
+ )}
376
+ />
377
+ </TabsContent>
378
+
379
+ {/* Credit Note Tab */}
380
+ <TabsContent value="credit_note" className="mt-4 space-y-4">
381
+ <FormField
382
+ control={form.control}
383
+ name="default_credit_note_note"
384
+ render={({ field }) => (
385
+ <FormItem>
386
+ <div className="flex items-center justify-between">
387
+ <FormLabel className="font-medium text-sm">{t("Default Note")}</FormLabel>
388
+ <SmartCodeInsertButton
389
+ textareaRef={creditNoteNoteRef}
390
+ value={field.value || ""}
391
+ onInsert={(newValue) => field.onChange(newValue)}
392
+ t={t}
393
+ />
394
+ </div>
395
+ <FormControl>
396
+ <InputWithPreview
397
+ ref={creditNoteNoteRef}
398
+ value={field.value || ""}
399
+ onChange={field.onChange}
400
+ placeholder={t("Credit note for invoice {document_number}.")}
401
+ entity={entity}
402
+ multiline
403
+ rows={3}
404
+ className="resize-y"
405
+ />
406
+ </FormControl>
407
+ <FormDescription className="text-xs">
408
+ {t("This note will be pre-filled when creating new credit notes")}
409
+ </FormDescription>
410
+ <FormMessage />
411
+ </FormItem>
412
+ )}
413
+ />
414
+
415
+ <FormField
416
+ control={form.control}
417
+ name="default_credit_note_payment_terms"
418
+ render={({ field }) => (
419
+ <FormItem>
420
+ <div className="flex items-center justify-between">
421
+ <FormLabel className="font-medium text-sm">{t("Default Payment Terms")}</FormLabel>
422
+ <SmartCodeInsertButton
423
+ textareaRef={creditNotePaymentTermsRef}
424
+ value={field.value || ""}
425
+ onInsert={(newValue) => field.onChange(newValue)}
426
+ t={t}
427
+ />
428
+ </div>
429
+ <FormControl>
430
+ <InputWithPreview
431
+ ref={creditNotePaymentTermsRef}
432
+ value={field.value || ""}
433
+ onChange={field.onChange}
434
+ placeholder={t("Credit will be applied to your account.")}
435
+ entity={entity}
436
+ multiline
437
+ rows={3}
438
+ className="resize-y"
439
+ />
440
+ </FormControl>
441
+ <FormDescription className="text-xs">
442
+ {t("Payment terms pre-filled when creating new credit notes")}
443
+ </FormDescription>
444
+ <FormMessage />
445
+ </FormItem>
446
+ )}
447
+ />
448
+ </TabsContent>
449
+ </Tabs>
450
+ </div>
451
+ );
452
+
453
+ // Footer section content
454
+ const footerContent = (
455
+ <div className="border-t pt-6">
456
+ <FormField
457
+ control={form.control}
458
+ name="document_footer"
459
+ render={({ field }) => (
460
+ <FormItem>
461
+ <div className="flex items-center justify-between">
462
+ <FormLabel className="font-medium text-sm">{t("Document Footer")}</FormLabel>
463
+ <SmartCodeInsertButton
464
+ textareaRef={documentFooterRef}
465
+ value={field.value || ""}
466
+ onInsert={(newValue) => field.onChange(newValue)}
467
+ t={t}
468
+ />
469
+ </div>
470
+ <FormControl>
471
+ <InputWithPreview
472
+ ref={documentFooterRef}
473
+ value={field.value || ""}
474
+ onChange={field.onChange}
475
+ placeholder={t("{entity_name} | Due Date: {document_due_date} | Invoice #{document_number}")}
476
+ entity={entity}
477
+ multiline
478
+ rows={2}
479
+ className="resize-y"
480
+ />
481
+ </FormControl>
482
+ <FormDescription className="text-xs">
483
+ {t("Footer text displayed at the bottom of all PDF documents")}
484
+ </FormDescription>
485
+ <FormMessage />
486
+ </FormItem>
487
+ )}
488
+ />
489
+ </div>
490
+ );
491
+
492
+ return (
493
+ <Form {...form}>
494
+ <form id="defaults-settings-form" onSubmit={form.handleSubmit(onSubmit)} className="space-y-6">
495
+ {wrapSection("localization", localizationContent)}
496
+ {wrapSection("documents", documentsContent)}
497
+ {wrapSection("footer", footerContent)}
498
+ </form>
499
+ </Form>
500
+ );
501
+ }