@spaceinvoices/react-ui 0.4.0 → 0.4.2

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 (200) hide show
  1. package/cli/dist/index.js +1 -1
  2. package/package.json +1 -1
  3. package/registry.json +23 -27
  4. package/src/components/advance-invoices/advance-invoices.hooks.ts +32 -2
  5. package/src/components/advance-invoices/create/create-advance-invoice-form.tsx +109 -4
  6. package/src/components/advance-invoices/create/locales/de.ts +2 -0
  7. package/src/components/advance-invoices/create/locales/es.ts +2 -0
  8. package/src/components/advance-invoices/create/locales/fr.ts +2 -0
  9. package/src/components/advance-invoices/create/locales/hr.ts +2 -0
  10. package/src/components/advance-invoices/create/locales/it.ts +2 -0
  11. package/src/components/advance-invoices/create/locales/nl.ts +2 -0
  12. package/src/components/advance-invoices/create/locales/pl.ts +2 -0
  13. package/src/components/advance-invoices/create/locales/pt.ts +2 -0
  14. package/src/components/advance-invoices/create/locales/sl.ts +2 -0
  15. package/src/components/advance-invoices/create/prepare-advance-invoice-submission.ts +17 -0
  16. package/src/components/advance-invoices/list/list-row-actions.tsx +3 -6
  17. package/src/components/advance-invoices/list/list-table.tsx +45 -2
  18. package/src/components/advance-invoices/list/locales/de.ts +3 -0
  19. package/src/components/advance-invoices/list/locales/en.ts +3 -0
  20. package/src/components/advance-invoices/list/locales/es.ts +3 -0
  21. package/src/components/advance-invoices/list/locales/fr.ts +3 -0
  22. package/src/components/advance-invoices/list/locales/hr.ts +3 -0
  23. package/src/components/advance-invoices/list/locales/it.ts +3 -0
  24. package/src/components/advance-invoices/list/locales/nl.ts +3 -0
  25. package/src/components/advance-invoices/list/locales/pl.ts +3 -0
  26. package/src/components/advance-invoices/list/locales/pt.ts +3 -0
  27. package/src/components/advance-invoices/list/locales/sl.ts +3 -0
  28. package/src/components/credit-notes/create/create-credit-note-form.tsx +177 -6
  29. package/src/components/credit-notes/create/locales/de.ts +8 -0
  30. package/src/components/credit-notes/create/locales/es.ts +8 -0
  31. package/src/components/credit-notes/create/locales/fr.ts +7 -0
  32. package/src/components/credit-notes/create/locales/hr.ts +7 -0
  33. package/src/components/credit-notes/create/locales/it.ts +9 -0
  34. package/src/components/credit-notes/create/locales/nl.ts +7 -0
  35. package/src/components/credit-notes/create/locales/pl.ts +7 -0
  36. package/src/components/credit-notes/create/locales/pt.ts +7 -0
  37. package/src/components/credit-notes/create/locales/sl.ts +7 -0
  38. package/src/components/credit-notes/credit-notes.hooks.ts +30 -0
  39. package/src/components/credit-notes/list/list-row-actions.tsx +3 -6
  40. package/src/components/credit-notes/list/list-table.tsx +45 -2
  41. package/src/components/credit-notes/list/locales/de.ts +3 -0
  42. package/src/components/credit-notes/list/locales/en.ts +3 -0
  43. package/src/components/credit-notes/list/locales/es.ts +3 -0
  44. package/src/components/credit-notes/list/locales/fr.ts +3 -0
  45. package/src/components/credit-notes/list/locales/hr.ts +3 -0
  46. package/src/components/credit-notes/list/locales/it.ts +3 -0
  47. package/src/components/credit-notes/list/locales/nl.ts +3 -0
  48. package/src/components/credit-notes/list/locales/pl.ts +3 -0
  49. package/src/components/credit-notes/list/locales/pt.ts +3 -0
  50. package/src/components/credit-notes/list/locales/sl.ts +3 -0
  51. package/src/components/customers/create-customer-form/create-customer-form.tsx +0 -1
  52. package/src/components/documents/create/document-details-section.tsx +67 -1
  53. package/src/components/documents/create/mark-as-paid-section.tsx +11 -2
  54. package/src/components/documents/view/document-actions-bar.tsx +30 -0
  55. package/src/components/documents/view/locales/de.ts +5 -0
  56. package/src/components/documents/view/locales/es.ts +5 -0
  57. package/src/components/documents/view/locales/fr.ts +5 -0
  58. package/src/components/documents/view/locales/hr.ts +5 -0
  59. package/src/components/documents/view/locales/it.ts +5 -0
  60. package/src/components/documents/view/locales/nl.ts +5 -0
  61. package/src/components/documents/view/locales/pl.ts +5 -0
  62. package/src/components/documents/view/locales/pt.ts +5 -0
  63. package/src/components/documents/view/locales/sl.ts +5 -0
  64. package/src/components/entities/create-entity-form.tsx +1 -1
  65. package/src/components/entities/entity-settings-form/entity-settings-form.tsx +2 -3
  66. package/src/components/entities/entity-settings-form/locales/es.ts +2 -0
  67. package/src/components/entities/entity-settings-form/locales/fr.ts +2 -0
  68. package/src/components/entities/entity-settings-form/locales/hr.ts +2 -0
  69. package/src/components/entities/entity-settings-form/locales/it.ts +2 -0
  70. package/src/components/entities/entity-settings-form/locales/nl.ts +2 -0
  71. package/src/components/entities/entity-settings-form/locales/pl.ts +2 -0
  72. package/src/components/entities/entity-settings-form/locales/pt.ts +2 -0
  73. package/src/components/entities/fina-settings-form/fina-operator-required-dialog.tsx +109 -0
  74. package/src/components/entities/fina-settings-form/fina-settings-form.tsx +365 -35
  75. package/src/components/entities/fina-settings-form/fina-settings.hooks.ts +101 -20
  76. package/src/components/entities/fina-settings-form/index.ts +1 -0
  77. package/src/components/entities/fina-settings-form/locales/de.ts +54 -34
  78. package/src/components/entities/fina-settings-form/locales/en.ts +51 -34
  79. package/src/components/entities/fina-settings-form/locales/es.ts +50 -34
  80. package/src/components/entities/fina-settings-form/locales/fr.ts +50 -34
  81. package/src/components/entities/fina-settings-form/locales/hr.ts +50 -34
  82. package/src/components/entities/fina-settings-form/locales/it.ts +50 -34
  83. package/src/components/entities/fina-settings-form/locales/nl.ts +50 -34
  84. package/src/components/entities/fina-settings-form/locales/pl.ts +50 -34
  85. package/src/components/entities/fina-settings-form/locales/pt.ts +50 -34
  86. package/src/components/entities/fina-settings-form/locales/sl.ts +50 -34
  87. package/src/components/entities/fina-settings-form/sections/certificate-settings-section.tsx +18 -0
  88. package/src/components/entities/fina-settings-form/sections/premises-management-section.tsx +64 -89
  89. package/src/components/entities/fina-settings-form/sections/register-premise-dialog.tsx +51 -323
  90. package/src/components/entities/furs-settings-form/furs-operator-required-dialog.tsx +106 -0
  91. package/src/components/entities/furs-settings-form/furs-settings-form.tsx +24 -10
  92. package/src/components/entities/furs-settings-form/furs-settings.hooks.ts +5 -9
  93. package/src/components/entities/furs-settings-form/index.ts +1 -0
  94. package/src/components/entities/furs-settings-form/locales/de.ts +27 -3
  95. package/src/components/entities/furs-settings-form/locales/en.ts +17 -3
  96. package/src/components/entities/furs-settings-form/locales/es.ts +26 -3
  97. package/src/components/entities/furs-settings-form/locales/fr.ts +26 -3
  98. package/src/components/entities/furs-settings-form/locales/hr.ts +26 -3
  99. package/src/components/entities/furs-settings-form/locales/it.ts +26 -3
  100. package/src/components/entities/furs-settings-form/locales/nl.ts +26 -3
  101. package/src/components/entities/furs-settings-form/locales/pl.ts +26 -3
  102. package/src/components/entities/furs-settings-form/locales/pt.ts +26 -3
  103. package/src/components/entities/furs-settings-form/locales/sl.ts +16 -3
  104. package/src/components/entities/furs-settings-form/sections/certificate-settings-section.tsx +22 -0
  105. package/src/components/entities/furs-settings-form/sections/general-settings-section.tsx +15 -2
  106. package/src/components/entities/furs-settings-form/sections/premises-management-section.tsx +1 -0
  107. package/src/components/entities/furs-settings-form/sections/register-premise-dialog.tsx +58 -34
  108. package/src/components/entities/settings/tax-rules-settings-form.tsx +4 -4
  109. package/src/components/estimates/list/list-row-actions.tsx +3 -7
  110. package/src/components/estimates/list/list-table.tsx +35 -2
  111. package/src/components/estimates/list/locales/de.ts +3 -0
  112. package/src/components/estimates/list/locales/en.ts +3 -0
  113. package/src/components/estimates/list/locales/es.ts +3 -0
  114. package/src/components/estimates/list/locales/fr.ts +3 -0
  115. package/src/components/estimates/list/locales/hr.ts +3 -0
  116. package/src/components/estimates/list/locales/it.ts +3 -0
  117. package/src/components/estimates/list/locales/nl.ts +3 -0
  118. package/src/components/estimates/list/locales/pl.ts +3 -0
  119. package/src/components/estimates/list/locales/pt.ts +3 -0
  120. package/src/components/estimates/list/locales/sl.ts +3 -0
  121. package/src/components/export/document-export-form.tsx +34 -34
  122. package/src/components/invoices/create/create-invoice-form.tsx +107 -5
  123. package/src/components/invoices/create/prepare-invoice-submission.ts +17 -0
  124. package/src/components/invoices/invoices.hooks.ts +32 -2
  125. package/src/components/invoices/list/list-row-actions.tsx +23 -8
  126. package/src/components/invoices/list/list-table.tsx +53 -2
  127. package/src/components/invoices/list/locales/de.ts +4 -0
  128. package/src/components/invoices/list/locales/en.ts +4 -0
  129. package/src/components/invoices/list/locales/es.ts +4 -0
  130. package/src/components/invoices/list/locales/fr.ts +4 -0
  131. package/src/components/invoices/list/locales/hr.ts +4 -0
  132. package/src/components/invoices/list/locales/it.ts +4 -0
  133. package/src/components/invoices/list/locales/nl.ts +4 -0
  134. package/src/components/invoices/list/locales/pl.ts +4 -0
  135. package/src/components/invoices/list/locales/pt.ts +4 -0
  136. package/src/components/invoices/list/locales/sl.ts +4 -0
  137. package/src/components/invoices/view/fiscalization-status-card.tsx +4 -1
  138. package/src/components/items/item-list-table/item-list-row-actions.tsx +3 -7
  139. package/src/components/items/item-list-table/item-list-row.tsx +3 -2
  140. package/src/components/items/item-list-table/item-list-table.tsx +5 -1
  141. package/src/components/recurring-invoices/create-recurring-invoice-form/create-recurring-invoice-form.tsx +418 -0
  142. package/src/components/recurring-invoices/create-recurring-invoice-form/locales/de.ts +45 -0
  143. package/src/components/recurring-invoices/create-recurring-invoice-form/locales/es.ts +44 -0
  144. package/src/components/recurring-invoices/create-recurring-invoice-form/locales/fr.ts +44 -0
  145. package/src/components/recurring-invoices/create-recurring-invoice-form/locales/hr.ts +44 -0
  146. package/src/components/recurring-invoices/create-recurring-invoice-form/locales/it.ts +44 -0
  147. package/src/components/recurring-invoices/create-recurring-invoice-form/locales/nl.ts +44 -0
  148. package/src/components/recurring-invoices/create-recurring-invoice-form/locales/pl.ts +44 -0
  149. package/src/components/recurring-invoices/create-recurring-invoice-form/locales/pt.ts +44 -0
  150. package/src/components/recurring-invoices/create-recurring-invoice-form/locales/sl.ts +44 -0
  151. package/src/components/recurring-invoices/index.ts +3 -0
  152. package/src/components/recurring-invoices/list/index.ts +2 -0
  153. package/src/components/recurring-invoices/list/list-row-actions.tsx +139 -0
  154. package/src/components/recurring-invoices/list/list-table.tsx +179 -0
  155. package/src/components/recurring-invoices/list/locales/de.ts +27 -0
  156. package/src/components/recurring-invoices/list/locales/en.ts +5 -0
  157. package/src/components/recurring-invoices/list/locales/es.ts +27 -0
  158. package/src/components/recurring-invoices/list/locales/fr.ts +27 -0
  159. package/src/components/recurring-invoices/list/locales/hr.ts +27 -0
  160. package/src/components/recurring-invoices/list/locales/it.ts +27 -0
  161. package/src/components/recurring-invoices/list/locales/nl.ts +27 -0
  162. package/src/components/recurring-invoices/list/locales/pl.ts +27 -0
  163. package/src/components/recurring-invoices/list/locales/pt.ts +27 -0
  164. package/src/components/recurring-invoices/list/locales/sl.ts +27 -0
  165. package/src/components/recurring-invoices/recurring-invoices.hooks.ts +28 -0
  166. package/src/components/table/data-table.tsx +122 -5
  167. package/src/components/table/selection-toolbar.tsx +36 -0
  168. package/src/components/tax-reports/kir-export-form.tsx +75 -55
  169. package/src/components/taxes/tax-list-table/tax-list-row-actions.tsx +3 -6
  170. package/src/components/taxes/tax-list-table/tax-list-row.tsx +3 -2
  171. package/src/components/taxes/tax-list-table/tax-list-table.tsx +5 -1
  172. package/src/components/ui/checkbox.tsx +5 -5
  173. package/src/generate-schemas.ts +46 -7
  174. package/src/generated/schemas/advanceinvoice.ts +79 -187
  175. package/src/generated/schemas/authorizeshopify_body.ts +22 -0
  176. package/src/generated/schemas/creditnote.ts +60 -88
  177. package/src/generated/schemas/customadvanceinvoice.ts +70 -97
  178. package/src/generated/schemas/customcreditnote.ts +70 -97
  179. package/src/generated/schemas/customestimate.ts +68 -97
  180. package/src/generated/schemas/custominvoice.ts +70 -97
  181. package/src/generated/schemas/entity.ts +1 -1
  182. package/src/generated/schemas/estimate.ts +67 -172
  183. package/src/generated/schemas/index.ts +39 -28
  184. package/src/generated/schemas/invoice.ts +79 -187
  185. package/src/generated/schemas/order.ts +127 -0
  186. package/src/generated/schemas/orderintegration.ts +51 -0
  187. package/src/generated/schemas/payment.ts +2 -0
  188. package/src/generated/schemas/recurringinvoice.ts +61 -0
  189. package/src/generated/schemas/registerfursrealestatepremise_body.ts +11 -7
  190. package/src/generated/schemas/renderadvanceinvoicepreview_body.ts +140 -269
  191. package/src/generated/schemas/rendercreditnotepreview_body.ts +141 -270
  192. package/src/generated/schemas/renderestimatepreview_body.ts +112 -212
  193. package/src/generated/schemas/renderinvoicepreview_body.ts +141 -270
  194. package/src/generated/schemas/webhook.ts +42 -0
  195. package/src/lib/furs-error-utils.ts +36 -0
  196. package/src/lib/schemas/advance-invoice.ts +3 -3
  197. package/src/lib/schemas/credit-note.ts +3 -3
  198. package/src/lib/schemas/estimate.ts +3 -3
  199. package/src/lib/schemas/invoice.ts +3 -3
  200. package/src/providers/white-label-provider.tsx +3 -0
