@flamingo-stack/openframe-frontend-core 0.0.739 → 0.0.741

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 (197) hide show
  1. package/dist/build/export-map.json +1 -1
  2. package/dist/{chunk-ENCAIAMY.cjs → chunk-4XL4YEZM.cjs} +3 -3
  3. package/dist/{chunk-FL6UO7IR.cjs → chunk-5SVOGLNK.cjs} +2 -2
  4. package/dist/{chunk-WFPCCBOM.cjs → chunk-7AM3AFM4.cjs} +10 -10
  5. package/dist/{chunk-S2CA5WE4.cjs → chunk-CWRVTQUO.cjs} +9 -1
  6. package/dist/{chunk-KHXZFLIN.cjs → chunk-DKOLQPE7.cjs} +8 -2
  7. package/dist/{chunk-UXFJXIUT.cjs → chunk-EKGL5K5K.cjs} +2 -2
  8. package/dist/{chunk-DTLHY2ZF.cjs → chunk-FQN6STIM.cjs} +12 -155
  9. package/dist/{chunk-V2ZFH42N.cjs → chunk-HYBMADYO.cjs} +3 -3
  10. package/dist/{chunk-NX6JQT25.cjs → chunk-I6UE6YVM.cjs} +4 -4
  11. package/dist/{chunk-SB4VWA5V.cjs → chunk-IK2RJUEA.cjs} +2118 -268
  12. package/dist/{chunk-CUDTMCXK.cjs → chunk-ITPEFCQ2.cjs} +13 -13
  13. package/dist/{chunk-WMKNZI4G.cjs → chunk-JFS6TZDX.cjs} +22 -22
  14. package/dist/{chunk-RGFT3P3L.cjs → chunk-LZ6NOVXX.cjs} +55 -55
  15. package/dist/{chunk-TF7J6VXG.cjs → chunk-QEUGYHFB.cjs} +9 -9
  16. package/dist/{chunk-II4QMH26.cjs → chunk-STEJZPIO.cjs} +3 -3
  17. package/dist/{chunk-UI3HROSI.cjs → chunk-XJ36TEGE.cjs} +33 -33
  18. package/dist/{chunk-UYP3G6PB.cjs → chunk-YQ37ZCD2.cjs} +2 -2
  19. package/dist/{chunk-Q7GG3WC5.cjs → chunk-ZJPDGVA6.cjs} +5 -5
  20. package/dist/{chunk-EGN4I5Q7.cjs → chunk-ZYOS7LVQ.cjs} +134 -46
  21. package/dist/{cloud-tenants-QSFSO3PA.cjs → cloud-tenants-MVJK52I2.cjs} +13 -13
  22. package/dist/components/case-studies/index.cjs +11 -11
  23. package/dist/components/chat/index.cjs +2 -2
  24. package/dist/components/contact/index.cjs +4 -4
  25. package/dist/components/docs/index.cjs +7 -7
  26. package/dist/components/embeds/index.cjs +4 -4
  27. package/dist/components/faq/index.cjs +5 -5
  28. package/dist/components/features/capability-explorer.d.ts +9 -2
  29. package/dist/components/features/capability-explorer.d.ts.map +1 -1
  30. package/dist/components/features/capability-explorer.js +113 -6
  31. package/dist/components/features/index.cjs +141 -3
  32. package/dist/components/features/index.d.ts +1 -0
  33. package/dist/components/features/index.d.ts.map +1 -1
  34. package/dist/components/features/index.js +1 -0
  35. package/dist/components/features/scripts/execution-cells.d.ts +65 -0
  36. package/dist/components/features/scripts/execution-cells.d.ts.map +1 -0
  37. package/dist/components/features/scripts/execution-cells.js +75 -0
  38. package/dist/components/features/scripts/execution-status.d.ts +48 -0
  39. package/dist/components/features/scripts/execution-status.d.ts.map +1 -0
  40. package/dist/components/features/scripts/execution-status.js +15 -0
  41. package/dist/components/features/scripts/index.d.ts +20 -0
  42. package/dist/components/features/scripts/index.d.ts.map +1 -0
  43. package/dist/components/features/scripts/index.js +59 -0
  44. package/dist/components/features/scripts/schedule-form/index.d.ts +18 -0
  45. package/dist/components/features/scripts/schedule-form/index.d.ts.map +1 -0
  46. package/dist/components/features/scripts/schedule-form/index.js +84 -0
  47. package/dist/components/features/scripts/schedule-form/schedule-enums.d.ts +24 -0
  48. package/dist/components/features/scripts/schedule-form/schedule-enums.d.ts.map +1 -0
  49. package/dist/components/features/scripts/schedule-form/schedule-enums.js +18 -0
  50. package/dist/components/features/scripts/schedule-form/schedule-form-fields.d.ts +57 -0
  51. package/dist/components/features/scripts/schedule-form/schedule-form-fields.d.ts.map +1 -0
  52. package/dist/components/features/scripts/schedule-form/schedule-form-fields.js +169 -0
  53. package/dist/components/features/scripts/schedule-form/schedule-form-types.d.ts +138 -0
  54. package/dist/components/features/scripts/schedule-form/schedule-form-types.d.ts.map +1 -0
  55. package/dist/components/features/scripts/schedule-form/schedule-form-types.js +72 -0
  56. package/dist/components/features/scripts/schedule-form/schedule-interval-input.d.ts +54 -0
  57. package/dist/components/features/scripts/schedule-form/schedule-interval-input.d.ts.map +1 -0
  58. package/dist/components/features/scripts/schedule-form/schedule-interval-input.js +60 -0
  59. package/dist/components/features/scripts/schedule-form/schedule-offline-fields.d.ts +29 -0
  60. package/dist/components/features/scripts/schedule-form/schedule-offline-fields.d.ts.map +1 -0
  61. package/dist/components/features/scripts/schedule-form/schedule-offline-fields.js +124 -0
  62. package/dist/components/features/scripts/schedule-form/schedule-script-picker-card.d.ts +52 -0
  63. package/dist/components/features/scripts/schedule-form/schedule-script-picker-card.d.ts.map +1 -0
  64. package/dist/components/features/scripts/schedule-form/schedule-script-picker-card.js +244 -0
  65. package/dist/components/features/scripts/schedule-form/schedule-script-search-field.d.ts +35 -0
  66. package/dist/components/features/scripts/schedule-form/schedule-script-search-field.d.ts.map +1 -0
  67. package/dist/components/features/scripts/schedule-form/schedule-script-search-field.js +58 -0
  68. package/dist/components/features/scripts/schedule-form/schedule-scripts-field.d.ts +25 -0
  69. package/dist/components/features/scripts/schedule-form/schedule-scripts-field.d.ts.map +1 -0
  70. package/dist/components/features/scripts/schedule-form/schedule-scripts-field.js +66 -0
  71. package/dist/components/features/scripts/schedule-form/schedule-timing-fields.d.ts +77 -0
  72. package/dist/components/features/scripts/schedule-form/schedule-timing-fields.d.ts.map +1 -0
  73. package/dist/components/features/scripts/schedule-form/schedule-timing-fields.js +262 -0
  74. package/dist/components/features/scripts/schedule-form/schedule-timing.d.ts +288 -0
  75. package/dist/components/features/scripts/schedule-form/schedule-timing.d.ts.map +1 -0
  76. package/dist/components/features/scripts/schedule-form/schedule-timing.js +165 -0
  77. package/dist/components/features/scripts/script-cells.d.ts +11 -0
  78. package/dist/components/features/scripts/script-cells.d.ts.map +1 -0
  79. package/dist/components/features/scripts/script-cells.js +19 -0
  80. package/dist/components/features/scripts/script-executions-table.d.ts +58 -0
  81. package/dist/components/features/scripts/script-executions-table.d.ts.map +1 -0
  82. package/dist/components/features/scripts/script-executions-table.js +88 -0
  83. package/dist/components/features/scripts/script-schedules-table.d.ts +38 -0
  84. package/dist/components/features/scripts/script-schedules-table.d.ts.map +1 -0
  85. package/dist/components/features/scripts/script-schedules-table.js +71 -0
  86. package/dist/components/features/scripts/script-shell-badge.d.ts +9 -0
  87. package/dist/components/features/scripts/script-shell-badge.d.ts.map +1 -0
  88. package/dist/components/features/scripts/script-shell-badge.js +15 -0
  89. package/dist/components/features/scripts/scripts-table-columns.d.ts +162 -0
  90. package/dist/components/features/scripts/scripts-table-columns.d.ts.map +1 -0
  91. package/dist/components/features/scripts/scripts-table-columns.js +69 -0
  92. package/dist/components/features/scripts/scripts-table-shared.d.ts +19 -0
  93. package/dist/components/features/scripts/scripts-table-shared.d.ts.map +1 -0
  94. package/dist/components/features/scripts/scripts-table-shared.js +35 -0
  95. package/dist/components/features/scripts/scripts-table.d.ts +40 -0
  96. package/dist/components/features/scripts/scripts-table.d.ts.map +1 -0
  97. package/dist/components/features/scripts/scripts-table.js +84 -0
  98. package/dist/components/features/scripts/scripts-tabs.d.ts +5 -0
  99. package/dist/components/features/scripts/scripts-tabs.d.ts.map +1 -0
  100. package/dist/components/features/scripts/scripts-tabs.js +10 -0
  101. package/dist/components/features/scripts/shell-types.d.ts +13 -0
  102. package/dist/components/features/scripts/shell-types.d.ts.map +1 -0
  103. package/dist/components/features/scripts/shell-types.js +21 -0
  104. package/dist/components/help-center-pages/index.cjs +53 -53
  105. package/dist/components/index.cjs +178 -34
  106. package/dist/components/meeting-scheduler/index.cjs +17 -17
  107. package/dist/components/navigation/index.cjs +6 -6
  108. package/dist/components/onboarding-guides/index.cjs +5 -5
  109. package/dist/components/product-demo/fixtures/scripts.d.ts +34 -0
  110. package/dist/components/product-demo/fixtures/scripts.d.ts.map +1 -0
  111. package/dist/components/product-demo/fixtures/scripts.js +123 -0
  112. package/dist/components/product-demo/fixtures/shared.d.ts +8 -0
  113. package/dist/components/product-demo/fixtures/shared.d.ts.map +1 -1
  114. package/dist/components/product-demo/fixtures/shared.js +7 -1
  115. package/dist/components/product-demo/fixtures/software-update.d.ts.map +1 -1
  116. package/dist/components/product-demo/fixtures/software-update.js +1 -5
  117. package/dist/components/product-demo/index.cjs +16 -13
  118. package/dist/components/product-demo/product-screen.d.ts.map +1 -1
  119. package/dist/components/product-demo/product-screen.js +2 -1
  120. package/dist/components/product-demo/registry.d.ts.map +1 -1
  121. package/dist/components/product-demo/registry.js +2 -1
  122. package/dist/components/product-demo/screen-keys.cjs +2 -1
  123. package/dist/components/product-demo/screen-keys.d.ts +1 -0
  124. package/dist/components/product-demo/screen-keys.d.ts.map +1 -1
  125. package/dist/components/product-demo/screen-keys.js +2 -1
  126. package/dist/components/product-demo/screens/scripts.d.ts +11 -0
  127. package/dist/components/product-demo/screens/scripts.d.ts.map +1 -0
  128. package/dist/components/product-demo/screens/scripts.js +130 -0
  129. package/dist/components/shared/legal-document/index.d.ts +2 -1
  130. package/dist/components/shared/legal-document/index.d.ts.map +1 -1
  131. package/dist/components/shared/legal-document/index.js +10 -2
  132. package/dist/components/shared/legal-document/legal-document-page.d.ts +35 -23
  133. package/dist/components/shared/legal-document/legal-document-page.d.ts.map +1 -1
  134. package/dist/components/shared/legal-document/legal-document-page.js +27 -10
  135. package/dist/components/shared/legal-document/use-legal-docs.d.ts +7 -3
  136. package/dist/components/shared/legal-document/use-legal-docs.d.ts.map +1 -1
  137. package/dist/components/shared/legal-document/use-legal-docs.js +7 -0
  138. package/dist/components/shared/legal-document/use-legal-documents.d.ts +31 -0
  139. package/dist/components/shared/legal-document/use-legal-documents.d.ts.map +1 -0
  140. package/dist/components/shared/legal-document/use-legal-documents.js +67 -0
  141. package/dist/components/tickets/index.cjs +8 -8
  142. package/dist/components/ui/index.cjs +3 -3
  143. package/dist/{devices-C7XLWJFC.cjs → devices-W3S7Q2PG.cjs} +9 -9
  144. package/dist/index.cjs +150 -8
  145. package/dist/{knowledge-3QKWTOE7.cjs → knowledge-AIYQ4FC3.cjs} +7 -7
  146. package/dist/{logs-JXD75NR4.cjs → logs-7SHJ2ARE.cjs} +25 -25
  147. package/dist/{policies-ZPN53PFQ.cjs → policies-EIZJ5SUP.cjs} +10 -10
  148. package/dist/{remote-session-DNFZ5OLY.cjs → remote-session-BZMNE6D2.cjs} +5 -5
  149. package/dist/scripts-J2FWC7E4.cjs +2112 -0
  150. package/dist/{software-update-CRSIBS3K.cjs → software-update-QAMNASVF.cjs} +14 -18
  151. package/dist/{tickets-board-CKZRB6YV.cjs → tickets-board-CEDHD3KB.cjs} +17 -17
  152. package/dist/utils/index.cjs +8 -0
  153. package/dist/utils/index.d.ts +1 -0
  154. package/dist/utils/index.d.ts.map +1 -1
  155. package/dist/utils/index.js +1 -0
  156. package/dist/utils/legal-documents.d.ts +18 -0
  157. package/dist/utils/legal-documents.d.ts.map +1 -0
  158. package/dist/utils/legal-documents.js +8 -0
  159. package/package.json +1 -1
  160. package/src/components/features/capability-explorer.tsx +134 -7
  161. package/src/components/features/index.ts +1 -0
  162. package/src/components/features/scripts/execution-cells.tsx +149 -0
  163. package/src/components/features/scripts/execution-status.ts +42 -0
  164. package/src/components/features/scripts/index.ts +42 -0
  165. package/src/components/features/scripts/schedule-form/index.ts +59 -0
  166. package/src/components/features/scripts/schedule-form/schedule-enums.ts +26 -0
  167. package/src/components/features/scripts/schedule-form/schedule-form-fields.tsx +249 -0
  168. package/src/components/features/scripts/schedule-form/schedule-form-types.ts +189 -0
  169. package/src/components/features/scripts/schedule-form/schedule-interval-input.tsx +121 -0
  170. package/src/components/features/scripts/schedule-form/schedule-offline-fields.tsx +218 -0
  171. package/src/components/features/scripts/schedule-form/schedule-script-picker-card.tsx +321 -0
  172. package/src/components/features/scripts/schedule-form/schedule-script-search-field.tsx +115 -0
  173. package/src/components/features/scripts/schedule-form/schedule-scripts-field.tsx +97 -0
  174. package/src/components/features/scripts/schedule-form/schedule-timing-fields.tsx +482 -0
  175. package/src/components/features/scripts/schedule-form/schedule-timing.ts +484 -0
  176. package/src/components/features/scripts/script-cells.tsx +29 -0
  177. package/src/components/features/scripts/script-executions-table.tsx +145 -0
  178. package/src/components/features/scripts/script-schedules-table.tsx +113 -0
  179. package/src/components/features/scripts/script-shell-badge.tsx +25 -0
  180. package/src/components/features/scripts/scripts-table-columns.ts +95 -0
  181. package/src/components/features/scripts/scripts-table-shared.tsx +43 -0
  182. package/src/components/features/scripts/scripts-table.tsx +124 -0
  183. package/src/components/features/scripts/scripts-tabs.ts +11 -0
  184. package/src/components/features/scripts/shell-types.ts +26 -0
  185. package/src/components/product-demo/fixtures/scripts.ts +186 -0
  186. package/src/components/product-demo/fixtures/shared.ts +7 -0
  187. package/src/components/product-demo/fixtures/software-update.ts +1 -7
  188. package/src/components/product-demo/product-screen.tsx +3 -1
  189. package/src/components/product-demo/registry.ts +1 -0
  190. package/src/components/product-demo/screen-keys.ts +1 -0
  191. package/src/components/product-demo/screens/scripts.tsx +192 -0
  192. package/src/components/shared/legal-document/index.ts +8 -0
  193. package/src/components/shared/legal-document/legal-document-page.tsx +83 -44
  194. package/src/components/shared/legal-document/use-legal-docs.ts +18 -3
  195. package/src/components/shared/legal-document/use-legal-documents.ts +113 -0
  196. package/src/utils/index.ts +1 -0
  197. package/src/utils/legal-documents.ts +21 -0
