@voyantjs/legal-ui 0.16.0 → 0.17.0
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/README.md +14 -0
- package/dist/components/attachment-dialog.d.ts.map +1 -1
- package/dist/components/attachment-dialog.js +18 -11
- package/dist/components/booking-contract-card.d.ts +2 -13
- package/dist/components/booking-contract-card.d.ts.map +1 -1
- package/dist/components/booking-contract-card.js +10 -15
- package/dist/components/policy-rule-dialog.d.ts.map +1 -1
- package/dist/components/policy-rule-dialog.js +33 -25
- package/dist/components/policy-version-dialog.d.ts.map +1 -1
- package/dist/components/policy-version-dialog.js +15 -6
- package/dist/components/signature-dialog.d.ts.map +1 -1
- package/dist/components/signature-dialog.js +23 -15
- package/dist/i18n/en.d.ts +156 -0
- package/dist/i18n/en.d.ts.map +1 -0
- package/dist/i18n/en.js +155 -0
- package/dist/i18n/index.d.ts +5 -0
- package/dist/i18n/index.d.ts.map +1 -0
- package/dist/i18n/index.js +3 -0
- package/dist/i18n/messages.d.ts +140 -0
- package/dist/i18n/messages.d.ts.map +1 -0
- package/dist/i18n/messages.js +9 -0
- package/dist/i18n/provider.d.ts +334 -0
- package/dist/i18n/provider.d.ts.map +1 -0
- package/dist/i18n/provider.js +44 -0
- package/dist/i18n/ro.d.ts +156 -0
- package/dist/i18n/ro.d.ts.map +1 -0
- package/dist/i18n/ro.js +155 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/package.json +23 -7
package/README.md
CHANGED
|
@@ -12,6 +12,20 @@ pnpm add @voyantjs/legal-ui @voyantjs/legal-react @voyantjs/ui @tanstack/react-q
|
|
|
12
12
|
|
|
13
13
|
All components accept a `className` prop and merge it with `cn()`. Wrap or compose to extend; use the registry copy-paste path (`npx shadcn add @voyant/...`) for components you want to fork outright.
|
|
14
14
|
|
|
15
|
+
## I18n
|
|
16
|
+
|
|
17
|
+
Components render English by default. To localize them, wrap your UI in
|
|
18
|
+
`LegalUiMessagesProvider` and import only the locales your app supports.
|
|
19
|
+
|
|
20
|
+
```tsx
|
|
21
|
+
import { LegalUiMessagesProvider } from "@voyantjs/legal-ui"
|
|
22
|
+
import { legalUiEn } from "@voyantjs/legal-ui/i18n/en"
|
|
23
|
+
import { legalUiRo } from "@voyantjs/legal-ui/i18n/ro"
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
English-only apps should import only `./i18n/en`. Bilingual apps can import
|
|
27
|
+
`./i18n/en` and `./i18n/ro`.
|
|
28
|
+
|
|
15
29
|
## Not included (registry-only)
|
|
16
30
|
|
|
17
31
|
Some components couple to TanStack Router or template-local helpers and remain available only via the shadcn registry: `contract-detail-page`, `contracts-page`, `policies-page`, `policy-detail-page`, `template-detail-page`, `templates-page`. Import via `npx shadcn add @voyant/<component>` and customize per-project.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"attachment-dialog.d.ts","sourceRoot":"","sources":["../../src/components/attachment-dialog.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,6BAA6B,EAEnC,MAAM,uBAAuB,CAAA;
|
|
1
|
+
{"version":3,"file":"attachment-dialog.d.ts","sourceRoot":"","sources":["../../src/components/attachment-dialog.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,6BAA6B,EAEnC,MAAM,uBAAuB,CAAA;AAkC9B,KAAK,qBAAqB,GAAG;IAC3B,IAAI,EAAE,OAAO,CAAA;IACb,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAA;IACrC,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,CAAC,EAAE,6BAA6B,CAAA;IAC1C,SAAS,EAAE,MAAM,IAAI,CAAA;CACtB,CAAA;AAED,wBAAgB,gBAAgB,CAAC,EAC/B,IAAI,EACJ,YAAY,EACZ,UAAU,EACV,UAAU,EACV,SAAS,GACV,EAAE,qBAAqB,2CAkIvB"}
|
|
@@ -6,22 +6,27 @@ import { Loader2 } from "lucide-react";
|
|
|
6
6
|
import { useEffect } from "react";
|
|
7
7
|
import { useForm } from "react-hook-form";
|
|
8
8
|
import { z } from "zod/v4";
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
9
|
+
import { useLegalUiMessagesOrDefault } from "../i18n";
|
|
10
|
+
function createAttachmentFormSchema(messages) {
|
|
11
|
+
return z.object({
|
|
12
|
+
name: z.string().min(1, messages.attachmentDialog.validation.nameRequired),
|
|
13
|
+
kind: z.string().min(1).optional(),
|
|
14
|
+
mimeType: z.string().optional(),
|
|
15
|
+
fileSize: z.coerce.number().int().optional(),
|
|
16
|
+
storageKey: z.string().optional(),
|
|
17
|
+
checksum: z.string().optional(),
|
|
18
|
+
});
|
|
19
|
+
}
|
|
17
20
|
export function AttachmentDialog({ open, onOpenChange, contractId, attachment, onSuccess, }) {
|
|
18
21
|
const isEditing = !!attachment;
|
|
19
22
|
const { create, update } = useLegalContractAttachmentMutation();
|
|
23
|
+
const messages = useLegalUiMessagesOrDefault();
|
|
24
|
+
const attachmentFormSchema = createAttachmentFormSchema(messages);
|
|
20
25
|
const form = useForm({
|
|
21
26
|
resolver: zodResolver(attachmentFormSchema),
|
|
22
27
|
defaultValues: {
|
|
23
28
|
name: "",
|
|
24
|
-
kind: "appendix",
|
|
29
|
+
kind: "appendix", // i18n-literal-ok domain default attachment kind
|
|
25
30
|
mimeType: "",
|
|
26
31
|
fileSize: undefined,
|
|
27
32
|
storageKey: "",
|
|
@@ -46,7 +51,7 @@ export function AttachmentDialog({ open, onOpenChange, contractId, attachment, o
|
|
|
46
51
|
const onSubmit = async (values) => {
|
|
47
52
|
const payload = {
|
|
48
53
|
name: values.name,
|
|
49
|
-
kind: values.kind || "appendix",
|
|
54
|
+
kind: values.kind || "appendix", // i18n-literal-ok domain default attachment kind
|
|
50
55
|
mimeType: values.mimeType || undefined,
|
|
51
56
|
fileSize: values.fileSize || undefined,
|
|
52
57
|
storageKey: values.storageKey || undefined,
|
|
@@ -60,5 +65,7 @@ export function AttachmentDialog({ open, onOpenChange, contractId, attachment, o
|
|
|
60
65
|
}
|
|
61
66
|
onSuccess();
|
|
62
67
|
};
|
|
63
|
-
return (_jsx(Dialog, { open: open, onOpenChange: onOpenChange, children: _jsxs(DialogContent, { children: [_jsx(DialogHeader, { children: _jsx(DialogTitle, { children: isEditing
|
|
68
|
+
return (_jsx(Dialog, { open: open, onOpenChange: onOpenChange, children: _jsxs(DialogContent, { children: [_jsx(DialogHeader, { children: _jsx(DialogTitle, { children: isEditing
|
|
69
|
+
? messages.attachmentDialog.titles.edit
|
|
70
|
+
: messages.attachmentDialog.titles.create }) }), _jsxs("form", { onSubmit: form.handleSubmit(onSubmit), children: [_jsxs(DialogBody, { className: "grid gap-4", children: [_jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(Label, { children: messages.attachmentDialog.fields.name }), _jsx(Input, { ...form.register("name"), placeholder: messages.attachmentDialog.placeholders.name }), form.formState.errors.name && (_jsx("p", { className: "text-xs text-destructive", children: form.formState.errors.name.message }))] }), _jsxs("div", { className: "grid grid-cols-2 gap-4", children: [_jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(Label, { children: messages.attachmentDialog.fields.kind }), _jsx(Input, { ...form.register("kind"), placeholder: messages.attachmentDialog.placeholders.kind })] }), _jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(Label, { children: messages.attachmentDialog.fields.mimeType }), _jsx(Input, { ...form.register("mimeType"), placeholder: messages.attachmentDialog.placeholders.mimeType })] })] }), _jsxs("div", { className: "grid grid-cols-2 gap-4", children: [_jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(Label, { children: messages.attachmentDialog.fields.fileSize }), _jsx(Input, { ...form.register("fileSize"), type: "number", placeholder: messages.attachmentDialog.placeholders.fileSize })] }), _jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(Label, { children: messages.attachmentDialog.fields.checksum }), _jsx(Input, { ...form.register("checksum"), placeholder: messages.attachmentDialog.placeholders.checksum })] })] }), _jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(Label, { children: messages.attachmentDialog.fields.storageKey }), _jsx(Input, { ...form.register("storageKey"), placeholder: messages.attachmentDialog.placeholders.storageKey })] })] }), _jsxs(DialogFooter, { children: [_jsx(Button, { type: "button", variant: "ghost", onClick: () => onOpenChange(false), children: messages.common.cancel }), _jsxs(Button, { type: "submit", disabled: form.formState.isSubmitting, children: [form.formState.isSubmitting && _jsx(Loader2, { className: "mr-2 h-4 w-4 animate-spin" }), isEditing ? messages.common.saveChanges : messages.attachmentDialog.actions.create] })] })] })] }) }));
|
|
64
71
|
}
|
|
@@ -1,16 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
empty?: string;
|
|
4
|
-
/** Button text when the contract has no document yet. */
|
|
5
|
-
generate?: string;
|
|
6
|
-
/** Button text when the contract already has a document. */
|
|
7
|
-
regenerate?: string;
|
|
8
|
-
download?: string;
|
|
9
|
-
noAttachments?: string;
|
|
10
|
-
issuedAt?: string;
|
|
11
|
-
contractNumber?: string;
|
|
12
|
-
unsaved?: string;
|
|
13
|
-
}
|
|
1
|
+
import type { LegalUiMessages } from "../i18n/messages";
|
|
2
|
+
export type BookingContractCardLabels = Partial<Omit<LegalUiMessages["bookingContractCard"], "contractStatusLabels">>;
|
|
14
3
|
export interface BookingContractCardProps {
|
|
15
4
|
/** Booking whose contracts we list. Required — the card filters server-side. */
|
|
16
5
|
bookingId: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"booking-contract-card.d.ts","sourceRoot":"","sources":["../../src/components/booking-contract-card.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"booking-contract-card.d.ts","sourceRoot":"","sources":["../../src/components/booking-contract-card.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AAgBvD,MAAM,MAAM,yBAAyB,GAAG,OAAO,CAC7C,IAAI,CAAC,eAAe,CAAC,qBAAqB,CAAC,EAAE,sBAAsB,CAAC,CACrE,CAAA;AAED,MAAM,WAAW,wBAAwB;IACvC,gFAAgF;IAChF,SAAS,EAAE,MAAM,CAAA;IACjB;;;;;OAKG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,MAAM,CAAC,EAAE,yBAAyB,CAAA;CACnC;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,mBAAmB,CAAC,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,EAAE,EAAE,wBAAwB,2CAmC9F"}
|
|
@@ -3,6 +3,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
3
3
|
import { useLegalContractAttachments, useLegalContractMutation, useLegalContracts, } from "@voyantjs/legal-react";
|
|
4
4
|
import { Badge, Button, Card, CardContent, CardHeader, CardTitle } from "@voyantjs/ui/components";
|
|
5
5
|
import { Download, FileText, Loader2, RotateCw } from "lucide-react";
|
|
6
|
+
import { useLegalUiI18nOrDefault } from "../i18n";
|
|
6
7
|
/**
|
|
7
8
|
* Status → badge style map. Keeps the card visually in sync with the
|
|
8
9
|
* contract detail page (same variant names, same ordering of severity).
|
|
@@ -16,17 +17,6 @@ const STATUS_VARIANT = {
|
|
|
16
17
|
expired: "destructive",
|
|
17
18
|
void: "destructive",
|
|
18
19
|
};
|
|
19
|
-
const DEFAULT_LABELS = {
|
|
20
|
-
heading: "Contract",
|
|
21
|
-
empty: "No contract has been generated for this booking yet.",
|
|
22
|
-
generate: "Generate",
|
|
23
|
-
regenerate: "Regenerate",
|
|
24
|
-
download: "Download",
|
|
25
|
-
noAttachments: "No documents attached yet.",
|
|
26
|
-
issuedAt: "Issued",
|
|
27
|
-
contractNumber: "#",
|
|
28
|
-
unsaved: "Pending",
|
|
29
|
-
};
|
|
30
20
|
/**
|
|
31
21
|
* Operator booking-detail "Contract" card. Mount next to the payments / docs
|
|
32
22
|
* card on the booking detail page. Responsibilities are deliberately narrow:
|
|
@@ -43,12 +33,14 @@ const DEFAULT_LABELS = {
|
|
|
43
33
|
* would require a template picker, out of scope here).
|
|
44
34
|
*/
|
|
45
35
|
export function BookingContractCard({ bookingId, apiBaseUrl, labels }) {
|
|
46
|
-
const
|
|
36
|
+
const i18n = useLegalUiI18nOrDefault();
|
|
37
|
+
const merged = { ...i18n.messages.bookingContractCard, ...labels };
|
|
47
38
|
const contractsQuery = useLegalContracts({ bookingId, limit: 25 });
|
|
48
39
|
const contracts = contractsQuery.data?.data ?? [];
|
|
49
|
-
return (_jsxs(Card, { children: [_jsx(CardHeader, { children: _jsxs(CardTitle, { className: "flex items-center gap-2 text-base", children: [_jsx(FileText, { className: "h-4 w-4" }), merged.heading] }) }), _jsx(CardContent, { className: "flex flex-col gap-3", children: contractsQuery.isLoading ? (
|
|
40
|
+
return (_jsxs(Card, { children: [_jsx(CardHeader, { children: _jsxs(CardTitle, { className: "flex items-center gap-2 text-base", children: [_jsx(FileText, { className: "h-4 w-4" }), merged.heading] }) }), _jsx(CardContent, { className: "flex flex-col gap-3", children: contractsQuery.isLoading ? (_jsxs("div", { className: "flex items-center gap-2 text-xs text-muted-foreground", children: [_jsx(Loader2, { className: "h-3.5 w-3.5 animate-spin" }), i18n.messages.common.loading] })) : contracts.length === 0 ? (_jsx("p", { className: "text-xs text-muted-foreground", children: merged.empty })) : (contracts.map((contract) => (_jsx(BookingContractRow, { contract: contract, apiBaseUrl: apiBaseUrl, labels: merged }, contract.id)))) })] }));
|
|
50
41
|
}
|
|
51
42
|
function BookingContractRow({ contract, apiBaseUrl, labels, }) {
|
|
43
|
+
const i18n = useLegalUiI18nOrDefault();
|
|
52
44
|
const attachmentsQuery = useLegalContractAttachments({ contractId: contract.id });
|
|
53
45
|
const attachments = attachmentsQuery.data ?? [];
|
|
54
46
|
const documentAttachments = attachments.filter((a) => a.kind === "document");
|
|
@@ -59,14 +51,17 @@ function BookingContractRow({ contract, apiBaseUrl, labels, }) {
|
|
|
59
51
|
const mutation = hasDocument ? regenerateDocument : generateDocument;
|
|
60
52
|
mutation.mutate({ id: contract.id, input: { replaceExisting: true, kind: "document" } });
|
|
61
53
|
};
|
|
62
|
-
return (_jsxs("div", { className: "flex flex-col gap-2 rounded-md border p-3", children: [_jsxs("div", { className: "flex items-center justify-between gap-2", children: [_jsxs("div", { className: "flex items-center gap-2 text-sm", children: [_jsxs("span", { className: "font-medium", children: [labels.contractNumber, contract.contractNumber ?? labels.unsaved] }), _jsx(Badge, { variant: STATUS_VARIANT[contract.status] ?? "outline", className: "text-[10px]", children: contract.status })] }), _jsxs(Button, { type: "button", variant: "ghost", size: "sm", onClick: handleGenerate, disabled: isPending, children: [isPending ? (_jsx(Loader2, { className: "h-3.5 w-3.5 animate-spin" })) : (_jsx(RotateCw, { className: "h-3.5 w-3.5" })), _jsx("span", { className: "ml-1 text-xs", children: hasDocument ? labels.regenerate : labels.generate })] })] }), contract.issuedAt ? (_jsxs("p", { className: "text-[11px] text-muted-foreground", children: [labels.issuedAt, ": ",
|
|
54
|
+
return (_jsxs("div", { className: "flex flex-col gap-2 rounded-md border p-3", children: [_jsxs("div", { className: "flex items-center justify-between gap-2", children: [_jsxs("div", { className: "flex items-center gap-2 text-sm", children: [_jsxs("span", { className: "font-medium", children: [labels.contractNumber, contract.contractNumber ?? labels.unsaved] }), _jsx(Badge, { variant: STATUS_VARIANT[contract.status] ?? "outline", className: "text-[10px]", children: i18n.messages.bookingContractCard.contractStatusLabels[contract.status] })] }), _jsxs(Button, { type: "button", variant: "ghost", size: "sm", onClick: handleGenerate, disabled: isPending, children: [isPending ? (_jsx(Loader2, { className: "h-3.5 w-3.5 animate-spin" })) : (_jsx(RotateCw, { className: "h-3.5 w-3.5" })), _jsx("span", { className: "ml-1 text-xs", children: hasDocument ? labels.regenerate : labels.generate })] })] }), contract.issuedAt ? (_jsxs("p", { className: "text-[11px] text-muted-foreground", children: [labels.issuedAt, ": ", i18n.formatDate(contract.issuedAt)] })) : null, documentAttachments.length > 0 ? (_jsx("div", { className: "flex flex-col gap-1", children: documentAttachments.map((attachment) => (_jsx(AttachmentDownloadRow, { attachment: attachment, apiBaseUrl: apiBaseUrl, downloadLabel: labels.download }, attachment.id))) })) : (_jsx("p", { className: "text-[11px] text-muted-foreground", children: labels.noAttachments }))] }));
|
|
63
55
|
}
|
|
64
56
|
function AttachmentDownloadRow({ attachment, apiBaseUrl, downloadLabel, }) {
|
|
57
|
+
const i18n = useLegalUiI18nOrDefault();
|
|
65
58
|
// The download endpoint returns a 302 to the signed URL. A plain <a> link
|
|
66
59
|
// with target="_blank" lets the browser follow it and open the file in a
|
|
67
60
|
// new tab. When apiBaseUrl is omitted we fall back to a relative URL,
|
|
68
61
|
// which is correct for same-origin admin apps.
|
|
69
62
|
const href = `${apiBaseUrl ?? ""}/v1/admin/legal/contracts/attachments/${attachment.id}/download`;
|
|
70
|
-
const sizeKb = typeof attachment.fileSize === "number"
|
|
63
|
+
const sizeKb = typeof attachment.fileSize === "number"
|
|
64
|
+
? `${i18n.formatNumber(Math.round(attachment.fileSize / 1024))} ${i18n.messages.common.kilobytes}`
|
|
65
|
+
: null;
|
|
71
66
|
return (_jsxs("a", { href: href, target: "_blank", rel: "noopener noreferrer", className: "flex items-center justify-between gap-2 rounded-md border px-2 py-1.5 text-xs hover:bg-muted", children: [_jsxs("span", { className: "flex min-w-0 items-center gap-1.5", children: [_jsx(FileText, { className: "h-3.5 w-3.5 shrink-0" }), _jsx("span", { className: "truncate", children: attachment.name }), sizeKb ? _jsxs("span", { className: "text-muted-foreground", children: ["\u00B7 ", sizeKb] }) : null] }), _jsxs("span", { className: "flex items-center gap-1 text-muted-foreground", children: [_jsx(Download, { className: "h-3 w-3" }), downloadLabel] })] }));
|
|
72
67
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"policy-rule-dialog.d.ts","sourceRoot":"","sources":["../../src/components/policy-rule-dialog.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,qBAAqB,EAA8B,MAAM,uBAAuB,CAAA;
|
|
1
|
+
{"version":3,"file":"policy-rule-dialog.d.ts","sourceRoot":"","sources":["../../src/components/policy-rule-dialog.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,qBAAqB,EAA8B,MAAM,uBAAuB,CAAA;AAqD9F,MAAM,MAAM,QAAQ,GAAG,qBAAqB,CAAA;AAE5C,KAAK,qBAAqB,GAAG;IAC3B,IAAI,EAAE,OAAO,CAAA;IACb,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAA;IACrC,SAAS,EAAE,MAAM,CAAA;IACjB,IAAI,CAAC,EAAE,QAAQ,CAAA;IACf,SAAS,EAAE,MAAM,IAAI,CAAA;CACtB,CAAA;AAED,wBAAgB,gBAAgB,CAAC,EAC/B,IAAI,EACJ,YAAY,EACZ,SAAS,EACT,IAAI,EACJ,SAAS,GACV,EAAE,qBAAqB,2CAkMvB"}
|
|
@@ -7,32 +7,38 @@ import { Loader2 } from "lucide-react";
|
|
|
7
7
|
import { useEffect } from "react";
|
|
8
8
|
import { useForm } from "react-hook-form";
|
|
9
9
|
import { z } from "zod/v4";
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
{ value: "credit", label: "Credit" },
|
|
30
|
-
{ value: "cash_or_credit", label: "Cash or Credit" },
|
|
31
|
-
{ value: "none", label: "None" },
|
|
32
|
-
];
|
|
10
|
+
import { useLegalUiMessagesOrDefault } from "../i18n";
|
|
11
|
+
import { legalRefundTypes, legalRuleTypes, } from "../i18n/messages";
|
|
12
|
+
function createRuleFormSchema(messages) {
|
|
13
|
+
return z.object({
|
|
14
|
+
ruleType: z.enum(legalRuleTypes),
|
|
15
|
+
label: z.string().optional(),
|
|
16
|
+
daysBeforeDeparture: z.coerce.number().int().optional(),
|
|
17
|
+
refundPercent: z.coerce
|
|
18
|
+
.number()
|
|
19
|
+
.int()
|
|
20
|
+
.min(0, messages.policyRuleDialog.validation.refundPercentMin)
|
|
21
|
+
.max(10000, messages.policyRuleDialog.validation.refundPercentMax)
|
|
22
|
+
.optional(),
|
|
23
|
+
refundType: z.enum(legalRefundTypes).optional(),
|
|
24
|
+
flatAmountCents: z.coerce.number().int().optional(),
|
|
25
|
+
currency: z.string().optional(),
|
|
26
|
+
sortOrder: z.coerce.number().int().optional(),
|
|
27
|
+
});
|
|
28
|
+
}
|
|
33
29
|
export function PolicyRuleDialog({ open, onOpenChange, versionId, rule, onSuccess, }) {
|
|
34
30
|
const isEditing = !!rule;
|
|
35
31
|
const { create, update } = useLegalPolicyRuleMutation();
|
|
32
|
+
const messages = useLegalUiMessagesOrDefault();
|
|
33
|
+
const ruleFormSchema = createRuleFormSchema(messages);
|
|
34
|
+
const ruleTypeItems = legalRuleTypes.map((value) => ({
|
|
35
|
+
value,
|
|
36
|
+
label: messages.policyRuleDialog.ruleTypeLabels[value],
|
|
37
|
+
}));
|
|
38
|
+
const refundTypeItems = legalRefundTypes.map((value) => ({
|
|
39
|
+
value,
|
|
40
|
+
label: messages.policyRuleDialog.refundTypeLabels[value],
|
|
41
|
+
}));
|
|
36
42
|
const form = useForm({
|
|
37
43
|
resolver: zodResolver(ruleFormSchema),
|
|
38
44
|
defaultValues: {
|
|
@@ -82,8 +88,10 @@ export function PolicyRuleDialog({ open, onOpenChange, versionId, rule, onSucces
|
|
|
82
88
|
}
|
|
83
89
|
onSuccess();
|
|
84
90
|
};
|
|
85
|
-
return (_jsx(Dialog, { open: open, onOpenChange: onOpenChange, children: _jsxs(DialogContent, { children: [_jsx(DialogHeader, { children: _jsx(DialogTitle, { children: isEditing
|
|
91
|
+
return (_jsx(Dialog, { open: open, onOpenChange: onOpenChange, children: _jsxs(DialogContent, { children: [_jsx(DialogHeader, { children: _jsx(DialogTitle, { children: isEditing
|
|
92
|
+
? messages.policyRuleDialog.titles.edit
|
|
93
|
+
: messages.policyRuleDialog.titles.create }) }), _jsxs("form", { onSubmit: form.handleSubmit(onSubmit), children: [_jsxs(DialogBody, { className: "grid gap-4", children: [_jsxs("div", { className: "grid grid-cols-2 gap-4", children: [_jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(Label, { children: messages.policyRuleDialog.fields.ruleType }), _jsxs(Select, { items: ruleTypeItems, value: form.watch("ruleType"), onValueChange: (v) => form.setValue("ruleType", v, { shouldValidate: true }), children: [_jsx(SelectTrigger, { className: "w-full", children: _jsx(SelectValue, {}) }), _jsx(SelectContent, { children: ruleTypeItems.map((t) => (_jsx(SelectItem, { value: t.value, children: t.label }, t.value))) })] })] }), _jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(Label, { children: messages.policyRuleDialog.fields.sortOrder }), _jsx(Input, { ...form.register("sortOrder"), type: "number" })] })] }), _jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(Label, { children: messages.policyRuleDialog.fields.label }), _jsx(Input, { ...form.register("label"), placeholder: messages.policyRuleDialog.placeholders.label })] }), _jsxs("div", { className: "grid grid-cols-2 gap-4", children: [_jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(Label, { children: messages.policyRuleDialog.fields.daysBeforeDeparture }), _jsx(Input, { ...form.register("daysBeforeDeparture"), type: "number", placeholder: messages.policyRuleDialog.placeholders.daysBeforeDeparture })] }), _jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(Label, { children: messages.policyRuleDialog.fields.refundPercent }), _jsx(Input, { ...form.register("refundPercent"), type: "number", placeholder: messages.policyRuleDialog.placeholders.refundPercent })] })] }), _jsxs("div", { className: "grid grid-cols-2 gap-4", children: [_jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(Label, { children: messages.policyRuleDialog.fields.refundType }), _jsxs(Select, { items: refundTypeItems, value: form.watch("refundType") ?? "", onValueChange: (v) => form.setValue("refundType", (v || undefined)), children: [_jsx(SelectTrigger, { className: "w-full", children: _jsx(SelectValue, { placeholder: messages.common.selectPlaceholder }) }), _jsx(SelectContent, { children: refundTypeItems.map((t) => (_jsx(SelectItem, { value: t.value, children: t.label }, t.value))) })] })] }), _jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(Label, { children: messages.policyRuleDialog.fields.currency }), _jsx(CurrencyCombobox, { value: form.watch("currency") || null, onChange: (next) => form.setValue("currency", next ?? "EUR" /* i18n-literal-ok domain default currency */, {
|
|
86
94
|
shouldValidate: true,
|
|
87
95
|
shouldDirty: true,
|
|
88
|
-
}) })] })] }), _jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(Label, { children:
|
|
96
|
+
}) })] })] }), _jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(Label, { children: messages.policyRuleDialog.fields.flatAmountCents }), _jsx(Input, { ...form.register("flatAmountCents"), type: "number", placeholder: messages.policyRuleDialog.placeholders.flatAmountCents })] })] }), _jsxs(DialogFooter, { children: [_jsx(Button, { type: "button", variant: "ghost", onClick: () => onOpenChange(false), children: messages.common.cancel }), _jsxs(Button, { type: "submit", disabled: form.formState.isSubmitting, children: [form.formState.isSubmitting && _jsx(Loader2, { className: "mr-2 h-4 w-4 animate-spin" }), isEditing ? messages.common.saveChanges : messages.policyRuleDialog.actions.create] })] })] })] }) }));
|
|
89
97
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"policy-version-dialog.d.ts","sourceRoot":"","sources":["../../src/components/policy-version-dialog.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,wBAAwB,EAAiC,MAAM,uBAAuB,CAAA;
|
|
1
|
+
{"version":3,"file":"policy-version-dialog.d.ts","sourceRoot":"","sources":["../../src/components/policy-version-dialog.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,wBAAwB,EAAiC,MAAM,uBAAuB,CAAA;AAgCpG,KAAK,wBAAwB,GAAG;IAC9B,IAAI,EAAE,OAAO,CAAA;IACb,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAA;IACrC,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,CAAC,EAAE,wBAAwB,CAAA;IAClC,SAAS,EAAE,MAAM,IAAI,CAAA;CACtB,CAAA;AAED,wBAAgB,mBAAmB,CAAC,EAClC,IAAI,EACJ,YAAY,EACZ,QAAQ,EACR,OAAO,EACP,SAAS,GACV,EAAE,wBAAwB,2CA2F1B"}
|
|
@@ -6,13 +6,18 @@ import { Loader2 } from "lucide-react";
|
|
|
6
6
|
import { useEffect } from "react";
|
|
7
7
|
import { useForm } from "react-hook-form";
|
|
8
8
|
import { z } from "zod/v4";
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
import { useLegalUiMessagesOrDefault } from "../i18n";
|
|
10
|
+
function createVersionFormSchema(messages) {
|
|
11
|
+
return z.object({
|
|
12
|
+
title: z.string().min(1, messages.policyVersionDialog.validation.titleRequired),
|
|
13
|
+
body: z.string().optional(),
|
|
14
|
+
});
|
|
15
|
+
}
|
|
13
16
|
export function PolicyVersionDialog({ open, onOpenChange, policyId, version, onSuccess, }) {
|
|
14
17
|
const isEditing = !!version;
|
|
15
18
|
const { create, update } = useLegalPolicyVersionMutation();
|
|
19
|
+
const messages = useLegalUiMessagesOrDefault();
|
|
20
|
+
const versionFormSchema = createVersionFormSchema(messages);
|
|
16
21
|
const form = useForm({
|
|
17
22
|
resolver: zodResolver(versionFormSchema),
|
|
18
23
|
defaultValues: {
|
|
@@ -44,9 +49,13 @@ export function PolicyVersionDialog({ open, onOpenChange, policyId, version, onS
|
|
|
44
49
|
}
|
|
45
50
|
onSuccess();
|
|
46
51
|
};
|
|
47
|
-
return (_jsx(Dialog, { open: open, onOpenChange: onOpenChange, children: _jsxs(DialogContent, { size: "lg", children: [_jsx(DialogHeader, { children: _jsx(DialogTitle, { children: isEditing
|
|
52
|
+
return (_jsx(Dialog, { open: open, onOpenChange: onOpenChange, children: _jsxs(DialogContent, { size: "lg", children: [_jsx(DialogHeader, { children: _jsx(DialogTitle, { children: isEditing
|
|
53
|
+
? messages.policyVersionDialog.titles.edit
|
|
54
|
+
: messages.policyVersionDialog.titles.create }) }), _jsxs("form", { onSubmit: form.handleSubmit(onSubmit), children: [_jsxs(DialogBody, { className: "grid gap-4", children: [_jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(Label, { children: messages.policyVersionDialog.fields.title }), _jsx(Input, { ...form.register("title"), placeholder: messages.policyVersionDialog.placeholders.title }), form.formState.errors.title && (_jsx("p", { className: "text-xs text-destructive", children: form.formState.errors.title.message }))] }), _jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(Label, { children: messages.policyVersionDialog.fields.body }), _jsx(RichTextEditor, { value: form.watch("body") ?? "", onChange: (value) => form.setValue("body", value, {
|
|
48
55
|
shouldDirty: true,
|
|
49
56
|
shouldTouch: true,
|
|
50
57
|
shouldValidate: true,
|
|
51
|
-
}), placeholder:
|
|
58
|
+
}), placeholder: messages.policyVersionDialog.placeholders.body })] })] }), _jsxs(DialogFooter, { children: [_jsx(Button, { type: "button", variant: "ghost", onClick: () => onOpenChange(false), children: messages.common.cancel }), _jsxs(Button, { type: "submit", disabled: form.formState.isSubmitting, children: [form.formState.isSubmitting && _jsx(Loader2, { className: "mr-2 h-4 w-4 animate-spin" }), isEditing
|
|
59
|
+
? messages.common.saveChanges
|
|
60
|
+
: messages.policyVersionDialog.actions.create] })] })] })] }) }));
|
|
52
61
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"signature-dialog.d.ts","sourceRoot":"","sources":["../../src/components/signature-dialog.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"signature-dialog.d.ts","sourceRoot":"","sources":["../../src/components/signature-dialog.tsx"],"names":[],"mappings":"AA6CA,KAAK,oBAAoB,GAAG;IAC1B,IAAI,EAAE,OAAO,CAAA;IACb,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAA;IACrC,UAAU,EAAE,MAAM,CAAA;IAClB,SAAS,EAAE,MAAM,IAAI,CAAA;CACtB,CAAA;AAED,wBAAgB,eAAe,CAAC,EAC9B,IAAI,EACJ,YAAY,EACZ,UAAU,EACV,SAAS,GACV,EAAE,oBAAoB,2CAoItB"}
|
|
@@ -6,22 +6,30 @@ import { Loader2 } from "lucide-react";
|
|
|
6
6
|
import { useEffect } from "react";
|
|
7
7
|
import { useForm } from "react-hook-form";
|
|
8
8
|
import { z } from "zod/v4";
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
9
|
+
import { useLegalUiMessagesOrDefault } from "../i18n";
|
|
10
|
+
import { legalSignatureMethods } from "../i18n/messages";
|
|
11
|
+
function createSignatureFormSchema(messages) {
|
|
12
|
+
return z.object({
|
|
13
|
+
signerName: z.string().min(1, messages.signatureDialog.validation.signerNameRequired),
|
|
14
|
+
signerEmail: z
|
|
15
|
+
.string()
|
|
16
|
+
.email(messages.signatureDialog.validation.signerEmailInvalid)
|
|
17
|
+
.optional()
|
|
18
|
+
.or(z.literal("")),
|
|
19
|
+
signerRole: z.string().optional(),
|
|
20
|
+
method: z.enum(legalSignatureMethods),
|
|
21
|
+
provider: z.string().optional(),
|
|
22
|
+
externalReference: z.string().optional(),
|
|
23
|
+
});
|
|
24
|
+
}
|
|
23
25
|
export function SignatureDialog({ open, onOpenChange, contractId, onSuccess, }) {
|
|
24
26
|
const { create } = useLegalContractSignatureMutation();
|
|
27
|
+
const messages = useLegalUiMessagesOrDefault();
|
|
28
|
+
const signatureFormSchema = createSignatureFormSchema(messages);
|
|
29
|
+
const methodItems = legalSignatureMethods.map((value) => ({
|
|
30
|
+
value,
|
|
31
|
+
label: messages.signatureDialog.methodLabels[value],
|
|
32
|
+
}));
|
|
25
33
|
const form = useForm({
|
|
26
34
|
resolver: zodResolver(signatureFormSchema),
|
|
27
35
|
defaultValues: {
|
|
@@ -52,5 +60,5 @@ export function SignatureDialog({ open, onOpenChange, contractId, onSuccess, })
|
|
|
52
60
|
});
|
|
53
61
|
onSuccess();
|
|
54
62
|
};
|
|
55
|
-
return (_jsx(Dialog, { open: open, onOpenChange: onOpenChange, children: _jsxs(DialogContent, { children: [_jsx(DialogHeader, { children: _jsx(DialogTitle, { children:
|
|
63
|
+
return (_jsx(Dialog, { open: open, onOpenChange: onOpenChange, children: _jsxs(DialogContent, { children: [_jsx(DialogHeader, { children: _jsx(DialogTitle, { children: messages.signatureDialog.title }) }), _jsxs("form", { onSubmit: form.handleSubmit(onSubmit), children: [_jsxs(DialogBody, { className: "grid gap-4", children: [_jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(Label, { children: messages.signatureDialog.fields.signerName }), _jsx(Input, { ...form.register("signerName"), placeholder: messages.signatureDialog.placeholders.signerName }), form.formState.errors.signerName && (_jsx("p", { className: "text-xs text-destructive", children: form.formState.errors.signerName.message }))] }), _jsxs("div", { className: "grid grid-cols-2 gap-4", children: [_jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(Label, { children: messages.signatureDialog.fields.signerEmail }), _jsx(Input, { ...form.register("signerEmail"), type: "email", placeholder: messages.signatureDialog.placeholders.signerEmail })] }), _jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(Label, { children: messages.signatureDialog.fields.signerRole }), _jsx(Input, { ...form.register("signerRole"), placeholder: messages.signatureDialog.placeholders.signerRole })] })] }), _jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(Label, { children: messages.signatureDialog.fields.method }), _jsxs(Select, { items: methodItems, value: form.watch("method"), onValueChange: (v) => form.setValue("method", v, { shouldValidate: true }), children: [_jsx(SelectTrigger, { className: "w-full", children: _jsx(SelectValue, {}) }), _jsx(SelectContent, { children: methodItems.map((m) => (_jsx(SelectItem, { value: m.value, children: m.label }, m.value))) })] })] }), _jsxs("div", { className: "grid grid-cols-2 gap-4", children: [_jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(Label, { children: messages.signatureDialog.fields.provider }), _jsx(Input, { ...form.register("provider"), placeholder: messages.signatureDialog.placeholders.provider })] }), _jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(Label, { children: messages.signatureDialog.fields.externalReference }), _jsx(Input, { ...form.register("externalReference"), placeholder: messages.signatureDialog.placeholders.externalReference })] })] })] }), _jsxs(DialogFooter, { children: [_jsx(Button, { type: "button", variant: "ghost", onClick: () => onOpenChange(false), children: messages.common.cancel }), _jsxs(Button, { type: "submit", disabled: form.formState.isSubmitting, children: [form.formState.isSubmitting && _jsx(Loader2, { className: "mr-2 h-4 w-4 animate-spin" }), messages.signatureDialog.actions.submit] })] })] })] }) }));
|
|
56
64
|
}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
export declare const legalUiEn: {
|
|
2
|
+
common: {
|
|
3
|
+
cancel: string;
|
|
4
|
+
saveChanges: string;
|
|
5
|
+
create: string;
|
|
6
|
+
edit: string;
|
|
7
|
+
add: string;
|
|
8
|
+
loading: string;
|
|
9
|
+
none: string;
|
|
10
|
+
selectPlaceholder: string;
|
|
11
|
+
optionalPlaceholder: string;
|
|
12
|
+
kilobytes: string;
|
|
13
|
+
};
|
|
14
|
+
bookingContractCard: {
|
|
15
|
+
heading: string;
|
|
16
|
+
empty: string;
|
|
17
|
+
generate: string;
|
|
18
|
+
regenerate: string;
|
|
19
|
+
download: string;
|
|
20
|
+
noAttachments: string;
|
|
21
|
+
issuedAt: string;
|
|
22
|
+
contractNumber: string;
|
|
23
|
+
unsaved: string;
|
|
24
|
+
contractStatusLabels: {
|
|
25
|
+
draft: string;
|
|
26
|
+
issued: string;
|
|
27
|
+
sent: string;
|
|
28
|
+
signed: string;
|
|
29
|
+
executed: string;
|
|
30
|
+
expired: string;
|
|
31
|
+
void: string;
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
attachmentDialog: {
|
|
35
|
+
titles: {
|
|
36
|
+
create: string;
|
|
37
|
+
edit: string;
|
|
38
|
+
};
|
|
39
|
+
fields: {
|
|
40
|
+
name: string;
|
|
41
|
+
kind: string;
|
|
42
|
+
mimeType: string;
|
|
43
|
+
fileSize: string;
|
|
44
|
+
checksum: string;
|
|
45
|
+
storageKey: string;
|
|
46
|
+
};
|
|
47
|
+
placeholders: {
|
|
48
|
+
name: string;
|
|
49
|
+
kind: string;
|
|
50
|
+
mimeType: string;
|
|
51
|
+
fileSize: string;
|
|
52
|
+
checksum: string;
|
|
53
|
+
storageKey: string;
|
|
54
|
+
};
|
|
55
|
+
actions: {
|
|
56
|
+
create: string;
|
|
57
|
+
};
|
|
58
|
+
validation: {
|
|
59
|
+
nameRequired: string;
|
|
60
|
+
};
|
|
61
|
+
};
|
|
62
|
+
policyRuleDialog: {
|
|
63
|
+
titles: {
|
|
64
|
+
create: string;
|
|
65
|
+
edit: string;
|
|
66
|
+
};
|
|
67
|
+
fields: {
|
|
68
|
+
ruleType: string;
|
|
69
|
+
sortOrder: string;
|
|
70
|
+
label: string;
|
|
71
|
+
daysBeforeDeparture: string;
|
|
72
|
+
refundPercent: string;
|
|
73
|
+
refundType: string;
|
|
74
|
+
currency: string;
|
|
75
|
+
flatAmountCents: string;
|
|
76
|
+
};
|
|
77
|
+
placeholders: {
|
|
78
|
+
label: string;
|
|
79
|
+
daysBeforeDeparture: string;
|
|
80
|
+
refundPercent: string;
|
|
81
|
+
flatAmountCents: string;
|
|
82
|
+
};
|
|
83
|
+
actions: {
|
|
84
|
+
create: string;
|
|
85
|
+
};
|
|
86
|
+
ruleTypeLabels: {
|
|
87
|
+
window: string;
|
|
88
|
+
percentage: string;
|
|
89
|
+
flat_amount: string;
|
|
90
|
+
date_range: string;
|
|
91
|
+
custom: string;
|
|
92
|
+
};
|
|
93
|
+
refundTypeLabels: {
|
|
94
|
+
cash: string;
|
|
95
|
+
credit: string;
|
|
96
|
+
cash_or_credit: string;
|
|
97
|
+
none: string;
|
|
98
|
+
};
|
|
99
|
+
validation: {
|
|
100
|
+
refundPercentMin: string;
|
|
101
|
+
refundPercentMax: string;
|
|
102
|
+
};
|
|
103
|
+
};
|
|
104
|
+
signatureDialog: {
|
|
105
|
+
title: string;
|
|
106
|
+
fields: {
|
|
107
|
+
signerName: string;
|
|
108
|
+
signerEmail: string;
|
|
109
|
+
signerRole: string;
|
|
110
|
+
method: string;
|
|
111
|
+
provider: string;
|
|
112
|
+
externalReference: string;
|
|
113
|
+
};
|
|
114
|
+
placeholders: {
|
|
115
|
+
signerName: string;
|
|
116
|
+
signerEmail: string;
|
|
117
|
+
signerRole: string;
|
|
118
|
+
provider: string;
|
|
119
|
+
externalReference: string;
|
|
120
|
+
};
|
|
121
|
+
actions: {
|
|
122
|
+
submit: string;
|
|
123
|
+
};
|
|
124
|
+
methodLabels: {
|
|
125
|
+
manual: string;
|
|
126
|
+
electronic: string;
|
|
127
|
+
docusign: string;
|
|
128
|
+
other: string;
|
|
129
|
+
};
|
|
130
|
+
validation: {
|
|
131
|
+
signerNameRequired: string;
|
|
132
|
+
signerEmailInvalid: string;
|
|
133
|
+
};
|
|
134
|
+
};
|
|
135
|
+
policyVersionDialog: {
|
|
136
|
+
titles: {
|
|
137
|
+
create: string;
|
|
138
|
+
edit: string;
|
|
139
|
+
};
|
|
140
|
+
fields: {
|
|
141
|
+
title: string;
|
|
142
|
+
body: string;
|
|
143
|
+
};
|
|
144
|
+
placeholders: {
|
|
145
|
+
title: string;
|
|
146
|
+
body: string;
|
|
147
|
+
};
|
|
148
|
+
actions: {
|
|
149
|
+
create: string;
|
|
150
|
+
};
|
|
151
|
+
validation: {
|
|
152
|
+
titleRequired: string;
|
|
153
|
+
};
|
|
154
|
+
};
|
|
155
|
+
};
|
|
156
|
+
//# sourceMappingURL=en.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"en.d.ts","sourceRoot":"","sources":["../../src/i18n/en.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA0JK,CAAA"}
|