@@ -39,4 +39,8 @@ export default {
39
39
  "No results found": "Aucune facture trouvée",
40
40
  "Try adjusting your search criteria": "Essayez de modifier vos critères de recherche",
41
41
  "Clear search": "Effacer la recherche",
42
+ selected: "sélectionnés",
43
+ "Export PDFs": "Exporter les PDF",
44
+ "Deselect all": "Tout désélectionner",
45
+ Void: "Annuler",
42
46
  } as const;
@@ -39,4 +39,8 @@ export default {
39
39
  "No results found": "Nisu pronađeni računi",
40
40
  "Try adjusting your search criteria": "Pokušajte prilagoditi kriterije pretrage",
41
41
  "Clear search": "Očisti pretragu",
42
+ selected: "odabranih",
43
+ "Export PDFs": "Izvezi PDF-ove",
44
+ "Deselect all": "Poništi odabir",
45
+ Void: "Storniraj",
42
46
  } as const;
@@ -39,4 +39,8 @@ export default {
39
39
  "No results found": "Nessuna fattura trovata",
40
40
  "Try adjusting your search criteria": "Prova a modificare i criteri di ricerca",
41
41
  "Clear search": "Cancella ricerca",
42
+ selected: "selezionati",
43
+ "Export PDFs": "Esporta PDF",
44
+ "Deselect all": "Deseleziona tutto",
45
+ Void: "Annulla",
42
46
  } as const;