@@ -0,0 +1,130 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import { useMemo } from "react";
4
+ import {
5
+ EXECUTION_COLUMNS,
6
+ ScriptExecutionResult,
7
+ ScriptExecutionsTable,
8
+ ScriptShellBadge
9
+ } from "../../features/scripts/index.js";
10
+ import { TimerIcon } from "../../icons-v2-generated/date-and-time/timer-icon.js";
11
+ import { TruncateText } from "../../ui/truncate-text.js";
12
+ import { useProductDemoCast } from "../cast.js";
13
+ import { buildScriptsFixture } from "../fixtures/scripts.js";
14
+ const WIDE_HIDDEN_COLUMNS = ["result", "open"];
15
+ const COMPACT_COLUMNS = [
16
+ { ...EXECUTION_COLUMNS.machineId, width: "flex-1 min-w-0", hideAt: void 0 },
17
+ EXECUTION_COLUMNS.status
18
+ ];
19
+ const COMPACT_ROWS = 4;
20
+ const TOKEN_CLASS = {
21
+ comment: "italic text-ods-text-tertiary",
22
+ keyword: "text-ods-warning",
23
+ string: "text-ods-flamingo-cyan",
24
+ variable: "text-ods-flamingo-cyan",
25
+ command: "text-ods-success",
26
+ parameter: "text-ods-text-secondary",
27
+ number: "text-ods-open-yellow",
28
+ plain: "text-ods-text-primary"
29
+ };
30
+ const TOKEN_PATTERN = /(#.*$)|("(?:[^"\\]|\\.)*"|'[^']*')|(\$[\w:]+)|\b(foreach|in|if|else|exit|return|param)\b|\b([A-Z][a-z]+-[A-Z][A-Za-z]+)\b|(-[A-Za-z]+)\b|\b(\d+(?:GB|MB|KB)?)\b/g;
31
+ const TOKEN_KINDS = [
32
+ "comment",
33
+ "string",
34
+ "variable",
35
+ "keyword",
36
+ "command",
37
+ "parameter",
38
+ "number"
39
+ ];
40
+ function tokenize(line) {
41
+ const tokens = [];
42
+ let last = 0;
43
+ for (const match of line.matchAll(TOKEN_PATTERN)) {
44
+ const start = match.index ?? 0;
45
+ if (start > last) tokens.push({ text: line.slice(last, start), kind: "plain" });
46
+ const group = match.slice(1).findIndex(Boolean);
47
+ tokens.push({ text: match[0], kind: TOKEN_KINDS[group] ?? "plain" });
48
+ last = start + match[0].length;
49
+ }
50
+ if (last < line.length) tokens.push({ text: line.slice(last), kind: "plain" });
51
+ return tokens;
52
+ }
53
+ function ScriptCodePicture({ script }) {
54
+ const lines = useMemo(
55
+ () => script.code.split("\n").map((line, index) => ({ number: index + 1, tokens: tokenize(line) })),
56
+ [script.code]
57
+ );
58
+ const { schedule, provenance } = script;
59
+ return /* @__PURE__ */ jsxs(
60
+ "section",
61
+ {
62
+ "aria-label": script.name,
63
+ className: "flex h-full min-w-0 flex-col overflow-hidden rounded-[8px] border border-ods-border bg-ods-card",
64
+ children: [
65
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-[var(--spacing-system-xxs)] border-b border-ods-border p-[var(--spacing-system-m)]", children: [
66
+ /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 items-center justify-between gap-[var(--spacing-system-m)]", children: [
67
+ /* @__PURE__ */ jsx(TruncateText, { variant: "h4", children: script.name }),
68
+ /* @__PURE__ */ jsxs("span", { className: "flex shrink-0 items-center gap-[var(--spacing-system-xxs)] text-ods-text-primary text-h6", children: [
69
+ /* @__PURE__ */ jsx(TimerIcon, { className: "size-4 text-ods-text-secondary" }),
70
+ `${schedule.repeat} ${schedule.time} \xB7 ${schedule.deviceCount} devices`
71
+ ] })
72
+ ] }),
73
+ /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 items-center justify-between gap-[var(--spacing-system-m)]", children: [
74
+ /* @__PURE__ */ jsx(TruncateText, { variant: "h6", tone: "secondary", children: `Written by ${provenance.author} \xB7 approved by ${provenance.approver}` }),
75
+ /* @__PURE__ */ jsx(
76
+ ScriptShellBadge,
77
+ {
78
+ value: script.shellType,
79
+ className: "shrink-0 text-ods-text-secondary text-h6",
80
+ iconClassName: "size-4"
81
+ }
82
+ )
83
+ ] })
84
+ ] }),
85
+ /* @__PURE__ */ jsx("pre", { className: "m-0 min-h-0 flex-1 overflow-hidden bg-ods-bg py-3 font-mono text-[14px] leading-[22px]", children: lines.map((line) => /* @__PURE__ */ jsxs("div", { className: "flex", children: [
86
+ /* @__PURE__ */ jsx("span", { className: "w-[46px] shrink-0 select-none pr-[4px] text-right text-ods-text-tertiary", children: line.number }),
87
+ /* @__PURE__ */ jsx("code", { className: "whitespace-pre pl-[32px]", children: line.tokens.map((token, at) => /* @__PURE__ */ jsx("span", { className: TOKEN_CLASS[token.kind], children: token.text }, `${at}-${token.text}`)) })
88
+ ] }, line.number)) })
89
+ ]
90
+ }
91
+ );
92
+ }
93
+ function ScriptsScreen({ compact = false }) {
94
+ const cast = useProductDemoCast();
95
+ const fixture = useMemo(() => buildScriptsFixture(cast), [cast]);
96
+ if (compact) {
97
+ return (
98
+ // Four runs of the card's row height fill the frame; the padding is what is left round them.
99
+ /* @__PURE__ */ jsx("div", { className: "h-full overflow-hidden bg-ods-bg p-[var(--spacing-system-xsf)]", children: /* @__PURE__ */ jsx(
100
+ ScriptExecutionsTable,
101
+ {
102
+ rows: fixture.executions.slice(0, COMPACT_ROWS),
103
+ columns: COMPACT_COLUMNS,
104
+ showHeader: false,
105
+ compact: true
106
+ }
107
+ ) })
108
+ );
109
+ }
110
+ const renderOutput = (row) => row.id === fixture.openExecutionId ? /* @__PURE__ */ jsx(ScriptExecutionResult, { result: row.result, empty: "\u2014" }) : null;
111
+ return (
112
+ // The frame's tighter padding and no header row: the output opened under a run needs the height.
113
+ /* @__PURE__ */ jsxs("div", { className: "flex h-full gap-[var(--spacing-system-m)] overflow-hidden bg-ods-bg p-[var(--spacing-system-m)]", children: [
114
+ /* @__PURE__ */ jsx("div", { className: "w-[39%] shrink-0", children: /* @__PURE__ */ jsx(ScriptCodePicture, { script: fixture.script }) }),
115
+ /* @__PURE__ */ jsx("div", { className: "min-w-0 flex-1 overflow-hidden", children: /* @__PURE__ */ jsx(
116
+ ScriptExecutionsTable,
117
+ {
118
+ rows: fixture.executions,
119
+ hideColumns: WIDE_HIDDEN_COLUMNS,
120
+ renderSubRow: renderOutput,
121
+ showHeader: false,
122
+ compact: true
123
+ }
124
+ ) })
125
+ ] })
126
+ );
127
+ }
128
+ export {
129
+ ScriptsScreen as default
130
+ };
@@ -5,6 +5,7 @@
5
5
  * formerly-duplicated `PrivacyPolicyPage` + `TermsOfServicePage`
