@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.
- package/LICENSE +21 -0
- package/README.md +340 -0
- package/cli/dist/index.js +922 -0
- package/package.json +87 -0
- package/registry.json +600 -0
- package/spaceinvoices.schema.json +47 -0
- package/src/app.tsx +25 -0
- package/src/common/autocomplete.tsx +135 -0
- package/src/components/activities/activity-timeline.tsx +160 -0
- package/src/components/activities/index.ts +1 -0
- package/src/components/activities/locales/de.ts +30 -0
- package/src/components/activities/locales/sl.ts +30 -0
- package/src/components/advance-invoices/advance-invoices.hooks.ts +75 -0
- package/src/components/advance-invoices/create/create-advance-invoice-form.tsx +702 -0
- package/src/components/advance-invoices/create/locales/de.ts +29 -0
- package/src/components/advance-invoices/create/locales/sl.ts +25 -0
- package/src/components/advance-invoices/create/prepare-advance-invoice-submission.ts +74 -0
- package/src/components/advance-invoices/index.ts +5 -0
- package/src/components/advance-invoices/list/index.ts +3 -0
- package/src/components/advance-invoices/list/list-row-actions.tsx +119 -0
- package/src/components/advance-invoices/list/list-table.tsx +178 -0
- package/src/components/advance-invoices/list/locales/de.ts +32 -0
- package/src/components/advance-invoices/list/locales/sl.ts +32 -0
- package/src/components/advance-invoices/list/use-advance-invoice-download.ts +63 -0
- package/src/components/button-loader.tsx +11 -0
- package/src/components/combobox.tsx +96 -0
- package/src/components/company-registry/company-registry-autocomplete.tsx +151 -0
- package/src/components/company-registry/company-registry.hooks.ts +67 -0
- package/src/components/company-registry/index.ts +7 -0
- package/src/components/credit-notes/create/create-credit-note-form.tsx +332 -0
- package/src/components/credit-notes/create/index.ts +1 -0
- package/src/components/credit-notes/create/locales/de.ts +69 -0
- package/src/components/credit-notes/create/locales/sl.ts +67 -0
- package/src/components/credit-notes/credit-notes.hooks.ts +22 -0
- package/src/components/credit-notes/index.ts +10 -0
- package/src/components/credit-notes/list/index.ts +3 -0
- package/src/components/credit-notes/list/list-row-actions.tsx +116 -0
- package/src/components/credit-notes/list/list-table.tsx +183 -0
- package/src/components/credit-notes/list/locales/de.ts +33 -0
- package/src/components/credit-notes/list/locales/sl.ts +33 -0
- package/src/components/credit-notes/list/use-credit-note-download.ts +65 -0
- package/src/components/customers/create-customer-form/create-customer-form.tsx +134 -0
- package/src/components/customers/create-customer-form/locales/de.ts +20 -0
- package/src/components/customers/create-customer-form/locales/sl.ts +20 -0
- package/src/components/customers/customer-autocomplete.tsx +173 -0
- package/src/components/customers/customer-combobox.tsx +130 -0
- package/src/components/customers/customer-list-table/customer-list-row-actions.tsx +48 -0
- package/src/components/customers/customer-list-table/customer-list-table.tsx +124 -0
- package/src/components/customers/customer-list-table/index.ts +2 -0
- package/src/components/customers/customer-list-table/locales/de.ts +16 -0
- package/src/components/customers/customer-list-table/locales/sl.ts +16 -0
- package/src/components/customers/customers.hooks.test.ts +348 -0
- package/src/components/customers/customers.hooks.ts +57 -0
- package/src/components/customers/index.ts +5 -0
- package/src/components/dashboard/chart-empty-state.tsx +29 -0
- package/src/components/dashboard/collection-rate-card/collection-rate-card.tsx +80 -0
- package/src/components/dashboard/collection-rate-card/index.ts +4 -0
- package/src/components/dashboard/collection-rate-card/locales/sl.ts +3 -0
- package/src/components/dashboard/collection-rate-card/use-collection-rate.ts +74 -0
- package/src/components/dashboard/index.ts +54 -0
- package/src/components/dashboard/invoice-status-chart/index.ts +4 -0
- package/src/components/dashboard/invoice-status-chart/invoice-status-chart.tsx +130 -0
- package/src/components/dashboard/invoice-status-chart/locales/sl.ts +9 -0
- package/src/components/dashboard/invoice-status-chart/use-invoice-status.ts +105 -0
- package/src/components/dashboard/loading-card.tsx +19 -0
- package/src/components/dashboard/payment-methods-chart/index.ts +4 -0
- package/src/components/dashboard/payment-methods-chart/locales/sl.ts +12 -0
- package/src/components/dashboard/payment-methods-chart/payment-methods-chart.tsx +152 -0
- package/src/components/dashboard/payment-methods-chart/use-payment-methods.ts +50 -0
- package/src/components/dashboard/payment-trend-chart/index.ts +4 -0
- package/src/components/dashboard/payment-trend-chart/locales/sl.ts +5 -0
- package/src/components/dashboard/payment-trend-chart/payment-trend-chart.tsx +137 -0
- package/src/components/dashboard/payment-trend-chart/use-payment-trend.ts +92 -0
- package/src/components/dashboard/revenue-card.tsx +49 -0
- package/src/components/dashboard/revenue-trend-chart/index.ts +4 -0
- package/src/components/dashboard/revenue-trend-chart/locales/sl.ts +5 -0
- package/src/components/dashboard/revenue-trend-chart/revenue-trend-chart.tsx +137 -0
- package/src/components/dashboard/revenue-trend-chart/use-revenue-trend.ts +93 -0
- package/src/components/dashboard/shared/index.ts +5 -0
- package/src/components/dashboard/shared/use-revenue-data.ts +160 -0
- package/src/components/dashboard/shared/use-stats-counts.ts +89 -0
- package/src/components/dashboard/shared/use-stats-query.ts +38 -0
- package/src/components/dashboard/stat-card.tsx +41 -0
- package/src/components/dashboard/tax-collected-card/index.ts +2 -0
- package/src/components/dashboard/tax-collected-card/tax-collected-card.tsx +77 -0
- package/src/components/dashboard/tax-collected-card/use-tax-collected.ts +145 -0
- package/src/components/dashboard/top-customers-chart/index.ts +4 -0
- package/src/components/dashboard/top-customers-chart/locales/sl.ts +5 -0
- package/src/components/dashboard/top-customers-chart/top-customers-chart.tsx +130 -0
- package/src/components/dashboard/top-customers-chart/use-top-customers.ts +72 -0
- package/src/components/documents/create/document-add-item-form.tsx +379 -0
- package/src/components/documents/create/document-add-item-tax-rate-field.tsx +120 -0
- package/src/components/documents/create/document-details-section.tsx +597 -0
- package/src/components/documents/create/document-items-section.tsx +133 -0
- package/src/components/documents/create/document-recipient-section.tsx +101 -0
- package/src/components/documents/create/form-types.ts +36 -0
- package/src/components/documents/create/index.ts +9 -0
- package/src/components/documents/create/live-preview.tsx +235 -0
- package/src/components/documents/create/mark-as-paid-section.tsx +82 -0
- package/src/components/documents/create/prepare-document-submission.test.ts +132 -0
- package/src/components/documents/create/prepare-document-submission.ts +187 -0
- package/src/components/documents/create/prepare-preview-data.test.ts +155 -0
- package/src/components/documents/create/prepare-preview-data.ts +16 -0
- package/src/components/documents/create/smart-code-insert-button.tsx +139 -0
- package/src/components/documents/create/use-document-customer-form.ts +161 -0
- package/src/components/documents/document-preview.tsx +13 -0
- package/src/components/documents/documents.hooks.ts +146 -0
- package/src/components/documents/index.ts +23 -0
- package/src/components/documents/shared/document-preview-display.tsx +172 -0
- package/src/components/documents/shared/index.ts +3 -0
- package/src/components/documents/shared/scaled-document-preview.tsx +70 -0
- package/src/components/documents/shared/use-a4-scaling.ts +62 -0
- package/src/components/documents/types.ts +61 -0
- package/src/components/documents/view/document-actions-bar.tsx +328 -0
- package/src/components/documents/view/document-details-card.tsx +179 -0
- package/src/components/documents/view/document-payments-list.tsx +256 -0
- package/src/components/documents/view/index.ts +4 -0
- package/src/components/documents/view/locales/de.ts +85 -0
- package/src/components/documents/view/locales/sl.ts +84 -0
- package/src/components/documents/view/use-document-download.ts +125 -0
- package/src/components/entities/create-entity-form.tsx +105 -0
- package/src/components/entities/entities.hooks.ts +50 -0
- package/src/components/entities/entity-settings-form/email-template-variables-info.tsx +103 -0
- package/src/components/entities/entity-settings-form/entity-settings-form.tsx +1326 -0
- package/src/components/entities/entity-settings-form/image-upload-with-crop.tsx +222 -0
- package/src/components/entities/entity-settings-form/index.ts +2 -0
- package/src/components/entities/entity-settings-form/input-with-preview.tsx +190 -0
- package/src/components/entities/entity-settings-form/locales/de.ts +192 -0
- package/src/components/entities/entity-settings-form/locales/sl.ts +188 -0
- package/src/components/entities/furs-settings-form/furs-settings-form.tsx +410 -0
- package/src/components/entities/furs-settings-form/furs-settings.hooks.ts +320 -0
- package/src/components/entities/furs-settings-form/index.ts +3 -0
- package/src/components/entities/furs-settings-form/locales/de.ts +233 -0
- package/src/components/entities/furs-settings-form/locales/en.ts +194 -0
- package/src/components/entities/furs-settings-form/locales/sl.ts +196 -0
- package/src/components/entities/furs-settings-form/sections/certificate-settings-section.tsx +242 -0
- package/src/components/entities/furs-settings-form/sections/enable-fiscalization-section.tsx +139 -0
- package/src/components/entities/furs-settings-form/sections/general-settings-section.tsx +252 -0
- package/src/components/entities/furs-settings-form/sections/premises-management-section.tsx +370 -0
- package/src/components/entities/furs-settings-form/sections/register-premise-dialog.tsx +420 -0
- package/src/components/entities/keys.ts +2 -0
- package/src/components/entities/settings/branding-settings-form.tsx +274 -0
- package/src/components/entities/settings/company-settings-form.tsx +256 -0
- package/src/components/entities/settings/defaults-settings-form.tsx +501 -0
- package/src/components/entities/settings/email-settings-form.tsx +288 -0
- package/src/components/entities/settings/eslog-settings-form.tsx +113 -0
- package/src/components/entities/settings/index.ts +8 -0
- package/src/components/entities/settings/number-format-settings-form.tsx +244 -0
- package/src/components/entities/settings/pdf-template-selector/demo-invoice-data.ts +164 -0
- package/src/components/entities/settings/pdf-template-selector/index.ts +2 -0
- package/src/components/entities/settings/pdf-template-selector/locales/de.ts +18 -0
- package/src/components/entities/settings/pdf-template-selector/locales/sl.ts +18 -0
- package/src/components/entities/settings/pdf-template-selector/pdf-template-cards.tsx +49 -0
- package/src/components/entities/settings/settings-footer.tsx +16 -0
- package/src/components/entities/settings/tax-rules-settings-form.tsx +346 -0
- package/src/components/estimates/create/create-estimate-form.tsx +384 -0
- package/src/components/estimates/create/locales/de.ts +64 -0
- package/src/components/estimates/create/locales/sl.ts +63 -0
- package/src/components/estimates/create/prepare-estimate-submission.ts +39 -0
- package/src/components/estimates/create/use-estimate-customer-form.ts +5 -0
- package/src/components/estimates/estimates.hooks.ts +15 -0
- package/src/components/estimates/index.ts +6 -0
- package/src/components/estimates/list/index.ts +3 -0
- package/src/components/estimates/list/list-row-actions.tsx +103 -0
- package/src/components/estimates/list/list-table.tsx +171 -0
- package/src/components/estimates/list/locales/de.ts +26 -0
- package/src/components/estimates/list/locales/sl.ts +26 -0
- package/src/components/estimates/list/use-estimate-download.ts +63 -0
- package/src/components/export/document-export-form.tsx +288 -0
- package/src/components/export/index.ts +2 -0
- package/src/components/form/form-input.tsx +89 -0
- package/src/components/form/index.ts +1 -0
- package/src/components/invoices/create/create-invoice-form.tsx +852 -0
- package/src/components/invoices/create/eslog-validation.test.ts +242 -0
- package/src/components/invoices/create/eslog-validation.ts +208 -0
- package/src/components/invoices/create/locales/de.ts +118 -0
- package/src/components/invoices/create/locales/sl.ts +114 -0
- package/src/components/invoices/create/prepare-invoice-submission.test.ts +777 -0
- package/src/components/invoices/create/prepare-invoice-submission.ts +79 -0
- package/src/components/invoices/create/use-invoice-customer-form.ts +5 -0
- package/src/components/invoices/index.ts +9 -0
- package/src/components/invoices/invoices-furs.hooks.ts +28 -0
- package/src/components/invoices/invoices.hooks.ts +110 -0
- package/src/components/invoices/list/index.ts +3 -0
- package/src/components/invoices/list/list-row-actions.tsx +132 -0
- package/src/components/invoices/list/list-table.tsx +165 -0
- package/src/components/invoices/list/locales/de.ts +33 -0
- package/src/components/invoices/list/locales/sl.ts +33 -0
- package/src/components/invoices/list/use-invoice-download.ts +62 -0
- package/src/components/invoices/send-email-dialog/index.ts +1 -0
- package/src/components/invoices/send-email-dialog/locales/de.ts +18 -0
- package/src/components/invoices/send-email-dialog/locales/sl.ts +17 -0
- package/src/components/invoices/send-email-dialog/send-email-dialog.tsx +289 -0
- package/src/components/invoices/send-email-dialog.tsx +2 -0
- package/src/components/invoices/shared/index.ts +2 -0
- package/src/components/invoices/shared/scaled-document-preview.tsx +32 -0
- package/src/components/invoices/shared/use-a4-scaling.tsx +39 -0
- package/src/components/invoices/view/eslog-info-display.tsx +160 -0
- package/src/components/invoices/view/furs-info-display.tsx +213 -0
- package/src/components/items/create-item-form/create-item-form.tsx +155 -0
- package/src/components/items/create-item-form/locales/de.ts +14 -0
- package/src/components/items/create-item-form/locales/en.ts +9 -0
- package/src/components/items/create-item-form/locales/sl.ts +14 -0
- package/src/components/items/item-combobox.tsx +147 -0
- package/src/components/items/item-list-table/item-list-header.tsx +33 -0
- package/src/components/items/item-list-table/item-list-row-actions.tsx +48 -0
- package/src/components/items/item-list-table/item-list-row.tsx +32 -0
- package/src/components/items/item-list-table/item-list-table.tsx +76 -0
- package/src/components/items/item-list-table/locales/de.ts +10 -0
- package/src/components/items/item-list-table/locales/en.ts +10 -0
- package/src/components/items/item-list-table/locales/sl.ts +10 -0
- package/src/components/items/items.hooks.ts +63 -0
- package/src/components/loading-spinner.tsx +24 -0
- package/src/components/payments/create-payment-form/create-payment-form.tsx +222 -0
- package/src/components/payments/create-payment-form/locales/de.ts +20 -0
- package/src/components/payments/create-payment-form/locales/sl.ts +20 -0
- package/src/components/payments/edit-payment-form/edit-payment-form.tsx +230 -0
- package/src/components/payments/edit-payment-form/index.ts +1 -0
- package/src/components/payments/edit-payment-form/locales/de.ts +20 -0
- package/src/components/payments/edit-payment-form/locales/sl.ts +20 -0
- package/src/components/payments/index.ts +4 -0
- package/src/components/payments/list/index.ts +2 -0
- package/src/components/payments/list/list-row-actions.tsx +98 -0
- package/src/components/payments/list/list-table.tsx +186 -0
- package/src/components/payments/list/locales/de.ts +19 -0
- package/src/components/payments/list/locales/sl.ts +19 -0
- package/src/components/payments/payments.hooks.ts +15 -0
- package/src/components/request-logs/index.ts +3 -0
- package/src/components/request-logs/request-log-detail.tsx +242 -0
- package/src/components/request-logs/request-log-list-table.tsx +266 -0
- package/src/components/request-logs/request-logs-page.tsx +10 -0
- package/src/components/table/README.md +410 -0
- package/src/components/table/data-table.tsx +251 -0
- package/src/components/table/date-cell.tsx +35 -0
- package/src/components/table/filter-bar.tsx +114 -0
- package/src/components/table/filter-panel.tsx +407 -0
- package/src/components/table/hooks/use-table-fetch.ts +17 -0
- package/src/components/table/hooks/use-table-query.ts +36 -0
- package/src/components/table/hooks/use-table-state.ts +293 -0
- package/src/components/table/index.ts +35 -0
- package/src/components/table/search-input.tsx +85 -0
- package/src/components/table/sortable-header.tsx +56 -0
- package/src/components/table/table-empty-state.tsx +40 -0
- package/src/components/table/table-no-results.tsx +41 -0
- package/src/components/table/table-pagination.tsx +42 -0
- package/src/components/table/table-skeleton.tsx +54 -0
- package/src/components/table/types.ts +136 -0
- package/src/components/tax-reports/index.ts +1 -0
- package/src/components/tax-reports/kir-export-form.tsx +172 -0
- package/src/components/taxes/create-tax-form/create-tax-form.tsx +112 -0
- package/src/components/taxes/create-tax-form/locales/de.ts +8 -0
- package/src/components/taxes/create-tax-form/locales/en.ts +7 -0
- package/src/components/taxes/create-tax-form/locales/sl.ts +8 -0
- package/src/components/taxes/tax-list-table/locales/de.ts +11 -0
- package/src/components/taxes/tax-list-table/locales/en.ts +10 -0
- package/src/components/taxes/tax-list-table/locales/sl.ts +11 -0
- package/src/components/taxes/tax-list-table/tax-list-header.tsx +29 -0
- package/src/components/taxes/tax-list-table/tax-list-row-actions.tsx +43 -0
- package/src/components/taxes/tax-list-table/tax-list-row.tsx +46 -0
- package/src/components/taxes/tax-list-table/tax-list-table.tsx +59 -0
- package/src/components/taxes/taxes.hooks.ts +35 -0
- package/src/components/ui/alert-dialog.tsx +61 -0
- package/src/components/ui/alert.tsx +72 -0
- package/src/components/ui/badge.tsx +48 -0
- package/src/components/ui/breadcrumb.tsx +132 -0
- package/src/components/ui/button.tsx +61 -0
- package/src/components/ui/calendar.tsx +213 -0
- package/src/components/ui/card.tsx +94 -0
- package/src/components/ui/chart.tsx +380 -0
- package/src/components/ui/checkbox.tsx +27 -0
- package/src/components/ui/collapsible.tsx +56 -0
- package/src/components/ui/command.tsx +187 -0
- package/src/components/ui/dialog.tsx +187 -0
- package/src/components/ui/drawer.tsx +123 -0
- package/src/components/ui/dropdown-menu.tsx +291 -0
- package/src/components/ui/form.tsx +166 -0
- package/src/components/ui/input-group.tsx +149 -0
- package/src/components/ui/input.tsx +20 -0
- package/src/components/ui/label.tsx +18 -0
- package/src/components/ui/loading-spinner.tsx +16 -0
- package/src/components/ui/popover.tsx +108 -0
- package/src/components/ui/radio-group.tsx +37 -0
- package/src/components/ui/select.tsx +200 -0
- package/src/components/ui/separator.tsx +23 -0
- package/src/components/ui/sheet.tsx +145 -0
- package/src/components/ui/sidebar.tsx +771 -0
- package/src/components/ui/skeleton.tsx +13 -0
- package/src/components/ui/sonner.tsx +60 -0
- package/src/components/ui/spinner.tsx +10 -0
- package/src/components/ui/sticky-form-footer.tsx +55 -0
- package/src/components/ui/switch.tsx +30 -0
- package/src/components/ui/table.tsx +101 -0
- package/src/components/ui/tabs.tsx +80 -0
- package/src/components/ui/textarea.tsx +18 -0
- package/src/components/ui/tooltip.tsx +89 -0
- package/src/components/wl-subscription/index.ts +2 -0
- package/src/components/wl-subscription/locked-feature.tsx +173 -0
- package/src/components/wl-subscription/upgrade-modal.tsx +209 -0
- package/src/frontend.tsx +28 -0
- package/src/generate-schemas.ts +265 -0
- package/src/generated/schemas/advanceinvoice.ts +177 -0
- package/src/generated/schemas/creditnote.ts +187 -0
- package/src/generated/schemas/customer.ts +29 -0
- package/src/generated/schemas/entity.ts +252 -0
- package/src/generated/schemas/estimate.ts +159 -0
- package/src/generated/schemas/furssettings.ts +25 -0
- package/src/generated/schemas/index.ts +24 -0
- package/src/generated/schemas/invoice.ts +167 -0
- package/src/generated/schemas/item.ts +38 -0
- package/src/generated/schemas/payment.ts +44 -0
- package/src/generated/schemas/previewadvanceinvoice_body.ts +354 -0
- package/src/generated/schemas/previewestimate_body.ts +309 -0
- package/src/generated/schemas/registerfursmovablepremise_body.ts +22 -0
- package/src/generated/schemas/registerfursrealestatepremise_body.ts +32 -0
- package/src/generated/schemas/renderdocument_body.ts +594 -0
- package/src/generated/schemas/sendemail_body.ts +26 -0
- package/src/generated/schemas/startpdfexport_body.ts +20 -0
- package/src/generated/schemas/tax.ts +48 -0
- package/src/generated/schemas/uploadfile_body.ts +23 -0
- package/src/generated/schemas/uploadfurscertificate_body.ts +20 -0
- package/src/generated/schemas/userfurssettings.ts +19 -0
- package/src/hooks/create-resource-hooks.test.ts +483 -0
- package/src/hooks/create-resource-hooks.ts +300 -0
- package/src/hooks/use-debounce.ts +12 -0
- package/src/hooks/use-duplicate-document.ts +185 -0
- package/src/hooks/use-media-query.tsx +19 -0
- package/src/hooks/use-mobile.ts +39 -0
- package/src/hooks/use-next-document-number.ts +57 -0
- package/src/hooks/use-resource-mutation.ts +118 -0
- package/src/hooks/use-vies-check.ts +130 -0
- package/src/index.css +11 -0
- package/src/index.html +13 -0
- package/src/index.tsx +12 -0
- package/src/lib/auth.ts +4 -0
- package/src/lib/browser-cookies.ts +70 -0
- package/src/lib/constants.ts +287 -0
- package/src/lib/cookies.ts +36 -0
- package/src/lib/schemas/advance-invoice.ts +43 -0
- package/src/lib/schemas/credit-note.ts +32 -0
- package/src/lib/schemas/estimate.ts +31 -0
- package/src/lib/schemas/index.ts +18 -0
- package/src/lib/schemas/invoice.ts +43 -0
- package/src/lib/schemas/shared.ts +79 -0
- package/src/lib/translation.ts +38 -0
- package/src/lib/utils.ts +6 -0
- package/src/providers/entities-context.tsx +41 -0
- package/src/providers/entities-provider.tsx +201 -0
- package/src/providers/form-footer-context.tsx +72 -0
- package/src/providers/sdk-provider.tsx +164 -0
- package/src/providers/white-label-provider.tsx +91 -0
- package/src/providers/wl-subscription-provider.tsx +277 -0
- package/src/utils/string-helpers.ts +111 -0
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
// Company settings
|
|
3
|
+
"Company Information": "Podatki o podjetju",
|
|
4
|
+
"Basic information about your company": "Osnovni podatki o vašem podjetju",
|
|
5
|
+
// Branding settings
|
|
6
|
+
Branding: "Blagovna znamka",
|
|
7
|
+
"Primary Color": "Primarna barva",
|
|
8
|
+
Logo: "Logotip",
|
|
9
|
+
"Logo URL": "URL logotipa",
|
|
10
|
+
"Enter the URL of your company logo": "Vnesite URL logotipa vašega podjetja",
|
|
11
|
+
"Upload your company logo for invoices": "Naložite logotip vašega podjetja za račune",
|
|
12
|
+
"Upload Logo": "Naloži logotip",
|
|
13
|
+
"Change Logo": "Spremeni logotip",
|
|
14
|
+
"Current logo (displayed on invoices)": "Trenutni logotip (prikazan na računih)",
|
|
15
|
+
"Logo preview": "Predogled logotipa",
|
|
16
|
+
"Crop Your Logo": "Obreži logotip",
|
|
17
|
+
Signature: "Podpis",
|
|
18
|
+
"Upload a signature image for PDFs (optional)": "Naložite sliko podpisa za PDF-je (neobvezno)",
|
|
19
|
+
"Upload Signature": "Naloži podpis",
|
|
20
|
+
"Change Signature": "Spremeni podpis",
|
|
21
|
+
"Current signature (for PDF documents)": "Trenutni podpis (za PDF dokumente)",
|
|
22
|
+
"Signature preview": "Predogled podpisa",
|
|
23
|
+
"Crop Your Signature": "Obreži podpis",
|
|
24
|
+
"Adjust the crop area or upload the full image": "Prilagodite območje obrezovanja ali naložite celotno sliko",
|
|
25
|
+
"Upload failed. Please try again.": "Nalaganje ni uspelo. Prosim poskusite znova.",
|
|
26
|
+
"Uploading...": "Nalaganje...",
|
|
27
|
+
"Upload & Save": "Naloži in shrani",
|
|
28
|
+
Cancel: "Prekliči",
|
|
29
|
+
Localization: "Lokalizacija",
|
|
30
|
+
"Currency Code": "Koda valute",
|
|
31
|
+
"ISO 4217 currency code (e.g., USD, EUR, GBP)": "ISO 4217 koda valute (npr. USD, EUR, GBP)",
|
|
32
|
+
Locale: "Lokalnost",
|
|
33
|
+
"BCP 47 language tag (e.g., en-US, de-DE, sl-SI)": "BCP 47 jezikovna oznaka (npr. en-US, de-DE, sl-SI)",
|
|
34
|
+
"Select currency": "Izberite valuto",
|
|
35
|
+
"Select locale": "Izberite lokalnost",
|
|
36
|
+
"Configure entity localization": "Konfigurirajte lokalizacijo pravne osebe",
|
|
37
|
+
"Email Settings": "Nastavitve e-pošte",
|
|
38
|
+
"Configure email settings for invoices": "Konfigurirajte nastavitve e-pošte za račune",
|
|
39
|
+
"Email Address": "Naslov e-pošte",
|
|
40
|
+
"Email address to send invoices to": "Naslov e-pošte za pošiljanje računov",
|
|
41
|
+
"Email Subject": "Zadeva e-pošte",
|
|
42
|
+
"Subject line for email invoices": "Vrstica zadeve za e-pošte računov",
|
|
43
|
+
"Email Body": "Vsebina e-pošte",
|
|
44
|
+
"Body content for email invoices": "Vsebina teksta za e-pošte računov",
|
|
45
|
+
"Save Settings": "Shrani nastavitve",
|
|
46
|
+
// Document Defaults section
|
|
47
|
+
"Document Defaults": "Privzete vrednosti dokumentov",
|
|
48
|
+
"Default values for new documents": "Privzete vrednosti za nove dokumente",
|
|
49
|
+
"Default Note": "Privzeta opomba",
|
|
50
|
+
"Default Invoice Note": "Privzeta opomba računa",
|
|
51
|
+
"This note will be pre-filled when creating new invoices":
|
|
52
|
+
"Ta opomba bo vnaprej izpolnjena pri ustvarjanju novih računov",
|
|
53
|
+
"This note will be pre-filled when creating new estimates":
|
|
54
|
+
"Ta opomba bo vnaprej izpolnjena pri ustvarjanju novih predračunov",
|
|
55
|
+
"This note will be pre-filled when creating new credit notes":
|
|
56
|
+
"Ta opomba bo vnaprej izpolnjena pri ustvarjanju novih dobropisov",
|
|
57
|
+
"Payment terms pre-filled when creating new invoices":
|
|
58
|
+
"Plačilni pogoji bodo vnaprej izpolnjeni pri ustvarjanju novih računov",
|
|
59
|
+
"Payment terms pre-filled when creating new estimates":
|
|
60
|
+
"Plačilni pogoji bodo vnaprej izpolnjeni pri ustvarjanju novih predračunov",
|
|
61
|
+
"Payment terms pre-filled when creating new credit notes":
|
|
62
|
+
"Plačilni pogoji bodo vnaprej izpolnjeni pri ustvarjanju novih dobropisov",
|
|
63
|
+
"Payment due by {document_due_date}. Please reference invoice {document_number}.":
|
|
64
|
+
"Rok plačila {document_due_date}. Prosimo, navedite številko računa {document_number}.",
|
|
65
|
+
"Net 30 days. Payment due by {document_due_date}.": "Neto 30 dni. Rok plačila {document_due_date}.",
|
|
66
|
+
"This estimate is valid until {document_valid_until}.": "Ta predračun velja do {document_valid_until}.",
|
|
67
|
+
"Payment due upon acceptance.": "Plačilo ob sprejemu.",
|
|
68
|
+
"Credit note for invoice {document_number}.": "Dobropis za račun {document_number}.",
|
|
69
|
+
"Credit will be applied to your account.": "Dobropis bo upoštevan na vašem računu.",
|
|
70
|
+
"Invoice Notes": "Opombe računa",
|
|
71
|
+
"Smart Template Variables": "Pametne spremenljivke predloge",
|
|
72
|
+
"Use variables to personalize your notes automatically": "Uporabite spremenljivke za samodejno prilagajanje opomb",
|
|
73
|
+
"Set a default note that will appear on all new invoices. Use template variables to personalize the note automatically.":
|
|
74
|
+
"Nastavite privzeto opombo, ki bo prikazana na vseh novih računih. Uporabite spremenljivke predloge za samodejno prilagajanje opombe.",
|
|
75
|
+
// Smart code insert button
|
|
76
|
+
"Insert variable": "Vstavi spremenljivko",
|
|
77
|
+
Entity: "Podjetje",
|
|
78
|
+
Document: "Dokument",
|
|
79
|
+
Customer: "Stranka",
|
|
80
|
+
Other: "Drugo",
|
|
81
|
+
"Company name": "Ime podjetja",
|
|
82
|
+
"Email address": "E-poštni naslov",
|
|
83
|
+
"Invoice number": "Številka računa",
|
|
84
|
+
"Invoice date": "Datum računa",
|
|
85
|
+
"Due date": "Rok plačila",
|
|
86
|
+
"Total amount": "Skupni znesek",
|
|
87
|
+
Currency: "Valuta",
|
|
88
|
+
"Customer name": "Ime stranke",
|
|
89
|
+
"Customer email": "E-pošta stranke",
|
|
90
|
+
"Today's date": "Današnji datum",
|
|
91
|
+
"Current year": "Tekoče leto",
|
|
92
|
+
// Payment terms defaults
|
|
93
|
+
"Default Payment Terms": "Privzeti plačilni pogoji",
|
|
94
|
+
"This payment terms will be pre-filled when creating new documents":
|
|
95
|
+
"Ti plačilni pogoji bodo vnaprej izpolnjeni pri ustvarjanju novih dokumentov",
|
|
96
|
+
"Payment Terms": "Plačilni pogoji",
|
|
97
|
+
"Add payment terms...": "Dodajte plačilne pogoje...",
|
|
98
|
+
// Document footer
|
|
99
|
+
"Document Footer": "Noga dokumenta",
|
|
100
|
+
"Footer text displayed at the bottom of PDF documents": "Besedilo noge, prikazano na dnu PDF dokumentov",
|
|
101
|
+
"Footer text displayed at the bottom of all PDF documents": "Besedilo noge, prikazano na dnu vseh PDF dokumentov",
|
|
102
|
+
"{entity_name} | Due Date: {document_due_date} | Invoice #{document_number}":
|
|
103
|
+
"{entity_name} | Rok plačila: {document_due_date} | Račun #{document_number}",
|
|
104
|
+
// Overdue Notifications section
|
|
105
|
+
"Overdue Notifications": "Opomniki o zapadlih računih",
|
|
106
|
+
"Automatically remind customers about overdue invoices": "Samodejno opominjajte stranke o zapadlih računih",
|
|
107
|
+
"Enable Notifications": "Omogoči opominke",
|
|
108
|
+
"Send automatic payment reminder emails to customers with overdue invoices":
|
|
109
|
+
"Pošiljajte avtomatska opomniška e-poštna sporočila strankam z zapadlimi računi",
|
|
110
|
+
"Reminder Days": "Dnevi opomnikov",
|
|
111
|
+
"Days after due date to send reminders (comma-separated). E.g., '7, 14, 30' sends reminders at 7, 14, and 30 days overdue.":
|
|
112
|
+
"Dnevi po roku plačila za pošiljanje opomnikov (ločeni z vejico). Npr. '7, 14, 30' pošlje opomnike 7, 14 in 30 dni po zapadlosti.",
|
|
113
|
+
"Custom Reminder Templates": "Prilagojene predloge opomnikov",
|
|
114
|
+
"Subject line for overdue notification emails": "Vrstica zadeve za e-pošte opomnikov o zapadlosti",
|
|
115
|
+
"Body content for overdue emails. Use {invoice_list} to include the invoice table, or it will be auto-appended.":
|
|
116
|
+
"Vsebina teksta za e-pošte o zapadlosti. Uporabite {invoice_list} za vključitev tabele računov, sicer bo samodejno dodana.",
|
|
117
|
+
"Dear {customer_name},\n\nThis is a reminder about your overdue invoices...":
|
|
118
|
+
"Spoštovani {customer_name},\n\nTo je opomnik o vaših zapadlih računih...",
|
|
119
|
+
"Payment Reminders": "Opomniki o plačilih",
|
|
120
|
+
"When enabled, customers will automatically receive email reminders when their invoices become overdue. Emails are sent on the exact day each threshold is reached.":
|
|
121
|
+
"Ko je omogočeno, bodo stranke samodejno prejele e-poštne opomnike, ko njihovi računi zapadejo. E-pošta se pošlje natančno na dan, ko je dosežen vsak prag.",
|
|
122
|
+
"Available Variables": "Razpoložljive spremenljivke",
|
|
123
|
+
"{customer_name}, {entity_name}, {entity_email}, {invoice_list}, {total_amount}, {overdue_count}":
|
|
124
|
+
"{customer_name}, {entity_name}, {entity_email}, {invoice_list}, {total_amount}, {overdue_count}",
|
|
125
|
+
// UPN QR Payment section
|
|
126
|
+
"UPN QR Payment": "UPN QR plačilo",
|
|
127
|
+
"Configure UPN QR payment slip for invoices": "Konfigurirajte UPN QR plačilni nalog za račune",
|
|
128
|
+
IBAN: "IBAN",
|
|
129
|
+
"Bank account IBAN for receiving payments": "IBAN bančnega računa za prejemanje plačil",
|
|
130
|
+
"Enable UPN QR on invoices": "Omogoči UPN QR na računih",
|
|
131
|
+
"Show payment QR code on PDF invoices for easy mobile banking payments":
|
|
132
|
+
"Prikaži QR kodo za plačilo na PDF računih za enostavna mobilna bančna plačila",
|
|
133
|
+
"Display Mode": "Način prikaza",
|
|
134
|
+
"QR code only": "Samo QR koda",
|
|
135
|
+
"Shows compact QR code inline with invoice content": "Prikaže kompaktno QR kodo v vrstici z vsebino računa",
|
|
136
|
+
"Full UPN payment slip": "Celoten UPN plačilni nalog",
|
|
137
|
+
"Shows complete payment slip at bottom of page": "Prikaže celoten plačilni nalog na dnu strani",
|
|
138
|
+
"Purpose Code": "Koda namena",
|
|
139
|
+
"OTHR - Other": "OTHR - Drugo",
|
|
140
|
+
"GDSV - Goods and Services": "GDSV - Blago in storitve",
|
|
141
|
+
"SUPP - Supplier Payment": "SUPP - Plačilo dobavitelju",
|
|
142
|
+
"Payment purpose code (ISO 20022)": "Koda namena plačila (ISO 20022)",
|
|
143
|
+
"UPN QR Payments": "UPN QR plačila",
|
|
144
|
+
"UPN QR is a Slovenian standard for payment slips. When enabled, your invoices will include a QR code that customers can scan with their mobile banking app to pay instantly.":
|
|
145
|
+
"UPN QR je slovenski standard za plačilne naloge. Ko je omogočen, bodo vaši računi vključevali QR kodo, ki jo stranke lahko skenirajo z mobilno bančno aplikacijo za takojšnje plačilo.",
|
|
146
|
+
// Number format settings
|
|
147
|
+
Invoice: "Račun",
|
|
148
|
+
Estimate: "Predračun",
|
|
149
|
+
"Credit Note": "Dobropis",
|
|
150
|
+
"Advance Invoice": "Avansni račun",
|
|
151
|
+
"Number Format": "Format številke",
|
|
152
|
+
Preview: "Predogled",
|
|
153
|
+
// Tax rules settings
|
|
154
|
+
"EU Tax Rules": "EU davčna pravila",
|
|
155
|
+
"Automatic tax handling for cross-border transactions": "Samodejno obravnavanje davkov za čezmejne transakcije",
|
|
156
|
+
"tax-rules.vies_validate_vat.label": "VIES preverjanje DDV",
|
|
157
|
+
"tax-rules.vies_validate_vat.description":
|
|
158
|
+
"Preveri EU DDV številke preko VIES API-ja. DDV številke strank se preverijo pred ustvarjanjem računov.",
|
|
159
|
+
"tax-rules.auto_reverse_charge.label": "Samodejni obrnjeni davek",
|
|
160
|
+
"tax-rules.auto_reverse_charge.description":
|
|
161
|
+
"Samodejno uporabi 0% davek (obrnjena davčna obveznost) za intra-EU B2B transakcije z veljavnimi DDV številkami.",
|
|
162
|
+
"tax-rules.auto_remove_tax_export.label": "Samodejno odstrani izvozni davek",
|
|
163
|
+
"tax-rules.auto_remove_tax_export.description": "Samodejno odstrani vse davke za izvoz v države izven EU.",
|
|
164
|
+
"tax-rules.require_gross_prices.label": "Zahtevaj bruto cene",
|
|
165
|
+
"tax-rules.require_gross_prices.description":
|
|
166
|
+
"Zahtevaj bruto cene, ko se uporabi obrnjena davčna obveznost. Prepreči nepričakovane spremembe skupnih zneskov računov.",
|
|
167
|
+
// Tax clauses settings
|
|
168
|
+
"Default Tax Clauses": "Privzete davčne klavzule",
|
|
169
|
+
"Set default tax clauses that are automatically added to documents based on transaction type":
|
|
170
|
+
"Nastavite privzete davčne klavzule, ki se samodejno dodajo dokumentom glede na vrsto transakcije.",
|
|
171
|
+
"tax-clauses.other-title": "Čezmejne davčne klavzule",
|
|
172
|
+
"tax-clauses.other-description": "Davčne klavzule za EU in mednarodne transakcije (samoobdavčitev, izvoz).",
|
|
173
|
+
"tax-clauses.intra_eu_b2b.label": "Intra-EU B2B (obrnjena davčna obveznost)",
|
|
174
|
+
"tax-clauses.intra_eu_b2b.description":
|
|
175
|
+
"Za prodajo EU podjetjem z veljavnimi DDV številkami. Običajno vključuje izjavo o obrnjeni davčni obveznosti.",
|
|
176
|
+
"Enter reverse charge clause...": "Vnesite klavzulo za samoobdavčitev...",
|
|
177
|
+
"tax-clauses.export.label": "Izvoz (izven EU)",
|
|
178
|
+
"tax-clauses.export.description": "Za prodajo strankam izven EU. Običajno navaja oprostitev DDV za izvoz.",
|
|
179
|
+
"Enter export exemption clause...": "Vnesite klavzulo za izvozno oprostitev...",
|
|
180
|
+
"tax-clauses.domestic.label": "Privzeto / Domače",
|
|
181
|
+
"tax-clauses.domestic.description":
|
|
182
|
+
"Privzeta klavzula za domače transakcije. Za subjekte, ki niso zavezanci za DDV, se prikaže na vseh dokumentih.",
|
|
183
|
+
"Enter default tax clause...": "Vnesite privzeto davčno klavzulo...",
|
|
184
|
+
"tax-clauses.intra_eu_b2c.label": "Intra-EU B2C",
|
|
185
|
+
"Enter EU consumer sales clause...": "Vnesite klavzulo za EU potrošniško prodajo...",
|
|
186
|
+
"tax-clauses.other.description":
|
|
187
|
+
"Te vrste transakcij običajno ne zahtevajo posebnih davčnih klavzul, vendar jih lahko konfigurirate po potrebi.",
|
|
188
|
+
} as const;
|
|
@@ -0,0 +1,410 @@
|
|
|
1
|
+
import { zodResolver } from "@hookform/resolvers/zod";
|
|
2
|
+
import type { Entity } from "@spaceinvoices/js-sdk";
|
|
3
|
+
import { AlertCircle, CheckCircle2, Info } from "lucide-react";
|
|
4
|
+
import { type FC, type ReactNode, useCallback, useEffect, useState } from "react";
|
|
5
|
+
import { useForm } from "react-hook-form";
|
|
6
|
+
import type { z } from "zod";
|
|
7
|
+
import { Alert, AlertDescription, AlertTitle } from "@/ui/components/ui/alert";
|
|
8
|
+
import { Form } from "@/ui/components/ui/form";
|
|
9
|
+
import { PageLoadingSpinner } from "@/ui/components/ui/loading-spinner";
|
|
10
|
+
import { Tabs, TabsList, TabsTrigger } from "@/ui/components/ui/tabs";
|
|
11
|
+
import { Tooltip, TooltipContent, TooltipTrigger } from "@/ui/components/ui/tooltip";
|
|
12
|
+
import { updateFursSettingsSchema } from "@/ui/generated/schemas";
|
|
13
|
+
import type { ComponentTranslationProps } from "@/ui/lib/translation";
|
|
14
|
+
import { createTranslation } from "@/ui/lib/translation";
|
|
15
|
+
import { cn } from "@/ui/lib/utils";
|
|
16
|
+
import { useFormFooterRegistration } from "@/ui/providers/form-footer-context";
|
|
17
|
+
import { useFursPremises, useFursSettings, useUpdateFursSettings } from "./furs-settings.hooks";
|
|
18
|
+
// Import locale files
|
|
19
|
+
import de from "./locales/de";
|
|
20
|
+
import en from "./locales/en";
|
|
21
|
+
import sl from "./locales/sl";
|
|
22
|
+
import { CertificateSettingsSection } from "./sections/certificate-settings-section";
|
|
23
|
+
import { EnableFiscalizationSection } from "./sections/enable-fiscalization-section";
|
|
24
|
+
import { GeneralSettingsSection } from "./sections/general-settings-section";
|
|
25
|
+
import { PremisesManagementSection } from "./sections/premises-management-section";
|
|
26
|
+
|
|
27
|
+
const translations = { de, sl, en } as const;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* FURS Settings Form Schema
|
|
31
|
+
* Uses generated schema from OpenAPI spec
|
|
32
|
+
*/
|
|
33
|
+
const fursSettingsFormSchema = updateFursSettingsSchema.required({
|
|
34
|
+
enabled: true,
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
export type FursSettingsFormSchema = z.infer<typeof fursSettingsFormSchema>;
|
|
38
|
+
|
|
39
|
+
export type StepType = "settings" | "certificate" | "premises" | "enable";
|
|
40
|
+
export type SectionType =
|
|
41
|
+
| "operator"
|
|
42
|
+
| "fiscalization"
|
|
43
|
+
| "advanced"
|
|
44
|
+
| "certificate-upload"
|
|
45
|
+
| "premises-list"
|
|
46
|
+
| "enable-toggle";
|
|
47
|
+
|
|
48
|
+
interface FursSettingsFormProps extends ComponentTranslationProps {
|
|
49
|
+
entity: Entity;
|
|
50
|
+
onSuccess?: () => void;
|
|
51
|
+
onError?: (error: unknown) => void;
|
|
52
|
+
/**
|
|
53
|
+
* Current active step (optional, for URL state management at page level)
|
|
54
|
+
*/
|
|
55
|
+
initialStep?: StepType;
|
|
56
|
+
/**
|
|
57
|
+
* Callback when step changes (optional, for URL state management at page level)
|
|
58
|
+
*/
|
|
59
|
+
onStepChange?: (step: StepType) => void;
|
|
60
|
+
/**
|
|
61
|
+
* Optional render prop to wrap each section with help content
|
|
62
|
+
*/
|
|
63
|
+
renderSection?: (section: SectionType, content: ReactNode) => ReactNode;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* FURS Settings Form Component
|
|
68
|
+
*
|
|
69
|
+
* Implements progressive unlocking flow:
|
|
70
|
+
* 1. General Settings (Step 1 - always accessible, configure numbering strategy & operator info)
|
|
71
|
+
* 2. Certificate Upload (Step 2 - always accessible, upload P12/PFX certificate)
|
|
72
|
+
* 3. Business Premises (Step 3 - unlocked after valid certificate, register locations & devices)
|
|
73
|
+
* 4. Enable Fiscalization (Step 4 - unlocked when all prerequisites met, final activation step)
|
|
74
|
+
*
|
|
75
|
+
* Smart initial step selection: Opens to first incomplete step, or first step if all complete.
|
|
76
|
+
*/
|
|
77
|
+
export const FursSettingsForm: FC<FursSettingsFormProps> = ({
|
|
78
|
+
entity,
|
|
79
|
+
onSuccess,
|
|
80
|
+
onError,
|
|
81
|
+
t: translateFn,
|
|
82
|
+
namespace,
|
|
83
|
+
locale,
|
|
84
|
+
initialStep = "settings",
|
|
85
|
+
onStepChange,
|
|
86
|
+
renderSection,
|
|
87
|
+
}) => {
|
|
88
|
+
// Step navigation state (can be controlled via props for URL sync)
|
|
89
|
+
const [activeStep, setActiveStep] = useState<StepType>(initialStep);
|
|
90
|
+
const [hasInitializedStep, setHasInitializedStep] = useState(false);
|
|
91
|
+
|
|
92
|
+
// Create a guaranteed translation function using the createTranslation utility
|
|
93
|
+
const translate = createTranslation({
|
|
94
|
+
t: translateFn,
|
|
95
|
+
namespace,
|
|
96
|
+
locale,
|
|
97
|
+
translations,
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
// Handle step changes
|
|
101
|
+
const handleStepChange = useCallback(
|
|
102
|
+
(newStep: StepType) => {
|
|
103
|
+
setActiveStep(newStep);
|
|
104
|
+
onStepChange?.(newStep); // Notify parent (e.g., for URL updates)
|
|
105
|
+
},
|
|
106
|
+
[onStepChange],
|
|
107
|
+
);
|
|
108
|
+
|
|
109
|
+
// Fetch FURS settings and premises
|
|
110
|
+
const { data: fursSettings, isLoading: settingsLoading } = useFursSettings(entity.id);
|
|
111
|
+
const { data: premises, isLoading: premisesLoading } = useFursPremises(entity.id);
|
|
112
|
+
|
|
113
|
+
const { mutate: updateSettings, isPending } = useUpdateFursSettings({
|
|
114
|
+
onSuccess: () => {
|
|
115
|
+
onSuccess?.();
|
|
116
|
+
},
|
|
117
|
+
onError: (error) => {
|
|
118
|
+
onError?.(error);
|
|
119
|
+
},
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
const form = useForm<FursSettingsFormSchema>({
|
|
123
|
+
resolver: zodResolver(fursSettingsFormSchema),
|
|
124
|
+
values: {
|
|
125
|
+
enabled: fursSettings?.enabled || false,
|
|
126
|
+
numbering_strategy: fursSettings?.numbering_strategy || "C",
|
|
127
|
+
operator_tax_number: fursSettings?.operator_tax_number || "",
|
|
128
|
+
operator_label: fursSettings?.operator_label || "",
|
|
129
|
+
},
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
// Register with form footer for sticky save button
|
|
133
|
+
useFormFooterRegistration({
|
|
134
|
+
formId: "furs-settings-form",
|
|
135
|
+
isPending,
|
|
136
|
+
isDirty: form.formState.isDirty,
|
|
137
|
+
label: translate("Save Settings"),
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
// Determine completion status
|
|
141
|
+
const hasCertificate = fursSettings?.has_certificate || false;
|
|
142
|
+
const certificateValid = fursSettings?.certificate_status === "valid";
|
|
143
|
+
const hasPremises = (premises?.length || 0) > 0;
|
|
144
|
+
// Check if at least one premise has at least one device
|
|
145
|
+
const hasPremiseWithDevice =
|
|
146
|
+
hasPremises && premises?.some((premise: any) => premise.Devices && premise.Devices.length > 0);
|
|
147
|
+
|
|
148
|
+
// Step unlocking logic (new flow: settings -> certificate -> premises -> enable)
|
|
149
|
+
// - Step 1 (Settings): Always accessible
|
|
150
|
+
// - Step 2 (Certificate): Always accessible
|
|
151
|
+
// - Step 3 (Premises): Requires valid certificate
|
|
152
|
+
// - Step 4 (Enable): Requires certificate + premise + device
|
|
153
|
+
const fursEnabled = fursSettings?.enabled || false;
|
|
154
|
+
const canAccessCertificate = true; // Always accessible
|
|
155
|
+
const canAccessPremises = hasCertificate && certificateValid;
|
|
156
|
+
const canAccessEnable = certificateValid && hasPremises && hasPremiseWithDevice;
|
|
157
|
+
|
|
158
|
+
const steps = [
|
|
159
|
+
{
|
|
160
|
+
id: "settings" as const,
|
|
161
|
+
title: translate("General Settings"),
|
|
162
|
+
complete: true, // Settings are always "complete" - just configuration
|
|
163
|
+
unlocked: true,
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
id: "certificate" as const,
|
|
167
|
+
title: translate("Certificate"),
|
|
168
|
+
complete: hasCertificate && certificateValid,
|
|
169
|
+
unlocked: canAccessCertificate,
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
id: "premises" as const,
|
|
173
|
+
title: translate("Business Premises"),
|
|
174
|
+
complete: hasPremiseWithDevice,
|
|
175
|
+
unlocked: canAccessPremises,
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
id: "enable" as const,
|
|
179
|
+
title: translate("Enable Fiscalization"),
|
|
180
|
+
complete: fursEnabled,
|
|
181
|
+
unlocked: canAccessEnable,
|
|
182
|
+
},
|
|
183
|
+
];
|
|
184
|
+
|
|
185
|
+
// Smart initial step selection: open to first incomplete step
|
|
186
|
+
const getDefaultStep = (): StepType => {
|
|
187
|
+
// If URL param provided, use it (if valid and unlocked)
|
|
188
|
+
if (initialStep) {
|
|
189
|
+
const stepInfo = steps.find((s) => s.id === initialStep);
|
|
190
|
+
if (stepInfo?.unlocked) return initialStep;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// Find first incomplete unlocked step
|
|
194
|
+
if (!certificateValid) return "certificate";
|
|
195
|
+
if (!hasPremiseWithDevice) return "premises";
|
|
196
|
+
if (!fursEnabled) return "enable";
|
|
197
|
+
|
|
198
|
+
// All complete - show first step
|
|
199
|
+
return "settings";
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
// Smart initial step selection on first load (when data is ready)
|
|
203
|
+
// biome-ignore lint/correctness/useExhaustiveDependencies: Intentionally run only when data loads, not on every dep change
|
|
204
|
+
useEffect(() => {
|
|
205
|
+
if (!hasInitializedStep && !settingsLoading && !premisesLoading) {
|
|
206
|
+
const smartStep = getDefaultStep();
|
|
207
|
+
if (smartStep !== activeStep) {
|
|
208
|
+
handleStepChange(smartStep);
|
|
209
|
+
}
|
|
210
|
+
setHasInitializedStep(true);
|
|
211
|
+
}
|
|
212
|
+
}, [settingsLoading, premisesLoading, hasInitializedStep]);
|
|
213
|
+
|
|
214
|
+
// Validate step and redirect if current step becomes locked
|
|
215
|
+
// biome-ignore lint/correctness/useExhaustiveDependencies: steps is recreated on each render but values are stable
|
|
216
|
+
useEffect(() => {
|
|
217
|
+
const currentStepInfo = steps.find((s) => s.id === activeStep);
|
|
218
|
+
if (currentStepInfo && !currentStepInfo.unlocked) {
|
|
219
|
+
// If current step is locked, redirect to first unlocked step
|
|
220
|
+
const firstUnlockedStep = steps.find((s) => s.unlocked);
|
|
221
|
+
if (firstUnlockedStep) {
|
|
222
|
+
handleStepChange(firstUnlockedStep.id);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}, [activeStep, handleStepChange]);
|
|
226
|
+
|
|
227
|
+
// Check if entity is Slovenian
|
|
228
|
+
if (entity.country_code !== "SI") {
|
|
229
|
+
return (
|
|
230
|
+
<Alert variant="destructive">
|
|
231
|
+
<AlertCircle className="h-4 w-4" />
|
|
232
|
+
<AlertTitle>{translate("FURS is for Slovenian Entities")}</AlertTitle>
|
|
233
|
+
<AlertDescription>
|
|
234
|
+
{translate("FURS fiscalization is only available for entities with country code SI")}
|
|
235
|
+
</AlertDescription>
|
|
236
|
+
</Alert>
|
|
237
|
+
);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
const onSubmit = (data: FursSettingsFormSchema) => {
|
|
241
|
+
updateSettings({
|
|
242
|
+
entityId: entity.id,
|
|
243
|
+
data,
|
|
244
|
+
});
|
|
245
|
+
};
|
|
246
|
+
|
|
247
|
+
if (settingsLoading || premisesLoading) {
|
|
248
|
+
return <PageLoadingSpinner text={translate("Loading...")} />;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
// Check if entity is in sandbox (test) mode
|
|
252
|
+
const isSandboxMode = entity.environment === "sandbox";
|
|
253
|
+
|
|
254
|
+
// Shared tabs navigation component - in left column only
|
|
255
|
+
const tabsNavigation = (
|
|
256
|
+
<div className="grid items-start gap-6 lg:grid-cols-[1fr_280px]">
|
|
257
|
+
<Tabs
|
|
258
|
+
value={activeStep}
|
|
259
|
+
onValueChange={(value) => handleStepChange(value as typeof activeStep)}
|
|
260
|
+
className="w-full"
|
|
261
|
+
>
|
|
262
|
+
<TabsList className="grid w-full grid-cols-4 rounded-none p-0">
|
|
263
|
+
{steps.map((step, index) => {
|
|
264
|
+
const isLocked = !step.unlocked;
|
|
265
|
+
let tooltipText = "";
|
|
266
|
+
|
|
267
|
+
if (isLocked) {
|
|
268
|
+
if (step.id === "premises") {
|
|
269
|
+
tooltipText = translate("Upload and validate digital certificate first");
|
|
270
|
+
} else if (step.id === "enable") {
|
|
271
|
+
if (!certificateValid) {
|
|
272
|
+
tooltipText = translate("Upload and validate digital certificate first");
|
|
273
|
+
} else if (!hasPremises) {
|
|
274
|
+
tooltipText = translate("Register at least one business premise first");
|
|
275
|
+
} else {
|
|
276
|
+
tooltipText = translate("Register at least one electronic device first");
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
const trigger = (
|
|
282
|
+
<TabsTrigger
|
|
283
|
+
value={step.id}
|
|
284
|
+
disabled={isLocked}
|
|
285
|
+
className={cn("cursor-pointer justify-center", !step.unlocked && "opacity-50")}
|
|
286
|
+
>
|
|
287
|
+
<span className="flex items-center gap-2">
|
|
288
|
+
{step.complete ? (
|
|
289
|
+
<CheckCircle2 className="h-4 w-4 text-green-500" />
|
|
290
|
+
) : (
|
|
291
|
+
<span className="text-xs">{index + 1}</span>
|
|
292
|
+
)}
|
|
293
|
+
{step.title}
|
|
294
|
+
</span>
|
|
295
|
+
</TabsTrigger>
|
|
296
|
+
);
|
|
297
|
+
|
|
298
|
+
if (isLocked) {
|
|
299
|
+
return (
|
|
300
|
+
<Tooltip key={step.id} delayDuration={0}>
|
|
301
|
+
<TooltipTrigger asChild>
|
|
302
|
+
<span className="flex cursor-not-allowed justify-center">{trigger}</span>
|
|
303
|
+
</TooltipTrigger>
|
|
304
|
+
<TooltipContent>
|
|
305
|
+
<p>{tooltipText}</p>
|
|
306
|
+
</TooltipContent>
|
|
307
|
+
</Tooltip>
|
|
308
|
+
);
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
return (
|
|
312
|
+
<span key={step.id} className="flex justify-center">
|
|
313
|
+
{trigger}
|
|
314
|
+
</span>
|
|
315
|
+
);
|
|
316
|
+
})}
|
|
317
|
+
</TabsList>
|
|
318
|
+
</Tabs>
|
|
319
|
+
<div className="hidden lg:block" />
|
|
320
|
+
</div>
|
|
321
|
+
);
|
|
322
|
+
|
|
323
|
+
// Helper to wrap section content with render prop if provided
|
|
324
|
+
const wrapSection = (section: SectionType, content: ReactNode) => {
|
|
325
|
+
if (renderSection) {
|
|
326
|
+
return renderSection(section, content);
|
|
327
|
+
}
|
|
328
|
+
return content;
|
|
329
|
+
};
|
|
330
|
+
|
|
331
|
+
return (
|
|
332
|
+
<Form {...form}>
|
|
333
|
+
<form id="furs-settings-form" onSubmit={form.handleSubmit(onSubmit)} className="space-y-6">
|
|
334
|
+
{/* Sandbox notice - wrapped in grid for left alignment */}
|
|
335
|
+
{isSandboxMode && (
|
|
336
|
+
<div className="grid items-start gap-6 lg:grid-cols-[1fr_280px]">
|
|
337
|
+
<Alert>
|
|
338
|
+
<Info className="h-4 w-4" />
|
|
339
|
+
<AlertTitle>{translate("Test Mode (Sandbox)")}</AlertTitle>
|
|
340
|
+
<AlertDescription>
|
|
341
|
+
{translate(
|
|
342
|
+
"This entity is in test mode. FURS invoices will be sent to the test/demo environment. No real fiscalization will occur.",
|
|
343
|
+
)}
|
|
344
|
+
</AlertDescription>
|
|
345
|
+
</Alert>
|
|
346
|
+
<div className="hidden lg:block" />
|
|
347
|
+
</div>
|
|
348
|
+
)}
|
|
349
|
+
|
|
350
|
+
{/* Tabs navigation */}
|
|
351
|
+
{tabsNavigation}
|
|
352
|
+
|
|
353
|
+
{/* Step content - each section wrapped with its own help */}
|
|
354
|
+
{activeStep === "settings" && (
|
|
355
|
+
<GeneralSettingsSection
|
|
356
|
+
form={form}
|
|
357
|
+
entity={entity}
|
|
358
|
+
t={translate}
|
|
359
|
+
onSuccess={onSuccess}
|
|
360
|
+
onError={onError}
|
|
361
|
+
wrapSection={wrapSection}
|
|
362
|
+
/>
|
|
363
|
+
)}
|
|
364
|
+
|
|
365
|
+
{activeStep === "certificate" && (
|
|
366
|
+
<CertificateSettingsSection
|
|
367
|
+
entity={entity}
|
|
368
|
+
fursSettings={fursSettings}
|
|
369
|
+
t={translate}
|
|
370
|
+
onSuccess={onSuccess}
|
|
371
|
+
onError={onError}
|
|
372
|
+
wrapSection={wrapSection}
|
|
373
|
+
/>
|
|
374
|
+
)}
|
|
375
|
+
|
|
376
|
+
{activeStep === "premises" && (
|
|
377
|
+
<div className="space-y-6">
|
|
378
|
+
{!hasCertificate && (
|
|
379
|
+
<Alert>
|
|
380
|
+
<AlertCircle className="h-4 w-4" />
|
|
381
|
+
<AlertTitle>{translate("Certificate Required")}</AlertTitle>
|
|
382
|
+
<AlertDescription>
|
|
383
|
+
{translate("You must upload a digital certificate before you can register business premises")}
|
|
384
|
+
</AlertDescription>
|
|
385
|
+
</Alert>
|
|
386
|
+
)}
|
|
387
|
+
<PremisesManagementSection
|
|
388
|
+
entity={entity}
|
|
389
|
+
premises={(premises || []) as any}
|
|
390
|
+
t={translate}
|
|
391
|
+
onSuccess={onSuccess}
|
|
392
|
+
onError={onError}
|
|
393
|
+
wrapSection={wrapSection}
|
|
394
|
+
/>
|
|
395
|
+
</div>
|
|
396
|
+
)}
|
|
397
|
+
|
|
398
|
+
{activeStep === "enable" && (
|
|
399
|
+
<EnableFiscalizationSection
|
|
400
|
+
form={form}
|
|
401
|
+
fursSettings={fursSettings}
|
|
402
|
+
premises={(premises || []) as any}
|
|
403
|
+
t={translate}
|
|
404
|
+
wrapSection={wrapSection}
|
|
405
|
+
/>
|
|
406
|
+
)}
|
|
407
|
+
</form>
|
|
408
|
+
</Form>
|
|
409
|
+
);
|
|
410
|
+
};
|