@@ -39,4 +39,8 @@ export default {
39
39
  "No results found": "Geen facturen gevonden",
40
40
  "Try adjusting your search criteria": "Probeer uw zoekcriteria aan te passen",
41
41
  "Clear search": "Zoekopdracht wissen",
42
+ selected: "geselecteerd",
43
+ "Export PDFs": "PDFs exporteren",
44
+ "Deselect all": "Alles deselecteren",
45
+ Void: "Nietig verklaren",
42
46
  } as const;
@@ -39,4 +39,8 @@ export default {
39
39
  "No results found": "Nie znaleziono faktur",
40
40
  "Try adjusting your search criteria": "Spróbuj dostosować kryteria wyszukiwania",
41
41
  "Clear search": "Wyczyść wyszukiwanie",
42
+ selected: "wybranych",
43
+ "Export PDFs": "Eksportuj PDF-y",
44
+ "Deselect all": "Odznacz wszystko",
45
+ Void: "Anuluj",
42
46
  } as const;
@@ -39,4 +39,8 @@ export default {
39
39
  "No results found": "Nenhuma fatura encontrada",
40
40
  "Try adjusting your search criteria": "Tente ajustar os seus critérios de pesquisa",
41
41
  "Clear search": "Limpar pesquisa",
42
+ selected: "selecionados",
43
+ "Export PDFs": "Exportar PDFs",
44
+ "Deselect all": "Desselecionar tudo",
45
+ Void: "Anular",
42
46
  } as const;
