@voyant-travel/legal-react 0.119.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (238) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +66 -0
  3. package/dist/admin/contract-detail-host.d.ts +21 -0
  4. package/dist/admin/contract-detail-host.d.ts.map +1 -0
  5. package/dist/admin/contract-detail-host.js +118 -0
  6. package/dist/admin/contract-dialog-fields.d.ts +79 -0
  7. package/dist/admin/contract-dialog-fields.d.ts.map +1 -0
  8. package/dist/admin/contract-dialog-fields.js +178 -0
  9. package/dist/admin/contract-dialog.d.ts +4 -0
  10. package/dist/admin/contract-dialog.d.ts.map +1 -0
  11. package/dist/admin/contract-dialog.js +479 -0
  12. package/dist/admin/contract-upload-field.d.ts +12 -0
  13. package/dist/admin/contract-upload-field.d.ts.map +1 -0
  14. package/dist/admin/contract-upload-field.js +31 -0
  15. package/dist/admin/contracts-host.d.ts +10 -0
  16. package/dist/admin/contracts-host.d.ts.map +1 -0
  17. package/dist/admin/contracts-host.js +32 -0
  18. package/dist/admin/index.d.ts +78 -0
  19. package/dist/admin/index.d.ts.map +1 -0
  20. package/dist/admin/index.js +193 -0
  21. package/dist/admin/legal-admin-shared.d.ts +31 -0
  22. package/dist/admin/legal-admin-shared.d.ts.map +1 -0
  23. package/dist/admin/legal-admin-shared.js +48 -0
  24. package/dist/admin/number-series-dialog.d.ts +11 -0
  25. package/dist/admin/number-series-dialog.d.ts.map +1 -0
  26. package/dist/admin/number-series-dialog.js +110 -0
  27. package/dist/admin/number-series-host.d.ts +7 -0
  28. package/dist/admin/number-series-host.d.ts.map +1 -0
  29. package/dist/admin/number-series-host.js +12 -0
  30. package/dist/admin/pages/contract-detail-page.d.ts +7 -0
  31. package/dist/admin/pages/contract-detail-page.d.ts.map +1 -0
  32. package/dist/admin/pages/contract-detail-page.js +9 -0
  33. package/dist/admin/pages/policy-detail-page.d.ts +7 -0
  34. package/dist/admin/pages/policy-detail-page.d.ts.map +1 -0
  35. package/dist/admin/pages/policy-detail-page.js +9 -0
  36. package/dist/admin/pages/template-detail-page.d.ts +7 -0
  37. package/dist/admin/pages/template-detail-page.d.ts.map +1 -0
  38. package/dist/admin/pages/template-detail-page.js +9 -0
  39. package/dist/admin/policies-host.d.ts +9 -0
  40. package/dist/admin/policies-host.d.ts.map +1 -0
  41. package/dist/admin/policies-host.js +16 -0
  42. package/dist/admin/policy-assignment-dialog.d.ts +11 -0
  43. package/dist/admin/policy-assignment-dialog.d.ts.map +1 -0
  44. package/dist/admin/policy-assignment-dialog.js +234 -0
  45. package/dist/admin/policy-detail-host.d.ts +12 -0
  46. package/dist/admin/policy-detail-host.d.ts.map +1 -0
  47. package/dist/admin/policy-detail-host.js +17 -0
  48. package/dist/admin/policy-dialog.d.ts +10 -0
  49. package/dist/admin/policy-dialog.d.ts.map +1 -0
  50. package/dist/admin/policy-dialog.js +81 -0
  51. package/dist/admin/template-detail-host.d.ts +11 -0
  52. package/dist/admin/template-detail-host.d.ts.map +1 -0
  53. package/dist/admin/template-detail-host.js +20 -0
  54. package/dist/admin/template-dialog.d.ts +10 -0
  55. package/dist/admin/template-dialog.d.ts.map +1 -0
  56. package/dist/admin/template-dialog.js +117 -0
  57. package/dist/admin/template-version-dialog.d.ts +9 -0
  58. package/dist/admin/template-version-dialog.d.ts.map +1 -0
  59. package/dist/admin/template-version-dialog.js +67 -0
  60. package/dist/admin/templates-host.d.ts +9 -0
  61. package/dist/admin/templates-host.d.ts.map +1 -0
  62. package/dist/admin/templates-host.js +20 -0
  63. package/dist/client.d.ts +14 -0
  64. package/dist/client.d.ts.map +1 -0
  65. package/dist/client.js +69 -0
  66. package/dist/components/attachment-dialog.d.ts +11 -0
  67. package/dist/components/attachment-dialog.d.ts.map +1 -0
  68. package/dist/components/attachment-dialog.js +154 -0
  69. package/dist/components/booking-contract-card.d.ts +37 -0
  70. package/dist/components/booking-contract-card.d.ts.map +1 -0
  71. package/dist/components/booking-contract-card.js +101 -0
  72. package/dist/components/contract-detail-page.d.ts +36 -0
  73. package/dist/components/contract-detail-page.d.ts.map +1 -0
  74. package/dist/components/contract-detail-page.js +156 -0
  75. package/dist/components/contract-dialog-fields.d.ts +114 -0
  76. package/dist/components/contract-dialog-fields.d.ts.map +1 -0
  77. package/dist/components/contract-dialog-fields.js +233 -0
  78. package/dist/components/contract-dialog.d.ts +5 -0
  79. package/dist/components/contract-dialog.d.ts.map +1 -0
  80. package/dist/components/contract-dialog.js +345 -0
  81. package/dist/components/contract-send-dialog.d.ts +37 -0
  82. package/dist/components/contract-send-dialog.d.ts.map +1 -0
  83. package/dist/components/contract-send-dialog.js +56 -0
  84. package/dist/components/contracts-page.d.ts +30 -0
  85. package/dist/components/contracts-page.d.ts.map +1 -0
  86. package/dist/components/contracts-page.js +192 -0
  87. package/dist/components/number-series-page.d.ts +13 -0
  88. package/dist/components/number-series-page.d.ts.map +1 -0
  89. package/dist/components/number-series-page.js +37 -0
  90. package/dist/components/policies-page.d.ts +13 -0
  91. package/dist/components/policies-page.d.ts.map +1 -0
  92. package/dist/components/policies-page.js +70 -0
  93. package/dist/components/policy-detail-page.d.ts +23 -0
  94. package/dist/components/policy-detail-page.d.ts.map +1 -0
  95. package/dist/components/policy-detail-page.js +171 -0
  96. package/dist/components/policy-rule-dialog.d.ts +12 -0
  97. package/dist/components/policy-rule-dialog.d.ts.map +1 -0
  98. package/dist/components/policy-rule-dialog.js +101 -0
  99. package/dist/components/policy-version-dialog.d.ts +11 -0
  100. package/dist/components/policy-version-dialog.d.ts.map +1 -0
  101. package/dist/components/policy-version-dialog.js +62 -0
  102. package/dist/components/signature-dialog.d.ts +9 -0
  103. package/dist/components/signature-dialog.d.ts.map +1 -0
  104. package/dist/components/signature-dialog.js +64 -0
  105. package/dist/components/template-detail-page.d.ts +10 -0
  106. package/dist/components/template-detail-page.d.ts.map +1 -0
  107. package/dist/components/template-detail-page.js +84 -0
  108. package/dist/components/templates-page.d.ts +27 -0
  109. package/dist/components/templates-page.d.ts.map +1 -0
  110. package/dist/components/templates-page.js +65 -0
  111. package/dist/hooks/index.d.ts +31 -0
  112. package/dist/hooks/index.d.ts.map +1 -0
  113. package/dist/hooks/index.js +30 -0
  114. package/dist/hooks/use-contract-attachment-mutation.d.ts +119 -0
  115. package/dist/hooks/use-contract-attachment-mutation.d.ts.map +1 -0
  116. package/dist/hooks/use-contract-attachment-mutation.js +72 -0
  117. package/dist/hooks/use-contract-attachments.d.ts +23 -0
  118. package/dist/hooks/use-contract-attachments.d.ts.map +1 -0
  119. package/dist/hooks/use-contract-attachments.js +12 -0
  120. package/dist/hooks/use-contract-mutation.d.ts +427 -0
  121. package/dist/hooks/use-contract-mutation.d.ts.map +1 -0
  122. package/dist/hooks/use-contract-mutation.js +151 -0
  123. package/dist/hooks/use-contract-signature-mutation.d.ts +35 -0
  124. package/dist/hooks/use-contract-signature-mutation.d.ts.map +1 -0
  125. package/dist/hooks/use-contract-signature-mutation.js +23 -0
  126. package/dist/hooks/use-contract-signatures.d.ts +28 -0
  127. package/dist/hooks/use-contract-signatures.d.ts.map +1 -0
  128. package/dist/hooks/use-contract-signatures.js +12 -0
  129. package/dist/hooks/use-contract-template-authoring.d.ts +5 -0
  130. package/dist/hooks/use-contract-template-authoring.d.ts.map +1 -0
  131. package/dist/hooks/use-contract-template-authoring.js +7 -0
  132. package/dist/hooks/use-contract-template-mutation.d.ts +56 -0
  133. package/dist/hooks/use-contract-template-mutation.d.ts.map +1 -0
  134. package/dist/hooks/use-contract-template-mutation.js +39 -0
  135. package/dist/hooks/use-contract-template-version-mutation.d.ts +22 -0
  136. package/dist/hooks/use-contract-template-version-mutation.d.ts.map +1 -0
  137. package/dist/hooks/use-contract-template-version-mutation.js +22 -0
  138. package/dist/hooks/use-contract-template-versions.d.ts +15 -0
  139. package/dist/hooks/use-contract-template-versions.d.ts.map +1 -0
  140. package/dist/hooks/use-contract-template-versions.js +12 -0
  141. package/dist/hooks/use-contract-template.d.ts +20 -0
  142. package/dist/hooks/use-contract-template.d.ts.map +1 -0
  143. package/dist/hooks/use-contract-template.js +12 -0
  144. package/dist/hooks/use-contract-templates.d.ts +26 -0
  145. package/dist/hooks/use-contract-templates.d.ts.map +1 -0
  146. package/dist/hooks/use-contract-templates.js +12 -0
  147. package/dist/hooks/use-contract.d.ts +47 -0
  148. package/dist/hooks/use-contract.d.ts.map +1 -0
  149. package/dist/hooks/use-contract.js +12 -0
  150. package/dist/hooks/use-contracts.d.ts +53 -0
  151. package/dist/hooks/use-contracts.d.ts.map +1 -0
  152. package/dist/hooks/use-contracts.js +12 -0
  153. package/dist/hooks/use-default-contract-template.d.ts +21 -0
  154. package/dist/hooks/use-default-contract-template.d.ts.map +1 -0
  155. package/dist/hooks/use-default-contract-template.js +12 -0
  156. package/dist/hooks/use-evaluate-cancellation.d.ts +46 -0
  157. package/dist/hooks/use-evaluate-cancellation.d.ts.map +1 -0
  158. package/dist/hooks/use-evaluate-cancellation.js +43 -0
  159. package/dist/hooks/use-number-series-mutation.d.ts +58 -0
  160. package/dist/hooks/use-number-series-mutation.d.ts.map +1 -0
  161. package/dist/hooks/use-number-series-mutation.js +38 -0
  162. package/dist/hooks/use-number-series.d.ts +24 -0
  163. package/dist/hooks/use-number-series.d.ts.map +1 -0
  164. package/dist/hooks/use-number-series.js +12 -0
  165. package/dist/hooks/use-policies.d.ts +22 -0
  166. package/dist/hooks/use-policies.d.ts.map +1 -0
  167. package/dist/hooks/use-policies.js +12 -0
  168. package/dist/hooks/use-policy-acceptances.d.ts +26 -0
  169. package/dist/hooks/use-policy-acceptances.d.ts.map +1 -0
  170. package/dist/hooks/use-policy-acceptances.js +12 -0
  171. package/dist/hooks/use-policy-assignment-mutation.d.ts +63 -0
  172. package/dist/hooks/use-policy-assignment-mutation.d.ts.map +1 -0
  173. package/dist/hooks/use-policy-assignment-mutation.js +41 -0
  174. package/dist/hooks/use-policy-assignments.d.ts +23 -0
  175. package/dist/hooks/use-policy-assignments.d.ts.map +1 -0
  176. package/dist/hooks/use-policy-assignments.js +12 -0
  177. package/dist/hooks/use-policy-mutation.d.ts +44 -0
  178. package/dist/hooks/use-policy-mutation.d.ts.map +1 -0
  179. package/dist/hooks/use-policy-mutation.js +40 -0
  180. package/dist/hooks/use-policy-rule-mutation.d.ts +56 -0
  181. package/dist/hooks/use-policy-rule-mutation.d.ts.map +1 -0
  182. package/dist/hooks/use-policy-rule-mutation.js +39 -0
  183. package/dist/hooks/use-policy-rules.d.ts +22 -0
  184. package/dist/hooks/use-policy-rules.d.ts.map +1 -0
  185. package/dist/hooks/use-policy-rules.js +12 -0
  186. package/dist/hooks/use-policy-version-mutation.d.ts +69 -0
  187. package/dist/hooks/use-policy-version-mutation.d.ts.map +1 -0
  188. package/dist/hooks/use-policy-version-mutation.js +50 -0
  189. package/dist/hooks/use-policy-versions.d.ts +19 -0
  190. package/dist/hooks/use-policy-versions.d.ts.map +1 -0
  191. package/dist/hooks/use-policy-versions.js +12 -0
  192. package/dist/hooks/use-policy.d.ts +16 -0
  193. package/dist/hooks/use-policy.d.ts.map +1 -0
  194. package/dist/hooks/use-policy.js +12 -0
  195. package/dist/hooks/use-resolve-policy.d.ts +72 -0
  196. package/dist/hooks/use-resolve-policy.d.ts.map +1 -0
  197. package/dist/hooks/use-resolve-policy.js +16 -0
  198. package/dist/hooks/use-term.d.ts +27 -0
  199. package/dist/hooks/use-term.d.ts.map +1 -0
  200. package/dist/hooks/use-term.js +12 -0
  201. package/dist/hooks/use-terms.d.ts +33 -0
  202. package/dist/hooks/use-terms.d.ts.map +1 -0
  203. package/dist/hooks/use-terms.js +12 -0
  204. package/dist/i18n/en.d.ts +548 -0
  205. package/dist/i18n/en.d.ts.map +1 -0
  206. package/dist/i18n/en.js +547 -0
  207. package/dist/i18n/index.d.ts +6 -0
  208. package/dist/i18n/index.d.ts.map +1 -0
  209. package/dist/i18n/index.js +4 -0
  210. package/dist/i18n/messages.d.ts +504 -0
  211. package/dist/i18n/messages.d.ts.map +1 -0
  212. package/dist/i18n/messages.js +29 -0
  213. package/dist/i18n/provider.d.ts +1118 -0
  214. package/dist/i18n/provider.d.ts.map +1 -0
  215. package/dist/i18n/provider.js +44 -0
  216. package/dist/i18n/ro.d.ts +548 -0
  217. package/dist/i18n/ro.d.ts.map +1 -0
  218. package/dist/i18n/ro.js +547 -0
  219. package/dist/index.d.ts +7 -0
  220. package/dist/index.d.ts.map +1 -0
  221. package/dist/index.js +6 -0
  222. package/dist/provider.d.ts +2 -0
  223. package/dist/provider.d.ts.map +1 -0
  224. package/dist/provider.js +1 -0
  225. package/dist/query-keys.d.ts +120 -0
  226. package/dist/query-keys.d.ts.map +1 -0
  227. package/dist/query-keys.js +27 -0
  228. package/dist/query-options.d.ts +1929 -0
  229. package/dist/query-options.d.ts.map +1 -0
  230. package/dist/query-options.js +183 -0
  231. package/dist/schemas.d.ts +1547 -0
  232. package/dist/schemas.d.ts.map +1 -0
  233. package/dist/schemas.js +269 -0
  234. package/dist/ui.d.ts +16 -0
  235. package/dist/ui.d.ts.map +1 -0
  236. package/dist/ui.js +15 -0
  237. package/package.json +159 -0
  238. package/src/styles.css +11 -0
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Packaged admin host for the operator-grade contract templates list page
3
+ * (packaged-admin RFC Phase 3). Zero-prop: list state stays
4
+ * component-local, opening a row resolves through the
5
+ * `contractTemplate.detail` semantic destination, and the create/edit
6
+ * dialog (rich-text editor) stays lazily loaded inside the package.
7
+ */
8
+ export declare function TemplatesHost(): import("react/jsx-runtime").JSX.Element;
9
+ //# sourceMappingURL=templates-host.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"templates-host.d.ts","sourceRoot":"","sources":["../../src/admin/templates-host.tsx"],"names":[],"mappings":"AAcA;;;;;;GAMG;AACH,wBAAgB,aAAa,4CAa5B"}
@@ -0,0 +1,20 @@
1
+ "use client";
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { useAdminNavigate } from "@voyant-travel/admin";
4
+ import { lazy, Suspense } from "react";
5
+ import { TemplatesPage } from "../components/templates-page.js";
6
+ // Lazy-load: the template dialog pulls tiptap + prosemirror (~600 KB raw).
7
+ // Keeping it out of the page chunk means the dialog modules + their
8
+ // dependencies only download when the user opens the dialog.
9
+ const TemplateDialog = lazy(() => import("./template-dialog.js").then((m) => ({ default: m.TemplateDialog })));
10
+ /**
11
+ * Packaged admin host for the operator-grade contract templates list page
12
+ * (packaged-admin RFC Phase 3). Zero-prop: list state stays
13
+ * component-local, opening a row resolves through the
14
+ * `contractTemplate.detail` semantic destination, and the create/edit
15
+ * dialog (rich-text editor) stays lazily loaded inside the package.
16
+ */
17
+ export function TemplatesHost() {
18
+ const navigateTo = useAdminNavigate();
19
+ return (_jsx(TemplatesPage, { onOpenTemplate: (id) => navigateTo("contractTemplate.detail", { templateId: id }), renderTemplateDialog: (props) => (_jsx(Suspense, { fallback: null, children: _jsx(TemplateDialog, { ...props }) })) }));
20
+ }
@@ -0,0 +1,14 @@
1
+ import type { z } from "zod";
2
+ export type VoyantFetcher = (url: string, init?: RequestInit) => Promise<Response>;
3
+ export declare const defaultFetcher: VoyantFetcher;
4
+ export declare class VoyantApiError extends Error {
5
+ readonly status: number;
6
+ readonly body: unknown;
7
+ constructor(message: string, status: number, body: unknown);
8
+ }
9
+ export interface FetchWithValidationOptions {
10
+ baseUrl: string;
11
+ fetcher: VoyantFetcher;
12
+ }
13
+ export declare function fetchWithValidation<TOut>(path: string, schema: z.ZodType<TOut>, options: FetchWithValidationOptions, init?: RequestInit): Promise<TOut>;
14
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAE5B,MAAM,MAAM,aAAa,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAA;AAElF,eAAO,MAAM,cAAc,EAAE,aACoB,CAAA;AAEjD,qBAAa,cAAe,SAAQ,KAAK;IACvC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;gBAEV,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO;CAM3D;AAaD,MAAM,WAAW,0BAA0B;IACzC,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,aAAa,CAAA;CACvB;AAED,wBAAsB,mBAAmB,CAAC,IAAI,EAC5C,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,EACvB,OAAO,EAAE,0BAA0B,EACnC,IAAI,CAAC,EAAE,WAAW,GACjB,OAAO,CAAC,IAAI,CAAC,CA+Bf"}
package/dist/client.js ADDED
@@ -0,0 +1,69 @@
1
+ export const defaultFetcher = (url, init) => fetch(url, { credentials: "include", ...init });
2
+ export class VoyantApiError extends Error {
3
+ status;
4
+ body;
5
+ constructor(message, status, body) {
6
+ super(message);
7
+ this.name = "VoyantApiError";
8
+ this.status = status;
9
+ this.body = body;
10
+ }
11
+ }
12
+ function extractErrorMessage(status, statusText, body) {
13
+ if (typeof body === "object" && body !== null && "error" in body) {
14
+ const err = body.error;
15
+ if (typeof err === "string")
16
+ return err;
17
+ if (typeof err === "object" && err !== null && "message" in err) {
18
+ return String(err.message);
19
+ }
20
+ }
21
+ return `Voyant API error: ${status} ${statusText}`;
22
+ }
23
+ export async function fetchWithValidation(path, schema, options, init) {
24
+ const url = joinUrl(options.baseUrl, path);
25
+ const headers = new Headers(init?.headers);
26
+ const isFormDataBody = typeof FormData !== "undefined" && init?.body instanceof FormData;
27
+ if (init?.body !== undefined && !isFormDataBody && !headers.has("Content-Type")) {
28
+ headers.set("Content-Type", "application/json");
29
+ }
30
+ const response = await options.fetcher(url, { ...init, headers });
31
+ if (!response.ok) {
32
+ const body = await safeJson(response);
33
+ throw new VoyantApiError(extractErrorMessage(response.status, response.statusText, body), response.status, body);
34
+ }
35
+ if (response.status === 204)
36
+ return schema.parse(undefined);
37
+ const body = await safeJson(response);
38
+ const parsed = schema.safeParse(body);
39
+ if (!parsed.success) {
40
+ throw new VoyantApiError(`Voyant API response failed validation: ${parsed.error.message}`, response.status, body);
41
+ }
42
+ return parsed.data;
43
+ }
44
+ async function safeJson(response) {
45
+ const text = await response.text();
46
+ if (!text)
47
+ return undefined;
48
+ try {
49
+ return JSON.parse(text);
50
+ }
51
+ catch {
52
+ return text;
53
+ }
54
+ }
55
+ function joinUrl(baseUrl, path) {
56
+ const resolvedBaseUrl = resolveBaseUrl(baseUrl);
57
+ const trimmedBase = resolvedBaseUrl.endsWith("/") ? resolvedBaseUrl.slice(0, -1) : resolvedBaseUrl;
58
+ const trimmedPath = path.startsWith("/") ? path : `/${path}`;
59
+ return `${trimmedBase}${trimmedPath}`;
60
+ }
61
+ function resolveBaseUrl(baseUrl) {
62
+ if (baseUrl.trim()) {
63
+ return baseUrl;
64
+ }
65
+ if (typeof window !== "undefined") {
66
+ return `${window.location.origin}/api`;
67
+ }
68
+ return "http://localhost:3300/api";
69
+ }
@@ -0,0 +1,11 @@
1
+ import { type LegalContractAttachmentRecord } from "../index.js";
2
+ type AttachmentDialogProps = {
3
+ open: boolean;
4
+ onOpenChange: (open: boolean) => void;
5
+ contractId: string;
6
+ attachment?: LegalContractAttachmentRecord;
7
+ onSuccess: () => void;
8
+ };
9
+ export declare function AttachmentDialog({ open, onOpenChange, contractId, attachment, onSuccess, }: AttachmentDialogProps): import("react/jsx-runtime").JSX.Element;
10
+ export {};
11
+ //# sourceMappingURL=attachment-dialog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"attachment-dialog.d.ts","sourceRoot":"","sources":["../../src/components/attachment-dialog.tsx"],"names":[],"mappings":"AAuBA,OAAO,EAAE,KAAK,6BAA6B,EAAsC,MAAM,aAAa,CAAA;AAqBpG,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,2CA8OvB"}
@@ -0,0 +1,154 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { Button, Dialog, DialogBody, DialogContent, DialogFooter, DialogHeader, DialogTitle, Input, Label, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@voyant-travel/ui/components";
3
+ import { zodResolver } from "@voyant-travel/ui/lib/zod-resolver";
4
+ import { FileText, Loader2, Upload } from "lucide-react";
5
+ import { useEffect, useRef, useState } from "react";
6
+ import { useForm } from "react-hook-form";
7
+ import { z } from "zod/v4";
8
+ import { useLegalUiMessagesOrDefault } from "../i18n/index.js";
9
+ import { useLegalContractAttachmentMutation } from "../index.js";
10
+ const attachmentKindValues = ["document", "appendix", "scan"];
11
+ function createAttachmentFormSchema(messages) {
12
+ return z.object({
13
+ name: z.string().min(1, messages.attachmentDialog.validation.nameRequired),
14
+ kind: z.string().min(1).optional(),
15
+ mimeType: z.string().optional(),
16
+ fileSize: z.preprocess((value) => (value === "" || value == null ? undefined : value), z.coerce.number().int().optional()),
17
+ storageKey: z.string().optional(),
18
+ checksum: z.string().optional(),
19
+ });
20
+ }
21
+ export function AttachmentDialog({ open, onOpenChange, contractId, attachment, onSuccess, }) {
22
+ const isEditing = !!attachment;
23
+ const { update, upload, replaceFile } = useLegalContractAttachmentMutation();
24
+ const messages = useLegalUiMessagesOrDefault();
25
+ const attachmentFormSchema = createAttachmentFormSchema(messages);
26
+ const fileInputRef = useRef(null);
27
+ const [selectedFile, setSelectedFile] = useState(null);
28
+ const [fileError, setFileError] = useState(null);
29
+ const [isDragging, setIsDragging] = useState(false);
30
+ const kindItems = attachmentKindValues.map((value) => ({
31
+ value,
32
+ label: messages.attachmentDialog.kindLabels[value],
33
+ }));
34
+ if (attachment?.kind && !attachmentKindValues.includes(attachment.kind)) {
35
+ kindItems.push({ value: attachment.kind, label: attachment.kind });
36
+ }
37
+ const form = useForm({
38
+ resolver: zodResolver(attachmentFormSchema),
39
+ defaultValues: {
40
+ name: "",
41
+ kind: "document", // i18n-literal-ok domain attachment kind
42
+ mimeType: "",
43
+ fileSize: undefined,
44
+ storageKey: "",
45
+ checksum: "",
46
+ },
47
+ });
48
+ useEffect(() => {
49
+ if (open && attachment) {
50
+ form.reset({
51
+ name: attachment.name,
52
+ kind: attachment.kind,
53
+ mimeType: attachment.mimeType ?? "",
54
+ fileSize: attachment.fileSize ?? undefined,
55
+ storageKey: attachment.storageKey ?? "",
56
+ checksum: attachment.checksum ?? "",
57
+ });
58
+ setSelectedFile(null);
59
+ setFileError(null);
60
+ }
61
+ else if (open) {
62
+ form.reset();
63
+ setSelectedFile(null);
64
+ setFileError(null);
65
+ }
66
+ setIsDragging(false);
67
+ }, [open, attachment, form]);
68
+ const applySelectedFile = (file) => {
69
+ setSelectedFile(file);
70
+ setFileError(null);
71
+ setIsDragging(false);
72
+ const currentName = form.getValues("name");
73
+ if (!currentName || currentName === attachment?.name) {
74
+ form.setValue("name", file.name, { shouldDirty: true, shouldValidate: true });
75
+ }
76
+ form.setValue("mimeType", file.type || "", { shouldDirty: true, shouldValidate: true });
77
+ form.setValue("fileSize", file.size, { shouldDirty: true, shouldValidate: true });
78
+ };
79
+ const onFileChange = (event) => {
80
+ const file = event.currentTarget.files?.[0];
81
+ if (!file)
82
+ return;
83
+ applySelectedFile(file);
84
+ event.currentTarget.value = "";
85
+ };
86
+ const onFileDrop = (event) => {
87
+ event.preventDefault();
88
+ event.stopPropagation();
89
+ const file = event.dataTransfer.files?.[0];
90
+ if (file)
91
+ applySelectedFile(file);
92
+ };
93
+ const onFileDragOver = (event) => {
94
+ event.preventDefault();
95
+ event.stopPropagation();
96
+ setIsDragging(true);
97
+ };
98
+ const onFileDragLeave = (event) => {
99
+ event.preventDefault();
100
+ event.stopPropagation();
101
+ setIsDragging(false);
102
+ };
103
+ const onSubmit = async (values) => {
104
+ const uploadInput = selectedFile
105
+ ? {
106
+ file: selectedFile,
107
+ name: values.name,
108
+ kind: values.kind || "document", // i18n-literal-ok domain attachment kind
109
+ }
110
+ : null;
111
+ if (uploadInput && isEditing && attachment) {
112
+ await replaceFile.mutateAsync({ contractId, id: attachment.id, input: uploadInput });
113
+ onSuccess();
114
+ return;
115
+ }
116
+ if (uploadInput) {
117
+ await upload.mutateAsync({ contractId, input: uploadInput });
118
+ onSuccess();
119
+ return;
120
+ }
121
+ if (!isEditing) {
122
+ setFileError(messages.attachmentDialog.validation.fileRequired);
123
+ return;
124
+ }
125
+ await update.mutateAsync({
126
+ contractId,
127
+ id: attachment.id,
128
+ input: {
129
+ name: values.name,
130
+ kind: values.kind || "document", // i18n-literal-ok domain attachment kind
131
+ mimeType: values.mimeType || undefined,
132
+ fileSize: values.fileSize,
133
+ storageKey: values.storageKey || undefined,
134
+ checksum: values.checksum || undefined,
135
+ },
136
+ });
137
+ onSuccess();
138
+ };
139
+ const isSubmitting = form.formState.isSubmitting || update.isPending || upload.isPending || replaceFile.isPending;
140
+ const submitError = update.error ?? upload.error ?? replaceFile.error ?? null;
141
+ return (_jsx(Dialog, { open: open, onOpenChange: onOpenChange, children: _jsxs(DialogContent, { children: [_jsx(DialogHeader, { children: _jsx(DialogTitle, { children: isEditing
142
+ ? messages.attachmentDialog.titles.edit
143
+ : messages.attachmentDialog.titles.create }) }), _jsxs("form", { onSubmit: form.handleSubmit(onSubmit), children: [_jsxs(DialogBody, { className: "grid gap-4", children: [_jsx("input", { type: "hidden", ...form.register("mimeType") }), _jsx("input", { type: "hidden", ...form.register("fileSize") }), _jsx("input", { type: "hidden", ...form.register("storageKey") }), _jsx("input", { type: "hidden", ...form.register("checksum") }), _jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(Label, { children: messages.attachmentDialog.fields.file }), _jsx("button", { type: "button", onClick: () => fileInputRef.current?.click(), onDrop: onFileDrop, onDragOver: onFileDragOver, onDragLeave: onFileDragLeave, "data-dragging": isDragging, className: "flex min-h-32 flex-col items-center justify-center gap-2 rounded-md border border-dashed px-4 py-6 text-center transition-colors hover:border-foreground/30 hover:bg-muted/30 data-[dragging=true]:border-primary data-[dragging=true]:bg-primary/5", children: selectedFile ? (_jsxs(_Fragment, { children: [_jsx(FileText, { className: "size-6 text-muted-foreground", "aria-hidden": "true" }), _jsx("span", { className: "max-w-full truncate font-medium text-sm", children: selectedFile.name }), _jsxs("span", { className: "text-muted-foreground text-xs", children: [formatUploadSize(selectedFile.size), selectedFile.type ? ` - ${selectedFile.type}` : ""] })] })) : (_jsxs(_Fragment, { children: [_jsx(Upload, { className: "size-6 text-muted-foreground", "aria-hidden": "true" }), _jsx("span", { className: "text-muted-foreground text-sm", children: messages.attachmentDialog.placeholders.file })] })) }), _jsx("input", { ref: fileInputRef, type: "file", className: "hidden", onChange: onFileChange }), fileError ? _jsx("p", { className: "text-xs text-destructive", children: fileError }) : null] }), _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.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: "flex flex-col gap-2", children: [_jsx(Label, { children: messages.attachmentDialog.fields.kind }), _jsxs(Select, { items: kindItems, value: form.watch("kind"), onValueChange: (value) => form.setValue("kind", value ?? undefined, {
144
+ shouldDirty: true,
145
+ shouldValidate: true,
146
+ }), children: [_jsx(SelectTrigger, { className: "w-full", children: _jsx(SelectValue, {}) }), _jsx(SelectContent, { children: kindItems.map((item) => (_jsx(SelectItem, { value: item.value, children: item.label }, item.value))) })] })] })] }), submitError ? _jsx("p", { className: "text-xs text-destructive", children: submitError.message }) : null] }), _jsxs(DialogFooter, { children: [_jsx(Button, { type: "button", variant: "ghost", onClick: () => onOpenChange(false), children: messages.common.cancel }), _jsxs(Button, { type: "submit", disabled: isSubmitting, children: [isSubmitting && _jsx(Loader2, { className: "mr-2 h-4 w-4 animate-spin" }), isEditing ? messages.common.saveChanges : messages.attachmentDialog.actions.create] })] })] })] }) }));
147
+ }
148
+ function formatUploadSize(bytes) {
149
+ if (bytes < 1024)
150
+ return `${bytes} B`;
151
+ if (bytes < 1024 * 1024)
152
+ return `${Math.round(bytes / 1024)} KB`;
153
+ return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
154
+ }
@@ -0,0 +1,37 @@
1
+ import type { LegalUiMessages } from "../i18n/messages.js";
2
+ export type BookingContractCardLabels = Partial<Omit<LegalUiMessages["bookingContractCard"], "contractStatusLabels">>;
3
+ export interface BookingContractCardProps {
4
+ /** Booking whose contracts we list. Required — the card filters server-side. */
5
+ bookingId: string;
6
+ /** Contract scope used to resolve the default template + active number series. */
7
+ contractScope?: "customer" | "supplier" | "partner" | "channel" | "other";
8
+ /** Optional language preference for default-template resolution. */
9
+ language?: string;
10
+ /** Optional channel preference for default-template resolution. */
11
+ channelId?: string | null;
12
+ /** Optional language fallbacks for default-template resolution. */
13
+ fallbackLanguages?: string[];
14
+ /**
15
+ * API base for attachment download redirects. Defaults to the active
16
+ * `VoyantLegalProvider` base URL; override when a host needs a different
17
+ * download origin than its data hooks use.
18
+ */
19
+ apiBaseUrl?: string;
20
+ labels?: BookingContractCardLabels;
21
+ }
22
+ /**
23
+ * Operator booking-detail "Contract" card. Mount next to the payments / docs
24
+ * card on the booking detail page. Responsibilities are deliberately narrow:
25
+ * - List contracts linked to this booking
26
+ * - Show each contract's latest status + number
27
+ * - Let the operator download the generated PDF (opens in a new tab)
28
+ * - Let the operator force a regeneration when the template or booking
29
+ * data has changed
30
+ *
31
+ * Contract creation is handled by the package booking generation endpoint.
32
+ * The card only offers the action when the server-visible prerequisites
33
+ * exist: a default template with a current version and exactly one active
34
+ * number series for the selected scope.
35
+ */
36
+ export declare function BookingContractCard({ bookingId, contractScope, language, channelId, fallbackLanguages, apiBaseUrl, labels, }: BookingContractCardProps): import("react/jsx-runtime").JSX.Element;
37
+ //# sourceMappingURL=booking-contract-card.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"booking-contract-card.d.ts","sourceRoot":"","sources":["../../src/components/booking-contract-card.tsx"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAA;AA0B1D,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,kFAAkF;IAClF,aAAa,CAAC,EAAE,UAAU,GAAG,UAAU,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,CAAA;IACzE,oEAAoE;IACpE,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,mEAAmE;IACnE,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,mEAAmE;IACnE,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAA;IAC5B;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,MAAM,CAAC,EAAE,yBAAyB,CAAA;CACnC;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,mBAAmB,CAAC,EAClC,SAAS,EACT,aAA0B,EAC1B,QAAQ,EACR,SAAS,EACT,iBAAiB,EACjB,UAAU,EACV,MAAM,GACP,EAAE,wBAAwB,2CA2F1B"}
@@ -0,0 +1,101 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { Badge, Button, Card, CardContent, CardHeader, CardTitle, } from "@voyant-travel/ui/components";
4
+ import { Download, FilePlus2, FileText, Loader2, RotateCw } from "lucide-react";
5
+ import { useLegalUiI18nOrDefault } from "../i18n/index.js";
6
+ import { useDefaultLegalContractTemplate, useLegalContractAttachments, useLegalContractMutation, useLegalContractNumberSeries, useLegalContracts, useVoyantLegalContext, } from "../index.js";
7
+ /**
8
+ * Status → badge style map. Keeps the card visually in sync with the
9
+ * contract detail page (same variant names, same ordering of severity).
10
+ */
11
+ const STATUS_VARIANT = {
12
+ draft: "outline",
13
+ issued: "secondary",
14
+ sent: "secondary",
15
+ signed: "default",
16
+ executed: "default",
17
+ expired: "destructive",
18
+ void: "destructive",
19
+ };
20
+ /**
21
+ * Operator booking-detail "Contract" card. Mount next to the payments / docs
22
+ * card on the booking detail page. Responsibilities are deliberately narrow:
23
+ * - List contracts linked to this booking
24
+ * - Show each contract's latest status + number
25
+ * - Let the operator download the generated PDF (opens in a new tab)
26
+ * - Let the operator force a regeneration when the template or booking
27
+ * data has changed
28
+ *
29
+ * Contract creation is handled by the package booking generation endpoint.
30
+ * The card only offers the action when the server-visible prerequisites
31
+ * exist: a default template with a current version and exactly one active
32
+ * number series for the selected scope.
33
+ */
34
+ export function BookingContractCard({ bookingId, contractScope = "customer", language, channelId, fallbackLanguages, apiBaseUrl, labels, }) {
35
+ const i18n = useLegalUiI18nOrDefault();
36
+ const { baseUrl } = useVoyantLegalContext();
37
+ const resolvedApiBaseUrl = apiBaseUrl ?? baseUrl;
38
+ const merged = { ...i18n.messages.bookingContractCard, ...labels };
39
+ const contractsQuery = useLegalContracts({ bookingId, limit: 25 });
40
+ const contracts = contractsQuery.data?.data ?? [];
41
+ const shouldCheckGeneration = !contractsQuery.isLoading && contracts.length === 0;
42
+ const defaultTemplateQuery = useDefaultLegalContractTemplate({
43
+ scope: contractScope,
44
+ language,
45
+ channelId: channelId ?? undefined,
46
+ fallbackLanguages,
47
+ enabled: shouldCheckGeneration,
48
+ });
49
+ const numberSeriesQuery = useLegalContractNumberSeries({
50
+ scope: contractScope,
51
+ active: true,
52
+ enabled: shouldCheckGeneration,
53
+ });
54
+ const { generateForBooking } = useLegalContractMutation();
55
+ const activeSeries = numberSeriesQuery.data?.data ?? [];
56
+ const canGenerate = Boolean(defaultTemplateQuery.data?.currentVersionId) && activeSeries.length === 1;
57
+ const generationPrerequisitesLoaded = shouldCheckGeneration && !defaultTemplateQuery.isLoading && !numberSeriesQuery.isLoading;
58
+ const handleGenerateForBooking = () => {
59
+ generateForBooking.mutate({
60
+ bookingId,
61
+ input: {
62
+ scope: contractScope,
63
+ language,
64
+ channelId,
65
+ fallbackLanguages,
66
+ requireNumberSeries: true,
67
+ },
68
+ });
69
+ };
70
+ 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 ? (_jsxs("div", { className: "flex flex-col gap-2", children: [_jsx("p", { className: "text-xs text-muted-foreground", children: merged.empty }), generationPrerequisitesLoaded && canGenerate ? (_jsxs(Button, { type: "button", size: "sm", onClick: handleGenerateForBooking, disabled: generateForBooking.isPending, className: "w-fit", children: [generateForBooking.isPending ? (_jsx(Loader2, { className: "h-3.5 w-3.5 animate-spin" })) : (_jsx(FilePlus2, { className: "h-3.5 w-3.5" })), _jsx("span", { className: "ml-1 text-xs", children: generateForBooking.isPending ? merged.generating : merged.generateContract })] })) : generationPrerequisitesLoaded ? (_jsx("p", { className: "text-[11px] text-muted-foreground", children: merged.generateUnavailable })) : null] })) : (contracts.map((contract) => (_jsx(BookingContractRow, { contract: contract, apiBaseUrl: resolvedApiBaseUrl, labels: merged }, contract.id)))) })] }));
71
+ }
72
+ function BookingContractRow({ contract, apiBaseUrl, labels, }) {
73
+ const i18n = useLegalUiI18nOrDefault();
74
+ const attachmentsQuery = useLegalContractAttachments({ contractId: contract.id });
75
+ const attachments = attachmentsQuery.data ?? [];
76
+ const documentAttachments = attachments.filter((a) => a.kind === "document");
77
+ const { generateDocument, regenerateDocument } = useLegalContractMutation();
78
+ const isPending = generateDocument.isPending || regenerateDocument.isPending;
79
+ const hasDocument = documentAttachments.length > 0;
80
+ const handleGenerate = () => {
81
+ const mutation = hasDocument ? regenerateDocument : generateDocument;
82
+ mutation.mutate({ id: contract.id, input: { replaceExisting: true, kind: "document" } });
83
+ };
84
+ 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 }))] }));
85
+ }
86
+ function withApiBaseUrl(baseUrl, path) {
87
+ const trimmedBase = baseUrl.endsWith("/") ? baseUrl.slice(0, -1) : baseUrl;
88
+ const normalizedPath = path.startsWith("/") ? path : `/${path}`;
89
+ return `${trimmedBase}${normalizedPath}`;
90
+ }
91
+ function AttachmentDownloadRow({ attachment, apiBaseUrl, downloadLabel, }) {
92
+ const i18n = useLegalUiI18nOrDefault();
93
+ // The download endpoint returns a 302 to the signed URL. A plain <a> link
94
+ // with target="_blank" lets the browser follow it and open the file in a
95
+ // new tab. The href uses the same API base as the data hooks by default.
96
+ const href = withApiBaseUrl(apiBaseUrl ?? "", `/v1/admin/legal/contracts/attachments/${attachment.id}/download`);
97
+ const sizeKb = typeof attachment.fileSize === "number"
98
+ ? `${i18n.formatNumber(Math.round(attachment.fileSize / 1024))} ${i18n.messages.common.kilobytes}`
99
+ : null;
100
+ 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] })] }));
101
+ }
@@ -0,0 +1,36 @@
1
+ import type { ReactNode } from "react";
2
+ import { type LegalContractAttachmentRecord, type LegalContractRecord } from "../index.js";
3
+ export interface ContractDetailPageProps {
4
+ id: string;
5
+ onBackToContracts?: () => void;
6
+ renderContractDialog?: (props: ContractDetailDialogRenderProps) => ReactNode;
7
+ renderReference?: (props: ContractReferenceRenderProps) => ReactNode;
8
+ getAttachmentDownloadHref?: (attachment: LegalContractAttachmentRecord) => string;
9
+ slots?: ContractDetailPageSlots;
10
+ /**
11
+ * Resolve the recipient email for the Send-contract dialog. Operator
12
+ * templates wire this to the linked CRM person's primary email; if
13
+ * unset the dialog displays a "no recipient" warning and disables Send.
14
+ */
15
+ resolveSendRecipientEmail?: (contract: LegalContractRecord) => string | null | undefined;
16
+ }
17
+ export interface ContractDetailPageSlots {
18
+ detailsContent?: ReactNode;
19
+ partiesContent?: ReactNode;
20
+ signaturesContent?: ReactNode;
21
+ documentsContent?: ReactNode;
22
+ }
23
+ export type ContractReferenceKind = "person" | "organization" | "supplier" | "channel" | "booking" | "target" | "legacyTransactionOffer" | "legacyTransactionOrder" | "templateVersion" | "series";
24
+ export interface ContractReferenceRenderProps {
25
+ kind: ContractReferenceKind;
26
+ id: string;
27
+ contract: LegalContractRecord;
28
+ }
29
+ export interface ContractDetailDialogRenderProps {
30
+ open: boolean;
31
+ onOpenChange: (open: boolean) => void;
32
+ contract: LegalContractRecord;
33
+ onSuccess: () => void;
34
+ }
35
+ export declare function ContractDetailPage({ id, onBackToContracts, renderContractDialog, renderReference, getAttachmentDownloadHref, slots, resolveSendRecipientEmail, }: ContractDetailPageProps): import("react/jsx-runtime").JSX.Element;
36
+ //# sourceMappingURL=contract-detail-page.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contract-detail-page.d.ts","sourceRoot":"","sources":["../../src/components/contract-detail-page.tsx"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAItC,OAAO,EACL,KAAK,6BAA6B,EAClC,KAAK,mBAAmB,EAOzB,MAAM,aAAa,CAAA;AA2DpB,MAAM,WAAW,uBAAuB;IACtC,EAAE,EAAE,MAAM,CAAA;IACV,iBAAiB,CAAC,EAAE,MAAM,IAAI,CAAA;IAC9B,oBAAoB,CAAC,EAAE,CAAC,KAAK,EAAE,+BAA+B,KAAK,SAAS,CAAA;IAC5E,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,4BAA4B,KAAK,SAAS,CAAA;IACpE,yBAAyB,CAAC,EAAE,CAAC,UAAU,EAAE,6BAA6B,KAAK,MAAM,CAAA;IACjF,KAAK,CAAC,EAAE,uBAAuB,CAAA;IAC/B;;;;OAIG;IACH,yBAAyB,CAAC,EAAE,CAAC,QAAQ,EAAE,mBAAmB,KAAK,MAAM,GAAG,IAAI,GAAG,SAAS,CAAA;CACzF;AAED,MAAM,WAAW,uBAAuB;IACtC,cAAc,CAAC,EAAE,SAAS,CAAA;IAC1B,cAAc,CAAC,EAAE,SAAS,CAAA;IAC1B,iBAAiB,CAAC,EAAE,SAAS,CAAA;IAC7B,gBAAgB,CAAC,EAAE,SAAS,CAAA;CAC7B;AAED,MAAM,MAAM,qBAAqB,GAC7B,QAAQ,GACR,cAAc,GACd,UAAU,GACV,SAAS,GACT,SAAS,GACT,QAAQ,GACR,wBAAwB,GACxB,wBAAwB,GACxB,iBAAiB,GACjB,QAAQ,CAAA;AAEZ,MAAM,WAAW,4BAA4B;IAC3C,IAAI,EAAE,qBAAqB,CAAA;IAC3B,EAAE,EAAE,MAAM,CAAA;IACV,QAAQ,EAAE,mBAAmB,CAAA;CAC9B;AAED,MAAM,WAAW,+BAA+B;IAC9C,IAAI,EAAE,OAAO,CAAA;IACb,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAA;IACrC,QAAQ,EAAE,mBAAmB,CAAA;IAC7B,SAAS,EAAE,MAAM,IAAI,CAAA;CACtB;AAED,wBAAgB,kBAAkB,CAAC,EACjC,EAAE,EACF,iBAAiB,EACjB,oBAAoB,EACpB,eAAe,EACf,yBAAyB,EACzB,KAAK,EACL,yBAAyB,GAC1B,EAAE,uBAAuB,2CAgazB"}