6
6
  * (95% identical, differing only in copy strings).
7
7
  */
8
- export { LegalDocumentPage, type LegalDocumentPageProps, type LegalDocumentMarkdownRendererProps, } from './legal-document-page';
8
+ export { LegalDocumentPage, legalDocumentStampLabel, type LegalDocumentPageProps, type LegalDocumentMarkdownRendererProps, } from './legal-document-page';
9
9
  export { useLegalDocs, type LegalDocument, type UseLegalDocsOptions, type UseLegalDocsReturn } from './use-legal-docs';
10
+ export { useLegalDocuments, toLegalDocumentSummaries, type LegalDocumentSummary, type UseLegalDocumentsOptions, type UseLegalDocumentsReturn, } from './use-legal-documents';
10
11
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/shared/legal-document/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EACL,iBAAiB,EACjB,KAAK,sBAAsB,EAC3B,KAAK,kCAAkC,GACxC,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,YAAY,EAAE,KAAK,aAAa,EAAE,KAAK,mBAAmB,EAAE,KAAK,kBAAkB,EAAE,MAAM,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/shared/legal-document/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EACL,iBAAiB,EACjB,uBAAuB,EACvB,KAAK,sBAAsB,EAC3B,KAAK,kCAAkC,GACxC,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,YAAY,EAAE,KAAK,aAAa,EAAE,KAAK,mBAAmB,EAAE,KAAK,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACvH,OAAO,EACL,iBAAiB,EACjB,wBAAwB,EACxB,KAAK,oBAAoB,EACzB,KAAK,wBAAwB,EAC7B,KAAK,uBAAuB,GAC7B,MAAM,uBAAuB,CAAC"}
@@ -1,8 +1,16 @@
1
1
  import {
2
- LegalDocumentPage
2
+ LegalDocumentPage,
3
+ legalDocumentStampLabel
3
4
  } from "./legal-document-page.js";
