@spaceinvoices/react-ui 0.3.0 → 0.4.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/cli/dist/index.js +1 -1
- package/package.json +1 -1
- package/registry.json +0 -230
- package/src/components/advance-invoices/advance-invoices.hooks.ts +2 -2
- package/src/components/documents/documents.hooks.ts +5 -48
- package/src/components/documents/shared/document-preview-display.tsx +12 -1
- package/src/components/documents/view/document-actions-bar.tsx +20 -12
- package/src/components/documents/view/document-activities-list.tsx +166 -0
- package/src/components/documents/view/document-details-card.tsx +6 -6
- package/src/components/documents/view/index.ts +1 -0
- package/src/components/documents/view/locales/de.ts +32 -0
- package/src/components/documents/view/locales/es.ts +32 -0
- package/src/components/documents/view/locales/fr.ts +32 -0
- package/src/components/documents/view/locales/hr.ts +32 -0
- package/src/components/documents/view/locales/it.ts +32 -0
- package/src/components/documents/view/locales/nl.ts +32 -0
- package/src/components/documents/view/locales/pl.ts +32 -0
- package/src/components/documents/view/locales/pt.ts +32 -0
- package/src/components/documents/view/locales/sl.ts +32 -0
- package/src/components/entities/fina-settings-form/locales/de.ts +3 -0
- package/src/components/entities/fina-settings-form/locales/en.ts +3 -0
- package/src/components/entities/fina-settings-form/locales/es.ts +3 -0
- package/src/components/entities/fina-settings-form/locales/fr.ts +3 -0
- package/src/components/entities/fina-settings-form/locales/hr.ts +3 -0
- package/src/components/entities/fina-settings-form/locales/it.ts +3 -0
- package/src/components/entities/fina-settings-form/locales/nl.ts +3 -0
- package/src/components/entities/fina-settings-form/locales/pl.ts +3 -0
- package/src/components/entities/fina-settings-form/locales/pt.ts +3 -0
- package/src/components/entities/fina-settings-form/locales/sl.ts +3 -0
- package/src/components/entities/furs-settings-form/furs-settings-form.tsx +15 -7
- package/src/components/entities/furs-settings-form/furs-settings.hooks.ts +1 -1
- package/src/components/entities/furs-settings-form/locales/de.ts +2 -0
- package/src/components/entities/furs-settings-form/locales/en.ts +12 -0
- package/src/components/entities/furs-settings-form/locales/es.ts +2 -0
- package/src/components/entities/furs-settings-form/locales/fr.ts +2 -0
- package/src/components/entities/furs-settings-form/locales/hr.ts +2 -0
- package/src/components/entities/furs-settings-form/locales/it.ts +2 -0
- package/src/components/entities/furs-settings-form/locales/nl.ts +2 -0
- package/src/components/entities/furs-settings-form/locales/pl.ts +2 -0
- package/src/components/entities/furs-settings-form/locales/pt.ts +2 -0
- package/src/components/entities/furs-settings-form/locales/sl.ts +14 -0
- package/src/components/entities/furs-settings-form/sections/general-settings-section.tsx +121 -1
- package/src/components/entities/furs-settings-form/sections/premises-management-section.tsx +1 -0
- package/src/components/entities/furs-settings-form/sections/register-premise-dialog.tsx +44 -32
- package/src/components/invoices/index.ts +1 -1
- package/src/components/invoices/send-email-dialog/send-email-dialog.tsx +2 -2
- package/src/components/invoices/view/fiscalization-status-card.tsx +121 -0
- package/src/generate-schemas.ts +13 -1
- package/src/generated/schemas/advanceinvoice.ts +79 -187
- package/src/generated/schemas/creditnote.ts +63 -86
- package/src/generated/schemas/customadvanceinvoice.ts +70 -97
- package/src/generated/schemas/customcreditnote.ts +70 -97
- package/src/generated/schemas/customestimate.ts +68 -97
- package/src/generated/schemas/custominvoice.ts +70 -97
- package/src/generated/schemas/estimate.ts +67 -172
- package/src/generated/schemas/invoice.ts +79 -187
- package/src/generated/schemas/registerfursrealestatepremise_body.ts +11 -7
- package/src/generated/schemas/renderadvanceinvoicepreview_body.ts +61 -157
- package/src/generated/schemas/rendercreditnotepreview_body.ts +61 -157
- package/src/generated/schemas/renderestimatepreview_body.ts +61 -157
- package/src/generated/schemas/renderinvoicepreview_body.ts +61 -157
- package/src/hooks/use-duplicate-document.ts +19 -11
- package/src/providers/entities-provider.tsx +21 -0
- package/src/components/invoices/view/fina-info-display.tsx +0 -196
- package/src/components/invoices/view/furs-info-display.tsx +0 -213
package/cli/dist/index.js
CHANGED
|
@@ -870,7 +870,7 @@ async function list(options = {}) {
|
|
|
870
870
|
|
|
871
871
|
// cli/src/index.ts
|
|
872
872
|
var program = new Command();
|
|
873
|
-
program.name("spaceinvoices-ui").description("CLI for adding Space Invoices React UI components to your project").version("0.
|
|
873
|
+
program.name("spaceinvoices-ui").description("CLI for adding Space Invoices React UI components to your project").version("0.4.1");
|
|
874
874
|
program.option("--local <path>", "Use local registry from specified path (for development)");
|
|
875
875
|
program.command("init").description("Initialize Space Invoices UI in your project").option("-y, --yes", "Skip prompts and use defaults").option("-f, --force", "Overwrite existing configuration").option("--cwd <path>", "Working directory (defaults to current directory)").action(async (options) => {
|
|
876
876
|
const globalOpts = program.opts();
|
package/package.json
CHANGED
package/registry.json
CHANGED
|
@@ -530,236 +530,6 @@
|
|
|
530
530
|
"dependencies": ["ui/card", "dashboard/loading-card"],
|
|
531
531
|
"providers": ["sdk-provider"],
|
|
532
532
|
"utils": ["translation"]
|
|
533
|
-
},
|
|
534
|
-
"dashboard/tax-collected-card": {
|
|
535
|
-
"name": "Tax Collected Card",
|
|
536
|
-
"category": "feature",
|
|
537
|
-
"files": [
|
|
538
|
-
"components/dashboard/tax-collected-card/tax-collected-card.tsx",
|
|
539
|
-
"components/dashboard/tax-collected-card/use-tax-collected.ts",
|
|
540
|
-
"components/dashboard/tax-collected-card/index.ts"
|
|
541
|
-
],
|
|
542
|
-
"dependencies": ["ui/card", "dashboard/loading-card"],
|
|
543
|
-
"providers": ["sdk-provider"]
|
|
544
|
-
},
|
|
545
|
-
"advance-invoices/create-advance-invoice-form": {
|
|
546
|
-
"name": "Create Advance Invoice Form",
|
|
547
|
-
"category": "feature",
|
|
548
|
-
"files": [
|
|
549
|
-
"components/advance-invoices/create/create-advance-invoice-form.tsx",
|
|
550
|
-
"components/advance-invoices/create/prepare-advance-invoice-submission.ts",
|
|
551
|
-
"components/advance-invoices/create/locales/de.ts",
|
|
552
|
-
"components/advance-invoices/create/locales/sl.ts",
|
|
553
|
-
"components/advance-invoices/advance-invoices.hooks.ts"
|
|
554
|
-
],
|
|
555
|
-
"dependencies": [
|
|
556
|
-
"form/form-input",
|
|
557
|
-
"ui/form",
|
|
558
|
-
"ui/card",
|
|
559
|
-
"ui/button",
|
|
560
|
-
"ui/calendar",
|
|
561
|
-
"ui/popover",
|
|
562
|
-
"customers/customer-combobox"
|
|
563
|
-
],
|
|
564
|
-
"providers": ["sdk-provider", "entities-provider"],
|
|
565
|
-
"utils": ["translation", "hooks"],
|
|
566
|
-
"schemas": ["createAdvanceInvoiceSchema"]
|
|
567
|
-
},
|
|
568
|
-
"advance-invoices/advance-invoice-list-table": {
|
|
569
|
-
"name": "Advance Invoice List Table",
|
|
570
|
-
"category": "feature",
|
|
571
|
-
"files": [
|
|
572
|
-
"components/advance-invoices/list/list-table.tsx",
|
|
573
|
-
"components/advance-invoices/list/list-row-actions.tsx",
|
|
574
|
-
"components/advance-invoices/list/use-advance-invoice-download.ts",
|
|
575
|
-
"components/advance-invoices/list/index.ts",
|
|
576
|
-
"components/advance-invoices/advance-invoices.hooks.ts"
|
|
577
|
-
],
|
|
578
|
-
"dependencies": ["table/data-table", "ui/dropdown-menu", "ui/button", "ui/badge"],
|
|
579
|
-
"providers": ["sdk-provider"],
|
|
580
|
-
"utils": ["translation", "hooks"]
|
|
581
|
-
},
|
|
582
|
-
"activities/activity-timeline": {
|
|
583
|
-
"name": "Activity Timeline",
|
|
584
|
-
"category": "feature",
|
|
585
|
-
"files": [
|
|
586
|
-
"components/activities/activity-timeline.tsx",
|
|
587
|
-
"components/activities/locales/de.ts",
|
|
588
|
-
"components/activities/locales/sl.ts",
|
|
589
|
-
"components/activities/index.ts"
|
|
590
|
-
],
|
|
591
|
-
"dependencies": ["ui/badge"],
|
|
592
|
-
"providers": ["sdk-provider"],
|
|
593
|
-
"utils": ["translation"]
|
|
594
|
-
},
|
|
595
|
-
"export/document-export-form": {
|
|
596
|
-
"name": "Document Export Form",
|
|
597
|
-
"category": "feature",
|
|
598
|
-
"files": [
|
|
599
|
-
"components/export/document-export-form.tsx",
|
|
600
|
-
"components/export/index.ts"
|
|
601
|
-
],
|
|
602
|
-
"dependencies": ["ui/form", "ui/button", "ui/select", "ui/calendar", "ui/popover"],
|
|
603
|
-
"providers": ["sdk-provider", "entities-provider"],
|
|
604
|
-
"utils": ["translation"]
|
|
605
|
-
},
|
|
606
|
-
"tax-reports/kir-export-form": {
|
|
607
|
-
"name": "KIR Export Form",
|
|
608
|
-
"category": "feature",
|
|
609
|
-
"files": [
|
|
610
|
-
"components/tax-reports/kir-export-form.tsx",
|
|
611
|
-
"components/tax-reports/index.ts"
|
|
612
|
-
],
|
|
613
|
-
"dependencies": ["ui/form", "ui/button", "ui/select", "ui/calendar", "ui/popover"],
|
|
614
|
-
"providers": ["sdk-provider", "entities-provider"],
|
|
615
|
-
"utils": ["translation"]
|
|
616
|
-
},
|
|
617
|
-
"company-registry/company-registry-autocomplete": {
|
|
618
|
-
"name": "Company Registry Autocomplete",
|
|
619
|
-
"category": "feature",
|
|
620
|
-
"files": [
|
|
621
|
-
"components/company-registry/company-registry-autocomplete.tsx",
|
|
622
|
-
"components/company-registry/company-registry.hooks.ts",
|
|
623
|
-
"components/company-registry/index.ts"
|
|
624
|
-
],
|
|
625
|
-
"dependencies": ["ui/command", "ui/popover", "ui/button"],
|
|
626
|
-
"providers": ["sdk-provider"],
|
|
627
|
-
"utils": ["translation"]
|
|
628
|
-
},
|
|
629
|
-
"request-logs/request-logs-page": {
|
|
630
|
-
"name": "Request Logs Page",
|
|
631
|
-
"category": "feature",
|
|
632
|
-
"files": [
|
|
633
|
-
"components/request-logs/request-logs-page.tsx",
|
|
634
|
-
"components/request-logs/request-log-list-table.tsx",
|
|
635
|
-
"components/request-logs/request-log-detail.tsx",
|
|
636
|
-
"components/request-logs/index.ts"
|
|
637
|
-
],
|
|
638
|
-
"dependencies": ["table/data-table", "ui/card", "ui/badge"],
|
|
639
|
-
"providers": ["sdk-provider"]
|
|
640
|
-
},
|
|
641
|
-
"customers/edit-customer-form": {
|
|
642
|
-
"name": "Edit Customer Form",
|
|
643
|
-
"category": "feature",
|
|
644
|
-
"files": [
|
|
645
|
-
"components/customers/edit-customer-form/edit-customer-form.tsx",
|
|
646
|
-
"components/customers/edit-customer-form/locales/de.ts",
|
|
647
|
-
"components/customers/edit-customer-form/locales/sl.ts",
|
|
648
|
-
"components/customers/customers.hooks.ts"
|
|
649
|
-
],
|
|
650
|
-
"dependencies": ["form/form-input", "ui/form"],
|
|
651
|
-
"providers": ["sdk-provider"],
|
|
652
|
-
"utils": ["translation", "hooks"]
|
|
653
|
-
},
|
|
654
|
-
"items/edit-item-form": {
|
|
655
|
-
"name": "Edit Item Form",
|
|
656
|
-
"category": "feature",
|
|
657
|
-
"files": [
|
|
658
|
-
"components/items/edit-item-form/edit-item-form.tsx",
|
|
659
|
-
"components/items/edit-item-form/locales/de.ts",
|
|
660
|
-
"components/items/edit-item-form/locales/sl.ts",
|
|
661
|
-
"components/items/items.hooks.ts"
|
|
662
|
-
],
|
|
663
|
-
"dependencies": ["form/form-input", "ui/form"],
|
|
664
|
-
"providers": ["sdk-provider"],
|
|
665
|
-
"utils": ["translation", "hooks"]
|
|
666
|
-
},
|
|
667
|
-
"taxes/edit-tax-form": {
|
|
668
|
-
"name": "Edit Tax Form",
|
|
669
|
-
"category": "feature",
|
|
670
|
-
"files": [
|
|
671
|
-
"components/taxes/edit-tax-form/edit-tax-form.tsx",
|
|
672
|
-
"components/taxes/edit-tax-form/locales/de.ts",
|
|
673
|
-
"components/taxes/edit-tax-form/locales/sl.ts",
|
|
674
|
-
"components/taxes/taxes.hooks.ts"
|
|
675
|
-
],
|
|
676
|
-
"dependencies": ["form/form-input", "ui/form"],
|
|
677
|
-
"providers": ["sdk-provider"],
|
|
678
|
-
"utils": ["translation", "hooks"]
|
|
679
|
-
},
|
|
680
|
-
"payments/edit-payment-form": {
|
|
681
|
-
"name": "Edit Payment Form",
|
|
682
|
-
"category": "feature",
|
|
683
|
-
"files": [
|
|
684
|
-
"components/payments/edit-payment-form/edit-payment-form.tsx",
|
|
685
|
-
"components/payments/edit-payment-form/locales/de.ts",
|
|
686
|
-
"components/payments/edit-payment-form/locales/sl.ts",
|
|
687
|
-
"components/payments/edit-payment-form/index.ts",
|
|
688
|
-
"components/payments/payments.hooks.ts"
|
|
689
|
-
],
|
|
690
|
-
"dependencies": ["form/form-input", "ui/form", "ui/select"],
|
|
691
|
-
"providers": ["sdk-provider"],
|
|
692
|
-
"utils": ["translation", "hooks"]
|
|
693
|
-
},
|
|
694
|
-
"payments/payment-list-table": {
|
|
695
|
-
"name": "Payment List Table",
|
|
696
|
-
"category": "feature",
|
|
697
|
-
"files": [
|
|
698
|
-
"components/payments/list/list-table.tsx",
|
|
699
|
-
"components/payments/list/list-row-actions.tsx",
|
|
700
|
-
"components/payments/list/index.ts",
|
|
701
|
-
"components/payments/payments.hooks.ts"
|
|
702
|
-
],
|
|
703
|
-
"dependencies": ["table/data-table", "ui/dropdown-menu", "ui/button"],
|
|
704
|
-
"providers": ["sdk-provider"],
|
|
705
|
-
"utils": ["translation", "hooks"]
|
|
706
|
-
},
|
|
707
|
-
"entities/furs-settings-form": {
|
|
708
|
-
"name": "FURS Settings Form",
|
|
709
|
-
"category": "feature",
|
|
710
|
-
"files": [
|
|
711
|
-
"components/entities/furs-settings-form/furs-settings-form.tsx",
|
|
712
|
-
"components/entities/furs-settings-form/furs-settings.hooks.ts",
|
|
713
|
-
"components/entities/furs-settings-form/sections/general-settings-section.tsx",
|
|
714
|
-
"components/entities/furs-settings-form/sections/certificate-settings-section.tsx",
|
|
715
|
-
"components/entities/furs-settings-form/sections/enable-fiscalization-section.tsx",
|
|
716
|
-
"components/entities/furs-settings-form/sections/premises-management-section.tsx",
|
|
717
|
-
"components/entities/furs-settings-form/sections/register-premise-dialog.tsx",
|
|
718
|
-
"components/entities/furs-settings-form/locales/de.ts",
|
|
719
|
-
"components/entities/furs-settings-form/locales/sl.ts",
|
|
720
|
-
"components/entities/furs-settings-form/index.ts"
|
|
721
|
-
],
|
|
722
|
-
"dependencies": ["ui/form", "ui/button", "ui/card", "ui/switch", "ui/alert", "form/form-input"],
|
|
723
|
-
"providers": ["sdk-provider", "entities-provider"],
|
|
724
|
-
"utils": ["translation", "hooks"]
|
|
725
|
-
},
|
|
726
|
-
"entities/fina-settings-form": {
|
|
727
|
-
"name": "FINA Settings Form",
|
|
728
|
-
"category": "feature",
|
|
729
|
-
"files": [
|
|
730
|
-
"components/entities/fina-settings-form/fina-settings-form.tsx",
|
|
731
|
-
"components/entities/fina-settings-form/fina-settings.hooks.ts",
|
|
732
|
-
"components/entities/fina-settings-form/sections/certificate-settings-section.tsx",
|
|
733
|
-
"components/entities/fina-settings-form/sections/premises-management-section.tsx",
|
|
734
|
-
"components/entities/fina-settings-form/sections/register-premise-dialog.tsx",
|
|
735
|
-
"components/entities/fina-settings-form/locales/de.ts",
|
|
736
|
-
"components/entities/fina-settings-form/locales/sl.ts",
|
|
737
|
-
"components/entities/fina-settings-form/index.ts"
|
|
738
|
-
],
|
|
739
|
-
"dependencies": ["ui/form", "ui/button", "ui/card", "ui/switch", "ui/alert", "form/form-input"],
|
|
740
|
-
"providers": ["sdk-provider", "entities-provider"],
|
|
741
|
-
"utils": ["translation", "hooks"]
|
|
742
|
-
},
|
|
743
|
-
"entities/entity-settings": {
|
|
744
|
-
"name": "Entity Settings",
|
|
745
|
-
"category": "feature",
|
|
746
|
-
"files": [
|
|
747
|
-
"components/entities/settings/company-settings-form.tsx",
|
|
748
|
-
"components/entities/settings/email-settings-form.tsx",
|
|
749
|
-
"components/entities/settings/branding-settings-form.tsx",
|
|
750
|
-
"components/entities/settings/defaults-settings-form.tsx",
|
|
751
|
-
"components/entities/settings/number-format-settings-form.tsx",
|
|
752
|
-
"components/entities/settings/tax-rules-settings-form.tsx",
|
|
753
|
-
"components/entities/settings/eslog-settings-form.tsx",
|
|
754
|
-
"components/entities/settings/settings-footer.tsx",
|
|
755
|
-
"components/entities/settings/index.ts",
|
|
756
|
-
"components/entities/settings/pdf-template-selector/pdf-template-cards.tsx",
|
|
757
|
-
"components/entities/settings/pdf-template-selector/demo-invoice-data.ts",
|
|
758
|
-
"components/entities/settings/pdf-template-selector/index.ts"
|
|
759
|
-
],
|
|
760
|
-
"dependencies": ["ui/form", "ui/button", "ui/card", "ui/select", "ui/switch", "ui/tabs", "form/form-input"],
|
|
761
|
-
"providers": ["sdk-provider", "entities-provider"],
|
|
762
|
-
"utils": ["translation", "hooks"]
|
|
763
533
|
}
|
|
764
534
|
}
|
|
765
535
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { AdvanceInvoice, CreateAdvanceInvoiceBody } from "@spaceinvoices/js-sdk";
|
|
2
2
|
import { useMutation, useQueryClient } from "@tanstack/react-query";
|
|
3
3
|
import { NEXT_DOCUMENT_NUMBER_CACHE_KEY } from "@/ui/hooks/use-next-document-number";
|
|
4
4
|
import { useSDK } from "@/ui/providers/sdk-provider";
|
|
@@ -12,7 +12,7 @@ export const ADVANCE_INVOICES_CACHE_KEY = "advance-invoices";
|
|
|
12
12
|
|
|
13
13
|
type UseCreateAdvanceInvoiceOptions = {
|
|
14
14
|
entityId: string;
|
|
15
|
-
onSuccess?: (data:
|
|
15
|
+
onSuccess?: (data: AdvanceInvoice) => void;
|
|
16
16
|
onError?: (error: unknown) => void;
|
|
17
17
|
};
|
|
18
18
|
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { useMutation, useQueryClient } from "@tanstack/react-query";
|
|
2
|
-
import {
|
|
3
|
-
import { getCookie } from "@/ui/lib/browser-cookies";
|
|
2
|
+
import { useSDK } from "@/ui/providers/sdk-provider";
|
|
4
3
|
|
|
5
4
|
// Document type union for API calls
|
|
6
5
|
export type DocumentType = "invoice" | "estimate" | "credit_note" | "advance_invoice";
|
|
@@ -13,44 +12,6 @@ const CACHE_KEYS: Record<DocumentType, string> = {
|
|
|
13
12
|
advance_invoice: "advance-invoices",
|
|
14
13
|
};
|
|
15
14
|
|
|
16
|
-
/**
|
|
17
|
-
* Get API base URL from environment
|
|
18
|
-
*/
|
|
19
|
-
function getApiBaseUrl(): string {
|
|
20
|
-
if (typeof window === "undefined") return "";
|
|
21
|
-
return (import.meta.env?.VITE_API_URL || import.meta.env?.BUN_PUBLIC_API_URL || "") as string;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Make authenticated API request
|
|
26
|
-
*/
|
|
27
|
-
async function apiRequest<T>(path: string, options: RequestInit & { entityId: string }): Promise<T> {
|
|
28
|
-
const token = getCookie(AUTH_COOKIES.TOKEN);
|
|
29
|
-
const baseUrl = getApiBaseUrl();
|
|
30
|
-
|
|
31
|
-
const response = await fetch(`${baseUrl}${path}`, {
|
|
32
|
-
...options,
|
|
33
|
-
headers: {
|
|
34
|
-
"Content-Type": "application/json",
|
|
35
|
-
Authorization: `Bearer ${token}`,
|
|
36
|
-
"x-entity-id": options.entityId,
|
|
37
|
-
...options.headers,
|
|
38
|
-
},
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
if (!response.ok) {
|
|
42
|
-
const errorData = await response.json().catch(() => ({}));
|
|
43
|
-
throw new Error(errorData.message || `Request failed with status ${response.status}`);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// DELETE returns 204 No Content
|
|
47
|
-
if (response.status === 204) {
|
|
48
|
-
return undefined as T;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
return response.json();
|
|
52
|
-
}
|
|
53
|
-
|
|
54
15
|
// ============================================================================
|
|
55
16
|
// Finalize Document Hook
|
|
56
17
|
// ============================================================================
|
|
@@ -71,14 +32,12 @@ type FinalizeDocumentVariables = {
|
|
|
71
32
|
* Assigns a document number and runs fiscalization (if applicable)
|
|
72
33
|
*/
|
|
73
34
|
export function useFinalizeDocument(options: FinalizeDocumentOptions) {
|
|
35
|
+
const { sdk } = useSDK();
|
|
74
36
|
const queryClient = useQueryClient();
|
|
75
37
|
|
|
76
38
|
return useMutation({
|
|
77
39
|
mutationFn: async ({ documentId, documentType }: FinalizeDocumentVariables) => {
|
|
78
|
-
return
|
|
79
|
-
method: "POST",
|
|
80
|
-
entityId: options.entityId,
|
|
81
|
-
});
|
|
40
|
+
return sdk.documents.finalizeDocument(documentId, { type: documentType });
|
|
82
41
|
},
|
|
83
42
|
onSuccess: (data, variables) => {
|
|
84
43
|
// Invalidate list cache
|
|
@@ -118,14 +77,12 @@ type DeleteDraftDocumentVariables = {
|
|
|
118
77
|
* Only draft documents can be deleted
|
|
119
78
|
*/
|
|
120
79
|
export function useDeleteDraftDocument(options: DeleteDraftDocumentOptions) {
|
|
80
|
+
const { sdk } = useSDK();
|
|
121
81
|
const queryClient = useQueryClient();
|
|
122
82
|
|
|
123
83
|
return useMutation({
|
|
124
84
|
mutationFn: async ({ documentId, documentType }: DeleteDraftDocumentVariables) => {
|
|
125
|
-
return
|
|
126
|
-
method: "DELETE",
|
|
127
|
-
entityId: options.entityId,
|
|
128
|
-
});
|
|
85
|
+
return sdk.documents.delete(documentId, { type: documentType });
|
|
129
86
|
},
|
|
130
87
|
onSuccess: (_, variables) => {
|
|
131
88
|
// Invalidate list cache
|
|
@@ -63,6 +63,7 @@ export function DocumentPreviewDisplay({
|
|
|
63
63
|
|
|
64
64
|
const { containerRef, contentRef, scale, contentHeight, A4_WIDTH_PX } = useA4Scaling(previewHtml);
|
|
65
65
|
|
|
66
|
+
// biome-ignore lint/correctness/useExhaustiveDependencies: document.updated_at intentionally triggers re-fetch when document changes server-side (e.g. after payment)
|
|
66
67
|
useEffect(() => {
|
|
67
68
|
const fetchPreview = async () => {
|
|
68
69
|
// For public view, use per-type shareable HTML endpoint
|
|
@@ -113,7 +114,17 @@ export function DocumentPreviewDisplay({
|
|
|
113
114
|
};
|
|
114
115
|
|
|
115
116
|
fetchPreview();
|
|
116
|
-
}, [
|
|
117
|
+
}, [
|
|
118
|
+
document?.id,
|
|
119
|
+
document?.updated_at,
|
|
120
|
+
activeEntity?.id,
|
|
121
|
+
template,
|
|
122
|
+
apiBaseUrl,
|
|
123
|
+
locale,
|
|
124
|
+
isPublicView,
|
|
125
|
+
shareableId,
|
|
126
|
+
sdk,
|
|
127
|
+
]);
|
|
117
128
|
|
|
118
129
|
return (
|
|
119
130
|
<div ref={containerRef} className={cn("relative h-full", className)}>
|
|
@@ -42,13 +42,17 @@ const translations = { sl, de, it, fr, es, pt, nl, pl, hr } as const;
|
|
|
42
42
|
|
|
43
43
|
type Document = Invoice | Estimate | CreditNote | AdvanceInvoice;
|
|
44
44
|
|
|
45
|
-
const
|
|
46
|
-
{
|
|
47
|
-
{
|
|
48
|
-
{
|
|
49
|
-
{
|
|
50
|
-
{
|
|
51
|
-
{
|
|
45
|
+
const PDF_LOCALE_CODES = [
|
|
46
|
+
{ label: "English", code: "en-US" },
|
|
47
|
+
{ label: "German", code: "de-DE" },
|
|
48
|
+
{ label: "Slovenian", code: "sl-SI" },
|
|
49
|
+
{ label: "Italian", code: "it-IT" },
|
|
50
|
+
{ label: "French", code: "fr-FR" },
|
|
51
|
+
{ label: "Spanish", code: "es-ES" },
|
|
52
|
+
{ label: "Portuguese", code: "pt-PT" },
|
|
53
|
+
{ label: "Dutch", code: "nl-NL" },
|
|
54
|
+
{ label: "Polish", code: "pl-PL" },
|
|
55
|
+
{ label: "Croatian", code: "hr-HR" },
|
|
52
56
|
] as const;
|
|
53
57
|
|
|
54
58
|
interface DocumentActionsBarProps extends ComponentTranslationProps {
|
|
@@ -89,11 +93,15 @@ interface DocumentActionsBarProps extends ComponentTranslationProps {
|
|
|
89
93
|
function getApiLocale(uiLanguage: string): string {
|
|
90
94
|
const localeMap: Record<string, string> = {
|
|
91
95
|
en: "en-US",
|
|
92
|
-
sl: "sl-SI",
|
|
93
96
|
de: "de-DE",
|
|
94
|
-
|
|
95
|
-
fr: "fr-FR",
|
|
97
|
+
sl: "sl-SI",
|
|
96
98
|
it: "it-IT",
|
|
99
|
+
fr: "fr-FR",
|
|
100
|
+
es: "es-ES",
|
|
101
|
+
pt: "pt-PT",
|
|
102
|
+
nl: "nl-NL",
|
|
103
|
+
pl: "pl-PL",
|
|
104
|
+
hr: "hr-HR",
|
|
97
105
|
};
|
|
98
106
|
return localeMap[uiLanguage] || "en-US";
|
|
99
107
|
}
|
|
@@ -185,13 +193,13 @@ export function DocumentActionsBar({
|
|
|
185
193
|
</Button>
|
|
186
194
|
</DropdownMenuTrigger>
|
|
187
195
|
<DropdownMenuContent align="end">
|
|
188
|
-
{
|
|
196
|
+
{PDF_LOCALE_CODES.map((locale) => (
|
|
189
197
|
<DropdownMenuItem
|
|
190
198
|
key={locale.code}
|
|
191
199
|
onClick={() => handleDownloadPdf(locale.code)}
|
|
192
200
|
className="cursor-pointer"
|
|
193
201
|
>
|
|
194
|
-
{locale.label}
|
|
202
|
+
{t(locale.label)}
|
|
195
203
|
</DropdownMenuItem>
|
|
196
204
|
))}
|
|
197
205
|
</DropdownMenuContent>
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import type { GetActivities200DataItem } from "@spaceinvoices/js-sdk";
|
|
2
|
+
import { useQuery } from "@tanstack/react-query";
|
|
3
|
+
import { ChevronLeft, ChevronRight } from "lucide-react";
|
|
4
|
+
import { useState } from "react";
|
|
5
|
+
import { Button } from "@/ui/components/ui/button";
|
|
6
|
+
import { Card, CardContent, CardHeader, CardTitle } from "@/ui/components/ui/card";
|
|
7
|
+
import { Skeleton } from "@/ui/components/ui/skeleton";
|
|
8
|
+
import type { ComponentTranslationProps } from "@/ui/lib/translation";
|
|
9
|
+
import { createTranslation } from "@/ui/lib/translation";
|
|
10
|
+
import { useSDK } from "@/ui/providers/sdk-provider";
|
|
11
|
+
import de from "./locales/de";
|
|
12
|
+
import es from "./locales/es";
|
|
13
|
+
import fr from "./locales/fr";
|
|
14
|
+
import hr from "./locales/hr";
|
|
15
|
+
import it from "./locales/it";
|
|
16
|
+
import nl from "./locales/nl";
|
|
17
|
+
import pl from "./locales/pl";
|
|
18
|
+
import pt from "./locales/pt";
|
|
19
|
+
import sl from "./locales/sl";
|
|
20
|
+
|
|
21
|
+
const translations = { sl, de, it, fr, es, pt, nl, pl, hr } as const;
|
|
22
|
+
|
|
23
|
+
const PAGE_SIZE = 5;
|
|
24
|
+
|
|
25
|
+
interface DocumentActivitiesListProps extends ComponentTranslationProps {
|
|
26
|
+
documentId: string;
|
|
27
|
+
entityId: string;
|
|
28
|
+
currentUserId?: string;
|
|
29
|
+
locale?: string;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function formatActivityDate(date: string, locale: string): string {
|
|
33
|
+
const d = new Date(date);
|
|
34
|
+
return new Intl.DateTimeFormat(locale, {
|
|
35
|
+
month: "short",
|
|
36
|
+
day: "numeric",
|
|
37
|
+
hour: "2-digit",
|
|
38
|
+
minute: "2-digit",
|
|
39
|
+
}).format(d);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function getActionLabel(action: string, t: (key: string) => string): string {
|
|
43
|
+
const labels: Record<string, string> = {
|
|
44
|
+
created: t("Created"),
|
|
45
|
+
updated: t("Updated"),
|
|
46
|
+
voided: t("Voided"),
|
|
47
|
+
sent: t("Sent"),
|
|
48
|
+
deleted: t("Deleted"),
|
|
49
|
+
};
|
|
50
|
+
return labels[action] || action;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function getActorLabel(activity: GetActivities200DataItem, t: (key: string) => string, currentUserId?: string): string {
|
|
54
|
+
if (currentUserId && activity.actor_id === currentUserId) return t("me");
|
|
55
|
+
if (activity.actor_label) return activity.actor_label;
|
|
56
|
+
const typeLabels: Record<string, string> = {
|
|
57
|
+
system: t("System"),
|
|
58
|
+
api_key: "API",
|
|
59
|
+
cron: t("Scheduled"),
|
|
60
|
+
webhook: "Webhook",
|
|
61
|
+
};
|
|
62
|
+
return typeLabels[activity.actor_type] || activity.actor_type;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export function DocumentActivitiesList({
|
|
66
|
+
documentId,
|
|
67
|
+
entityId,
|
|
68
|
+
currentUserId,
|
|
69
|
+
locale = "en",
|
|
70
|
+
...i18nProps
|
|
71
|
+
}: DocumentActivitiesListProps) {
|
|
72
|
+
const t = createTranslation({ translations, locale, ...i18nProps });
|
|
73
|
+
const { sdk } = useSDK();
|
|
74
|
+
|
|
75
|
+
const [cursors, setCursors] = useState<string[]>([]);
|
|
76
|
+
const currentCursor = cursors.length > 0 ? cursors[cursors.length - 1] : undefined;
|
|
77
|
+
|
|
78
|
+
const { data: activitiesData, isLoading } = useQuery({
|
|
79
|
+
queryKey: ["activities", documentId, entityId, currentCursor],
|
|
80
|
+
queryFn: async () => {
|
|
81
|
+
if (!sdk) throw new Error("SDK not initialized");
|
|
82
|
+
|
|
83
|
+
return sdk.activities.list({
|
|
84
|
+
entity_id: entityId,
|
|
85
|
+
resource_id: documentId,
|
|
86
|
+
order_by: "-created_at",
|
|
87
|
+
limit: PAGE_SIZE,
|
|
88
|
+
next_cursor: currentCursor,
|
|
89
|
+
});
|
|
90
|
+
},
|
|
91
|
+
enabled: !!sdk && !!entityId && !!documentId,
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
const activities = activitiesData?.data || [];
|
|
95
|
+
const pagination = activitiesData?.pagination;
|
|
96
|
+
|
|
97
|
+
const handleNextPage = () => {
|
|
98
|
+
if (pagination?.next_cursor) {
|
|
99
|
+
setCursors((prev) => [...prev, pagination.next_cursor!]);
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
const handlePrevPage = () => {
|
|
104
|
+
setCursors((prev) => prev.slice(0, -1));
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
const hasPrev = cursors.length > 0;
|
|
108
|
+
const hasNext = !!pagination?.has_more;
|
|
109
|
+
|
|
110
|
+
return (
|
|
111
|
+
<Card>
|
|
112
|
+
<CardHeader className="flex flex-row items-center justify-between pb-3">
|
|
113
|
+
<CardTitle className="text-lg">
|
|
114
|
+
{t("Activity")} {pagination && pagination.total > 0 && `(${pagination.total})`}
|
|
115
|
+
</CardTitle>
|
|
116
|
+
{(hasPrev || hasNext) && (
|
|
117
|
+
<div className="flex items-center gap-1">
|
|
118
|
+
<Button
|
|
119
|
+
variant="ghost"
|
|
120
|
+
size="sm"
|
|
121
|
+
onClick={handlePrevPage}
|
|
122
|
+
disabled={!hasPrev}
|
|
123
|
+
className="h-8 w-8 cursor-pointer p-0"
|
|
124
|
+
>
|
|
125
|
+
<ChevronLeft className="h-4 w-4" />
|
|
126
|
+
</Button>
|
|
127
|
+
<Button
|
|
128
|
+
variant="ghost"
|
|
129
|
+
size="sm"
|
|
130
|
+
onClick={handleNextPage}
|
|
131
|
+
disabled={!hasNext}
|
|
132
|
+
className="h-8 w-8 cursor-pointer p-0"
|
|
133
|
+
>
|
|
134
|
+
<ChevronRight className="h-4 w-4" />
|
|
135
|
+
</Button>
|
|
136
|
+
</div>
|
|
137
|
+
)}
|
|
138
|
+
</CardHeader>
|
|
139
|
+
<CardContent>
|
|
140
|
+
{isLoading ? (
|
|
141
|
+
<div className="space-y-2">
|
|
142
|
+
<Skeleton className="h-10 w-full" />
|
|
143
|
+
<Skeleton className="h-10 w-full" />
|
|
144
|
+
<Skeleton className="h-10 w-full" />
|
|
145
|
+
</div>
|
|
146
|
+
) : activities.length === 0 ? (
|
|
147
|
+
<p className="py-4 text-center text-muted-foreground text-sm">{t("No activity")}</p>
|
|
148
|
+
) : (
|
|
149
|
+
<div className="space-y-2">
|
|
150
|
+
{activities.map((activity) => (
|
|
151
|
+
<div key={activity.id} className="flex items-start justify-between rounded-md border p-3">
|
|
152
|
+
<div className="flex flex-col gap-0.5">
|
|
153
|
+
<span className="font-medium text-sm">{getActionLabel(activity.action, t)}</span>
|
|
154
|
+
<span className="text-muted-foreground text-xs">
|
|
155
|
+
{t("by")} {getActorLabel(activity, t, currentUserId)}
|
|
156
|
+
</span>
|
|
157
|
+
</div>
|
|
158
|
+
<span className="text-muted-foreground text-xs">{formatActivityDate(activity.created_at, locale)}</span>
|
|
159
|
+
</div>
|
|
160
|
+
))}
|
|
161
|
+
</div>
|
|
162
|
+
)}
|
|
163
|
+
</CardContent>
|
|
164
|
+
</Card>
|
|
165
|
+
);
|
|
166
|
+
}
|
|
@@ -112,15 +112,15 @@ export function DocumentDetailsCard({ document, documentType, locale = "en", ...
|
|
|
112
112
|
{/* Document info */}
|
|
113
113
|
<div className="grid grid-cols-2 gap-x-4 gap-y-2 text-sm">
|
|
114
114
|
<div className="text-muted-foreground">{t("Number")}</div>
|
|
115
|
-
<div className="font-medium">{document.number}</div>
|
|
115
|
+
<div className="text-right font-medium">{document.number}</div>
|
|
116
116
|
|
|
117
117
|
<div className="text-muted-foreground">{t("Date")}</div>
|
|
118
|
-
<div>{fmtDate(document.date)}</div>
|
|
118
|
+
<div className="text-right">{fmtDate(document.date)}</div>
|
|
119
119
|
|
|
120
120
|
{isInvoiceOrAdvance && (
|
|
121
121
|
<>
|
|
122
122
|
<div className="text-muted-foreground">{t("Due date")}</div>
|
|
123
|
-
<div>{fmtDate(invoiceDoc.date_due)}</div>
|
|
123
|
+
<div className="text-right">{fmtDate(invoiceDoc.date_due)}</div>
|
|
124
124
|
</>
|
|
125
125
|
)}
|
|
126
126
|
|
|
@@ -129,7 +129,7 @@ export function DocumentDetailsCard({ document, documentType, locale = "en", ...
|
|
|
129
129
|
<div className="text-muted-foreground">
|
|
130
130
|
{(invoiceDoc as any).date_service_to ? t("Service period") : t("Service date")}
|
|
131
131
|
</div>
|
|
132
|
-
<div>
|
|
132
|
+
<div className="text-right">
|
|
133
133
|
{(invoiceDoc as any).date_service_to
|
|
134
134
|
? `${fmtDate((invoiceDoc as any).date_service)} - ${fmtDate((invoiceDoc as any).date_service_to)}`
|
|
135
135
|
: fmtDate((invoiceDoc as any).date_service)}
|
|
@@ -140,12 +140,12 @@ export function DocumentDetailsCard({ document, documentType, locale = "en", ...
|
|
|
140
140
|
{isEstimate && estimateDoc.date_valid_till && (
|
|
141
141
|
<>
|
|
142
142
|
<div className="text-muted-foreground">{t("Valid until")}</div>
|
|
143
|
-
<div>{fmtDate(estimateDoc.date_valid_till)}</div>
|
|
143
|
+
<div className="text-right">{fmtDate(estimateDoc.date_valid_till)}</div>
|
|
144
144
|
</>
|
|
145
145
|
)}
|
|
146
146
|
|
|
147
147
|
<div className="text-muted-foreground">{t("Customer")}</div>
|
|
148
|
-
<div>{customerName}</div>
|
|
148
|
+
<div className="text-right">{customerName}</div>
|
|
149
149
|
</div>
|
|
150
150
|
|
|
151
151
|
<Separator />
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { DocumentActionsBar } from "./document-actions-bar";
|
|
2
|
+
export { DocumentActivitiesList } from "./document-activities-list";
|
|
2
3
|
export { DocumentDetailsCard } from "./document-details-card";
|
|
3
4
|
export { DocumentPaymentsList } from "./document-payments-list";
|
|
4
5
|
export { useDocumentDownload } from "./use-document-download";
|