@flamingo-stack/openframe-frontend-core 0.0.739 → 0.0.740
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/build/export-map.json +1 -1
- package/dist/{chunk-WMKNZI4G.cjs → chunk-2Y5Y4FLM.cjs} +22 -22
- package/dist/{chunk-ENCAIAMY.cjs → chunk-3ZIQOYNX.cjs} +3 -3
- package/dist/{chunk-UI3HROSI.cjs → chunk-4RLGLB45.cjs} +33 -33
- package/dist/{chunk-FL6UO7IR.cjs → chunk-5SVOGLNK.cjs} +2 -2
- package/dist/{chunk-DTLHY2ZF.cjs → chunk-7UIQPMBJ.cjs} +11 -11
- package/dist/{chunk-UYP3G6PB.cjs → chunk-BDA5F6RM.cjs} +2 -2
- package/dist/{chunk-S2CA5WE4.cjs → chunk-CWRVTQUO.cjs} +9 -1
- package/dist/{chunk-CUDTMCXK.cjs → chunk-D5KEWWLW.cjs} +13 -13
- package/dist/{chunk-UXFJXIUT.cjs → chunk-EKGL5K5K.cjs} +2 -2
- package/dist/{chunk-V2ZFH42N.cjs → chunk-HYBMADYO.cjs} +3 -3
- package/dist/{chunk-Q7GG3WC5.cjs → chunk-LLAC2UZ3.cjs} +5 -5
- package/dist/{chunk-EGN4I5Q7.cjs → chunk-SWR22DOZ.cjs} +134 -46
- package/dist/{chunk-TF7J6VXG.cjs → chunk-UW3YXDC4.cjs} +9 -9
- package/dist/{chunk-SB4VWA5V.cjs → chunk-VC4IV3AY.cjs} +70 -70
- package/dist/{chunk-RGFT3P3L.cjs → chunk-VU4CKUJW.cjs} +55 -55
- package/dist/{chunk-NX6JQT25.cjs → chunk-ZLTCQKTD.cjs} +4 -4
- package/dist/{cloud-tenants-QSFSO3PA.cjs → cloud-tenants-PVXDI5MU.cjs} +3 -3
- package/dist/components/case-studies/index.cjs +11 -11
- package/dist/components/chat/index.cjs +2 -2
- package/dist/components/contact/index.cjs +4 -4
- package/dist/components/docs/index.cjs +7 -7
- package/dist/components/embeds/index.cjs +4 -4
- package/dist/components/faq/index.cjs +5 -5
- package/dist/components/features/index.cjs +3 -3
- package/dist/components/help-center-pages/index.cjs +53 -53
- package/dist/components/index.cjs +39 -33
- package/dist/components/meeting-scheduler/index.cjs +17 -17
- package/dist/components/navigation/index.cjs +6 -6
- package/dist/components/onboarding-guides/index.cjs +5 -5
- package/dist/components/product-demo/index.cjs +6 -6
- package/dist/components/shared/legal-document/index.d.ts +2 -1
- package/dist/components/shared/legal-document/index.d.ts.map +1 -1
- package/dist/components/shared/legal-document/index.js +10 -2
- package/dist/components/shared/legal-document/legal-document-page.d.ts +35 -23
- package/dist/components/shared/legal-document/legal-document-page.d.ts.map +1 -1
- package/dist/components/shared/legal-document/legal-document-page.js +27 -10
- package/dist/components/shared/legal-document/use-legal-docs.d.ts +7 -3
- package/dist/components/shared/legal-document/use-legal-docs.d.ts.map +1 -1
- package/dist/components/shared/legal-document/use-legal-docs.js +7 -0
- package/dist/components/shared/legal-document/use-legal-documents.d.ts +31 -0
- package/dist/components/shared/legal-document/use-legal-documents.d.ts.map +1 -0
- package/dist/components/shared/legal-document/use-legal-documents.js +67 -0
- package/dist/components/tickets/index.cjs +8 -8
- package/dist/components/ui/index.cjs +3 -3
- package/dist/{devices-C7XLWJFC.cjs → devices-TWEA7XOR.cjs} +4 -4
- package/dist/index.cjs +11 -7
- package/dist/{knowledge-3QKWTOE7.cjs → knowledge-4GQDBNQB.cjs} +3 -3
- package/dist/{logs-JXD75NR4.cjs → logs-EVU6GJHZ.cjs} +11 -11
- package/dist/{policies-ZPN53PFQ.cjs → policies-OZUEA5YS.cjs} +7 -7
- package/dist/{software-update-CRSIBS3K.cjs → software-update-BLIVYOY2.cjs} +6 -6
- package/dist/utils/index.cjs +8 -0
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +1 -0
- package/dist/utils/legal-documents.d.ts +18 -0
- package/dist/utils/legal-documents.d.ts.map +1 -0
- package/dist/utils/legal-documents.js +8 -0
- package/package.json +1 -1
- package/src/components/shared/legal-document/index.ts +8 -0
- package/src/components/shared/legal-document/legal-document-page.tsx +83 -44
- package/src/components/shared/legal-document/use-legal-docs.ts +18 -3
- package/src/components/shared/legal-document/use-legal-documents.ts +113 -0
- package/src/utils/index.ts +1 -0
- package/src/utils/legal-documents.ts +21 -0
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* useLegalDocuments — the list of legal documents a hub publishes (privacy
|
|
5
|
+
* policy, terms of service, payment terms, license, security policy, and
|
|
6
|
+
* whatever it adds later), each with its page and the version it states.
|
|
7
|
+
*
|
|
8
|
+
* A host that lists legal pages reads this list, shows one entry per published
|
|
9
|
+
* document, each leading to that document's own page, and names no document
|
|
10
|
+
* itself: a document the hub adds appears with no change here.
|
|
11
|
+
*
|
|
12
|
+
* Endpoint: default `/api/legal`; an embedder passes its proxied path.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import { useEffect, useState } from 'react';
|
|
16
|
+
import { contentFetch } from '../../../utils/embed-content-fetch';
|
|
17
|
+
|
|
18
|
+
export interface LegalDocumentSummary {
|
|
19
|
+
/** The identifier `useLegalDocs` and `<LegalDocumentPage>` take. */
|
|
20
|
+
docType: string;
|
|
21
|
+
title: string;
|
|
22
|
+
/** One line saying what the document is, for a card that lists it. */
|
|
23
|
+
summary: string;
|
|
24
|
+
/** The document's page on the hub's own site (a path). */
|
|
25
|
+
route: string;
|
|
26
|
+
sourceFile: string;
|
|
27
|
+
/** The topic the document's FAQs are written for, when the hub has one. */
|
|
28
|
+
faqTopic: string | null;
|
|
29
|
+
version: string | null;
|
|
30
|
+
effectiveDate: string | null;
|
|
31
|
+
/** False while the hub has no content for it yet. */
|
|
32
|
+
published: boolean;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface UseLegalDocumentsOptions {
|
|
36
|
+
/** Full GET endpoint URL. Default `/api/legal`. */
|
|
37
|
+
apiEndpoint?: string;
|
|
38
|
+
/** False: read nothing and answer an empty list. Default true. */
|
|
39
|
+
enabled?: boolean;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export interface UseLegalDocumentsReturn {
|
|
43
|
+
documents: LegalDocumentSummary[];
|
|
44
|
+
isLoading: boolean;
|
|
45
|
+
error: string | null;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
49
|
+
return typeof value === 'object' && value !== null;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function text(source: Record<string, unknown>, key: string): string | null {
|
|
53
|
+
const value = source[key];
|
|
54
|
+
return typeof value === 'string' && value ? value : null;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/** Decode the endpoint's answer; a row without a type and a title is left out. */
|
|
58
|
+
export function toLegalDocumentSummaries(payload: unknown): LegalDocumentSummary[] {
|
|
59
|
+
const rows: unknown = isRecord(payload) ? payload.documents : null;
|
|
60
|
+
if (!Array.isArray(rows)) return [];
|
|
61
|
+
const documents: LegalDocumentSummary[] = [];
|
|
62
|
+
for (const row of rows as readonly unknown[]) {
|
|
63
|
+
if (!isRecord(row)) continue;
|
|
64
|
+
const docType = text(row, 'docType');
|
|
65
|
+
const title = text(row, 'title');
|
|
66
|
+
if (!docType || !title) continue;
|
|
67
|
+
documents.push({
|
|
68
|
+
docType,
|
|
69
|
+
title,
|
|
70
|
+
summary: text(row, 'summary') ?? '',
|
|
71
|
+
route: text(row, 'route') ?? '',
|
|
72
|
+
sourceFile: text(row, 'sourceFile') ?? '',
|
|
73
|
+
faqTopic: text(row, 'faqTopic'),
|
|
74
|
+
version: text(row, 'version'),
|
|
75
|
+
effectiveDate: text(row, 'effectiveDate'),
|
|
76
|
+
published: row.published === true,
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
return documents;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export function useLegalDocuments(options: UseLegalDocumentsOptions = {}): UseLegalDocumentsReturn {
|
|
83
|
+
const endpoint = options.apiEndpoint ?? '/api/legal';
|
|
84
|
+
const enabled = options.enabled ?? true;
|
|
85
|
+
const [state, setState] = useState<UseLegalDocumentsReturn>({ documents: [], isLoading: enabled, error: null });
|
|
86
|
+
|
|
87
|
+
useEffect(() => {
|
|
88
|
+
let current = enabled;
|
|
89
|
+
const load = async () => {
|
|
90
|
+
try {
|
|
91
|
+
const response = await contentFetch(endpoint);
|
|
92
|
+
if (!response.ok) throw new Error(`Failed to fetch legal documents: ${response.status} ${response.statusText}`);
|
|
93
|
+
const payload: unknown = await response.json();
|
|
94
|
+
if (current) setState({ documents: toLegalDocumentSummaries(payload), isLoading: false, error: null });
|
|
95
|
+
} catch (err) {
|
|
96
|
+
console.error('Error fetching legal documents:', err);
|
|
97
|
+
if (current) {
|
|
98
|
+
setState({
|
|
99
|
+
documents: [],
|
|
100
|
+
isLoading: false,
|
|
101
|
+
error: err instanceof Error ? err.message : 'Unknown error occurred',
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
if (enabled) void load();
|
|
107
|
+
return () => {
|
|
108
|
+
current = false;
|
|
109
|
+
};
|
|
110
|
+
}, [endpoint, enabled]);
|
|
111
|
+
|
|
112
|
+
return state;
|
|
113
|
+
}
|
package/src/utils/index.ts
CHANGED
|
@@ -415,6 +415,7 @@ export * from './humanity-signals';
|
|
|
415
415
|
// so the host's draft endpoint re-applies the same filter the browser hook runs.
|
|
416
416
|
// Also exported via the granular subpath `./utils/form-rescue`.
|
|
417
417
|
export * from './form-rescue';
|
|
418
|
+
export * from './legal-documents';
|
|
418
419
|
|
|
419
420
|
// Doc-source viewer utilities (path parsing, tree building, section extraction,
|
|
420
421
|
// embed-URL conversion) — single home for all doc-viewer pure helpers across
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The types of legal document a hub can publish, each with a page of its own
|
|
3
|
+
* (`/api/legal/<type>`, `<LegalDocumentPage docType>`).
|
|
4
|
+
*
|
|
5
|
+
* WHICH of them are published, and each one's title, version and effective
|
|
6
|
+
* date, is the hub's answer at run time (`GET /api/legal`, `useLegalDocuments`).
|
|
7
|
+
* This list exists for a host that must know every possible page before it
|
|
8
|
+
* runs: a statically exported app prerenders one legal page per type here and
|
|
9
|
+
* links only the ones the hub's list says are published.
|
|
10
|
+
*
|
|
11
|
+
* Pure and server-safe. The hub's own list of legal documents carries exactly
|
|
12
|
+
* these types.
|
|
13
|
+
*/
|
|
14
|
+
export const LEGAL_DOCUMENT_TYPES = ['privacy', 'terms', 'payment', 'license', 'security'] as const;
|
|
15
|
+
|
|
16
|
+
export type LegalDocumentType = (typeof LEGAL_DOCUMENT_TYPES)[number];
|
|
17
|
+
|
|
18
|
+
/** True for a type a host has a page for (one of {@link LEGAL_DOCUMENT_TYPES}). */
|
|
19
|
+
export function isLegalDocumentType(value: string): value is LegalDocumentType {
|
|
20
|
+
return (LEGAL_DOCUMENT_TYPES as readonly string[]).includes(value);
|
|
21
|
+
}
|