4
5
  import { useLegalDocs } from "./use-legal-docs.js";
6
+ import {
7
+ useLegalDocuments,
8
+ toLegalDocumentSummaries
9
+ } from "./use-legal-documents.js";
5
10
  export {
6
11
  LegalDocumentPage,
7
- useLegalDocs
12
+ legalDocumentStampLabel,
13
+ toLegalDocumentSummaries,
14
+ useLegalDocs,
15
+ useLegalDocuments
8
16
  };
@@ -28,25 +28,24 @@ export interface LegalDocumentMarkdownRendererProps {
28
28
  }
29
29
  export interface LegalDocumentPageProps {
30
30
  /** Document type identifier — drives the default API endpoint
31
- * `/api/legal/<docType>` AND the error-log prefix. Common values:
32
- * `'privacy'`, `'terms'`. Embedders may use any string. */
31
+ * `/api/legal/<docType>` AND the error-log prefix. One of the types the
32
+ * host's list answers (`useLegalDocuments`). */
33
33
  docType: string;
34
- /** Heading text (e.g. "Privacy Policy", "Terms of Service"). */
35
- title: string;
36
- /** Fallback subtitle shown when no `lastUpdated` date is available
37
- * (e.g. "Our privacy policy and data protection practices"). */
38
- fallbackDescription: string;
39
- /** Email shown in the error + empty-state copy
40
- * (e.g. `'privacy@openframe.io'`, `'legal@openframe.io'`). */
41
- contactEmail: string;
42
- /** Prompt shown above the contact link in the error state
43
- * (e.g. "For privacy-related questions, please contact:"). */
44
- errorContactPrompt: string;
45
- /** Title for the error block (e.g. "Unable to load privacy policy"). */
46
- errorTitle: string;
47
- /** Sentence shown when the API returns no document
48
- * (e.g. "Privacy policy content is not available at this time."). */
49
- emptyStateMessage: string;
34
+ /** Heading text. Default: the title the served document carries, so a host
35
+ * that shows whatever the list holds states no per-document copy. */
36
+ title?: string;
37
+ /** Subtitle shown when the document states neither a version nor a date. */
38
+ fallbackDescription?: string;
39
+ /** Email shown in the error + empty-state copy. Absent: no contact line. */
40
+ contactEmail?: string;
41
+ /** Prompt shown above the contact link in the error state.
42
+ * Default "For questions about this document, please contact:". */
43
+ errorContactPrompt?: string;
44
+ /** Title for the error block. Default "Unable to load <title>". */
45
+ errorTitle?: string;
46
+ /** Sentence shown when the API returns no document.
47
+ * Default "<title> is not available at this time.". */
48
+ emptyStateMessage?: string;
50
49
  /** SSR-prepared document, if available. */
51
50
  initialData?: LegalDocument | null;
52
51
  /** SSR-prepared formatted "Last Updated" label. Stable across hydration. */
@@ -63,15 +62,28 @@ export interface LegalDocumentPageProps {
63
62
  href?: string;
64
63
  } | false;
65
64
  /**
66
- * The page's own FAQ block: the topic the page is about (stated by the host,
67
- * never read from its address) and where the host serves the FAQs. Rendered
68
- * after the page's content, inside its container. Absent: no FAQ block.
65
+ * The hub's list of legal documents (`GET /api/legal`). Given it, the page
66
+ * takes the document's title and FAQ topic from the list, so a host passes
67
+ * only the type and its endpoints and states nothing per document; the title
68
+ * then names the document even when its text fails to load.
69
69
  */
70
- faq?: PageFaqSlot;
70
+ documentsEndpoint?: string;
71
+ /**
72
+ * The page's own FAQ block: the topic the page is about and where the host
73
+ * serves the FAQs. Rendered after the page's content, inside its container.
74
+ * Without a `topic`, the topic is the one the list (`documentsEndpoint`)
75
+ * gives the document. Absent, or no topic known: no FAQ block.
76
+ */
77
+ faq?: PageFaqSlot | Omit<PageFaqSlot, 'topic'>;
71
78
  /** Render the standalone `<PageShell>`. Default true. Pass false when the host
72
79
  * layout already provides the page container — only the padding box renders,
73
80
  * avoiding a nested `<main>`. */
74
81
  shell?: boolean;
75
82
  }