@@ -39,4 +39,8 @@ export default {
39
39
  "No results found": "Ni najdenih računov",
40
40
  "Try adjusting your search criteria": "Poskusite prilagoditi iskalne kriterije",
41
41
  "Clear search": "Počisti iskanje",
42
+ selected: "izbranih",
43
+ "Export PDFs": "Izvozi PDF-je",
44
+ "Deselect all": "Počisti izbiro",
45
+ Void: "Storniraj",
42
46
  } as const;
@@ -18,7 +18,10 @@ import sl from "../../documents/view/locales/sl";
18
18
 
19
19
  const translations = { de, es, fr, hr, it, nl, pl, pt, sl } as const;
20
20
 
21
- type FiscalizationData = FursFiscalizationResponse | FinaFiscalizationResponse;
21
+ type FiscalizationStatus = "pending" | "success" | "failed" | "skipped";
22
+ type FiscalizationData = (Exclude<FursFiscalizationResponse, null> | Exclude<FinaFiscalizationResponse, null>) & {
23
+ status: FiscalizationStatus;
24
+ };
22
25
 
23
26
  interface FiscalizationStatusCardProps extends ComponentTranslationProps {
24
27
  fiscalizationType: "furs" | "fina";
@@ -15,9 +15,10 @@ import { createTranslation } from "@/ui/lib/translation";
15
15
 
16
16
  type ItemListRowActionsProps = {
17
17
  item: Item;
18
+ onView?: (item: Item) => void;
18
19
  } & ComponentTranslationProps;
19
20
 
20
- export default function ItemListRowActions({ item, ...i18nProps }: ItemListRowActionsProps) {
21
+ export default function ItemListRowActions({ item, onView, ...i18nProps }: ItemListRowActionsProps) {
21
22
  const t = createTranslation(i18nProps);
22
23
 
23
24
  return (
@@ -34,12 +35,7 @@ export default function ItemListRowActions({ item, ...i18nProps }: ItemListRowAc
34
35
  {t("Copy item ID")}
35
36
  </DropdownMenuItem>
36
37
  <DropdownMenuSeparator />
37
- <DropdownMenuItem
38
- className="cursor-pointer"
39
- onClick={() => {
40
- window.location.href = `/app/items/${item.id}`;
41
- }}
42
- >
38
+ <DropdownMenuItem className="cursor-pointer" onClick={() => onView?.(item)}>
43
39
  {t("View item")}
44
40
  </DropdownMenuItem>
45
41
  </DropdownMenuContent>
@@ -9,9 +9,10 @@ import ItemListRowActions from "./item-list-row-actions";
9
9
  type ItemListRowProps = {
10
10
  item: Item;
11
11
  onRowClick?: (item: Item) => void;
12
+ onView?: (item: Item) => void;
12
13
  } & ComponentTranslationProps;
13
14
 
14
- export default function ItemListRow({ item, onRowClick, ...i18nProps }: ItemListRowProps) {
15
+ export default function ItemListRow({ item, onRowClick, onView, ...i18nProps }: ItemListRowProps) {
15
16
  const t = createTranslation(i18nProps);
16
17
 
17
18
  return (
@@ -25,7 +26,7 @@ export default function ItemListRow({ item, onRowClick, ...i18nProps }: ItemList
25
26
  <TableCell>{item.description}</TableCell>
26
27
  <TableCell className="text-right">{item.price}</TableCell>
27
28
  <TableCell className="text-right">
28
- <ItemListRowActions item={item} t={t} />
29
+ <ItemListRowActions item={item} onView={onView} t={t} />
29
30
  </TableCell>
30
31
  </TableRow>
31
32
  );
@@ -37,12 +37,14 @@ type ItemListTableProps = {
37
37
  namespace?: string;
38
38
  locale?: string;
39
39
  entityId?: string;
40
+ onView?: (item: Item) => void;
40
41
  } & ListTableProps<Item>;
41
42
 
42
43
  export default function ItemListTable({
43
44
  queryParams,
44
45
  createNewTrigger,
45
46
  onRowClick,
47
+ onView,
46
48
  onChangeParams,
47
49
  entityId,
48
50
  ...i18nProps
@@ -67,7 +69,9 @@ export default function ItemListTable({
67
69
  { id: "price", header: t("Price"), align: "right" },
68
70
  { id: "actions", header: "", align: "right" },
69
71
  ]}
70
- renderRow={(item) => <ItemListRow item={item} key={item.id} onRowClick={(item) => onRowClick?.(item)} t={t} />}
72
+ renderRow={(item) => (
73
+ <ItemListRow item={item} key={item.id} onRowClick={(item) => onRowClick?.(item)} onView={onView} t={t} />
74
+ )}
71
75
  renderHeader={(headerProps) => <ItemListHeader orderBy={headerProps.orderBy} onSort={headerProps.onSort} t={t} />}
72
76
  queryParams={queryParams}
73
77
  resourceName="item"
@@ -0,0 +1,418 @@
1
+ import { zodResolver } from "@hookform/resolvers/zod";
2
+ import type { CreateRecurringInvoiceBody, RecurringInvoice } from "@spaceinvoices/js-sdk";
3
+ import { CalendarIcon } from "lucide-react";
4
+ import { useForm, useWatch } from "react-hook-form";
5
+ import { Button } from "@/ui/components/ui/button";
6
+ import { Calendar } from "@/ui/components/ui/calendar";
7
+ import { Checkbox } from "@/ui/components/ui/checkbox";
8
+ import {
9
+ Form,
10
+ FormControl,
11
+ FormDescription,
12
+ FormField,
13
+ FormItem,
14
+ FormLabel,
15
+ FormMessage,
16
+ } from "@/ui/components/ui/form";
17
+ import { Input } from "@/ui/components/ui/input";
18
+ import { Popover, PopoverContent, PopoverTrigger } from "@/ui/components/ui/popover";
19
+ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/ui/components/ui/select";
20
+ import type { CreateRecurringInvoiceSchema } from "@/ui/generated/schemas/recurringinvoice";
21
+ import { createRecurringInvoiceSchema } from "@/ui/generated/schemas/recurringinvoice";
22
+ import type { ComponentTranslationProps } from "@/ui/lib/translation";
23
+ import { createTranslation } from "@/ui/lib/translation";
24
+ import { cn } from "@/ui/lib/utils";
25
+
26
+ import { useCreateRecurringInvoice } from "../recurring-invoices.hooks";
27
+ import de from "./locales/de";
28
+ import es from "./locales/es";
29
+ import fr from "./locales/fr";
30
+ import hr from "./locales/hr";
31
+ import it from "./locales/it";
32
+ import nl from "./locales/nl";
33
+ import pl from "./locales/pl";
34
+ import pt from "./locales/pt";
35
+ import sl from "./locales/sl";
36
+
37
+ const translations = {
38
+ sl,
39
+ de,
40
+ it,
41
+ fr,
42
+ es,
43
+ pt,
44
+ nl,
45
+ pl,
46
+ hr,
47
+ } as const;
48
+
49
+ const FREQUENCY_LABELS: Record<string, string> = {
50
+ daily: "Daily",
51
+ weekly: "Weekly",
52
+ monthly: "Monthly",
53
+ yearly: "Yearly",
54
+ };
55
+
56
+ const DAY_OF_WEEK_LABELS: Record<number, string> = {
57
+ 0: "Sunday",
58
+ 1: "Monday",
59
+ 2: "Tuesday",
60
+ 3: "Wednesday",
61
+ 4: "Thursday",
62
+ 5: "Friday",
63
+ 6: "Saturday",
64
+ };
65
+
66
+ const MONTH_LABELS: Record<number, string> = {
67
+ 1: "January",
68
+ 2: "February",
69
+ 3: "March",
70
+ 4: "April",
71
+ 5: "May",
72
+ 6: "June",
73
+ 7: "July",
74
+ 8: "August",
75
+ 9: "September",
76
+ 10: "October",
77
+ 11: "November",
78
+ 12: "December",
79
+ };
80
+
81
+ function formatDateToYMD(date: Date): string {
82
+ const y = date.getFullYear();
83
+ const m = String(date.getMonth() + 1).padStart(2, "0");
84
+ const d = String(date.getDate()).padStart(2, "0");
85
+ return `${y}-${m}-${d}`;
86
+ }
87
+
88
+ type CreateRecurringInvoiceFormProps = {
89
+ entityId: string;
90
+ documentId: string;
91
+ onSuccess?: (recurringInvoice: RecurringInvoice) => void;
92
+ onError?: (error: Error) => void;
93
+ renderSubmitButton?: (props: { isSubmitting: boolean; submit: () => void }) => React.ReactNode;
94
+ } & ComponentTranslationProps;
95
+
96
+ export default function CreateRecurringInvoiceForm({
97
+ entityId,
98
+ documentId,
99
+ onSuccess,
100
+ onError,
101
+ renderSubmitButton,
102
+ ...i18nProps
103
+ }: CreateRecurringInvoiceFormProps) {
104
+ const t = createTranslation({
105
+ ...i18nProps,
106
+ translations,
107
+ });
108
+
109
+ const form = useForm<CreateRecurringInvoiceSchema>({
110
+ resolver: zodResolver(createRecurringInvoiceSchema),
111
+ defaultValues: {
112
+ document_id: documentId,
113
+ name: "",
114
+ frequency: "monthly",
115
+ interval: 1,
116
+ day_of_week: null,
117
+ day_of_month: null,
118
+ month_of_year: null,
119
+ start_date: formatDateToYMD(new Date()),
120
+ end_date: undefined,
121
+ auto_send: false,
122
+ create_as_draft: false,
123
+ },
124
+ });
125
+
126
+ const frequency = useWatch({ control: form.control, name: "frequency" });
127
+
128
+ const { mutate: createRecurringInvoice, isPending } = useCreateRecurringInvoice({
129
+ entityId,
130
+ onSuccess: (recurringInvoice, _variables, _context) => {
131
+ onSuccess?.(recurringInvoice);
132
+ form.reset();
133
+ },
134
+ onError: (error, _variables, _context) => {
135
+ form.setError("root", {
136
+ type: "submit",
137
+ message: t("There was an error creating the schedule"),
138
+ });
139
+ onError?.(error);
140
+ },
141
+ });
142
+
143
+ const onSubmit = async (values: CreateRecurringInvoiceSchema) => {
144
+ createRecurringInvoice(values as CreateRecurringInvoiceBody);
145
+ };
146
+
147
+ const handleSubmitClick = () => {
148
+ form.handleSubmit(onSubmit)();
149
+ };
150
+
151
+ return (
152
+ <Form {...form}>
153
+ <form onSubmit={form.handleSubmit(onSubmit)} className="space-y-4">
154
+ <FormField
155
+ control={form.control}
156
+ name="name"
157
+ render={({ field }) => (
158
+ <FormItem>
159
+ <FormLabel>
160
+ {t("Name")}
161
+ <span className="ml-1 text-red-500">*</span>
162
+ </FormLabel>
163
+ <FormControl>
164
+ <Input placeholder={t("Enter schedule name")} {...field} />
165
+ </FormControl>
166
+ <FormMessage />
167
+ </FormItem>
168
+ )}
169
+ />
170
+
171
+ <div className="grid grid-cols-2 gap-4">
172
+ <FormField
173
+ control={form.control}
174
+ name="frequency"
175
+ render={({ field }) => (
176
+ <FormItem>
177
+ <FormLabel>
178
+ {t("Frequency")}
179
+ <span className="ml-1 text-red-500">*</span>
180
+ </FormLabel>
181
+ <Select onValueChange={field.onChange} defaultValue={field.value}>
182
+ <FormControl>
183
+ <SelectTrigger>
184
+ <SelectValue placeholder={t("Select frequency")}>
185
+ {field.value && t(FREQUENCY_LABELS[field.value])}
186
+ </SelectValue>
187
+ </SelectTrigger>
188
+ </FormControl>
189
+ <SelectContent>
190
+ {Object.entries(FREQUENCY_LABELS).map(([value, label]) => (
191
+ <SelectItem key={value} value={value}>
192
+ {t(label)}
193
+ </SelectItem>
194
+ ))}
195
+ </SelectContent>
196
+ </Select>
197
+ <FormMessage />
198
+ </FormItem>
199
+ )}
200
+ />
201
+
202
+ <FormField
203
+ control={form.control}
204
+ name="interval"
205
+ render={({ field }) => (
206
+ <FormItem>
207
+ <FormLabel>{t("Interval")}</FormLabel>
208
+ <FormControl>
209
+ <Input
210
+ type="number"
211
+ min="1"
212
+ max="365"
213
+ placeholder="1"
214
+ {...field}
215
+ onChange={(e) => field.onChange(Number(e.target.value))}
216
+ />
217
+ </FormControl>
218
+ <FormMessage />
219
+ </FormItem>
220
+ )}
221
+ />
222
+ </div>
223
+
224
+ {frequency === "weekly" && (
225
+ <FormField
226
+ control={form.control}
227
+ name="day_of_week"
228
+ render={({ field }) => (
229
+ <FormItem>
230
+ <FormLabel>{t("Day of Week")}</FormLabel>
231
+ <Select
232
+ onValueChange={(v) => field.onChange(Number(v))}
233
+ value={field.value != null ? String(field.value) : undefined}
234
+ >
235
+ <FormControl>
236
+ <SelectTrigger>
237
+ <SelectValue placeholder={t("Select day")}>
238
+ {field.value != null && t(DAY_OF_WEEK_LABELS[field.value])}
239
+ </SelectValue>
240
+ </SelectTrigger>
241
+ </FormControl>
242
+ <SelectContent>
243
+ {Object.entries(DAY_OF_WEEK_LABELS).map(([value, label]) => (
244
+ <SelectItem key={value} value={value}>
245
+ {t(label)}
246
+ </SelectItem>
247
+ ))}
248
+ </SelectContent>
249
+ </Select>
250
+ <FormMessage />
251
+ </FormItem>
252
+ )}
253
+ />
254
+ )}
255
+
256
+ {(frequency === "monthly" || frequency === "yearly") && (
257
+ <FormField
258
+ control={form.control}
259
+ name="day_of_month"
260
+ render={({ field }) => (
261
+ <FormItem>
262
+ <FormLabel>{t("Day of Month")}</FormLabel>
263
+ <FormControl>
264
+ <Input
265
+ type="number"
266
+ min="1"
267
+ max="31"
268
+ placeholder="1"
269
+ {...field}
270
+ value={field.value ?? ""}
271
+ onChange={(e) => field.onChange(e.target.value ? Number(e.target.value) : null)}
272
+ />
273
+ </FormControl>
274
+ <FormMessage />
275
+ </FormItem>
276
+ )}
277
+ />
278
+ )}
279
+
280
+ {frequency === "yearly" && (
281
+ <FormField
282
+ control={form.control}
283
+ name="month_of_year"
284
+ render={({ field }) => (
285
+ <FormItem>
286
+ <FormLabel>{t("Month")}</FormLabel>
287
+ <Select
288
+ onValueChange={(v) => field.onChange(Number(v))}
289
+ value={field.value != null ? String(field.value) : undefined}
290
+ >
291
+ <FormControl>
292
+ <SelectTrigger>
293
+ <SelectValue placeholder={t("Select month")}>
294
+ {field.value != null && t(MONTH_LABELS[field.value])}
295
+ </SelectValue>
296
+ </SelectTrigger>
297
+ </FormControl>
298
+ <SelectContent>
299
+ {Object.entries(MONTH_LABELS).map(([value, label]) => (
300
+ <SelectItem key={value} value={value}>
301
+ {t(label)}
302
+ </SelectItem>
303
+ ))}
304
+ </SelectContent>
305
+ </Select>
306
+ <FormMessage />
307
+ </FormItem>
308
+ )}
309
+ />
310
+ )}
311
+
312
+ <FormField
313
+ control={form.control}
314
+ name="start_date"
315
+ render={({ field }) => (
316
+ <FormItem>
317
+ <FormLabel>
318
+ {t("Start Date")}
319
+ <span className="ml-1 text-red-500">*</span>
320
+ </FormLabel>
321
+ <Popover>
322
+ <PopoverTrigger asChild>
323
+ <FormControl>
324
+ <Button
325
+ variant="outline"
326
+ className={cn("w-full pl-3 text-left font-normal", !field.value && "text-muted-foreground")}
327
+ >
328
+ {field.value ? field.value : <span>{t("Pick a date")}</span>}
329
+ <CalendarIcon className="ml-auto h-4 w-4 opacity-50" />
330
+ </Button>
331
+ </FormControl>
332
+ </PopoverTrigger>
333
+ <PopoverContent className="w-auto p-0" align="start">
334
+ <Calendar
335
+ mode="single"
336
+ selected={field.value ? new Date(`${field.value}T00:00:00`) : undefined}
337
+ onSelect={(date) => field.onChange(date ? formatDateToYMD(date) : undefined)}
338
+ initialFocus
339
+ />
340
+ </PopoverContent>
341
+ </Popover>
342
+ <FormMessage />
343
+ </FormItem>
344
+ )}
345
+ />
346
+
347
+ <FormField
348
+ control={form.control}
349
+ name="end_date"
350
+ render={({ field }) => (
351
+ <FormItem>
352
+ <FormLabel>{t("End Date")}</FormLabel>
353
+ <Popover>
354
+ <PopoverTrigger asChild>
355
+ <FormControl>
356
+ <Button
357
+ variant="outline"
358
+ className={cn("w-full pl-3 text-left font-normal", !field.value && "text-muted-foreground")}
359
+ >
360
+ {field.value ? field.value : <span>{t("No end date")}</span>}
361
+ <CalendarIcon className="ml-auto h-4 w-4 opacity-50" />
362
+ </Button>
363
+ </FormControl>
364
+ </PopoverTrigger>
365
+ <PopoverContent className="w-auto p-0" align="start">
366
+ <Calendar
367
+ mode="single"
368
+ selected={field.value ? new Date(`${field.value}T00:00:00`) : undefined}
369
+ onSelect={(date) => field.onChange(date ? formatDateToYMD(date) : undefined)}
370
+ initialFocus
371
+ />
372
+ </PopoverContent>
373
+ </Popover>
374
+ <FormMessage />
375
+ </FormItem>
376
+ )}
377
+ />
378
+
379
+ <FormField
380
+ control={form.control}
381
+ name="auto_send"
382
+ render={({ field }) => (
383
+ <FormItem className="flex flex-row items-start space-x-3 space-y-0">
384
+ <FormControl>
385
+ <Checkbox checked={field.value} onCheckedChange={field.onChange} />
386
+ </FormControl>
387
+ <div className="space-y-1 leading-none">
388
+ <FormLabel>{t("Auto-send")}</FormLabel>
389
+ <FormDescription>{t("Automatically email generated invoices")}</FormDescription>
390
+ </div>
391
+ </FormItem>
392
+ )}
393
+ />
394
+
395
+ <FormField
396
+ control={form.control}
397
+ name="create_as_draft"
398
+ render={({ field }) => (
399
+ <FormItem className="flex flex-row items-start space-x-3 space-y-0">
400
+ <FormControl>
401
+ <Checkbox checked={field.value} onCheckedChange={field.onChange} />
402
+ </FormControl>
403
+ <div className="space-y-1 leading-none">
404
+ <FormLabel>{t("Create as draft")}</FormLabel>
405
+ <FormDescription>{t("Generated invoices will be drafts for review")}</FormDescription>
406
+ </div>
407
+ </FormItem>
408
+ )}
409
+ />
410
+
411
+ {renderSubmitButton?.({
412
+ isSubmitting: isPending || form.formState.isSubmitting,
413
+ submit: handleSubmitClick,
414
+ })}
415
+ </form>
416
+ </Form>
417
+ );
418
+ }
@@ -0,0 +1,45 @@
1
+ export default {
2
+ Name: "Name",
3
+ "Enter schedule name": "Planname eingeben",
4
+ Frequency: "Häufigkeit",
5
+ "Select frequency": "Häufigkeit wählen",
6
+ Daily: "Täglich",
7
+ Weekly: "Wöchentlich",
8
+ Monthly: "Monatlich",
9
+ Yearly: "Jährlich",
10
+ Interval: "Intervall",
11
+ "Day of Week": "Wochentag",
12
+ "Select day": "Tag wählen",
13
+ Sunday: "Sonntag",
14
+ Monday: "Montag",
15
+ Tuesday: "Dienstag",
16
+ Wednesday: "Mittwoch",
17
+ Thursday: "Donnerstag",
18
+ Friday: "Freitag",
19
+ Saturday: "Samstag",
20
+ "Day of Month": "Tag im Monat",
21
+ Month: "Monat",
22
+ "Select month": "Monat wählen",
23
+ January: "Januar",
24
+ February: "Februar",
25
+ March: "März",
26
+ April: "April",
27
+ May: "Mai",
28
+ June: "Juni",
29
+ July: "Juli",
30
+ August: "August",
31
+ September: "September",
32
+ October: "Oktober",
33
+ November: "November",
34
+ December: "Dezember",
35
+ "Start Date": "Startdatum",
36
+ "End Date": "Enddatum",
37
+ "Pick a date": "Datum wählen",
38
+ "No end date": "Kein Enddatum",
39
+ "Auto-send": "Automatisch senden",
40
+ "Automatically email generated invoices": "Erstellte Rechnungen automatisch per E-Mail senden",
41
+ "Create as draft": "Als Entwurf erstellen",
42
+ "Generated invoices will be drafts for review":
43
+ "Erstellte Rechnungen werden als Entwürfe zur Überprüfung gespeichert",
44
+ "There was an error creating the schedule": "Beim Erstellen des Plans ist ein Fehler aufgetreten",
45
+ } as const;
@@ -0,0 +1,44 @@
1
+ export default {
2
+ Name: "Nombre",
3
+ "Enter schedule name": "Ingrese nombre del programa",
4
+ Frequency: "Frecuencia",
5
+ "Select frequency": "Seleccionar frecuencia",
6
+ Daily: "Diario",
7
+ Weekly: "Semanal",
8
+ Monthly: "Mensual",
9
+ Yearly: "Anual",
10
+ Interval: "Intervalo",
11
+ "Day of Week": "Día de la semana",
12
+ "Select day": "Seleccionar día",
13
+ Sunday: "Domingo",
14
+ Monday: "Lunes",
15
+ Tuesday: "Martes",
16
+ Wednesday: "Miércoles",
17
+ Thursday: "Jueves",
18
+ Friday: "Viernes",
19
+ Saturday: "Sábado",
20
+ "Day of Month": "Día del mes",
21
+ Month: "Mes",
22
+ "Select month": "Seleccionar mes",
23
+ January: "Enero",
24
+ February: "Febrero",
25
+ March: "Marzo",
26
+ April: "Abril",
27
+ May: "Mayo",
28
+ June: "Junio",
29
+ July: "Julio",
30
+ August: "Agosto",
31
+ September: "Septiembre",
32
+ October: "Octubre",
33
+ November: "Noviembre",
34
+ December: "Diciembre",
35
+ "Start Date": "Fecha de inicio",
36
+ "End Date": "Fecha de fin",
37
+ "Pick a date": "Elegir fecha",
38
+ "No end date": "Sin fecha de fin",
39
+ "Auto-send": "Envío automático",
40
+ "Automatically email generated invoices": "Enviar automáticamente las facturas generadas por correo",
41
+ "Create as draft": "Crear como borrador",
42
+ "Generated invoices will be drafts for review": "Las facturas generadas serán borradores para revisión",
43
+ "There was an error creating the schedule": "Hubo un error al crear el programa",
44
+ } as const;