76
- export declare function LegalDocumentPage({ docType, title, fallbackDescription, contactEmail, errorContactPrompt, errorTitle, emptyStateMessage, initialData, initialLastUpdatedLabel, apiEndpoint, MarkdownRenderer, backButton, faq, shell, }: LegalDocumentPageProps): import("react").JSX.Element;
83
+ /**
84
+ * "Version 1.0 · Effective October 14, 2026" for a document that states them;
85
+ * null for one that states neither. One wording for every legal surface.
86
+ */
87
+ export declare function legalDocumentStampLabel(doc: Pick<LegalDocument, 'version' | 'effectiveDate'> | null | undefined): string | null;
88
+ export declare function LegalDocumentPage({ docType, title: titleProp, fallbackDescription, contactEmail, errorContactPrompt, errorTitle: errorTitleProp, emptyStateMessage: emptyStateMessageProp, initialData, initialLastUpdatedLabel, apiEndpoint, MarkdownRenderer, documentsEndpoint, backButton, faq, shell, }: LegalDocumentPageProps): import("react").JSX.Element;
77
89
  //# sourceMappingURL=legal-document-page.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"legal-document-page.d.ts","sourceRoot":"","sources":["../../../../src/components/shared/legal-document/legal-document-page.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAI3C,OAAO,EAA4B,KAAK,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAGnF,OAAO,EAAgB,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEpE,MAAM,WAAW,kCAAkC;IACjD,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACjE,oBAAoB,CAAC,EAAE,OAAO,CAAC;CAChC;AAED,MAAM,WAAW,sBAAsB;IACrC;;gEAE4D;IAC5D,OAAO,EAAE,MAAM,CAAC;IAChB,gEAAgE;IAChE,KAAK,EAAE,MAAM,CAAC;IACd;qEACiE;IACjE,mBAAmB,EAAE,MAAM,CAAC;IAC5B;mEAC+D;IAC/D,YAAY,EAAE,MAAM,CAAC;IACrB;mEAC+D;IAC/D,kBAAkB,EAAE,MAAM,CAAC;IAC3B,wEAAwE;IACxE,UAAU,EAAE,MAAM,CAAC;IACnB;0EACsE;IACtE,iBAAiB,EAAE,MAAM,CAAC;IAC1B,2CAA2C;IAC3C,WAAW,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC;IACnC,4EAA4E;IAC5E,uBAAuB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxC;0DACsD;IACtD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,8CAA8C;IAC9C,gBAAgB,CAAC,EAAE,aAAa,CAAC,kCAAkC,CAAC,CAAC;IACrE;mEAC+D;IAC/D,UAAU,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,KAAK,CAAC;IACvD;;;;OAIG;IACH,GAAG,CAAC,EAAE,WAAW,CAAC;IAClB;;sCAEkC;IAClC,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,wBAAgB,iBAAiB,CAAC,EAChC,OAAO,EACP,KAAK,EACL,mBAAmB,EACnB,YAAY,EACZ,kBAAkB,EAClB,UAAU,EACV,iBAAiB,EACjB,WAAkB,EAClB,uBAA8B,EAC9B,WAAW,EACX,gBAAuC,EACvC,UAAU,EACV,GAAG,EACH,KAAY,GACb,EAAE,sBAAsB,+BAkFxB"}
1
+ {"version":3,"file":"legal-document-page.d.ts","sourceRoot":"","sources":["../../../../src/components/shared/legal-document/legal-document-page.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAI3C,OAAO,EAA4B,KAAK,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAGnF,OAAO,EAAgB,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAGpE,MAAM,WAAW,kCAAkC;IACjD,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACjE,oBAAoB,CAAC,EAAE,OAAO,CAAC;CAChC;AAED,MAAM,WAAW,sBAAsB;IACrC;;qDAEiD;IACjD,OAAO,EAAE,MAAM,CAAC;IAChB;0EACsE;IACtE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,4EAA4E;IAC5E,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,4EAA4E;IAC5E,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;wEACoE;IACpE,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,mEAAmE;IACnE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;4DACwD;IACxD,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,2CAA2C;IAC3C,WAAW,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC;IACnC,4EAA4E;IAC5E,uBAAuB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxC;0DACsD;IACtD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,8CAA8C;IAC9C,gBAAgB,CAAC,EAAE,aAAa,CAAC,kCAAkC,CAAC,CAAC;IACrE;mEAC+D;IAC/D,UAAU,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,KAAK,CAAC;IACvD;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B;;;;;OAKG;IACH,GAAG,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IAC/C;;sCAEkC;IAClC,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CACrC,GAAG,EAAE,IAAI,CAAC,aAAa,EAAE,SAAS,GAAG,eAAe,CAAC,GAAG,IAAI,GAAG,SAAS,GACvE,MAAM,GAAG,IAAI,CAMf;AAED,wBAAgB,iBAAiB,CAAC,EAChC,OAAO,EACP,KAAK,EAAE,SAAS,EAChB,mBAAwB,EACxB,YAAY,EACZ,kBAAyE,EACzE,UAAU,EAAE,cAAc,EAC1B,iBAAiB,EAAE,qBAAqB,EACxC,WAAkB,EAClB,uBAA8B,EAC9B,WAAW,EACX,gBAAuC,EACvC,iBAAiB,EACjB,UAAU,EACV,GAAG,EACH,KAAY,GACb,EAAE,sBAAsB,+BAkGxB"}
@@ -7,18 +7,27 @@ import { FaqSection, pageFaqProps } from "../../faq/faq-section.js";
7
7
  import { PageShell, PageLayout } from "../../ui/index.js";
8
8
  import { RichMarkdownRenderer } from "../../ui/markdown/index.js";
9
9
  import { useLegalDocs } from "./use-legal-docs.js";
10
+ import { useLegalDocuments } from "./use-legal-documents.js";
11
+ function legalDocumentStampLabel(doc) {
12
+ const parts = [
13
+ doc?.version ? `Version ${doc.version}` : null,
14
+ doc?.effectiveDate ? `Effective ${doc.effectiveDate}` : null
15
+ ].filter((part) => part !== null);
16
+ return parts.length > 0 ? parts.join(" \xB7 ") : null;
17
+ }
10
18
  function LegalDocumentPage({
11
19
  docType,
12
- title,
13
- fallbackDescription,
20
+ title: titleProp,
21
+ fallbackDescription = "",
14
22
  contactEmail,
15
- errorContactPrompt,
16
- errorTitle,
17
- emptyStateMessage,
23
+ errorContactPrompt = "For questions about this document, please contact:",
24
+ errorTitle: errorTitleProp,
25
+ emptyStateMessage: emptyStateMessageProp,
18
26
  initialData = null,
19
27
  initialLastUpdatedLabel = null,
20
28
  apiEndpoint,
21
29
  MarkdownRenderer = RichMarkdownRenderer,
30
+ documentsEndpoint,
22
31
  backButton,
23
32
  faq,
24
33
  shell = true
@@ -29,9 +38,16 @@ function LegalDocumentPage({
29
38
  label: backButton?.label ?? "Back to home",
30
39
  onClick: () => router.push(backButton?.href ?? "/")
31
40
  };
41
+ const { documents } = useLegalDocuments({ apiEndpoint: documentsEndpoint, enabled: Boolean(documentsEndpoint) });
42
+ const listed = documents.find((doc) => doc.docType === docType);
43
+ const title = titleProp ?? data?.title ?? listed?.title ?? "Legal document";
44
+ const faqTopic = faq && "topic" in faq ? faq.topic : listed?.faqTopic;
45
+ const faqSlot = faq && faqTopic ? { ...faq, topic: faqTopic } : null;
46
+ const errorTitle = errorTitleProp ?? `Unable to load ${title}`;
47
+ const emptyStateMessage = emptyStateMessageProp ?? `${title} is not available at this time.`;
32
48
  const fallbackLastUpdatedLabel = data?.lastSynced != null ? formatLegalDate(data.lastSynced) : null;
33
49
  const effectiveLastUpdatedLabel = initialLastUpdatedLabel ?? fallbackLastUpdatedLabel;
34
- const subtitle = effectiveLastUpdatedLabel ? `Last Updated: ${effectiveLastUpdatedLabel}` : fallbackDescription;
50
+ const subtitle = legalDocumentStampLabel(data) ?? (effectiveLastUpdatedLabel ? `Last Updated: ${effectiveLastUpdatedLabel}` : fallbackDescription);
35
51
  const inner = /* @__PURE__ */ jsxs(PageLayout, { title, subtitle, backButton: backCfg, titleSize: "h1", titleWrap: true, children: [
36
52
  data?.sourceFile && /* @__PURE__ */ jsxs("p", { className: "text-ods-text-secondary opacity-75 text-h6", children: [
37
53
  "Source: ",
@@ -57,13 +73,13 @@ function LegalDocumentPage({
57
73
  /* @__PURE__ */ jsx("p", { className: "mb-2 text-ods-error", children: errorTitle }),
58
74
  /* @__PURE__ */ jsx("p", { className: "text-ods-error text-h6", children: error })
59
75
  ] }),
60
- /* @__PURE__ */ jsxs("div", { className: "text-ods-text-secondary", children: [
76
+ contactEmail && /* @__PURE__ */ jsxs("div", { className: "text-ods-text-secondary", children: [
61
77
  /* @__PURE__ */ jsx("p", { children: errorContactPrompt }),
62
78
  /* @__PURE__ */ jsx(Link, { href: `mailto:${contactEmail}`, className: "text-ods-accent hover:underline", children: contactEmail })
63
79
  ] })
64
80
  ] }) : data ? /* @__PURE__ */ jsx(MarkdownRenderer, { content: data.content, sectionIds: data.sections || [], demoteMarkdownH1ToH2: true }) : /* @__PURE__ */ jsxs("div", { className: "py-16 text-center text-ods-text-secondary", children: [
65
81
  /* @__PURE__ */ jsx("p", { className: "text-h4", children: emptyStateMessage }),
66
- /* @__PURE__ */ jsxs("p", { className: "mt-2", children: [
82
+ contactEmail && /* @__PURE__ */ jsxs("p", { className: "mt-2", children: [
67
83
  "Please contact",
68
84
  " ",
69
85
  /* @__PURE__ */ jsx(Link, { href: `mailto:${contactEmail}`, className: "text-ods-accent hover:underline", children: contactEmail }),
@@ -71,10 +87,11 @@ function LegalDocumentPage({
71
87
  "for more information."
72
88
  ] })
73
89
  ] }) }) }) }) }),
74
- faq && /* @__PURE__ */ jsx(FaqSection, { ...pageFaqProps(faq) })
90
+ faqSlot && /* @__PURE__ */ jsx(FaqSection, { ...pageFaqProps(faqSlot) })
75
91
  ] });
76
92
  return shell ? /* @__PURE__ */ jsx(PageShell, { children: inner }) : /* @__PURE__ */ jsx("div", { className: "page-shell-content", children: inner });
77
93
  }
78
94
  export {
79
- LegalDocumentPage
95
+ LegalDocumentPage,
96
+ legalDocumentStampLabel
80
97
  };
@@ -10,6 +10,10 @@ export interface LegalDocument {
10
10
  level: number;
11
11
  }>;
12
12
  docType: string;
13
+ /** The version the document states for itself ("1.0"); null when it states none. */
14
+ version: string | null;
15
+ /** The day that version takes effect, as the document words it; null when it states none. */
16
+ effectiveDate: string | null;
13
17
  meta: {
14
18
  sectionsCount: number;
15
19
  contentLength: number;
@@ -32,9 +36,9 @@ export interface UseLegalDocsOptions {
32
36
  /**
33
37
  * Hook to fetch a legal document.
34
38
  * @param docType — short identifier for the document (drives the
35
- * default endpoint path AND the error-log prefix). Common values:
36
- * `'privacy'` (SECURITY.md), `'terms'` (LICENSE). Embedders may use
37
- * any string — the hook treats it as opaque.
39
+ * default endpoint path AND the error-log prefix). The valid values are
40
+ * the ones the host's list endpoint answers (`useLegalDocuments`); the
41
+ * hook treats it as opaque.
38
42
  */
39
43
  export declare function useLegalDocs(docType: string, options?: UseLegalDocsOptions): UseLegalDocsReturn;
40
44
  //# sourceMappingURL=use-legal-docs.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"use-legal-docs.d.ts","sourceRoot":"","sources":["../../../../src/components/shared/legal-document/use-legal-docs.ts"],"names":[],"mappings":"AAkBA,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,QAAQ,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC9D,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE;QACJ,aAAa,EAAE,MAAM,CAAC;QACtB,aAAa,EAAE,MAAM,CAAC;QACtB,aAAa,EAAE,MAAM,CAAC;KACvB,CAAC;CACH;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,aAAa,GAAG,IAAI,CAAC;IAC3B,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,MAAM,WAAW,mBAAmB;IAClC;mDAC+C;IAC/C,WAAW,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC;IACnC,6DAA6D;IAC7D,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AA2ED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,mBAAwB,GAAG,kBAAkB,CAwGnG"}
1
+ {"version":3,"file":"use-legal-docs.d.ts","sourceRoot":"","sources":["../../../../src/components/shared/legal-document/use-legal-docs.ts"],"names":[],"mappings":"AAkBA,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,QAAQ,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC9D,OAAO,EAAE,MAAM,CAAC;IAChB,oFAAoF;IACpF,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,6FAA6F;IAC7F,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,IAAI,EAAE;QACJ,aAAa,EAAE,MAAM,CAAC;QACtB,aAAa,EAAE,MAAM,CAAC;QACtB,aAAa,EAAE,MAAM,CAAC;KACvB,CAAC;CACH;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,aAAa,GAAG,IAAI,CAAC;IAC3B,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,MAAM,WAAW,mBAAmB;IAClC;mDAC+C;IAC/C,WAAW,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC;IACnC,6DAA6D;IAC7D,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AA6ED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,mBAAwB,GAAG,kBAAkB,CAiHnG"}
@@ -42,6 +42,8 @@ function toLegalDocument(payload, docType) {
42
42
  githubSha: typeof githubSha === "string" ? githubSha : null,
43
43
  sections,
44
44
  docType: readString(payload, "docType") ?? docType,
45
+ version: readString(payload, "version") ?? null,
46
+ effectiveDate: readString(payload, "effectiveDate") ?? null,
45
47
  meta: {
46
48
  sectionsCount: typeof sectionsCount === "number" ? sectionsCount : sections.length,
47
49
  contentLength: typeof contentLength === "number" ? contentLength : content.length,
@@ -72,6 +74,11 @@ function useLegalDocs(docType, options = {}) {
72
74
  const fetchDocument = async () => {
73
75
  try {
74
76
  const response = await contentFetch(effectiveEndpoint);
77
+ if (response.status === 404) {
78
+ if (!isCurrent()) return;
79
+ setData(null);
80
+ return;
81
+ }
75
82
  if (!response.ok) {
76
83
  throw new Error(`Failed to fetch ${docType} document: ${response.status} ${response.statusText}`);
77
84
  }
@@ -0,0 +1,31 @@
1
+ export interface LegalDocumentSummary {
2
+ /** The identifier `useLegalDocs` and `<LegalDocumentPage>` take. */
3
+ docType: string;
4
+ title: string;
5
+ /** One line saying what the document is, for a card that lists it. */
6
+ summary: string;
7
+ /** The document's page on the hub's own site (a path). */
8
+ route: string;
9
+ sourceFile: string;
10
+ /** The topic the document's FAQs are written for, when the hub has one. */
11
+ faqTopic: string | null;
12
+ version: string | null;
13
+ effectiveDate: string | null;
14
+ /** False while the hub has no content for it yet. */
15
+ published: boolean;
16
+ }
17
+ export interface UseLegalDocumentsOptions {
18
+ /** Full GET endpoint URL. Default `/api/legal`. */
19
+ apiEndpoint?: string;
20
+ /** False: read nothing and answer an empty list. Default true. */
21
+ enabled?: boolean;
22
+ }
23
+ export interface UseLegalDocumentsReturn {
24
+ documents: LegalDocumentSummary[];
25
+ isLoading: boolean;
26
+ error: string | null;
27
+ }
28
+ /** Decode the endpoint's answer; a row without a type and a title is left out. */
29
+ export declare function toLegalDocumentSummaries(payload: unknown): LegalDocumentSummary[];
30
+ export declare function useLegalDocuments(options?: UseLegalDocumentsOptions): UseLegalDocumentsReturn;
31
+ //# sourceMappingURL=use-legal-documents.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-legal-documents.d.ts","sourceRoot":"","sources":["../../../../src/components/shared/legal-document/use-legal-documents.ts"],"names":[],"mappings":"AAiBA,MAAM,WAAW,oBAAoB;IACnC,oEAAoE;IACpE,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,sEAAsE;IACtE,OAAO,EAAE,MAAM,CAAC;IAChB,0DAA0D;IAC1D,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,2EAA2E;IAC3E,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,qDAAqD;IACrD,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,wBAAwB;IACvC,mDAAmD;IACnD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kEAAkE;IAClE,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,uBAAuB;IACtC,SAAS,EAAE,oBAAoB,EAAE,CAAC;IAClC,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAWD,kFAAkF;AAClF,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,OAAO,GAAG,oBAAoB,EAAE,CAsBjF;AAED,wBAAgB,iBAAiB,CAAC,OAAO,GAAE,wBAA6B,GAAG,uBAAuB,CA+BjG"}
@@ -0,0 +1,67 @@
1
+ "use client";
2
+ import { useEffect, useState } from "react";
3
+ import { contentFetch } from "../../../utils/embed-content-fetch.js";
4
+ function isRecord(value) {
5
+ return typeof value === "object" && value !== null;
6
+ }
7
+ function text(source, key) {
8
+ const value = source[key];
9
+ return typeof value === "string" && value ? value : null;
10
+ }
11
+ function toLegalDocumentSummaries(payload) {
12
+ const rows = isRecord(payload) ? payload.documents : null;
13
+ if (!Array.isArray(rows)) return [];
14
+ const documents = [];
15
+ for (const row of rows) {
16
+ if (!isRecord(row)) continue;
17
+ const docType = text(row, "docType");
18
+ const title = text(row, "title");
19
+ if (!docType || !title) continue;
20
+ documents.push({
21
+ docType,
22
+ title,
23
+ summary: text(row, "summary") ?? "",
24
+ route: text(row, "route") ?? "",
25
+ sourceFile: text(row, "sourceFile") ?? "",
26
+ faqTopic: text(row, "faqTopic"),
27
+ version: text(row, "version"),
28
+ effectiveDate: text(row, "effectiveDate"),
29
+ published: row.published === true
30
+ });
31
+ }
32
+ return documents;
33
+ }
34
+ function useLegalDocuments(options = {}) {
35
+ const endpoint = options.apiEndpoint ?? "/api/legal";
36
+ const enabled = options.enabled ?? true;
37
+ const [state, setState] = useState({ documents: [], isLoading: enabled, error: null });
38
+ useEffect(() => {
39
+ let current = enabled;
40
+ const load = async () => {
41
+ try {
42
+ const response = await contentFetch(endpoint);
43
+ if (!response.ok) throw new Error(`Failed to fetch legal documents: ${response.status} ${response.statusText}`);
44
+ const payload = await response.json();
45
+ if (current) setState({ documents: toLegalDocumentSummaries(payload), isLoading: false, error: null });
46
+ } catch (err) {
47
+ console.error("Error fetching legal documents:", err);
48
+ if (current) {
49
+ setState({
50
+ documents: [],
51
+ isLoading: false,
52
+ error: err instanceof Error ? err.message : "Unknown error occurred"
53
+ });
54
+ }
55
+ }
56
+ };
57
+ if (enabled) void load();
58
+ return () => {
59
+ current = false;
60
+ };
61
+ }, [endpoint, enabled]);
62
+ return state;
63
+ }
64
+ export {
65
+ toLegalDocumentSummaries,
66
+ useLegalDocuments
67
+ };
@@ -14,11 +14,11 @@
14
14
 
15
15
 
16
16
 
17
- var _chunkRGFT3P3Lcjs = require('../../chunk-RGFT3P3L.cjs');
18
- require('../../chunk-Q7GG3WC5.cjs');
19
- require('../../chunk-TF7J6VXG.cjs');
17
+ var _chunkLZ6NOVXXcjs = require('../../chunk-LZ6NOVXX.cjs');
18
+ require('../../chunk-ZJPDGVA6.cjs');
19
+ require('../../chunk-QEUGYHFB.cjs');
20
20
  require('../../chunk-WBANGORJ.cjs');
21
- require('../../chunk-V2ZFH42N.cjs');
21
+ require('../../chunk-HYBMADYO.cjs');
22
22
  require('../../chunk-HEVW75L3.cjs');
23
23
 
24
24
 
@@ -26,8 +26,8 @@ require('../../chunk-HEVW75L3.cjs');
26
26
 
27
27
 
28
28
 
29
- var _chunkFL6UO7IRcjs = require('../../chunk-FL6UO7IR.cjs');
30
- require('../../chunk-SB4VWA5V.cjs');
29
+ var _chunk5SVOGLNKcjs = require('../../chunk-5SVOGLNK.cjs');
30
+ require('../../chunk-IK2RJUEA.cjs');
31
31
  require('../../chunk-O67V3HJR.cjs');
32
32
  require('../../chunk-3HPB4H4C.cjs');
33
33
  require('../../chunk-DSVNFRY5.cjs');
@@ -43,7 +43,7 @@ require('../../chunk-YUMFVQIN.cjs');
43
43
 
44
44
 
45
45
 
46
- var _chunkS2CA5WE4cjs = require('../../chunk-S2CA5WE4.cjs');
46
+ var _chunkCWRVTQUOcjs = require('../../chunk-CWRVTQUO.cjs');
47
47
  require('../../chunk-BV5WZVOP.cjs');
48
48
  require('../../chunk-GABDE3FM.cjs');
49
49
  require('../../chunk-3RFQPQ7Z.cjs');
@@ -1902,4 +1902,4 @@ require('../../chunk-3ATAYP36.cjs');
1902
1902
 
1903
1903
 
1904
1904
 
1905
- exports.HelpCenterCard = _chunkRGFT3P3Lcjs.HelpCenterCard; exports.HelpCenterCreateForm = _chunkRGFT3P3Lcjs.HelpCenterCreateForm; exports.HelpCenterCreateFormSkeleton = _chunkRGFT3P3Lcjs.HelpCenterCreateFormSkeleton; exports.HelpCenterList = _chunkRGFT3P3Lcjs.HelpCenterList; exports.TICKET_OPEN_PARAM = _chunkS2CA5WE4cjs.TICKET_OPEN_PARAM; exports.TICKET_TOAST_COPY = _chunkFL6UO7IRcjs.TOAST_COPY; exports.TicketCenter = _chunkRGFT3P3Lcjs.TicketCenter; exports.TicketDetailDrawer = _chunkRGFT3P3Lcjs.TicketDetailDrawer; exports.TicketLinkedDeliveryCard = _chunkRGFT3P3Lcjs.TicketLinkedDeliveryCard; exports.TicketLiveProvider = _chunkFL6UO7IRcjs.TicketLiveProvider; exports.TicketOpenForm = _chunkRGFT3P3Lcjs.TicketOpenForm; exports.TicketReplyComposer = _chunkRGFT3P3Lcjs.TicketReplyComposer; exports.TicketRow = _chunkRGFT3P3Lcjs.TicketRow; exports.buildTicketOpenHref = _chunkS2CA5WE4cjs.buildTicketOpenHref; exports.isOptimistic = _chunkFL6UO7IRcjs.isOptimistic; exports.mapTicketActionError = _chunkRGFT3P3Lcjs.mapTicketActionError; exports.useOptionalTicketLive = _chunkFL6UO7IRcjs.useOptionalTicketLive; exports.useTicketActions = _chunkRGFT3P3Lcjs.useTicketActions; exports.useTicketEngagements = _chunkRGFT3P3Lcjs.useTicketEngagements; exports.useTicketLive = _chunkFL6UO7IRcjs.useTicketLive; exports.useTicketsList = _chunkRGFT3P3Lcjs.useTicketsList;
1905
+ exports.HelpCenterCard = _chunkLZ6NOVXXcjs.HelpCenterCard; exports.HelpCenterCreateForm = _chunkLZ6NOVXXcjs.HelpCenterCreateForm; exports.HelpCenterCreateFormSkeleton = _chunkLZ6NOVXXcjs.HelpCenterCreateFormSkeleton; exports.HelpCenterList = _chunkLZ6NOVXXcjs.HelpCenterList; exports.TICKET_OPEN_PARAM = _chunkCWRVTQUOcjs.TICKET_OPEN_PARAM; exports.TICKET_TOAST_COPY = _chunk5SVOGLNKcjs.TOAST_COPY; exports.TicketCenter = _chunkLZ6NOVXXcjs.TicketCenter; exports.TicketDetailDrawer = _chunkLZ6NOVXXcjs.TicketDetailDrawer; exports.TicketLinkedDeliveryCard = _chunkLZ6NOVXXcjs.TicketLinkedDeliveryCard; exports.TicketLiveProvider = _chunk5SVOGLNKcjs.TicketLiveProvider; exports.TicketOpenForm = _chunkLZ6NOVXXcjs.TicketOpenForm; exports.TicketReplyComposer = _chunkLZ6NOVXXcjs.TicketReplyComposer; exports.TicketRow = _chunkLZ6NOVXXcjs.TicketRow; exports.buildTicketOpenHref = _chunkCWRVTQUOcjs.buildTicketOpenHref; exports.isOptimistic = _chunk5SVOGLNKcjs.isOptimistic; exports.mapTicketActionError = _chunkLZ6NOVXXcjs.mapTicketActionError; exports.useOptionalTicketLive = _chunk5SVOGLNKcjs.useOptionalTicketLive; exports.useTicketActions = _chunkLZ6NOVXXcjs.useTicketActions; exports.useTicketEngagements = _chunkLZ6NOVXXcjs.useTicketEngagements; exports.useTicketLive = _chunk5SVOGLNKcjs.useTicketLive; exports.useTicketsList = _chunkLZ6NOVXXcjs.useTicketsList;