@flamingo-stack/openframe-frontend-core 0.0.296-snapshot.20260621021605 → 0.0.296
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -9
- package/dist/chunk-26PKDALD.js +2379 -0
- package/dist/chunk-26PKDALD.js.map +1 -0
- package/dist/chunk-3MCHAFHB.js +89 -0
- package/dist/chunk-3MCHAFHB.js.map +1 -0
- package/dist/{chunk-PI4WSYQV.js → chunk-3ZXUQQL4.js} +2 -2
- package/dist/{chunk-WMSTJAZT.cjs → chunk-5E2HOSSH.cjs} +51 -913
- package/dist/chunk-5E2HOSSH.cjs.map +1 -0
- package/dist/{chunk-IL47XWV5.js → chunk-5P3B2LZW.js} +14 -8
- package/dist/{chunk-IL47XWV5.js.map → chunk-5P3B2LZW.js.map} +1 -1
- package/dist/chunk-66AANIOC.cjs +619 -0
- package/dist/chunk-66AANIOC.cjs.map +1 -0
- package/dist/{chunk-AD6C23QY.js → chunk-6GCI7JOE.js} +7 -8
- package/dist/{chunk-AD6C23QY.js.map → chunk-6GCI7JOE.js.map} +1 -1
- package/dist/chunk-6JINAOI7.cjs +311 -0
- package/dist/chunk-6JINAOI7.cjs.map +1 -0
- package/dist/{chunk-2QG57XOJ.js → chunk-7RIYT7ZH.js} +205 -1067
- package/dist/chunk-7RIYT7ZH.js.map +1 -0
- package/dist/{chunk-L6PSSIUQ.cjs → chunk-AQOWFSMB.cjs} +1 -1
- package/dist/chunk-AQOWFSMB.cjs.map +1 -0
- package/dist/chunk-BOCFIKYS.cjs +3009 -0
- package/dist/chunk-BOCFIKYS.cjs.map +1 -0
- package/dist/{chunk-54KNMC2R.cjs → chunk-D3LEFMOA.cjs} +3 -3
- package/dist/{chunk-54KNMC2R.cjs.map → chunk-D3LEFMOA.cjs.map} +1 -1
- package/dist/chunk-D652TJBQ.js +3009 -0
- package/dist/chunk-D652TJBQ.js.map +1 -0
- package/dist/{chunk-PWQUAVA3.js → chunk-E4XABBSU.js} +98 -338
- package/dist/chunk-E4XABBSU.js.map +1 -0
- package/dist/{chunk-JALO4TAZ.js → chunk-EL6QLAWX.js} +55 -357
- package/dist/chunk-EL6QLAWX.js.map +1 -0
- package/dist/{chunk-6C526VNN.cjs → chunk-EYEW6PTA.cjs} +118 -358
- package/dist/chunk-EYEW6PTA.cjs.map +1 -0
- package/dist/chunk-FQJK446R.js +1606 -0
- package/dist/chunk-FQJK446R.js.map +1 -0
- package/dist/{chunk-4PSQS3SW.cjs → chunk-GLLDTKZK.cjs} +9 -7
- package/dist/chunk-GLLDTKZK.cjs.map +1 -0
- package/dist/{chunk-FQOTC3UU.cjs → chunk-IE6OU3WQ.cjs} +16 -318
- package/dist/chunk-IE6OU3WQ.cjs.map +1 -0
- package/dist/chunk-J54Z3OCR.cjs +1606 -0
- package/dist/chunk-J54Z3OCR.cjs.map +1 -0
- package/dist/{chunk-PC746XCO.js → chunk-K2PFPBMF.js} +5563 -15048
- package/dist/chunk-K2PFPBMF.js.map +1 -0
- package/dist/chunk-KXCRGTRN.cjs +2379 -0
- package/dist/chunk-KXCRGTRN.cjs.map +1 -0
- package/dist/{chunk-IZ7JSBFP.js → chunk-LCNMR277.js} +1 -1
- package/dist/chunk-LCNMR277.js.map +1 -0
- package/dist/chunk-LFGGF7OT.cjs +449 -0
- package/dist/chunk-LFGGF7OT.cjs.map +1 -0
- package/dist/chunk-M2OCXTNT.js +311 -0
- package/dist/chunk-M2OCXTNT.js.map +1 -0
- package/dist/{chunk-L7ULJKG7.js → chunk-MBFWU2EM.js} +10 -6
- package/dist/{chunk-L7ULJKG7.js.map → chunk-MBFWU2EM.js.map} +1 -1
- package/dist/chunk-ME4EVDFP.js +619 -0
- package/dist/chunk-ME4EVDFP.js.map +1 -0
- package/dist/chunk-OQ6X7ZOC.js +449 -0
- package/dist/chunk-OQ6X7ZOC.js.map +1 -0
- package/dist/{chunk-4TLE6VLU.js → chunk-OY7OF7E7.js} +24 -30
- package/dist/chunk-OY7OF7E7.js.map +1 -0
- package/dist/chunk-POKKCWKF.js +354 -0
- package/dist/chunk-POKKCWKF.js.map +1 -0
- package/dist/{chunk-GUTS7HGA.cjs → chunk-QHIXS3W2.cjs} +2514 -11999
- package/dist/chunk-QHIXS3W2.cjs.map +1 -0
- package/dist/chunk-TFSYSWPS.cjs +89 -0
- package/dist/chunk-TFSYSWPS.cjs.map +1 -0
- package/dist/{chunk-53FUMSZ5.cjs → chunk-W6M2FLLT.cjs} +46 -40
- package/dist/chunk-W6M2FLLT.cjs.map +1 -0
- package/dist/{chunk-3JIQVE7T.js → chunk-WHMATDVP.js} +15 -9
- package/dist/{chunk-3JIQVE7T.js.map → chunk-WHMATDVP.js.map} +1 -1
- package/dist/{chunk-YBYI62OE.cjs → chunk-X647HY3F.cjs} +37 -33
- package/dist/chunk-X647HY3F.cjs.map +1 -0
- package/dist/{chunk-UNVE2SDJ.cjs → chunk-X6BV7MB7.cjs} +31 -37
- package/dist/chunk-X6BV7MB7.cjs.map +1 -0
- package/dist/{chunk-7OVGB2DQ.cjs → chunk-XREEV72C.cjs} +25 -19
- package/dist/chunk-XREEV72C.cjs.map +1 -0
- package/dist/chunk-YETA25JW.cjs +354 -0
- package/dist/chunk-YETA25JW.cjs.map +1 -0
- package/dist/{chunk-FCDQNTDG.cjs → chunk-YIGPRLQY.cjs} +20 -21
- package/dist/chunk-YIGPRLQY.cjs.map +1 -0
- package/dist/{chunk-X4DOXQRT.js → chunk-ZP4AVIZP.js} +6 -4
- package/dist/{chunk-X4DOXQRT.js.map → chunk-ZP4AVIZP.js.map} +1 -1
- package/dist/components/chat/index.cjs +18 -8
- package/dist/components/chat/index.cjs.map +1 -1
- package/dist/components/chat/index.js +85 -75
- package/dist/components/contact/index.cjs +15 -8
- package/dist/components/contact/index.cjs.map +1 -1
- package/dist/components/contact/index.js +14 -7
- package/dist/components/docs/doc-viewer.d.ts +2 -39
- package/dist/components/docs/doc-viewer.d.ts.map +1 -1
- package/dist/components/docs/index.cjs +9 -17
- package/dist/components/docs/index.cjs.map +1 -1
- package/dist/components/docs/index.d.ts +0 -4
- package/dist/components/docs/index.d.ts.map +1 -1
- package/dist/components/docs/index.js +8 -16
- package/dist/components/docs/use-document-tree.d.ts.map +1 -1
- package/dist/components/embeds/embed-iframe.d.ts.map +1 -1
- package/dist/components/embeds/index.cjs +15 -38
- package/dist/components/embeds/index.cjs.map +1 -1
- package/dist/components/embeds/index.d.ts +0 -8
- package/dist/components/embeds/index.d.ts.map +1 -1
- package/dist/components/embeds/index.js +17 -40
- package/dist/components/faq/index.cjs +16 -9
- package/dist/components/faq/index.cjs.map +1 -1
- package/dist/components/faq/index.js +15 -8
- package/dist/components/features/index.cjs +16 -8
- package/dist/components/features/index.cjs.map +1 -1
- package/dist/components/features/index.js +32 -24
- package/dist/components/index.cjs +452 -257
- package/dist/components/index.cjs.map +1 -1
- package/dist/components/index.js +976 -781
- package/dist/components/index.js.map +1 -1
- package/dist/components/layout/page-layout.d.ts +1 -10
- package/dist/components/layout/page-layout.d.ts.map +1 -1
- package/dist/components/layout/title-block.d.ts +1 -17
- package/dist/components/layout/title-block.d.ts.map +1 -1
- package/dist/components/navigation/index.cjs +15 -7
- package/dist/components/navigation/index.cjs.map +1 -1
- package/dist/components/navigation/index.js +17 -9
- package/dist/components/onboarding-guides/index.cjs +36 -35
- package/dist/components/onboarding-guides/index.cjs.map +1 -1
- package/dist/components/onboarding-guides/index.js +14 -13
- package/dist/components/onboarding-guides/index.js.map +1 -1
- package/dist/components/onboarding-guides/onboarding-guide-detail-view.d.ts +1 -1
- package/dist/components/onboarding-guides/onboarding-guide-detail-view.d.ts.map +1 -1
- package/dist/components/related-content/index.cjs +16 -9
- package/dist/components/related-content/index.cjs.map +1 -1
- package/dist/components/related-content/index.js +15 -8
- package/dist/components/shared/dev-section/dev-section-page.d.ts +0 -9
- package/dist/components/shared/dev-section/dev-section-page.d.ts.map +1 -1
- package/dist/components/shared/dev-section/dev-section-view.d.ts.map +1 -1
- package/dist/components/shared/dev-section/index.d.ts +1 -1
- package/dist/components/shared/dev-section/index.d.ts.map +1 -1
- package/dist/components/shared/doc-search/use-doc-search.d.ts.map +1 -1
- package/dist/components/shared/legal-document/legal-document-page.d.ts.map +1 -1
- package/dist/components/shared/product-release/release-detail-page.d.ts.map +1 -1
- package/dist/components/tickets/index.cjs +112 -100
- package/dist/components/tickets/index.cjs.map +1 -1
- package/dist/components/tickets/index.js +32 -20
- package/dist/components/tickets/index.js.map +1 -1
- package/dist/components/ui/file-manager/index.cjs +52 -50
- package/dist/components/ui/file-manager/index.cjs.map +1 -1
- package/dist/components/ui/file-manager/index.js +6 -4
- package/dist/components/ui/file-manager/index.js.map +1 -1
- package/dist/components/ui/index.cjs +19 -13
- package/dist/components/ui/index.cjs.map +1 -1
- package/dist/components/ui/index.d.ts +0 -2
- package/dist/components/ui/index.d.ts.map +1 -1
- package/dist/components/ui/index.js +139 -133
- package/dist/components/ui/release-changelog-section.d.ts +2 -6
- package/dist/components/ui/release-changelog-section.d.ts.map +1 -1
- package/dist/components/ui/simple-markdown-renderer.d.ts +8 -2
- package/dist/components/ui/simple-markdown-renderer.d.ts.map +1 -1
- package/dist/contexts/chat-runtime-context.d.ts +0 -14
- package/dist/contexts/chat-runtime-context.d.ts.map +1 -1
- package/dist/contexts/index.cjs +3 -3
- package/dist/contexts/index.js +5 -5
- package/dist/embed-shims/index.cjs +3 -3
- package/dist/embed-shims/index.cjs.map +1 -1
- package/dist/embed-shims/index.js +4 -4
- package/dist/hooks/index.cjs +9 -4
- package/dist/hooks/index.cjs.map +1 -1
- package/dist/hooks/index.js +11 -6
- package/dist/index.cjs +20 -14
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +364 -358
- package/dist/types/doc-source.d.ts +1 -31
- package/dist/types/doc-source.d.ts.map +1 -1
- package/dist/utils/index.cjs +0 -4
- package/dist/utils/index.cjs.map +1 -1
- package/dist/utils/index.d.ts +0 -1
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +1 -4
- package/dist/utils/index.js.map +1 -1
- package/package.json +1 -7
- package/src/components/chat/embeddable-chat.tsx +1 -1
- package/src/components/docs/doc-viewer.tsx +19 -111
- package/src/components/docs/index.ts +0 -17
- package/src/components/docs/use-document-tree.ts +0 -21
- package/src/components/embeds/embed-iframe.tsx +9 -7
- package/src/components/embeds/index.ts +0 -30
- package/src/components/embeds/og-link-preview.tsx +13 -13
- package/src/components/layout/page-layout.tsx +1 -14
- package/src/components/layout/title-block.tsx +62 -40
- package/src/components/onboarding-guides/onboarding-guide-detail-view.tsx +3 -3
- package/src/components/shared/dev-section/dev-section-page.tsx +1 -9
- package/src/components/shared/dev-section/dev-section-view.tsx +9 -14
- package/src/components/shared/dev-section/index.ts +1 -1
- package/src/components/shared/doc-search/use-doc-search.ts +3 -7
- package/src/components/shared/legal-document/legal-document-page.tsx +2 -2
- package/src/components/shared/product-release/release-detail-page.tsx +4 -6
- package/src/components/ui/index.ts +0 -2
- package/src/components/ui/release-changelog-section.tsx +2 -7
- package/src/components/ui/simple-markdown-renderer.tsx +11 -7
- package/src/contexts/chat-runtime-context.tsx +0 -14
- package/src/types/doc-source.ts +1 -33
- package/src/utils/index.ts +0 -1
- package/dist/chunk-2QG57XOJ.js.map +0 -1
- package/dist/chunk-4PSQS3SW.cjs.map +0 -1
- package/dist/chunk-4TLE6VLU.js.map +0 -1
- package/dist/chunk-53FUMSZ5.cjs.map +0 -1
- package/dist/chunk-6C526VNN.cjs.map +0 -1
- package/dist/chunk-7OVGB2DQ.cjs.map +0 -1
- package/dist/chunk-F5OB2YAL.cjs +0 -144
- package/dist/chunk-F5OB2YAL.cjs.map +0 -1
- package/dist/chunk-FBWXMMRB.cjs +0 -2
- package/dist/chunk-FBWXMMRB.cjs.map +0 -1
- package/dist/chunk-FCDQNTDG.cjs.map +0 -1
- package/dist/chunk-FQOTC3UU.cjs.map +0 -1
- package/dist/chunk-GUTS7HGA.cjs.map +0 -1
- package/dist/chunk-GZ4C3XW6.js +0 -2
- package/dist/chunk-GZ4C3XW6.js.map +0 -1
- package/dist/chunk-IZ7JSBFP.js.map +0 -1
- package/dist/chunk-JALO4TAZ.js.map +0 -1
- package/dist/chunk-L6PSSIUQ.cjs.map +0 -1
- package/dist/chunk-PC746XCO.js.map +0 -1
- package/dist/chunk-PWQUAVA3.js.map +0 -1
- package/dist/chunk-SA2WPJVO.js +0 -144
- package/dist/chunk-SA2WPJVO.js.map +0 -1
- package/dist/chunk-UNVE2SDJ.cjs.map +0 -1
- package/dist/chunk-WMSTJAZT.cjs.map +0 -1
- package/dist/chunk-YBYI62OE.cjs.map +0 -1
- package/dist/components/case-studies/index.cjs +0 -126
- package/dist/components/case-studies/index.cjs.map +0 -1
- package/dist/components/case-studies/index.d.ts +0 -2
- package/dist/components/case-studies/index.d.ts.map +0 -1
- package/dist/components/case-studies/index.js +0 -126
- package/dist/components/case-studies/index.js.map +0 -1
- package/dist/components/case-studies/share-experience-section.d.ts +0 -48
- package/dist/components/case-studies/share-experience-section.d.ts.map +0 -1
- package/dist/components/docs/docs-hub-page.d.ts +0 -46
- package/dist/components/docs/docs-hub-page.d.ts.map +0 -1
- package/dist/components/docs/skeletons.d.ts +0 -32
- package/dist/components/docs/skeletons.d.ts.map +0 -1
- package/dist/components/docs/use-docs-resolve-link.d.ts +0 -20
- package/dist/components/docs/use-docs-resolve-link.d.ts.map +0 -1
- package/dist/components/embeds/embed-container.d.ts +0 -37
- package/dist/components/embeds/embed-container.d.ts.map +0 -1
- package/dist/components/embeds/file-download-card.d.ts +0 -18
- package/dist/components/embeds/file-download-card.d.ts.map +0 -1
- package/dist/components/embeds/linkedin-embed-client.d.ts +0 -8
- package/dist/components/embeds/linkedin-embed-client.d.ts.map +0 -1
- package/dist/components/embeds/markdown-image.d.ts +0 -5
- package/dist/components/embeds/markdown-image.d.ts.map +0 -1
- package/dist/components/embeds/reddit-embed-client.d.ts +0 -7
- package/dist/components/embeds/reddit-embed-client.d.ts.map +0 -1
- package/dist/components/embeds/rich-markdown-runtime.d.ts +0 -46
- package/dist/components/embeds/rich-markdown-runtime.d.ts.map +0 -1
- package/dist/components/embeds/twitter-embed-client.d.ts +0 -8
- package/dist/components/embeds/twitter-embed-client.d.ts.map +0 -1
- package/dist/components/layout/page-header.d.ts +0 -78
- package/dist/components/layout/page-header.d.ts.map +0 -1
- package/dist/components/layout/page-with-header.d.ts +0 -67
- package/dist/components/layout/page-with-header.d.ts.map +0 -1
- package/dist/components/ui/rich-markdown-renderer.d.ts +0 -34
- package/dist/components/ui/rich-markdown-renderer.d.ts.map +0 -1
- package/dist/utils/page-header-constants.d.ts +0 -15
- package/dist/utils/page-header-constants.d.ts.map +0 -1
- package/dist/utils/social-embed-cache.d.ts +0 -29
- package/dist/utils/social-embed-cache.d.ts.map +0 -1
- package/src/components/case-studies/index.ts +0 -4
- package/src/components/case-studies/share-experience-section.tsx +0 -185
- package/src/components/docs/docs-hub-page.tsx +0 -149
- package/src/components/docs/skeletons.tsx +0 -138
- package/src/components/docs/use-docs-resolve-link.ts +0 -52
- package/src/components/embeds/embed-container.tsx +0 -80
- package/src/components/embeds/file-download-card.tsx +0 -54
- package/src/components/embeds/linkedin-embed-client.tsx +0 -100
- package/src/components/embeds/markdown-image.tsx +0 -88
- package/src/components/embeds/reddit-embed-client.tsx +0 -550
- package/src/components/embeds/rich-markdown-runtime.tsx +0 -79
- package/src/components/embeds/twitter-embed-client.tsx +0 -308
- package/src/components/layout/page-header.tsx +0 -182
- package/src/components/layout/page-with-header.tsx +0 -110
- package/src/components/ui/rich-markdown-renderer.tsx +0 -1203
- package/src/utils/page-header-constants.ts +0 -15
- package/src/utils/social-embed-cache.ts +0 -391
- /package/dist/{chunk-PI4WSYQV.js.map → chunk-3ZXUQQL4.js.map} +0 -0
|
@@ -1,17 +1,34 @@
|
|
|
1
1
|
"use client";
|
|
2
|
+
import {
|
|
3
|
+
ELAPSED_MS_FIELD,
|
|
4
|
+
HONEYPOT_FIELD,
|
|
5
|
+
ToolTypeValues,
|
|
6
|
+
consumeAccessCode,
|
|
7
|
+
normalizeHashFragment,
|
|
8
|
+
scrollElementIntoView,
|
|
9
|
+
transformPlatformConfigsToOptions,
|
|
10
|
+
validateAccessCode,
|
|
11
|
+
validateAndConsumeAccessCode
|
|
12
|
+
} from "./chunk-OQ6X7ZOC.js";
|
|
2
13
|
import {
|
|
3
14
|
useRequiredEndpointsRuntime
|
|
4
15
|
} from "./chunk-MJNXIEV2.js";
|
|
16
|
+
import {
|
|
17
|
+
createNatsClient
|
|
18
|
+
} from "./chunk-PHWQLKVE.js";
|
|
19
|
+
import {
|
|
20
|
+
contentFetch
|
|
21
|
+
} from "./chunk-3MCHAFHB.js";
|
|
22
|
+
import {
|
|
23
|
+
useDebounce
|
|
24
|
+
} from "./chunk-POKKCWKF.js";
|
|
5
25
|
import {
|
|
6
26
|
init_next_navigation,
|
|
7
27
|
useRouter,
|
|
8
28
|
useSearchParams
|
|
9
29
|
} from "./chunk-PLJLE4A4.js";
|
|
10
30
|
import {
|
|
11
|
-
|
|
12
|
-
MiamiCyberGangLogoFaceOnly,
|
|
13
|
-
OpenFrameLogo,
|
|
14
|
-
OpenmspLogo
|
|
31
|
+
OpenFrameLogo
|
|
15
32
|
} from "./chunk-V4IIBNTA.js";
|
|
16
33
|
import {
|
|
17
34
|
cn,
|
|
@@ -26,108 +43,12 @@ import {
|
|
|
26
43
|
TacticalRmmLogoIcon,
|
|
27
44
|
XmarkIcon
|
|
28
45
|
} from "./chunk-J7AV6H63.js";
|
|
29
|
-
import {
|
|
30
|
-
createNatsClient
|
|
31
|
-
} from "./chunk-PHWQLKVE.js";
|
|
32
|
-
|
|
33
|
-
// src/hooks/ui/use-auto-limit-tags.ts
|
|
34
|
-
import { useCallback, useEffect, useRef, useState } from "react";
|
|
35
|
-
function useAutoLimitTags({
|
|
36
|
-
count,
|
|
37
|
-
limitTags = "auto",
|
|
38
|
-
placeholder = "",
|
|
39
|
-
reserveInputWidth = true
|
|
40
|
-
}) {
|
|
41
|
-
const middleRef = useRef(null);
|
|
42
|
-
const measureRef = useRef(null);
|
|
43
|
-
const textMeasureRef = useRef(null);
|
|
44
|
-
const badgeRef = useRef(null);
|
|
45
|
-
const inputRef = useRef(null);
|
|
46
|
-
const [visibleCount, setVisibleCount] = useState(count);
|
|
47
|
-
const recalculate = useCallback(() => {
|
|
48
|
-
if (limitTags !== "auto") {
|
|
49
|
-
setVisibleCount(Math.min(limitTags, count));
|
|
50
|
-
return;
|
|
51
|
-
}
|
|
52
|
-
const middle = middleRef.current;
|
|
53
|
-
const measure = measureRef.current;
|
|
54
|
-
if (!middle || !measure) {
|
|
55
|
-
setVisibleCount(count);
|
|
56
|
-
return;
|
|
57
|
-
}
|
|
58
|
-
if (count === 0) {
|
|
59
|
-
setVisibleCount(0);
|
|
60
|
-
return;
|
|
61
|
-
}
|
|
62
|
-
const cs = getComputedStyle(middle);
|
|
63
|
-
const padL = parseFloat(cs.paddingLeft) || 0;
|
|
64
|
-
const padR = parseFloat(cs.paddingRight) || 0;
|
|
65
|
-
const gap = parseFloat(cs.gap) || 0;
|
|
66
|
-
const middleW = middle.clientWidth;
|
|
67
|
-
let inputReservedW = 0;
|
|
68
|
-
let trailingGap = 0;
|
|
69
|
-
if (reserveInputWidth) {
|
|
70
|
-
const textW = textMeasureRef.current?.offsetWidth ?? 60;
|
|
71
|
-
const inputMinW = inputRef.current ? parseFloat(getComputedStyle(inputRef.current).minWidth) || 60 : 60;
|
|
72
|
-
inputReservedW = Math.max(textW + 8, inputMinW);
|
|
73
|
-
trailingGap = gap;
|
|
74
|
-
}
|
|
75
|
-
const available = middleW - padL - padR - inputReservedW - trailingGap;
|
|
76
|
-
const tagEls = Array.from(measure.children);
|
|
77
|
-
const widths = tagEls.map((el) => el.offsetWidth);
|
|
78
|
-
let total = 0;
|
|
79
|
-
for (let i = 0; i < widths.length; i++) {
|
|
80
|
-
total += widths[i] + (i > 0 ? gap : 0);
|
|
81
|
-
}
|
|
82
|
-
if (total <= available) {
|
|
83
|
-
setVisibleCount(count);
|
|
84
|
-
return;
|
|
85
|
-
}
|
|
86
|
-
const badgeW = badgeRef.current?.offsetWidth ?? 40;
|
|
87
|
-
const spaceWithBadge = available - badgeW - gap;
|
|
88
|
-
let used = 0;
|
|
89
|
-
let fitCount = 0;
|
|
90
|
-
for (let i = 0; i < widths.length; i++) {
|
|
91
|
-
const need = widths[i] + (i > 0 ? gap : 0);
|
|
92
|
-
if (used + need > spaceWithBadge) break;
|
|
93
|
-
used += need;
|
|
94
|
-
fitCount++;
|
|
95
|
-
}
|
|
96
|
-
setVisibleCount(Math.max(0, fitCount));
|
|
97
|
-
}, [count, limitTags, placeholder, reserveInputWidth]);
|
|
98
|
-
useEffect(() => {
|
|
99
|
-
recalculate();
|
|
100
|
-
}, [recalculate]);
|
|
101
|
-
useEffect(() => {
|
|
102
|
-
const el = middleRef.current;
|
|
103
|
-
if (!el) return;
|
|
104
|
-
const ro = new ResizeObserver(recalculate);
|
|
105
|
-
ro.observe(el);
|
|
106
|
-
return () => ro.disconnect();
|
|
107
|
-
}, [recalculate]);
|
|
108
|
-
return { visibleCount, middleRef, measureRef, textMeasureRef, badgeRef, inputRef };
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
// src/hooks/ui/use-debounce.ts
|
|
112
|
-
import { useState as useState2, useEffect as useEffect2 } from "react";
|
|
113
|
-
function useDebounce(value, delay = 500) {
|
|
114
|
-
const [debouncedValue, setDebouncedValue] = useState2(value);
|
|
115
|
-
useEffect2(() => {
|
|
116
|
-
const timer = setTimeout(() => {
|
|
117
|
-
setDebouncedValue(value);
|
|
118
|
-
}, delay);
|
|
119
|
-
return () => {
|
|
120
|
-
clearTimeout(timer);
|
|
121
|
-
};
|
|
122
|
-
}, [value, delay]);
|
|
123
|
-
return debouncedValue;
|
|
124
|
-
}
|
|
125
46
|
|
|
126
47
|
// src/hooks/ui/use-header-height.ts
|
|
127
|
-
import { useEffect
|
|
48
|
+
import { useEffect, useState } from "react";
|
|
128
49
|
function useHeaderHeight(defaultHeight = 64) {
|
|
129
|
-
const [height, setHeight] =
|
|
130
|
-
|
|
50
|
+
const [height, setHeight] = useState(defaultHeight);
|
|
51
|
+
useEffect(() => {
|
|
131
52
|
const measure = () => {
|
|
132
53
|
let total = 0;
|
|
133
54
|
const header2 = document.querySelector("header");
|
|
@@ -166,22 +87,22 @@ function useHeaderHeight(defaultHeight = 64) {
|
|
|
166
87
|
}
|
|
167
88
|
|
|
168
89
|
// src/hooks/ui/use-horizontal-scrollbar.ts
|
|
169
|
-
import { useRef
|
|
90
|
+
import { useRef, useState as useState2, useCallback } from "react";
|
|
170
91
|
function useHorizontalScrollbar() {
|
|
171
|
-
const scrollElRef =
|
|
172
|
-
const trackRef =
|
|
173
|
-
const thumbRef =
|
|
174
|
-
const roRef =
|
|
175
|
-
const moRef =
|
|
176
|
-
const [thumbRatio, setThumbRatio] =
|
|
177
|
-
const [canScrollLeft, setCanScrollLeft] =
|
|
178
|
-
const [canScrollRight, setCanScrollRight] =
|
|
179
|
-
const prevCanScrollLeftRef =
|
|
180
|
-
const prevCanScrollRightRef =
|
|
181
|
-
const isDraggingRef =
|
|
182
|
-
const dragStartRef =
|
|
183
|
-
const rafIdRef =
|
|
184
|
-
const syncThumbToDOM =
|
|
92
|
+
const scrollElRef = useRef(null);
|
|
93
|
+
const trackRef = useRef(null);
|
|
94
|
+
const thumbRef = useRef(null);
|
|
95
|
+
const roRef = useRef(null);
|
|
96
|
+
const moRef = useRef(null);
|
|
97
|
+
const [thumbRatio, setThumbRatio] = useState2(0);
|
|
98
|
+
const [canScrollLeft, setCanScrollLeft] = useState2(false);
|
|
99
|
+
const [canScrollRight, setCanScrollRight] = useState2(false);
|
|
100
|
+
const prevCanScrollLeftRef = useRef(false);
|
|
101
|
+
const prevCanScrollRightRef = useRef(false);
|
|
102
|
+
const isDraggingRef = useRef(false);
|
|
103
|
+
const dragStartRef = useRef({ mouseX: 0, scrollLeft: 0 });
|
|
104
|
+
const rafIdRef = useRef(0);
|
|
105
|
+
const syncThumbToDOM = useCallback(() => {
|
|
185
106
|
const el = scrollElRef.current;
|
|
186
107
|
const thumb = thumbRef.current;
|
|
187
108
|
if (!el || !thumb) return;
|
|
@@ -194,7 +115,7 @@ function useHorizontalScrollbar() {
|
|
|
194
115
|
const fraction = Math.min(Math.max(el.scrollLeft, 0), maxScroll) / maxScroll;
|
|
195
116
|
thumb.style.left = `${fraction * (1 - ratio) * 100}%`;
|
|
196
117
|
}, []);
|
|
197
|
-
const syncEdgeFades =
|
|
118
|
+
const syncEdgeFades = useCallback(() => {
|
|
198
119
|
const el = scrollElRef.current;
|
|
199
120
|
if (!el) return;
|
|
200
121
|
const maxScroll = el.scrollWidth - el.clientWidth;
|
|
@@ -222,7 +143,7 @@ function useHorizontalScrollbar() {
|
|
|
222
143
|
setCanScrollRight(right);
|
|
223
144
|
}
|
|
224
145
|
}, []);
|
|
225
|
-
const measure =
|
|
146
|
+
const measure = useCallback(() => {
|
|
226
147
|
const el = scrollElRef.current;
|
|
227
148
|
if (!el) return;
|
|
228
149
|
const ratio = el.clientWidth / el.scrollWidth;
|
|
@@ -230,7 +151,7 @@ function useHorizontalScrollbar() {
|
|
|
230
151
|
syncThumbToDOM();
|
|
231
152
|
syncEdgeFades();
|
|
232
153
|
}, [syncThumbToDOM, syncEdgeFades]);
|
|
233
|
-
const scrollRef =
|
|
154
|
+
const scrollRef = useCallback((node) => {
|
|
234
155
|
if (roRef.current) {
|
|
235
156
|
roRef.current.disconnect();
|
|
236
157
|
roRef.current = null;
|
|
@@ -272,7 +193,7 @@ function useHorizontalScrollbar() {
|
|
|
272
193
|
setCanScrollRight(false);
|
|
273
194
|
}
|
|
274
195
|
}, [measure, syncThumbToDOM, syncEdgeFades]);
|
|
275
|
-
const onScroll =
|
|
196
|
+
const onScroll = useCallback(() => {
|
|
276
197
|
if (isDraggingRef.current) return;
|
|
277
198
|
if (rafIdRef.current) cancelAnimationFrame(rafIdRef.current);
|
|
278
199
|
rafIdRef.current = requestAnimationFrame(() => {
|
|
@@ -280,7 +201,7 @@ function useHorizontalScrollbar() {
|
|
|
280
201
|
syncEdgeFades();
|
|
281
202
|
});
|
|
282
203
|
}, [syncThumbToDOM, syncEdgeFades]);
|
|
283
|
-
const onTrackClick =
|
|
204
|
+
const onTrackClick = useCallback((e) => {
|
|
284
205
|
if (e.target.closest("[data-scrollbar-thumb]")) return;
|
|
285
206
|
const track = trackRef.current;
|
|
286
207
|
const el = scrollElRef.current;
|
|
@@ -298,13 +219,13 @@ function useHorizontalScrollbar() {
|
|
|
298
219
|
const targetScrollLeft = targetFraction * (el.scrollWidth - el.clientWidth);
|
|
299
220
|
el.scrollTo({ left: targetScrollLeft, behavior: "smooth" });
|
|
300
221
|
}, []);
|
|
301
|
-
const onTrackWheel =
|
|
222
|
+
const onTrackWheel = useCallback((e) => {
|
|
302
223
|
const el = scrollElRef.current;
|
|
303
224
|
if (!el) return;
|
|
304
225
|
e.preventDefault();
|
|
305
226
|
el.scrollLeft += e.deltaX || e.deltaY;
|
|
306
227
|
}, []);
|
|
307
|
-
const onThumbPointerDown =
|
|
228
|
+
const onThumbPointerDown = useCallback((e) => {
|
|
308
229
|
e.preventDefault();
|
|
309
230
|
e.stopPropagation();
|
|
310
231
|
const el = scrollElRef.current;
|
|
@@ -315,7 +236,7 @@ function useHorizontalScrollbar() {
|
|
|
315
236
|
target.setPointerCapture(e.pointerId);
|
|
316
237
|
target.style.cursor = "grabbing";
|
|
317
238
|
}, []);
|
|
318
|
-
const onThumbPointerMove =
|
|
239
|
+
const onThumbPointerMove = useCallback((e) => {
|
|
319
240
|
if (!isDraggingRef.current) return;
|
|
320
241
|
const el = scrollElRef.current;
|
|
321
242
|
const track = trackRef.current;
|
|
@@ -335,7 +256,7 @@ function useHorizontalScrollbar() {
|
|
|
335
256
|
syncThumbToDOM();
|
|
336
257
|
syncEdgeFades();
|
|
337
258
|
}, [syncThumbToDOM, syncEdgeFades]);
|
|
338
|
-
const onThumbPointerUp =
|
|
259
|
+
const onThumbPointerUp = useCallback((e) => {
|
|
339
260
|
isDraggingRef.current = false;
|
|
340
261
|
const target = e.currentTarget;
|
|
341
262
|
target.releasePointerCapture(e.pointerId);
|
|
@@ -358,7 +279,7 @@ function useHorizontalScrollbar() {
|
|
|
358
279
|
}
|
|
359
280
|
|
|
360
281
|
// src/hooks/ui/use-image-edge-color.ts
|
|
361
|
-
import { useState as
|
|
282
|
+
import { useState as useState3, useEffect as useEffect2 } from "react";
|
|
362
283
|
function extractEdgeColor(img) {
|
|
363
284
|
const canvas = document.createElement("canvas");
|
|
364
285
|
const ctx = canvas.getContext("2d");
|
|
@@ -414,8 +335,8 @@ function extractEdgeColor(img) {
|
|
|
414
335
|
return `rgb(${r}, ${g}, ${b})`;
|
|
415
336
|
}
|
|
416
337
|
function useImageEdgeColor(imageUrl, fallback = "#000000") {
|
|
417
|
-
const [color, setColor] =
|
|
418
|
-
|
|
338
|
+
const [color, setColor] = useState3(fallback);
|
|
339
|
+
useEffect2(() => {
|
|
419
340
|
if (!imageUrl) {
|
|
420
341
|
setColor(fallback);
|
|
421
342
|
return;
|
|
@@ -444,9 +365,9 @@ function useImageEdgeColor(imageUrl, fallback = "#000000") {
|
|
|
444
365
|
}
|
|
445
366
|
|
|
446
367
|
// src/hooks/ui/use-local-storage.ts
|
|
447
|
-
import { useEffect as
|
|
368
|
+
import { useEffect as useEffect3, useRef as useRef2, useState as useState4 } from "react";
|
|
448
369
|
function useLocalStorage(key, initialValue) {
|
|
449
|
-
const [storedValue, setStoredValue] =
|
|
370
|
+
const [storedValue, setStoredValue] = useState4(() => {
|
|
450
371
|
try {
|
|
451
372
|
if (typeof window !== "undefined") {
|
|
452
373
|
const item = window.localStorage.getItem(key);
|
|
@@ -457,9 +378,9 @@ function useLocalStorage(key, initialValue) {
|
|
|
457
378
|
}
|
|
458
379
|
return initialValue;
|
|
459
380
|
});
|
|
460
|
-
const isInitialized =
|
|
461
|
-
const isFromStorageEvent =
|
|
462
|
-
|
|
381
|
+
const isInitialized = useRef2(true);
|
|
382
|
+
const isFromStorageEvent = useRef2(false);
|
|
383
|
+
useEffect3(() => {
|
|
463
384
|
if (!isInitialized.current) return;
|
|
464
385
|
const handleStorageChange = (e) => {
|
|
465
386
|
if (e.key === key && e.newValue !== null) {
|
|
@@ -498,7 +419,7 @@ function useLocalStorage(key, initialValue) {
|
|
|
498
419
|
window.removeEventListener("localStorageUpdate", handleCustomStorageUpdate);
|
|
499
420
|
};
|
|
500
421
|
}, [key]);
|
|
501
|
-
|
|
422
|
+
useEffect3(() => {
|
|
502
423
|
if (!isInitialized.current) return;
|
|
503
424
|
if (isFromStorageEvent.current) {
|
|
504
425
|
isFromStorageEvent.current = false;
|
|
@@ -524,9 +445,9 @@ function useLocalStorage(key, initialValue) {
|
|
|
524
445
|
}
|
|
525
446
|
|
|
526
447
|
// src/hooks/ui/use-media-query.ts
|
|
527
|
-
import { useLayoutEffect, useState as
|
|
448
|
+
import { useLayoutEffect, useState as useState5 } from "react";
|
|
528
449
|
function useMediaQuery(query) {
|
|
529
|
-
const [matches, setMatches] =
|
|
450
|
+
const [matches, setMatches] = useState5(void 0);
|
|
530
451
|
useLayoutEffect(() => {
|
|
531
452
|
const matchMedia = window.matchMedia(query);
|
|
532
453
|
const handleChange = () => {
|
|
@@ -559,24 +480,24 @@ function useLgUp() {
|
|
|
559
480
|
}
|
|
560
481
|
|
|
561
482
|
// src/hooks/ui/use-memoized-callback.ts
|
|
562
|
-
import { useCallback as
|
|
483
|
+
import { useCallback as useCallback2, useRef as useRef3 } from "react";
|
|
563
484
|
function useMemoizedCallback(callback, dependencies) {
|
|
564
|
-
const callbackRef =
|
|
565
|
-
const dependenciesRef =
|
|
485
|
+
const callbackRef = useRef3(callback);
|
|
486
|
+
const dependenciesRef = useRef3(dependencies);
|
|
566
487
|
callbackRef.current = callback;
|
|
567
488
|
const depsChanged = dependencies.some((dep, i) => !Object.is(dep, dependenciesRef.current[i]));
|
|
568
489
|
if (depsChanged) {
|
|
569
490
|
dependenciesRef.current = dependencies;
|
|
570
491
|
}
|
|
571
|
-
return
|
|
492
|
+
return useCallback2(((...args) => callbackRef.current(...args)), [depsChanged]);
|
|
572
493
|
}
|
|
573
494
|
|
|
574
495
|
// src/hooks/ui/use-notification-permission.ts
|
|
575
|
-
import { useCallback as
|
|
496
|
+
import { useCallback as useCallback3, useEffect as useEffect4, useState as useState6 } from "react";
|
|
576
497
|
function useNotificationPermission() {
|
|
577
|
-
const [supported, setSupported] =
|
|
578
|
-
const [permission, setPermission] =
|
|
579
|
-
|
|
498
|
+
const [supported, setSupported] = useState6(false);
|
|
499
|
+
const [permission, setPermission] = useState6("default");
|
|
500
|
+
useEffect4(() => {
|
|
580
501
|
if (typeof window === "undefined" || !("Notification" in window)) return;
|
|
581
502
|
setSupported(true);
|
|
582
503
|
const sync = () => setPermission(Notification.permission);
|
|
@@ -597,7 +518,7 @@ function useNotificationPermission() {
|
|
|
597
518
|
window.removeEventListener("focus", sync);
|
|
598
519
|
};
|
|
599
520
|
}, []);
|
|
600
|
-
const request =
|
|
521
|
+
const request = useCallback3(async () => {
|
|
601
522
|
if (typeof window === "undefined" || !("Notification" in window)) {
|
|
602
523
|
return "denied";
|
|
603
524
|
}
|
|
@@ -612,7 +533,7 @@ function useNotificationPermission() {
|
|
|
612
533
|
}
|
|
613
534
|
|
|
614
535
|
// src/hooks/ui/use-onboarding-state.ts
|
|
615
|
-
import { useState as
|
|
536
|
+
import { useState as useState7, useEffect as useEffect5, useCallback as useCallback4 } from "react";
|
|
616
537
|
|
|
617
538
|
// src/utils/onboarding-storage.ts
|
|
618
539
|
var DEFAULT_STATE = {
|
|
@@ -687,9 +608,9 @@ function dismissOnboarding(key) {
|
|
|
687
608
|
|
|
688
609
|
// src/hooks/ui/use-onboarding-state.ts
|
|
689
610
|
function useOnboardingState(storageKey = "openframe-onboarding-state") {
|
|
690
|
-
const [state, setState] =
|
|
691
|
-
const [, forceUpdate] =
|
|
692
|
-
|
|
611
|
+
const [state, setState] = useState7(() => loadOnboardingState(storageKey));
|
|
612
|
+
const [, forceUpdate] = useState7(0);
|
|
613
|
+
useEffect5(() => {
|
|
693
614
|
const handleStorageUpdate = (e) => {
|
|
694
615
|
if (e.detail.key === storageKey) {
|
|
695
616
|
const newState = loadOnboardingState(storageKey);
|
|
@@ -703,38 +624,38 @@ function useOnboardingState(storageKey = "openframe-onboarding-state") {
|
|
|
703
624
|
window.removeEventListener("localStorageUpdate", handleStorageUpdate);
|
|
704
625
|
};
|
|
705
626
|
}, [storageKey]);
|
|
706
|
-
const markComplete =
|
|
627
|
+
const markComplete = useCallback4((stepId) => {
|
|
707
628
|
console.log(`\u{1F3AF} markComplete called for: "${stepId}"`);
|
|
708
629
|
const newState = markStepComplete(storageKey, stepId);
|
|
709
630
|
setState(newState);
|
|
710
631
|
forceUpdate((prev) => prev + 1);
|
|
711
632
|
}, [storageKey]);
|
|
712
|
-
const markSkipped =
|
|
633
|
+
const markSkipped = useCallback4((stepId) => {
|
|
713
634
|
console.log(`\u23ED\uFE0F markSkipped called for: "${stepId}"`);
|
|
714
635
|
const newState = markStepSkipped(storageKey, stepId);
|
|
715
636
|
setState(newState);
|
|
716
637
|
forceUpdate((prev) => prev + 1);
|
|
717
638
|
}, [storageKey]);
|
|
718
|
-
const dismissOnboarding2 =
|
|
639
|
+
const dismissOnboarding2 = useCallback4(() => {
|
|
719
640
|
console.log(`\u{1F6AB} dismissOnboarding called`);
|
|
720
641
|
const newState = dismissOnboarding(storageKey);
|
|
721
642
|
setState(newState);
|
|
722
643
|
forceUpdate((prev) => prev + 1);
|
|
723
644
|
}, [storageKey]);
|
|
724
|
-
const markMultipleComplete2 =
|
|
645
|
+
const markMultipleComplete2 = useCallback4((stepIds) => {
|
|
725
646
|
console.log(`\u{1F3AF} markMultipleComplete called for:`, stepIds);
|
|
726
647
|
const newState = markMultipleComplete(storageKey, stepIds);
|
|
727
648
|
setState(newState);
|
|
728
649
|
forceUpdate((prev) => prev + 1);
|
|
729
650
|
console.log(`\u{1F4DD} State after batch:`, newState);
|
|
730
651
|
}, [storageKey]);
|
|
731
|
-
const isStepComplete =
|
|
652
|
+
const isStepComplete = useCallback4((stepId) => {
|
|
732
653
|
return state.completedSteps.includes(stepId);
|
|
733
654
|
}, [state.completedSteps]);
|
|
734
|
-
const isStepSkipped =
|
|
655
|
+
const isStepSkipped = useCallback4((stepId) => {
|
|
735
656
|
return state.skippedSteps.includes(stepId);
|
|
736
657
|
}, [state.skippedSteps]);
|
|
737
|
-
const allStepsComplete =
|
|
658
|
+
const allStepsComplete = useCallback4((steps) => {
|
|
738
659
|
return steps.every((step) => isStepComplete(step.id) || isStepSkipped(step.id));
|
|
739
660
|
}, [isStepComplete, isStepSkipped]);
|
|
740
661
|
return {
|
|
@@ -750,19 +671,19 @@ function useOnboardingState(storageKey = "openframe-onboarding-state") {
|
|
|
750
671
|
}
|
|
751
672
|
|
|
752
673
|
// src/hooks/ui/use-search.ts
|
|
753
|
-
import { useState as
|
|
674
|
+
import { useState as useState8, useEffect as useEffect6, useCallback as useCallback5 } from "react";
|
|
754
675
|
function useSearch(config) {
|
|
755
676
|
const { searchFn, mapResult, debounceMs = 300, minQueryLength = 2 } = config;
|
|
756
|
-
const [query, setQuery] =
|
|
757
|
-
const [results, setResults] =
|
|
758
|
-
const [isLoading, setIsLoading] =
|
|
759
|
-
const [error, setError] =
|
|
677
|
+
const [query, setQuery] = useState8("");
|
|
678
|
+
const [results, setResults] = useState8([]);
|
|
679
|
+
const [isLoading, setIsLoading] = useState8(false);
|
|
680
|
+
const [error, setError] = useState8(null);
|
|
760
681
|
const debouncedQuery = useDebounce(query, debounceMs);
|
|
761
|
-
const clearResults =
|
|
682
|
+
const clearResults = useCallback5(() => {
|
|
762
683
|
setResults([]);
|
|
763
684
|
setError(null);
|
|
764
685
|
}, []);
|
|
765
|
-
|
|
686
|
+
useEffect6(() => {
|
|
766
687
|
if (!debouncedQuery || debouncedQuery.length < minQueryLength) {
|
|
767
688
|
setResults([]);
|
|
768
689
|
setIsLoading(false);
|
|
@@ -835,11 +756,11 @@ function useTablePagination(config) {
|
|
|
835
756
|
}
|
|
836
757
|
|
|
837
758
|
// src/hooks/ui/use-throttle.ts
|
|
838
|
-
import { useState as
|
|
759
|
+
import { useState as useState9, useEffect as useEffect7, useRef as useRef4 } from "react";
|
|
839
760
|
function useThrottle(value, limit = 200) {
|
|
840
|
-
const [throttledValue, setThrottledValue] =
|
|
841
|
-
const lastUpdated =
|
|
842
|
-
|
|
761
|
+
const [throttledValue, setThrottledValue] = useState9(value);
|
|
762
|
+
const lastUpdated = useRef4(Date.now());
|
|
763
|
+
useEffect7(() => {
|
|
843
764
|
const now = Date.now();
|
|
844
765
|
const elapsed = now - lastUpdated.current;
|
|
845
766
|
if (elapsed >= limit) {
|
|
@@ -859,13 +780,13 @@ function useThrottle(value, limit = 200) {
|
|
|
859
780
|
}
|
|
860
781
|
|
|
861
782
|
// src/hooks/ui/use-window-size.ts
|
|
862
|
-
import { useLayoutEffect as useLayoutEffect2, useState as
|
|
783
|
+
import { useLayoutEffect as useLayoutEffect2, useState as useState10 } from "react";
|
|
863
784
|
function useWindowSize() {
|
|
864
|
-
const [windowSize, setWindowSize] =
|
|
785
|
+
const [windowSize, setWindowSize] = useState10({
|
|
865
786
|
width: 0,
|
|
866
787
|
height: 0
|
|
867
788
|
});
|
|
868
|
-
const [isClient, setIsClient] =
|
|
789
|
+
const [isClient, setIsClient] = useState10(false);
|
|
869
790
|
useLayoutEffect2(() => {
|
|
870
791
|
setIsClient(true);
|
|
871
792
|
if (!isClient) return;
|
|
@@ -883,188 +804,14 @@ function useWindowSize() {
|
|
|
883
804
|
}
|
|
884
805
|
|
|
885
806
|
// src/hooks/platform/use-platform-config.ts
|
|
886
|
-
import { useState as
|
|
887
|
-
|
|
888
|
-
// src/utils/platform-config.tsx
|
|
889
|
-
import { Globe } from "lucide-react";
|
|
890
|
-
import { jsx } from "react/jsx-runtime";
|
|
891
|
-
var platformIcons = {
|
|
892
|
-
openframe: /* @__PURE__ */ jsx(OpenFrameLogo, { className: "h-5 w-5", lowerPathColor: "#FFC008", upperPathColor: "#ffffff" }),
|
|
893
|
-
openmsp: /* @__PURE__ */ jsx(OpenmspLogo, { className: "h-5 w-5" }),
|
|
894
|
-
flamingo: /* @__PURE__ */ jsx(FlamingoLogo, { className: "h-5 w-5", fill: "#EC4899" }),
|
|
895
|
-
"flamingo-teaser": /* @__PURE__ */ jsx(FlamingoLogo, { className: "h-5 w-5", fill: "#EC4899" }),
|
|
896
|
-
"marketing-hub": /* @__PURE__ */ jsx(FlamingoLogo, { className: "h-5 w-5", fill: "#F357BB" }),
|
|
897
|
-
"product-hub": /* @__PURE__ */ jsx(FlamingoLogo, { className: "h-5 w-5", fill: "#5EA62E" }),
|
|
898
|
-
"revenue-hub": /* @__PURE__ */ jsx(FlamingoLogo, { className: "h-5 w-5", fill: "#FFC008" }),
|
|
899
|
-
"people-hub": /* @__PURE__ */ jsx(FlamingoLogo, { className: "h-5 w-5", fill: "#5EFAF0" }),
|
|
900
|
-
"company-hub": /* @__PURE__ */ jsx(FlamingoLogo, { className: "h-5 w-5", fill: "#f36666" }),
|
|
901
|
-
tmcg: /* @__PURE__ */ jsx(MiamiCyberGangLogoFaceOnly, { className: "h-5 w-5" }),
|
|
902
|
-
universal: /* @__PURE__ */ jsx(Globe, { className: "h-5 w-5 text-[#10B981]" })
|
|
903
|
-
};
|
|
904
|
-
var platformColors = {
|
|
905
|
-
openmsp: "bg-[#3B82F6]",
|
|
906
|
-
openframe: "bg-[#8B5CF6]",
|
|
907
|
-
flamingo: "bg-[#EC4899]",
|
|
908
|
-
"flamingo-teaser": "bg-[#F59E0B]",
|
|
909
|
-
"marketing-hub": "bg-[#F357BB]",
|
|
910
|
-
"product-hub": "bg-[#5EA62E]",
|
|
911
|
-
"revenue-hub": "bg-[#FFC008]",
|
|
912
|
-
"people-hub": "bg-[#5EFAF0]",
|
|
913
|
-
"company-hub": "bg-[#f36666]",
|
|
914
|
-
tmcg: "bg-[#FF6B6B]",
|
|
915
|
-
universal: "bg-[#10B981]"
|
|
916
|
-
};
|
|
917
|
-
var platformDisplayNames = {
|
|
918
|
-
openmsp: "OpenMSP",
|
|
919
|
-
openframe: "OpenFrame",
|
|
920
|
-
flamingo: "Flamingo",
|
|
921
|
-
"flamingo-teaser": "Flamingo Teaser",
|
|
922
|
-
"marketing-hub": "Flamingo Marketing Hub",
|
|
923
|
-
"product-hub": "Flamingo Product Hub",
|
|
924
|
-
"revenue-hub": "Flamingo Revenue Hub",
|
|
925
|
-
"people-hub": "Flamingo People Hub",
|
|
926
|
-
"company-hub": "Flamingo Company Hub",
|
|
927
|
-
tmcg: "TMCG",
|
|
928
|
-
universal: "Universal"
|
|
929
|
-
};
|
|
930
|
-
var platformDescriptions = {
|
|
931
|
-
openmsp: "Comprehensive directory and comparison platform for managed service providers (MSPs) and technology vendors. Reduce vendor costs and discover open-source alternatives.",
|
|
932
|
-
openframe: "AI-driven open-source security operations center (SOC) and endpoint detection platform for MSPs.",
|
|
933
|
-
flamingo: "AI-driven open-source OS for MSPs. Swap bloated vendor tools for open ones. Automate the boring crap. Take your margin back.",
|
|
934
|
-
"flamingo-teaser": "Preview of Flamingo - the AI-driven open-source OS for MSPs.",
|
|
935
|
-
tmcg: "The Miami Cyber Gang - A cybersecurity community focused on education and collaboration.",
|
|
936
|
-
universal: "Cross-platform universal content."
|
|
937
|
-
};
|
|
938
|
-
var platformSlogans = {
|
|
939
|
-
openmsp: "Find Your Perfect MSP Partner",
|
|
940
|
-
openframe: "Open-Source Security Operations",
|
|
941
|
-
flamingo: "Open-Source OS for MSPs",
|
|
942
|
-
"flamingo-teaser": "Coming Soon: Open-Source OS for MSPs",
|
|
943
|
-
tmcg: "Miami Cyber Community",
|
|
944
|
-
universal: "Universal Platform"
|
|
945
|
-
};
|
|
946
|
-
var platformHexColors = {
|
|
947
|
-
openmsp: "#FFC008",
|
|
948
|
-
openframe: "#FFC008",
|
|
949
|
-
flamingo: "#FF6B9D",
|
|
950
|
-
universal: "#FFC008",
|
|
951
|
-
"flamingo-teaser": "#F59E0B",
|
|
952
|
-
"marketing-hub": "#F357BB",
|
|
953
|
-
"product-hub": "#5EA62E",
|
|
954
|
-
"revenue-hub": "#FFC008",
|
|
955
|
-
"people-hub": "#5EFAF0",
|
|
956
|
-
"company-hub": "#f36666",
|
|
957
|
-
tmcg: "#FF6B6B"
|
|
958
|
-
};
|
|
959
|
-
var platformIconNames = {
|
|
960
|
-
openmsp: "openmsp-logo",
|
|
961
|
-
openframe: "openframe-logo",
|
|
962
|
-
flamingo: "flamingo-logo",
|
|
963
|
-
universal: "globe",
|
|
964
|
-
"flamingo-teaser": "flamingo-logo",
|
|
965
|
-
"marketing-hub": "flamingo-logo",
|
|
966
|
-
"product-hub": "flamingo-logo",
|
|
967
|
-
"revenue-hub": "flamingo-logo",
|
|
968
|
-
"people-hub": "flamingo-logo",
|
|
969
|
-
"company-hub": "flamingo-logo",
|
|
970
|
-
tmcg: "tmcg-logo"
|
|
971
|
-
};
|
|
972
|
-
function getDefaultColorForPlatform(platformName) {
|
|
973
|
-
return platformHexColors[platformName] || platformHexColors.universal;
|
|
974
|
-
}
|
|
975
|
-
function getDefaultIconForPlatform(platformName) {
|
|
976
|
-
return platformIconNames[platformName] || platformIconNames.universal;
|
|
977
|
-
}
|
|
978
|
-
function transformPlatformConfigsToOptions(platformConfigs) {
|
|
979
|
-
return platformConfigs.map((platform) => ({
|
|
980
|
-
id: platform.id,
|
|
981
|
-
// Database UUID for matching
|
|
982
|
-
name: platform.name,
|
|
983
|
-
// Platform name enum
|
|
984
|
-
displayName: platform.display_name,
|
|
985
|
-
// Human-readable name
|
|
986
|
-
description: platform.description,
|
|
987
|
-
icon: platformIcons[platform.name] || platformIcons.universal,
|
|
988
|
-
color: platformColors[platform.name] || platformColors.universal
|
|
989
|
-
}));
|
|
990
|
-
}
|
|
991
|
-
function getPlatformIcon(platformName) {
|
|
992
|
-
return platformIcons[platformName] || platformIcons.universal;
|
|
993
|
-
}
|
|
994
|
-
function getPlatformColor(platformName) {
|
|
995
|
-
return platformColors[platformName] || platformColors.universal;
|
|
996
|
-
}
|
|
997
|
-
function getPlatformDisplayName(platformName) {
|
|
998
|
-
return platformDisplayNames[platformName] || platformName;
|
|
999
|
-
}
|
|
1000
|
-
function getPlatformDescription(platformName) {
|
|
1001
|
-
return platformDescriptions[platformName] || platformName;
|
|
1002
|
-
}
|
|
1003
|
-
function getPlatformSlogan(platformName) {
|
|
1004
|
-
return platformSlogans[platformName] || platformName;
|
|
1005
|
-
}
|
|
1006
|
-
function getSmallPlatformIcon(platformName) {
|
|
1007
|
-
const className = "h-4 w-4 flex-shrink-0";
|
|
1008
|
-
switch (platformName) {
|
|
1009
|
-
case "openframe":
|
|
1010
|
-
return /* @__PURE__ */ jsx(OpenFrameLogo, { className, lowerPathColor: "#FFC008", upperPathColor: "#ffffff" });
|
|
1011
|
-
case "openmsp":
|
|
1012
|
-
return /* @__PURE__ */ jsx(OpenmspLogo, { className, frontBubbleColor: "#f1f1f1", innerFrontBubbleColor: "#000000", backBubbleColor: "#FFC008" });
|
|
1013
|
-
case "flamingo":
|
|
1014
|
-
case "flamingo-teaser":
|
|
1015
|
-
return /* @__PURE__ */ jsx(FlamingoLogo, { className: `${className}`, fill: "#EC4899" });
|
|
1016
|
-
case "marketing-hub":
|
|
1017
|
-
return /* @__PURE__ */ jsx(FlamingoLogo, { className, fill: "var(--ods-flamingo-pink-base)" });
|
|
1018
|
-
case "product-hub":
|
|
1019
|
-
return /* @__PURE__ */ jsx(FlamingoLogo, { className, fill: "var(--ods-attention-green-success)" });
|
|
1020
|
-
case "revenue-hub":
|
|
1021
|
-
return /* @__PURE__ */ jsx(FlamingoLogo, { className, fill: "var(--ods-attention-yellow-warning)" });
|
|
1022
|
-
case "people-hub":
|
|
1023
|
-
return /* @__PURE__ */ jsx(FlamingoLogo, { className, fill: "var(--ods-flamingo-cyan-base)" });
|
|
1024
|
-
case "company-hub":
|
|
1025
|
-
return /* @__PURE__ */ jsx(FlamingoLogo, { className, fill: "var(--ods-attention-red-error)" });
|
|
1026
|
-
case "tmcg":
|
|
1027
|
-
return /* @__PURE__ */ jsx(MiamiCyberGangLogoFaceOnly, { className });
|
|
1028
|
-
case "universal":
|
|
1029
|
-
default:
|
|
1030
|
-
return /* @__PURE__ */ jsx(Globe, { className });
|
|
1031
|
-
}
|
|
1032
|
-
}
|
|
1033
|
-
function getPlatformIconComponent(platformName, className = "h-6 w-6") {
|
|
1034
|
-
switch (platformName) {
|
|
1035
|
-
case "openframe":
|
|
1036
|
-
return /* @__PURE__ */ jsx(OpenFrameLogo, { className });
|
|
1037
|
-
case "openmsp":
|
|
1038
|
-
return /* @__PURE__ */ jsx(OpenmspLogo, { className, color: "#f1f1f1" });
|
|
1039
|
-
case "flamingo":
|
|
1040
|
-
case "flamingo-teaser":
|
|
1041
|
-
return /* @__PURE__ */ jsx(FlamingoLogo, { className: `${className} text-white` });
|
|
1042
|
-
case "marketing-hub":
|
|
1043
|
-
return /* @__PURE__ */ jsx(FlamingoLogo, { className, fill: "var(--ods-flamingo-pink-base)" });
|
|
1044
|
-
case "product-hub":
|
|
1045
|
-
return /* @__PURE__ */ jsx(FlamingoLogo, { className, fill: "var(--ods-attention-green-success)" });
|
|
1046
|
-
case "revenue-hub":
|
|
1047
|
-
return /* @__PURE__ */ jsx(FlamingoLogo, { className, fill: "var(--ods-attention-yellow-warning)" });
|
|
1048
|
-
case "people-hub":
|
|
1049
|
-
return /* @__PURE__ */ jsx(FlamingoLogo, { className, fill: "var(--ods-flamingo-cyan-base)" });
|
|
1050
|
-
case "company-hub":
|
|
1051
|
-
return /* @__PURE__ */ jsx(FlamingoLogo, { className, fill: "var(--ods-attention-red-error)" });
|
|
1052
|
-
case "tmcg":
|
|
1053
|
-
return /* @__PURE__ */ jsx(MiamiCyberGangLogoFaceOnly, { size: 24, className });
|
|
1054
|
-
case "universal":
|
|
1055
|
-
default:
|
|
1056
|
-
return /* @__PURE__ */ jsx(Globe, { className });
|
|
1057
|
-
}
|
|
1058
|
-
}
|
|
1059
|
-
|
|
1060
|
-
// src/hooks/platform/use-platform-config.ts
|
|
807
|
+
import { useState as useState11, useEffect as useEffect8 } from "react";
|
|
1061
808
|
var platformCache = null;
|
|
1062
809
|
var fetchPromise = null;
|
|
1063
810
|
function usePlatformConfig() {
|
|
1064
|
-
const [platforms, setPlatforms] =
|
|
1065
|
-
const [isLoading, setIsLoading] =
|
|
1066
|
-
const [error, setError] =
|
|
1067
|
-
|
|
811
|
+
const [platforms, setPlatforms] = useState11(platformCache || []);
|
|
812
|
+
const [isLoading, setIsLoading] = useState11(!platformCache);
|
|
813
|
+
const [error, setError] = useState11(null);
|
|
814
|
+
useEffect8(() => {
|
|
1068
815
|
if (platformCache) {
|
|
1069
816
|
setPlatforms(platformCache);
|
|
1070
817
|
setIsLoading(false);
|
|
@@ -1135,35 +882,11 @@ import { toast as sonnerToast2 } from "sonner";
|
|
|
1135
882
|
import * as React from "react";
|
|
1136
883
|
import { Toaster as SonnerToaster, toast as sonnerToast } from "sonner";
|
|
1137
884
|
|
|
1138
|
-
// src/types/tool.types.ts
|
|
1139
|
-
var ToolTypeValues = {
|
|
1140
|
-
TACTICAL_RMM: "TACTICAL_RMM",
|
|
1141
|
-
FLEET_MDM: "FLEET_MDM",
|
|
1142
|
-
MESHCENTRAL: "MESHCENTRAL",
|
|
1143
|
-
AUTHENTIK: "AUTHENTIK",
|
|
1144
|
-
OPENFRAME: "OPENFRAME",
|
|
1145
|
-
OPENFRAME_CHAT: "OPENFRAME_CHAT",
|
|
1146
|
-
OPENFRAME_CLIENT: "OPENFRAME_CLIENT",
|
|
1147
|
-
OSQUERY: "OSQUERY",
|
|
1148
|
-
SYSTEM: "SYSTEM"
|
|
1149
|
-
};
|
|
1150
|
-
var toolLabels = {
|
|
1151
|
-
TACTICAL_RMM: "Tactical",
|
|
1152
|
-
FLEET_MDM: "Fleet",
|
|
1153
|
-
MESHCENTRAL: "MeshCentral",
|
|
1154
|
-
AUTHENTIK: "Authentik",
|
|
1155
|
-
OPENFRAME: "OpenFrame",
|
|
1156
|
-
OPENFRAME_CHAT: "OpenFrame Chat",
|
|
1157
|
-
OPENFRAME_CLIENT: "OpenFrame Client",
|
|
1158
|
-
OSQUERY: "Osquery",
|
|
1159
|
-
SYSTEM: "System"
|
|
1160
|
-
};
|
|
1161
|
-
|
|
1162
885
|
// src/components/tool-icon.tsx
|
|
1163
|
-
import { Fragment, jsx
|
|
886
|
+
import { Fragment, jsx } from "react/jsx-runtime";
|
|
1164
887
|
var renderOpenFrameLogo = (_size, className) => (
|
|
1165
888
|
// eslint-disable-next-line deprecation/deprecation
|
|
1166
|
-
/* @__PURE__ */
|
|
889
|
+
/* @__PURE__ */ jsx(
|
|
1167
890
|
OpenFrameLogo,
|
|
1168
891
|
{
|
|
1169
892
|
className: className ?? "h-4 w-auto",
|
|
@@ -1173,22 +896,22 @@ var renderOpenFrameLogo = (_size, className) => (
|
|
|
1173
896
|
)
|
|
1174
897
|
);
|
|
1175
898
|
var toolIconMap = {
|
|
1176
|
-
[ToolTypeValues.FLEET_MDM]: (size, className) => /* @__PURE__ */
|
|
1177
|
-
[ToolTypeValues.MESHCENTRAL]: (size, className) => /* @__PURE__ */
|
|
1178
|
-
[ToolTypeValues.TACTICAL_RMM]: (size, className) => /* @__PURE__ */
|
|
899
|
+
[ToolTypeValues.FLEET_MDM]: (size, className) => /* @__PURE__ */ jsx(FleetMdmLogoGreyIcon, { size, className }),
|
|
900
|
+
[ToolTypeValues.MESHCENTRAL]: (size, className) => /* @__PURE__ */ jsx(MeshcentralLogoGreyIcon, { size, className }),
|
|
901
|
+
[ToolTypeValues.TACTICAL_RMM]: (size, className) => /* @__PURE__ */ jsx(TacticalRmmLogoIcon, { size, className }),
|
|
1179
902
|
[ToolTypeValues.OPENFRAME]: renderOpenFrameLogo,
|
|
1180
903
|
[ToolTypeValues.OPENFRAME_CHAT]: renderOpenFrameLogo,
|
|
1181
904
|
[ToolTypeValues.OPENFRAME_CLIENT]: renderOpenFrameLogo,
|
|
1182
|
-
[ToolTypeValues.AUTHENTIK]: (size, className) => /* @__PURE__ */
|
|
1183
|
-
[ToolTypeValues.OSQUERY]: (size, className) => /* @__PURE__ */
|
|
905
|
+
[ToolTypeValues.AUTHENTIK]: (size, className) => /* @__PURE__ */ jsx(AuthentikLogoGreyIcon, { size, className }),
|
|
906
|
+
[ToolTypeValues.OSQUERY]: (size, className) => /* @__PURE__ */ jsx(OsqueryLogoGreyIcon, { size, className }),
|
|
1184
907
|
[ToolTypeValues.SYSTEM]: () => null
|
|
1185
908
|
};
|
|
1186
|
-
var ToolIcon = ({ toolType, size = 16, className }) => /* @__PURE__ */
|
|
909
|
+
var ToolIcon = ({ toolType, size = 16, className }) => /* @__PURE__ */ jsx(Fragment, { children: toolIconMap[toolType]?.(size, className) ?? null });
|
|
1187
910
|
ToolIcon.displayName = "ToolIcon";
|
|
1188
911
|
|
|
1189
912
|
// src/components/ui/toaster.tsx
|
|
1190
913
|
init_cn();
|
|
1191
|
-
import { Fragment as Fragment2, jsx as
|
|
914
|
+
import { Fragment as Fragment2, jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
1192
915
|
var dotColorByVariant = {
|
|
1193
916
|
default: "bg-ods-text-secondary",
|
|
1194
917
|
success: "bg-ods-success",
|
|
@@ -1221,22 +944,22 @@ function ToastHeader({
|
|
|
1221
944
|
className
|
|
1222
945
|
),
|
|
1223
946
|
children: [
|
|
1224
|
-
/* @__PURE__ */
|
|
947
|
+
/* @__PURE__ */ jsx2("div", { className: "flex size-6 shrink-0 items-center justify-center", children: /* @__PURE__ */ jsx2("span", { className: cn("size-[9px] rounded-full", dotColorByVariant[variant]) }) }),
|
|
1225
948
|
/* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-1 flex-col justify-center font-['DM_Sans'] font-medium", children: [
|
|
1226
|
-
title ? /* @__PURE__ */
|
|
1227
|
-
description ? /* @__PURE__ */
|
|
949
|
+
title ? /* @__PURE__ */ jsx2("p", { className: "truncate pr-5 text-[18px] leading-6 text-ods-text-primary", title: typeof title === "string" ? title : void 0, children: title }) : null,
|
|
950
|
+
description ? /* @__PURE__ */ jsx2("p", { className: "text-[14px] leading-5 text-ods-text-secondary line-clamp-3", title: typeof description === "string" ? description : void 0, children: description }) : null
|
|
1228
951
|
] }),
|
|
1229
|
-
dismissible ? /* @__PURE__ */
|
|
952
|
+
dismissible ? /* @__PURE__ */ jsx2(
|
|
1230
953
|
"button",
|
|
1231
954
|
{
|
|
1232
955
|
type: "button",
|
|
1233
956
|
"aria-label": "Close",
|
|
1234
957
|
onClick: () => sonnerToast.dismiss(id),
|
|
1235
958
|
className: "absolute right-[7px] top-[7px] flex size-4 items-center justify-center text-ods-text-secondary transition-colors hover:text-ods-text-primary",
|
|
1236
|
-
children: /* @__PURE__ */
|
|
959
|
+
children: /* @__PURE__ */ jsx2(XmarkIcon, { size: 16 })
|
|
1237
960
|
}
|
|
1238
961
|
) : null,
|
|
1239
|
-
showProgress && duration !== Infinity && duration > 0 ? /* @__PURE__ */
|
|
962
|
+
showProgress && duration !== Infinity && duration > 0 ? /* @__PURE__ */ jsx2(
|
|
1240
963
|
"div",
|
|
1241
964
|
{
|
|
1242
965
|
className: cn(
|
|
@@ -1261,7 +984,7 @@ function ToastCard({
|
|
|
1261
984
|
dismissible = true,
|
|
1262
985
|
className
|
|
1263
986
|
}) {
|
|
1264
|
-
return /* @__PURE__ */
|
|
987
|
+
return /* @__PURE__ */ jsx2(
|
|
1265
988
|
"div",
|
|
1266
989
|
{
|
|
1267
990
|
role: "status",
|
|
@@ -1269,7 +992,7 @@ function ToastCard({
|
|
|
1269
992
|
"w-[368px] max-w-[calc(100vw-32px)] overflow-hidden rounded-md border border-ods-border bg-ods-card shadow-lg",
|
|
1270
993
|
className
|
|
1271
994
|
),
|
|
1272
|
-
children: /* @__PURE__ */
|
|
995
|
+
children: /* @__PURE__ */ jsx2(
|
|
1273
996
|
ToastHeader,
|
|
1274
997
|
{
|
|
1275
998
|
id,
|
|
@@ -1318,7 +1041,7 @@ function CommandApprovalToast({
|
|
|
1318
1041
|
className
|
|
1319
1042
|
),
|
|
1320
1043
|
children: [
|
|
1321
|
-
/* @__PURE__ */
|
|
1044
|
+
/* @__PURE__ */ jsx2(
|
|
1322
1045
|
ToastHeader,
|
|
1323
1046
|
{
|
|
1324
1047
|
id,
|
|
@@ -1331,7 +1054,7 @@ function CommandApprovalToast({
|
|
|
1331
1054
|
className: "border-b border-ods-border"
|
|
1332
1055
|
}
|
|
1333
1056
|
),
|
|
1334
|
-
/* @__PURE__ */
|
|
1057
|
+
/* @__PURE__ */ jsx2(
|
|
1335
1058
|
"div",
|
|
1336
1059
|
{
|
|
1337
1060
|
className: "grid transition-[grid-template-rows] duration-300 ease-out",
|
|
@@ -1339,13 +1062,13 @@ function CommandApprovalToast({
|
|
|
1339
1062
|
"aria-hidden": !expanded,
|
|
1340
1063
|
children: /* @__PURE__ */ jsxs("div", { className: "overflow-hidden", children: [
|
|
1341
1064
|
/* @__PURE__ */ jsxs("div", { className: "flex h-11 w-full items-center gap-2 border-b border-ods-border bg-ods-card px-3 py-2", children: [
|
|
1342
|
-
/* @__PURE__ */
|
|
1343
|
-
toolType ? /* @__PURE__ */
|
|
1065
|
+
/* @__PURE__ */ jsx2("p", { className: "min-w-0 flex-1 truncate font-['DM_Sans'] text-[14px] font-medium leading-5 text-ods-text-primary", title: command, children: command }),
|
|
1066
|
+
toolType ? /* @__PURE__ */ jsx2(ToolIcon, { toolType, size: 16 }) : null
|
|
1344
1067
|
] }),
|
|
1345
1068
|
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2 bg-ods-bg p-3", children: [
|
|
1346
|
-
approvalDescription ? /* @__PURE__ */
|
|
1069
|
+
approvalDescription ? /* @__PURE__ */ jsx2("p", { className: "font-['DM_Sans'] text-[14px] font-medium leading-5 text-ods-text-secondary", children: approvalDescription }) : null,
|
|
1347
1070
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-4", children: [
|
|
1348
|
-
/* @__PURE__ */
|
|
1071
|
+
/* @__PURE__ */ jsx2(
|
|
1349
1072
|
"button",
|
|
1350
1073
|
{
|
|
1351
1074
|
type: "button",
|
|
@@ -1355,7 +1078,7 @@ function CommandApprovalToast({
|
|
|
1355
1078
|
children: approveLabel
|
|
1356
1079
|
}
|
|
1357
1080
|
),
|
|
1358
|
-
/* @__PURE__ */
|
|
1081
|
+
/* @__PURE__ */ jsx2(
|
|
1359
1082
|
"button",
|
|
1360
1083
|
{
|
|
1361
1084
|
type: "button",
|
|
@@ -1378,8 +1101,8 @@ function CommandApprovalToast({
|
|
|
1378
1101
|
className: "flex w-full items-center gap-2 bg-ods-card px-3 py-2 text-left font-['DM_Sans'] text-[14px] font-medium leading-5 text-ods-text-primary transition-colors hover:bg-ods-bg-hover",
|
|
1379
1102
|
"aria-expanded": false,
|
|
1380
1103
|
children: [
|
|
1381
|
-
/* @__PURE__ */
|
|
1382
|
-
/* @__PURE__ */
|
|
1104
|
+
/* @__PURE__ */ jsx2("span", { className: "flex-1", children: "Show Command" }),
|
|
1105
|
+
/* @__PURE__ */ jsx2(Chevron02DownIcon, { size: 16 })
|
|
1383
1106
|
]
|
|
1384
1107
|
}
|
|
1385
1108
|
)
|
|
@@ -1396,13 +1119,13 @@ function Toaster({
|
|
|
1396
1119
|
} = {}) {
|
|
1397
1120
|
const { classNames: userClassNames, ...restToastOptions } = toastOptions ?? {};
|
|
1398
1121
|
return /* @__PURE__ */ jsxs(Fragment2, { children: [
|
|
1399
|
-
/* @__PURE__ */
|
|
1122
|
+
/* @__PURE__ */ jsx2("style", { children: `
|
|
1400
1123
|
@keyframes toast-progress {
|
|
1401
1124
|
from { transform: scaleX(1); }
|
|
1402
1125
|
to { transform: scaleX(0); }
|
|
1403
1126
|
}
|
|
1404
1127
|
` }),
|
|
1405
|
-
/* @__PURE__ */
|
|
1128
|
+
/* @__PURE__ */ jsx2(
|
|
1406
1129
|
SonnerToaster,
|
|
1407
1130
|
{
|
|
1408
1131
|
position,
|
|
@@ -1432,7 +1155,7 @@ function showToast(options) {
|
|
|
1432
1155
|
...rest
|
|
1433
1156
|
} = opts;
|
|
1434
1157
|
return sonnerToast.custom(
|
|
1435
|
-
(id) => /* @__PURE__ */
|
|
1158
|
+
(id) => /* @__PURE__ */ jsx2(
|
|
1436
1159
|
ToastCard,
|
|
1437
1160
|
{
|
|
1438
1161
|
id,
|
|
@@ -1464,7 +1187,7 @@ function showCommandApprovalToast(options) {
|
|
|
1464
1187
|
...rest
|
|
1465
1188
|
} = options;
|
|
1466
1189
|
return sonnerToast.custom(
|
|
1467
|
-
(id) => /* @__PURE__ */
|
|
1190
|
+
(id) => /* @__PURE__ */ jsx2(
|
|
1468
1191
|
CommandApprovalToast,
|
|
1469
1192
|
{
|
|
1470
1193
|
id,
|
|
@@ -1513,270 +1236,16 @@ var useToast = () => ({
|
|
|
1513
1236
|
});
|
|
1514
1237
|
|
|
1515
1238
|
// src/hooks/use-contact-submission.ts
|
|
1516
|
-
import { useState as
|
|
1239
|
+
import { useState as useState13, useCallback as useCallback6, useEffect as useEffect9 } from "react";
|
|
1517
1240
|
init_next_navigation();
|
|
1518
|
-
|
|
1519
|
-
// src/utils/local-storage-adapter.ts
|
|
1520
|
-
function getStorage(backend) {
|
|
1521
|
-
if (typeof window === "undefined") return null;
|
|
1522
|
-
try {
|
|
1523
|
-
return backend === "session" ? window.sessionStorage : window.localStorage;
|
|
1524
|
-
} catch {
|
|
1525
|
-
return null;
|
|
1526
|
-
}
|
|
1527
|
-
}
|
|
1528
|
-
function createLocalStorageAdapter(options) {
|
|
1529
|
-
const tag = options.logTag ?? "[local-storage]";
|
|
1530
|
-
const backend = options.backend ?? "local";
|
|
1531
|
-
const resolveKey = () => {
|
|
1532
|
-
const ns = options.namespace?.();
|
|
1533
|
-
return ns ? `${ns}.${options.key}` : options.key;
|
|
1534
|
-
};
|
|
1535
|
-
return {
|
|
1536
|
-
resolveKey,
|
|
1537
|
-
load() {
|
|
1538
|
-
const storage = getStorage(backend);
|
|
1539
|
-
if (!storage) return null;
|
|
1540
|
-
try {
|
|
1541
|
-
const raw = storage.getItem(resolveKey());
|
|
1542
|
-
if (!raw) return null;
|
|
1543
|
-
const parsed = JSON.parse(raw);
|
|
1544
|
-
if (options.validate && !options.validate(parsed)) return null;
|
|
1545
|
-
return parsed;
|
|
1546
|
-
} catch (err) {
|
|
1547
|
-
console.warn(`${tag} parse failed for key ${resolveKey()}:`, err);
|
|
1548
|
-
return null;
|
|
1549
|
-
}
|
|
1550
|
-
},
|
|
1551
|
-
save(value) {
|
|
1552
|
-
const storage = getStorage(backend);
|
|
1553
|
-
if (!storage) return;
|
|
1554
|
-
try {
|
|
1555
|
-
storage.setItem(resolveKey(), JSON.stringify(value));
|
|
1556
|
-
} catch (err) {
|
|
1557
|
-
console.warn(`${tag} write failed for key ${resolveKey()}:`, err);
|
|
1558
|
-
}
|
|
1559
|
-
},
|
|
1560
|
-
clear() {
|
|
1561
|
-
const storage = getStorage(backend);
|
|
1562
|
-
if (!storage) return;
|
|
1563
|
-
try {
|
|
1564
|
-
storage.removeItem(resolveKey());
|
|
1565
|
-
} catch (err) {
|
|
1566
|
-
console.warn(`${tag} clear failed for key ${resolveKey()}:`, err);
|
|
1567
|
-
}
|
|
1568
|
-
}
|
|
1569
|
-
};
|
|
1570
|
-
}
|
|
1571
|
-
|
|
1572
|
-
// src/utils/app-config.ts
|
|
1573
|
-
function getAppType() {
|
|
1574
|
-
return process.env.NEXT_PUBLIC_APP_TYPE || "openmsp";
|
|
1575
|
-
}
|
|
1576
|
-
|
|
1577
|
-
// src/utils/embed-proxy-auth-storage.ts
|
|
1578
|
-
function isValidPersistedAuth(value) {
|
|
1579
|
-
if (!value || typeof value !== "object") return false;
|
|
1580
|
-
const v = value;
|
|
1581
|
-
if (typeof v.secret !== "string" || v.secret.trim().length === 0 || typeof v.email !== "string" || v.email.trim().length === 0) return false;
|
|
1582
|
-
if (v.firstName != null && typeof v.firstName !== "string") return false;
|
|
1583
|
-
if (v.lastName != null && typeof v.lastName !== "string") return false;
|
|
1584
|
-
if (v.avatarUrl != null && typeof v.avatarUrl !== "string") return false;
|
|
1585
|
-
return true;
|
|
1586
|
-
}
|
|
1587
|
-
var adapter = createLocalStorageAdapter({
|
|
1588
|
-
// Storage key unchanged from the legacy chat-prefixed helper. Renaming
|
|
1589
|
-
// it would silently log every existing admin out — the key is a
|
|
1590
|
-
// storage contract, not a code identifier.
|
|
1591
|
-
key: "chat.proxy-auth.v1",
|
|
1592
|
-
namespace: () => getAppType(),
|
|
1593
|
-
validate: isValidPersistedAuth,
|
|
1594
|
-
logTag: "[embed-proxy-auth-storage]",
|
|
1595
|
-
// localStorage — survives tab close, new tabs, and browser restarts.
|
|
1596
|
-
// Admin re-pasting creds every tab cycle was the dev-experience
|
|
1597
|
-
// tradeoff prior `sessionStorage` setup demanded — rejected. See
|
|
1598
|
-
// file-level doc comment for the security tradeoff rationale.
|
|
1599
|
-
backend: "local"
|
|
1600
|
-
});
|
|
1601
|
-
function normalizeOptional(value) {
|
|
1602
|
-
if (!value) return void 0;
|
|
1603
|
-
const trimmed = value.trim();
|
|
1604
|
-
return trimmed.length > 0 ? trimmed : void 0;
|
|
1605
|
-
}
|
|
1606
|
-
function getEmbedProxyAuth() {
|
|
1607
|
-
const persisted = adapter.load();
|
|
1608
|
-
if (!persisted) return null;
|
|
1609
|
-
return {
|
|
1610
|
-
secret: persisted.secret,
|
|
1611
|
-
email: persisted.email.trim().toLowerCase(),
|
|
1612
|
-
firstName: normalizeOptional(persisted.firstName),
|
|
1613
|
-
lastName: normalizeOptional(persisted.lastName),
|
|
1614
|
-
avatarUrl: normalizeOptional(persisted.avatarUrl)
|
|
1615
|
-
};
|
|
1616
|
-
}
|
|
1617
|
-
function getPersistedProxyEmail() {
|
|
1618
|
-
const persisted = adapter.load();
|
|
1619
|
-
return persisted?.email.trim().toLowerCase() ?? null;
|
|
1620
|
-
}
|
|
1621
|
-
function setEmbedProxyAuth(value) {
|
|
1622
|
-
adapter.save({
|
|
1623
|
-
secret: value.secret,
|
|
1624
|
-
email: value.email.trim().toLowerCase(),
|
|
1625
|
-
firstName: normalizeOptional(value.firstName),
|
|
1626
|
-
lastName: normalizeOptional(value.lastName),
|
|
1627
|
-
avatarUrl: normalizeOptional(value.avatarUrl)
|
|
1628
|
-
});
|
|
1629
|
-
}
|
|
1630
|
-
function clearEmbedProxyAuth() {
|
|
1631
|
-
adapter.clear();
|
|
1632
|
-
}
|
|
1633
|
-
function applyProxyAuth(url, baseHeaders = { "Content-Type": "application/json" }) {
|
|
1634
|
-
const auth = getEmbedProxyAuth();
|
|
1635
|
-
const headers = { ...baseHeaders };
|
|
1636
|
-
if (auth?.secret) {
|
|
1637
|
-
headers.Authorization = `Bearer ${auth.secret}`;
|
|
1638
|
-
}
|
|
1639
|
-
if (auth?.email) {
|
|
1640
|
-
headers["X-Chat-Act-As"] = auth.email;
|
|
1641
|
-
}
|
|
1642
|
-
if (auth?.firstName) headers["X-Chat-First-Name"] = auth.firstName;
|
|
1643
|
-
if (auth?.lastName) headers["X-Chat-Last-Name"] = auth.lastName;
|
|
1644
|
-
if (auth?.avatarUrl) headers["X-Chat-Avatar-Url"] = auth.avatarUrl;
|
|
1645
|
-
return { url, headers };
|
|
1646
|
-
}
|
|
1647
|
-
|
|
1648
|
-
// src/utils/embed-authed-fetch.ts
|
|
1649
|
-
var ADAPTER_GLOBAL_KEY = "__embedAuthedFetchAdapter__";
|
|
1650
|
-
function getRegisteredAuthAdapter() {
|
|
1651
|
-
if (typeof globalThis === "undefined") return null;
|
|
1652
|
-
return globalThis[ADAPTER_GLOBAL_KEY] ?? null;
|
|
1653
|
-
}
|
|
1654
|
-
function storeRegisteredAuthAdapter(adapter2) {
|
|
1655
|
-
if (typeof globalThis === "undefined") return;
|
|
1656
|
-
globalThis[ADAPTER_GLOBAL_KEY] = adapter2;
|
|
1657
|
-
}
|
|
1658
|
-
function setEmbedAuthAdapter(adapter2) {
|
|
1659
|
-
if (adapter2 && getRegisteredAuthAdapter() && process.env.NODE_ENV !== "production") {
|
|
1660
|
-
console.warn(
|
|
1661
|
-
"[setEmbedAuthAdapter] overwriting a previously-registered auth adapter. Two chat-runtime providers should not coexist \u2014 verify mount order and pass `null` from the unmounting provider."
|
|
1662
|
-
);
|
|
1663
|
-
}
|
|
1664
|
-
storeRegisteredAuthAdapter(adapter2);
|
|
1665
|
-
}
|
|
1666
|
-
function hasEmbedAuthAdapter() {
|
|
1667
|
-
return getRegisteredAuthAdapter() !== null;
|
|
1668
|
-
}
|
|
1669
|
-
function embedAuthedFetch(url, init = {}) {
|
|
1670
|
-
assertSameOrigin(url);
|
|
1671
|
-
let baseHeaders;
|
|
1672
|
-
if (init.headers === void 0) {
|
|
1673
|
-
baseHeaders = { "Content-Type": "application/json" };
|
|
1674
|
-
} else {
|
|
1675
|
-
baseHeaders = {};
|
|
1676
|
-
if (init.headers instanceof Headers) {
|
|
1677
|
-
init.headers.forEach((v, k) => {
|
|
1678
|
-
baseHeaders[k] = v;
|
|
1679
|
-
});
|
|
1680
|
-
} else if (Array.isArray(init.headers)) {
|
|
1681
|
-
for (const [k, v] of init.headers) baseHeaders[k] = v;
|
|
1682
|
-
} else {
|
|
1683
|
-
Object.assign(baseHeaders, init.headers);
|
|
1684
|
-
}
|
|
1685
|
-
}
|
|
1686
|
-
return fetchWithRefresh(url, init, baseHeaders, false);
|
|
1687
|
-
}
|
|
1688
|
-
var IN_FLIGHT_REFRESH_GLOBAL_KEY = "__embedAuthedFetchInFlightRefresh__";
|
|
1689
|
-
function getInFlightRefresh() {
|
|
1690
|
-
if (typeof globalThis === "undefined") return null;
|
|
1691
|
-
return globalThis[IN_FLIGHT_REFRESH_GLOBAL_KEY] ?? null;
|
|
1692
|
-
}
|
|
1693
|
-
function setInFlightRefresh(refresh) {
|
|
1694
|
-
if (typeof globalThis === "undefined") return;
|
|
1695
|
-
globalThis[IN_FLIGHT_REFRESH_GLOBAL_KEY] = refresh;
|
|
1696
|
-
}
|
|
1697
|
-
function dedupedRefresh() {
|
|
1698
|
-
const adapter2 = getRegisteredAuthAdapter();
|
|
1699
|
-
if (!adapter2?.refresh) return Promise.resolve(false);
|
|
1700
|
-
let inFlightRefresh = getInFlightRefresh();
|
|
1701
|
-
if (!inFlightRefresh) {
|
|
1702
|
-
inFlightRefresh = Promise.resolve().then(() => adapter2.refresh()).catch(() => false).finally(() => {
|
|
1703
|
-
setInFlightRefresh(null);
|
|
1704
|
-
});
|
|
1705
|
-
setInFlightRefresh(inFlightRefresh);
|
|
1706
|
-
}
|
|
1707
|
-
return inFlightRefresh;
|
|
1708
|
-
}
|
|
1709
|
-
async function fetchWithRefresh(url, init, baseHeaders, isRetry) {
|
|
1710
|
-
const { url: authedUrl, headers } = applyProxyAuth(url, { ...baseHeaders });
|
|
1711
|
-
const adapter2 = getRegisteredAuthAdapter();
|
|
1712
|
-
if (adapter2?.getHeaders) {
|
|
1713
|
-
for (const [k, v] of Object.entries(adapter2.getHeaders())) {
|
|
1714
|
-
if (v !== void 0) headers[k] = v;
|
|
1715
|
-
}
|
|
1716
|
-
}
|
|
1717
|
-
const credentials = adapter2?.credentials ?? init.credentials ?? "same-origin";
|
|
1718
|
-
const response = await fetch(authedUrl, {
|
|
1719
|
-
...init,
|
|
1720
|
-
headers,
|
|
1721
|
-
// Default `same-origin` carries Supabase cookies for the MPH proxy-
|
|
1722
|
-
// auth model. Hosts on different origins (openframe-frontend ↔
|
|
1723
|
-
// openframe gateway) register `credentials: 'include'` via the
|
|
1724
|
-
// adapter to make their own cookies travel cross-origin (CORS +
|
|
1725
|
-
// `SameSite=None` must be configured server-side for that to work).
|
|
1726
|
-
credentials
|
|
1727
|
-
});
|
|
1728
|
-
if (response.status === 401 && !isRetry && adapter2?.refresh) {
|
|
1729
|
-
const refreshed = await dedupedRefresh();
|
|
1730
|
-
if (refreshed) {
|
|
1731
|
-
return fetchWithRefresh(url, init, baseHeaders, true);
|
|
1732
|
-
}
|
|
1733
|
-
}
|
|
1734
|
-
return response;
|
|
1735
|
-
}
|
|
1736
|
-
function assertSameOrigin(url) {
|
|
1737
|
-
if (typeof window === "undefined") return;
|
|
1738
|
-
let target;
|
|
1739
|
-
let pageOrigin;
|
|
1740
|
-
try {
|
|
1741
|
-
target = new URL(url, window.location.href);
|
|
1742
|
-
pageOrigin = new URL(window.location.href).origin;
|
|
1743
|
-
} catch {
|
|
1744
|
-
throw new Error(`embedAuthedFetch: refusing to fetch malformed URL (${JSON.stringify(url)})`);
|
|
1745
|
-
}
|
|
1746
|
-
if (target.protocol !== "http:" && target.protocol !== "https:") {
|
|
1747
|
-
throw new Error(
|
|
1748
|
-
`embedAuthedFetch: refusing non-http(s) URL (${target.protocol}) \u2014 pass a relative /api/* path instead`
|
|
1749
|
-
);
|
|
1750
|
-
}
|
|
1751
|
-
if (target.origin !== pageOrigin) {
|
|
1752
|
-
if (process.env.NODE_ENV !== "production") {
|
|
1753
|
-
console.warn(
|
|
1754
|
-
`[embedAuthedFetch] cross-origin fetch to ${target.origin} allowed in dev (NODE_ENV !== 'production'). Production builds will reject this \u2014 wire a same-origin proxy before shipping.`
|
|
1755
|
-
);
|
|
1756
|
-
return;
|
|
1757
|
-
}
|
|
1758
|
-
throw new Error(
|
|
1759
|
-
`embedAuthedFetch: refusing cross-origin fetch to ${target.origin} \u2014 pass a relative /api/* path instead`
|
|
1760
|
-
);
|
|
1761
|
-
}
|
|
1762
|
-
}
|
|
1763
|
-
|
|
1764
|
-
// src/utils/embed-content-fetch.ts
|
|
1765
|
-
var contentFetch = (input, init) => {
|
|
1766
|
-
if (!hasEmbedAuthAdapter()) return fetch(input, init);
|
|
1767
|
-
const url = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
|
|
1768
|
-
return embedAuthedFetch(url, init);
|
|
1769
|
-
};
|
|
1770
|
-
|
|
1771
|
-
// src/hooks/use-contact-submission.ts
|
|
1772
1241
|
function useContactSubmission(options = {}) {
|
|
1773
1242
|
const { userId, successRedirectUrl, successToastMessage, onSuccess } = options;
|
|
1774
1243
|
const { toast: toast2 } = useToast();
|
|
1775
1244
|
const router = useRouter();
|
|
1776
1245
|
const { contactUrl } = useRequiredEndpointsRuntime();
|
|
1777
|
-
const [isSubmitting, setIsSubmitting] =
|
|
1778
|
-
const [isSuccess, setIsSuccess] =
|
|
1779
|
-
const submit =
|
|
1246
|
+
const [isSubmitting, setIsSubmitting] = useState13(false);
|
|
1247
|
+
const [isSuccess, setIsSuccess] = useState13(false);
|
|
1248
|
+
const submit = useCallback6(async (formData) => {
|
|
1780
1249
|
if (isSubmitting) return;
|
|
1781
1250
|
setIsSubmitting(true);
|
|
1782
1251
|
try {
|
|
@@ -1811,7 +1280,7 @@ function useContactSubmission(options = {}) {
|
|
|
1811
1280
|
setIsSubmitting(false);
|
|
1812
1281
|
}
|
|
1813
1282
|
}, [isSubmitting, toast2, userId, successToastMessage, contactUrl]);
|
|
1814
|
-
|
|
1283
|
+
useEffect9(() => {
|
|
1815
1284
|
if (isSuccess && successRedirectUrl) {
|
|
1816
1285
|
console.log("\u{1F680} Contact submission successful, redirecting to:", successRedirectUrl);
|
|
1817
1286
|
const timer = setTimeout(() => {
|
|
@@ -1825,7 +1294,7 @@ function useContactSubmission(options = {}) {
|
|
|
1825
1294
|
return () => clearTimeout(timer);
|
|
1826
1295
|
}
|
|
1827
1296
|
}, [isSuccess, successRedirectUrl, router]);
|
|
1828
|
-
|
|
1297
|
+
useEffect9(() => {
|
|
1829
1298
|
if (isSuccess && onSuccess) {
|
|
1830
1299
|
onSuccess();
|
|
1831
1300
|
}
|
|
@@ -1834,19 +1303,19 @@ function useContactSubmission(options = {}) {
|
|
|
1834
1303
|
}
|
|
1835
1304
|
|
|
1836
1305
|
// src/hooks/use-quick-action-hint.ts
|
|
1837
|
-
import { useEffect as
|
|
1306
|
+
import { useEffect as useEffect10, useState as useState14, useRef as useRef5, useCallback as useCallback7 } from "react";
|
|
1838
1307
|
function useQuickActionHint({
|
|
1839
1308
|
actionCount,
|
|
1840
1309
|
cycleDuration = 5e3,
|
|
1841
1310
|
enabled = true
|
|
1842
1311
|
}) {
|
|
1843
|
-
const [activeHintIndex, setActiveHintIndex] =
|
|
1844
|
-
const containerRef =
|
|
1845
|
-
const timeoutRef =
|
|
1846
|
-
const cycleCountRef =
|
|
1847
|
-
const currentIndexRef =
|
|
1848
|
-
const sequenceRef =
|
|
1849
|
-
const shuffleIndices =
|
|
1312
|
+
const [activeHintIndex, setActiveHintIndex] = useState14(-1);
|
|
1313
|
+
const containerRef = useRef5(null);
|
|
1314
|
+
const timeoutRef = useRef5(null);
|
|
1315
|
+
const cycleCountRef = useRef5(0);
|
|
1316
|
+
const currentIndexRef = useRef5(0);
|
|
1317
|
+
const sequenceRef = useRef5([]);
|
|
1318
|
+
const shuffleIndices = useCallback7((length) => {
|
|
1850
1319
|
const indices = Array.from({ length }, (_, i) => i);
|
|
1851
1320
|
for (let i = indices.length - 1; i > 0; i--) {
|
|
1852
1321
|
const j = Math.floor(Math.random() * (i + 1));
|
|
@@ -1854,7 +1323,7 @@ function useQuickActionHint({
|
|
|
1854
1323
|
}
|
|
1855
1324
|
return indices;
|
|
1856
1325
|
}, []);
|
|
1857
|
-
const stopHint =
|
|
1326
|
+
const stopHint = useCallback7(() => {
|
|
1858
1327
|
if (timeoutRef.current) {
|
|
1859
1328
|
clearTimeout(timeoutRef.current);
|
|
1860
1329
|
timeoutRef.current = null;
|
|
@@ -1864,7 +1333,7 @@ function useQuickActionHint({
|
|
|
1864
1333
|
currentIndexRef.current = 0;
|
|
1865
1334
|
sequenceRef.current = [];
|
|
1866
1335
|
}, []);
|
|
1867
|
-
const advanceHint =
|
|
1336
|
+
const advanceHint = useCallback7(() => {
|
|
1868
1337
|
if (currentIndexRef.current === 0) {
|
|
1869
1338
|
sequenceRef.current = shuffleIndices(actionCount);
|
|
1870
1339
|
}
|
|
@@ -1877,7 +1346,7 @@ function useQuickActionHint({
|
|
|
1877
1346
|
}
|
|
1878
1347
|
timeoutRef.current = setTimeout(advanceHint, cycleDuration);
|
|
1879
1348
|
}, [actionCount, cycleDuration, shuffleIndices]);
|
|
1880
|
-
|
|
1349
|
+
useEffect10(() => {
|
|
1881
1350
|
if (!enabled || actionCount === 0) {
|
|
1882
1351
|
return;
|
|
1883
1352
|
}
|
|
@@ -1903,7 +1372,7 @@ function useQuickActionHint({
|
|
|
1903
1372
|
}
|
|
1904
1373
|
|
|
1905
1374
|
// src/hooks/use-copy-to-clipboard.ts
|
|
1906
|
-
import { useCallback as
|
|
1375
|
+
import { useCallback as useCallback8, useState as useState15 } from "react";
|
|
1907
1376
|
function useCopyToClipboard({
|
|
1908
1377
|
successTitle = "Copied",
|
|
1909
1378
|
successDescription = "Copied to clipboard",
|
|
@@ -1912,8 +1381,8 @@ function useCopyToClipboard({
|
|
|
1912
1381
|
resetDelay = 2e3
|
|
1913
1382
|
} = {}) {
|
|
1914
1383
|
const { toast: toast2 } = useToast();
|
|
1915
|
-
const [copied, setCopied] =
|
|
1916
|
-
const copy =
|
|
1384
|
+
const [copied, setCopied] = useState15(false);
|
|
1385
|
+
const copy = useCallback8(
|
|
1917
1386
|
async (text) => {
|
|
1918
1387
|
try {
|
|
1919
1388
|
await navigator.clipboard.writeText(text);
|
|
@@ -1930,7 +1399,7 @@ function useCopyToClipboard({
|
|
|
1930
1399
|
}
|
|
1931
1400
|
|
|
1932
1401
|
// src/hooks/use-batch-images.ts
|
|
1933
|
-
import { useEffect as
|
|
1402
|
+
import { useEffect as useEffect11, useMemo as useMemo2, useState as useState16, useRef as useRef6 } from "react";
|
|
1934
1403
|
var globalBatchImageConfig = {};
|
|
1935
1404
|
function configureBatchImageFetch(config) {
|
|
1936
1405
|
globalBatchImageConfig = { ...globalBatchImageConfig, ...config };
|
|
@@ -2003,14 +1472,14 @@ async function batchFetchAuthenticatedImages(imageUrls, config) {
|
|
|
2003
1472
|
return results;
|
|
2004
1473
|
}
|
|
2005
1474
|
function useBatchImages(imageUrls, config) {
|
|
2006
|
-
const [fetchedImages, setFetchedImages] =
|
|
2007
|
-
const [loading, setLoading] =
|
|
1475
|
+
const [fetchedImages, setFetchedImages] = useState16({});
|
|
1476
|
+
const [loading, setLoading] = useState16(false);
|
|
2008
1477
|
const uniqueUrls = useMemo2(
|
|
2009
1478
|
() => Array.from(new Set(imageUrls.filter((url) => Boolean(url)))),
|
|
2010
1479
|
[imageUrls]
|
|
2011
1480
|
);
|
|
2012
|
-
const requestedUrls =
|
|
2013
|
-
|
|
1481
|
+
const requestedUrls = useRef6(/* @__PURE__ */ new Set());
|
|
1482
|
+
useEffect11(() => {
|
|
2014
1483
|
if (uniqueUrls.length === 0) {
|
|
2015
1484
|
setFetchedImages({});
|
|
2016
1485
|
return;
|
|
@@ -2040,7 +1509,7 @@ function useBatchImages(imageUrls, config) {
|
|
|
2040
1509
|
}
|
|
2041
1510
|
|
|
2042
1511
|
// src/hooks/use-authenticated-image.ts
|
|
2043
|
-
import { useEffect as
|
|
1512
|
+
import { useEffect as useEffect12, useState as useState17, useRef as useRef7 } from "react";
|
|
2044
1513
|
var globalImageConfig = {};
|
|
2045
1514
|
var imageCache = /* @__PURE__ */ new Map();
|
|
2046
1515
|
var pendingRequests = /* @__PURE__ */ new Map();
|
|
@@ -2069,11 +1538,11 @@ function getImageConfig() {
|
|
|
2069
1538
|
};
|
|
2070
1539
|
}
|
|
2071
1540
|
function useAuthenticatedImage(imageUrl, refreshKey, config) {
|
|
2072
|
-
const [fetchedImageUrl, setFetchedImageUrl] =
|
|
2073
|
-
const [isLoading, setIsLoading] =
|
|
2074
|
-
const [error, setError] =
|
|
2075
|
-
const currentCacheKeyRef =
|
|
2076
|
-
|
|
1541
|
+
const [fetchedImageUrl, setFetchedImageUrl] = useState17();
|
|
1542
|
+
const [isLoading, setIsLoading] = useState17(false);
|
|
1543
|
+
const [error, setError] = useState17(null);
|
|
1544
|
+
const currentCacheKeyRef = useRef7(null);
|
|
1545
|
+
useEffect12(() => {
|
|
2077
1546
|
if (!imageUrl) {
|
|
2078
1547
|
setFetchedImageUrl(void 0);
|
|
2079
1548
|
setIsLoading(false);
|
|
@@ -2184,7 +1653,7 @@ function useAuthenticatedImage(imageUrl, refreshKey, config) {
|
|
|
2184
1653
|
});
|
|
2185
1654
|
pendingRequests.set(cacheKey, fetchPromise2);
|
|
2186
1655
|
}, [imageUrl, refreshKey, config]);
|
|
2187
|
-
|
|
1656
|
+
useEffect12(() => {
|
|
2188
1657
|
return () => {
|
|
2189
1658
|
if (currentCacheKeyRef.current) {
|
|
2190
1659
|
const entry = imageCache.get(currentCacheKeyRef.current);
|
|
@@ -2199,7 +1668,7 @@ function useAuthenticatedImage(imageUrl, refreshKey, config) {
|
|
|
2199
1668
|
|
|
2200
1669
|
// src/hooks/state/use-query-params.ts
|
|
2201
1670
|
init_next_navigation();
|
|
2202
|
-
import { useEffect as
|
|
1671
|
+
import { useEffect as useEffect13, useState as useState18, useMemo as useMemo3, useCallback as useCallback9 } from "react";
|
|
2203
1672
|
|
|
2204
1673
|
// src/hooks/state/graphql-parser.ts
|
|
2205
1674
|
import {
|
|
@@ -2661,14 +2130,14 @@ var introspector = new GraphQLIntrospector();
|
|
|
2661
2130
|
function useQueryParams(query, options = {}) {
|
|
2662
2131
|
const router = useRouter();
|
|
2663
2132
|
const searchParams = useSearchParams();
|
|
2664
|
-
const [isLoading, setIsLoading] =
|
|
2665
|
-
const [isReady, setIsReady] =
|
|
2666
|
-
const [error, setError] =
|
|
2667
|
-
const [schema, setSchema] =
|
|
2133
|
+
const [isLoading, setIsLoading] = useState18(true);
|
|
2134
|
+
const [isReady, setIsReady] = useState18(false);
|
|
2135
|
+
const [error, setError] = useState18(null);
|
|
2136
|
+
const [schema, setSchema] = useState18({});
|
|
2668
2137
|
const defaultValues = options.defaultValues || {};
|
|
2669
2138
|
const skipIntrospection = options.skipIntrospection || false;
|
|
2670
2139
|
const debug = options.debug || false;
|
|
2671
|
-
|
|
2140
|
+
useEffect13(() => {
|
|
2672
2141
|
async function initialize() {
|
|
2673
2142
|
try {
|
|
2674
2143
|
if (debug) console.log("[useQueryParams] Initializing...");
|
|
@@ -2738,14 +2207,14 @@ function useQueryParams(query, options = {}) {
|
|
|
2738
2207
|
});
|
|
2739
2208
|
return result;
|
|
2740
2209
|
}, [searchParams]);
|
|
2741
|
-
const updateUrl =
|
|
2210
|
+
const updateUrl = useCallback9((newParams) => {
|
|
2742
2211
|
const url = newParams.toString() ? `?${newParams.toString()}` : window.location.pathname;
|
|
2743
2212
|
if (debug) {
|
|
2744
2213
|
console.log("[useQueryParams] Updating URL:", url);
|
|
2745
2214
|
}
|
|
2746
2215
|
router.replace(url, { scroll: false });
|
|
2747
2216
|
}, [router, debug]);
|
|
2748
|
-
const setParam =
|
|
2217
|
+
const setParam = useCallback9((key, value) => {
|
|
2749
2218
|
if (!isReady) {
|
|
2750
2219
|
console.warn("[useQueryParams] Schema not ready, cannot set param");
|
|
2751
2220
|
return;
|
|
@@ -2759,7 +2228,7 @@ function useQueryParams(query, options = {}) {
|
|
|
2759
2228
|
console.error("[useQueryParams] Failed to set param:", err);
|
|
2760
2229
|
}
|
|
2761
2230
|
}, [variables, schema, isReady, updateUrl]);
|
|
2762
|
-
const setParams =
|
|
2231
|
+
const setParams = useCallback9((updates) => {
|
|
2763
2232
|
if (!isReady) {
|
|
2764
2233
|
console.warn("[useQueryParams] Schema not ready, cannot set params");
|
|
2765
2234
|
return;
|
|
@@ -2773,7 +2242,7 @@ function useQueryParams(query, options = {}) {
|
|
|
2773
2242
|
console.error("[useQueryParams] Failed to set params:", err);
|
|
2774
2243
|
}
|
|
2775
2244
|
}, [variables, schema, isReady, updateUrl]);
|
|
2776
|
-
const clearParamsHandler =
|
|
2245
|
+
const clearParamsHandler = useCallback9((keys) => {
|
|
2777
2246
|
if (!isReady) {
|
|
2778
2247
|
console.warn("[useQueryParams] Schema not ready, cannot clear params");
|
|
2779
2248
|
return;
|
|
@@ -2787,7 +2256,7 @@ function useQueryParams(query, options = {}) {
|
|
|
2787
2256
|
console.error("[useQueryParams] Failed to clear params:", err);
|
|
2788
2257
|
}
|
|
2789
2258
|
}, [variables, schema, isReady, updateUrl]);
|
|
2790
|
-
const resetParams =
|
|
2259
|
+
const resetParams = useCallback9(() => {
|
|
2791
2260
|
if (debug) {
|
|
2792
2261
|
console.log("[useQueryParams] Resetting params");
|
|
2793
2262
|
}
|
|
@@ -2820,9 +2289,9 @@ function applyParamMapping(schema, mapping) {
|
|
|
2820
2289
|
|
|
2821
2290
|
// src/hooks/state/use-api-params.ts
|
|
2822
2291
|
init_next_navigation();
|
|
2823
|
-
import { useCallback as
|
|
2292
|
+
import { useCallback as useCallback10, useMemo as useMemo4, useRef as useRef8 } from "react";
|
|
2824
2293
|
function useContentStable(value, key) {
|
|
2825
|
-
const ref =
|
|
2294
|
+
const ref = useRef8(void 0);
|
|
2826
2295
|
if (ref.current && ref.current.key === key) return ref.current.value;
|
|
2827
2296
|
ref.current = { value, key };
|
|
2828
2297
|
return value;
|
|
@@ -2855,7 +2324,7 @@ function useApiParams(schema, options = {}) {
|
|
|
2855
2324
|
}
|
|
2856
2325
|
return flattened;
|
|
2857
2326
|
}, [schemaKey]);
|
|
2858
|
-
const prevParamsRef =
|
|
2327
|
+
const prevParamsRef = useRef8(void 0);
|
|
2859
2328
|
const params = useMemo4(() => {
|
|
2860
2329
|
const sp = new URLSearchParams(searchString);
|
|
2861
2330
|
const result = {};
|
|
@@ -2879,7 +2348,7 @@ function useApiParams(schema, options = {}) {
|
|
|
2879
2348
|
prevParamsRef.current = result;
|
|
2880
2349
|
return result;
|
|
2881
2350
|
}, [searchString, schemaKey, debug]);
|
|
2882
|
-
const addParamToSearchParams =
|
|
2351
|
+
const addParamToSearchParams = useCallback10((searchParams, key, value) => {
|
|
2883
2352
|
if (value === void 0 || value === "" || value === null) {
|
|
2884
2353
|
return;
|
|
2885
2354
|
}
|
|
@@ -2907,7 +2376,7 @@ function useApiParams(schema, options = {}) {
|
|
|
2907
2376
|
}
|
|
2908
2377
|
return newParams;
|
|
2909
2378
|
}, [params, schemaKey, flattenedSchema, addParamToSearchParams]);
|
|
2910
|
-
const updateUrl =
|
|
2379
|
+
const updateUrl = useCallback10((newParams, keysToRemove = []) => {
|
|
2911
2380
|
const finalParams = new URLSearchParams(searchString);
|
|
2912
2381
|
keysToRemove.forEach((key) => {
|
|
2913
2382
|
if (key in stableSchema) {
|
|
@@ -2943,7 +2412,7 @@ function useApiParams(schema, options = {}) {
|
|
|
2943
2412
|
}
|
|
2944
2413
|
return false;
|
|
2945
2414
|
};
|
|
2946
|
-
const setParam =
|
|
2415
|
+
const setParam = useCallback10((key, value) => {
|
|
2947
2416
|
const config = stableSchema[key];
|
|
2948
2417
|
if (!config) {
|
|
2949
2418
|
console.warn(`[useApiParams] Unknown parameter: ${key}`);
|
|
@@ -2957,7 +2426,7 @@ function useApiParams(schema, options = {}) {
|
|
|
2957
2426
|
updateUrl(newParams);
|
|
2958
2427
|
}
|
|
2959
2428
|
}, [schemaKey, updateUrl, addParamToSearchParams]);
|
|
2960
|
-
const setParams =
|
|
2429
|
+
const setParams = useCallback10((updates) => {
|
|
2961
2430
|
const newParams = new URLSearchParams();
|
|
2962
2431
|
const keysToRemove = [];
|
|
2963
2432
|
for (const [key, value] of Object.entries(updates)) {
|
|
@@ -2974,11 +2443,11 @@ function useApiParams(schema, options = {}) {
|
|
|
2974
2443
|
}
|
|
2975
2444
|
updateUrl(newParams, keysToRemove);
|
|
2976
2445
|
}, [schemaKey, updateUrl, addParamToSearchParams]);
|
|
2977
|
-
const clearParams2 =
|
|
2446
|
+
const clearParams2 = useCallback10((keys) => {
|
|
2978
2447
|
const newParams = new URLSearchParams();
|
|
2979
2448
|
updateUrl(newParams, keys);
|
|
2980
2449
|
}, [updateUrl]);
|
|
2981
|
-
const resetParams =
|
|
2450
|
+
const resetParams = useCallback10(() => {
|
|
2982
2451
|
if (debug) {
|
|
2983
2452
|
console.log("[useApiParams] Resetting params");
|
|
2984
2453
|
}
|
|
@@ -3015,7 +2484,7 @@ function createSearchParams(params) {
|
|
|
3015
2484
|
}
|
|
3016
2485
|
|
|
3017
2486
|
// src/hooks/state/use-cursor-pagination-state.ts
|
|
3018
|
-
import { useCallback as
|
|
2487
|
+
import { useCallback as useCallback11, useEffect as useEffect14, useRef as useRef9, useState as useState19 } from "react";
|
|
3019
2488
|
var urlSchema = {
|
|
3020
2489
|
search: { type: "string", default: "" },
|
|
3021
2490
|
cursor: { type: "string", default: "" }
|
|
@@ -3026,13 +2495,13 @@ function useCursorPaginationState(options) {
|
|
|
3026
2495
|
onSearchChange
|
|
3027
2496
|
} = options;
|
|
3028
2497
|
const { params, setParam, setParams } = useApiParams(urlSchema);
|
|
3029
|
-
const [searchInput, setSearchInput] =
|
|
3030
|
-
const [hasLoadedBeyondFirst, setHasLoadedBeyondFirst] =
|
|
3031
|
-
const [initialLoadCount, setInitialLoadCount] =
|
|
3032
|
-
const lastSearchRef =
|
|
3033
|
-
const isSyncingFromUrl =
|
|
3034
|
-
const isInitialLoadInProgress =
|
|
3035
|
-
|
|
2498
|
+
const [searchInput, setSearchInput] = useState19(params.search || "");
|
|
2499
|
+
const [hasLoadedBeyondFirst, setHasLoadedBeyondFirst] = useState19(false);
|
|
2500
|
+
const [initialLoadCount, setInitialLoadCount] = useState19(0);
|
|
2501
|
+
const lastSearchRef = useRef9(null);
|
|
2502
|
+
const isSyncingFromUrl = useRef9(false);
|
|
2503
|
+
const isInitialLoadInProgress = useRef9(true);
|
|
2504
|
+
useEffect14(() => {
|
|
3036
2505
|
if (isInitialLoadInProgress.current) return;
|
|
3037
2506
|
const urlSearch = params.search || "";
|
|
3038
2507
|
if (urlSearch !== searchInput) {
|
|
@@ -3043,7 +2512,7 @@ function useCursorPaginationState(options) {
|
|
|
3043
2512
|
}, 0);
|
|
3044
2513
|
}
|
|
3045
2514
|
}, [params.search, initialLoadCount]);
|
|
3046
|
-
|
|
2515
|
+
useEffect14(() => {
|
|
3047
2516
|
if (isInitialLoadInProgress.current) return;
|
|
3048
2517
|
if (isSyncingFromUrl.current) return;
|
|
3049
2518
|
if (searchInput !== params.search) {
|
|
@@ -3054,7 +2523,7 @@ function useCursorPaginationState(options) {
|
|
|
3054
2523
|
});
|
|
3055
2524
|
}
|
|
3056
2525
|
}, [searchInput, params.search, setParams, initialLoadCount]);
|
|
3057
|
-
|
|
2526
|
+
useEffect14(() => {
|
|
3058
2527
|
if (initialLoadCount === 0) {
|
|
3059
2528
|
const cursor = params.cursor || null;
|
|
3060
2529
|
const search = params.search || "";
|
|
@@ -3068,7 +2537,7 @@ function useCursorPaginationState(options) {
|
|
|
3068
2537
|
});
|
|
3069
2538
|
}
|
|
3070
2539
|
}, []);
|
|
3071
|
-
|
|
2540
|
+
useEffect14(() => {
|
|
3072
2541
|
if (isInitialLoadInProgress.current) return;
|
|
3073
2542
|
if (initialLoadCount === 0) return;
|
|
3074
2543
|
const currentSearch = params.search || "";
|
|
@@ -3078,7 +2547,7 @@ function useCursorPaginationState(options) {
|
|
|
3078
2547
|
onSearchChange(currentSearch);
|
|
3079
2548
|
}
|
|
3080
2549
|
}, [params.search, onSearchChange, initialLoadCount]);
|
|
3081
|
-
const handleNextPage =
|
|
2550
|
+
const handleNextPage = useCallback11(
|
|
3082
2551
|
async (endCursor, fetchFn) => {
|
|
3083
2552
|
setParam("cursor", endCursor);
|
|
3084
2553
|
await fetchFn();
|
|
@@ -3086,7 +2555,7 @@ function useCursorPaginationState(options) {
|
|
|
3086
2555
|
},
|
|
3087
2556
|
[setParam]
|
|
3088
2557
|
);
|
|
3089
|
-
const handleResetToFirstPage =
|
|
2558
|
+
const handleResetToFirstPage = useCallback11(
|
|
3090
2559
|
async (fetchFn) => {
|
|
3091
2560
|
setParam("cursor", "");
|
|
3092
2561
|
await fetchFn();
|
|
@@ -3108,16 +2577,16 @@ function useCursorPaginationState(options) {
|
|
|
3108
2577
|
}
|
|
3109
2578
|
|
|
3110
2579
|
// src/hooks/nats/use-nats-client.ts
|
|
3111
|
-
import { useEffect as
|
|
2580
|
+
import { useEffect as useEffect15, useMemo as useMemo5, useState as useState20 } from "react";
|
|
3112
2581
|
function useNatsClient(clientOptions, options = {}) {
|
|
3113
2582
|
const { autoConnect = true } = options;
|
|
3114
2583
|
const client = useMemo5(() => {
|
|
3115
2584
|
if (!clientOptions) return null;
|
|
3116
2585
|
return createNatsClient(clientOptions);
|
|
3117
2586
|
}, [clientOptions]);
|
|
3118
|
-
const [status, setStatus] =
|
|
3119
|
-
const [lastError, setLastError] =
|
|
3120
|
-
|
|
2587
|
+
const [status, setStatus] = useState20("disconnected");
|
|
2588
|
+
const [lastError, setLastError] = useState20(null);
|
|
2589
|
+
useEffect15(() => {
|
|
3121
2590
|
if (!client) {
|
|
3122
2591
|
setStatus("disconnected");
|
|
3123
2592
|
setLastError(null);
|
|
@@ -3147,125 +2616,8 @@ function useNatsClient(clientOptions, options = {}) {
|
|
|
3147
2616
|
};
|
|
3148
2617
|
}
|
|
3149
2618
|
|
|
3150
|
-
// src/hooks/use-near-viewport.ts
|
|
3151
|
-
import { useEffect as useEffect18, useRef as useRef11, useState as useState23, useCallback as useCallback13 } from "react";
|
|
3152
|
-
var observers = /* @__PURE__ */ new Map();
|
|
3153
|
-
var subscribers = /* @__PURE__ */ new WeakMap();
|
|
3154
|
-
function getObserverFor(rootMargin) {
|
|
3155
|
-
const existing = observers.get(rootMargin);
|
|
3156
|
-
if (existing) return existing;
|
|
3157
|
-
const io = new IntersectionObserver(
|
|
3158
|
-
(entries) => {
|
|
3159
|
-
entries.forEach((entry) => {
|
|
3160
|
-
if (!entry.isIntersecting) return;
|
|
3161
|
-
const cb = subscribers.get(entry.target);
|
|
3162
|
-
if (cb) {
|
|
3163
|
-
cb();
|
|
3164
|
-
io.unobserve(entry.target);
|
|
3165
|
-
subscribers.delete(entry.target);
|
|
3166
|
-
}
|
|
3167
|
-
});
|
|
3168
|
-
},
|
|
3169
|
-
{ rootMargin }
|
|
3170
|
-
);
|
|
3171
|
-
observers.set(rootMargin, io);
|
|
3172
|
-
return io;
|
|
3173
|
-
}
|
|
3174
|
-
function useNearViewport(rootMargin = "500px") {
|
|
3175
|
-
const [isNear, setIsNear] = useState23(false);
|
|
3176
|
-
const elRef = useRef11(null);
|
|
3177
|
-
const ref = useCallback13(
|
|
3178
|
-
(node) => {
|
|
3179
|
-
const prev = elRef.current;
|
|
3180
|
-
if (prev) {
|
|
3181
|
-
const stillOurs = subscribers.get(prev);
|
|
3182
|
-
if (stillOurs) {
|
|
3183
|
-
subscribers.delete(prev);
|
|
3184
|
-
observers.get(rootMargin)?.unobserve(prev);
|
|
3185
|
-
}
|
|
3186
|
-
}
|
|
3187
|
-
elRef.current = node;
|
|
3188
|
-
if (!node) return;
|
|
3189
|
-
const cb = () => setIsNear(true);
|
|
3190
|
-
subscribers.set(node, cb);
|
|
3191
|
-
getObserverFor(rootMargin).observe(node);
|
|
3192
|
-
},
|
|
3193
|
-
[rootMargin]
|
|
3194
|
-
);
|
|
3195
|
-
useEffect18(() => {
|
|
3196
|
-
return () => {
|
|
3197
|
-
const el = elRef.current;
|
|
3198
|
-
if (!el) return;
|
|
3199
|
-
if (subscribers.get(el)) {
|
|
3200
|
-
subscribers.delete(el);
|
|
3201
|
-
observers.get(rootMargin)?.unobserve(el);
|
|
3202
|
-
}
|
|
3203
|
-
};
|
|
3204
|
-
}, [rootMargin]);
|
|
3205
|
-
return { ref, isNear };
|
|
3206
|
-
}
|
|
3207
|
-
|
|
3208
2619
|
// src/hooks/use-access-code-integration.ts
|
|
3209
2620
|
import React2 from "react";
|
|
3210
|
-
|
|
3211
|
-
// src/utils/access-code-client.ts
|
|
3212
|
-
async function validateAccessCode(email, code, endpoints) {
|
|
3213
|
-
try {
|
|
3214
|
-
const response = await fetch(endpoints.validateUrl, {
|
|
3215
|
-
method: "POST",
|
|
3216
|
-
headers: {
|
|
3217
|
-
"Content-Type": "application/json"
|
|
3218
|
-
},
|
|
3219
|
-
body: JSON.stringify({ email, code })
|
|
3220
|
-
});
|
|
3221
|
-
if (!response.ok) {
|
|
3222
|
-
const error = await response.json().catch(() => ({}));
|
|
3223
|
-
throw new Error(error.error || "Validation request failed");
|
|
3224
|
-
}
|
|
3225
|
-
return await response.json();
|
|
3226
|
-
} catch (error) {
|
|
3227
|
-
return {
|
|
3228
|
-
valid: false,
|
|
3229
|
-
message: error instanceof Error ? error.message : "Validation failed"
|
|
3230
|
-
};
|
|
3231
|
-
}
|
|
3232
|
-
}
|
|
3233
|
-
async function consumeAccessCode(email, code, endpoints) {
|
|
3234
|
-
try {
|
|
3235
|
-
const response = await fetch(endpoints.consumeUrl, {
|
|
3236
|
-
method: "POST",
|
|
3237
|
-
headers: {
|
|
3238
|
-
"Content-Type": "application/json"
|
|
3239
|
-
},
|
|
3240
|
-
body: JSON.stringify({ email, code })
|
|
3241
|
-
});
|
|
3242
|
-
if (!response.ok) {
|
|
3243
|
-
const error = await response.json().catch(() => ({}));
|
|
3244
|
-
throw new Error(error.error || "Consumption request failed");
|
|
3245
|
-
}
|
|
3246
|
-
return await response.json();
|
|
3247
|
-
} catch (error) {
|
|
3248
|
-
return {
|
|
3249
|
-
success: false,
|
|
3250
|
-
consumed: false,
|
|
3251
|
-
message: error instanceof Error ? error.message : "Consumption failed"
|
|
3252
|
-
};
|
|
3253
|
-
}
|
|
3254
|
-
}
|
|
3255
|
-
async function validateAndConsumeAccessCode(email, code, endpoints) {
|
|
3256
|
-
const validation = await validateAccessCode(email, code, endpoints);
|
|
3257
|
-
if (!validation.valid) {
|
|
3258
|
-
return validation;
|
|
3259
|
-
}
|
|
3260
|
-
const consumption = await consumeAccessCode(email, code, endpoints);
|
|
3261
|
-
return {
|
|
3262
|
-
...validation,
|
|
3263
|
-
consumed: consumption.consumed,
|
|
3264
|
-
message: consumption.consumed ? `Access granted for ${validation.cohort_name}` : consumption.message || validation.message
|
|
3265
|
-
};
|
|
3266
|
-
}
|
|
3267
|
-
|
|
3268
|
-
// src/hooks/use-access-code-integration.ts
|
|
3269
2621
|
function useAccessCodeIntegration() {
|
|
3270
2622
|
const runtime = useRequiredEndpointsRuntime();
|
|
3271
2623
|
const endpoints = runtime.accessCode;
|
|
@@ -3307,158 +2659,12 @@ function useAccessCodeIntegration() {
|
|
|
3307
2659
|
};
|
|
3308
2660
|
}
|
|
3309
2661
|
|
|
3310
|
-
// src/hooks/use-og-placeholder.ts
|
|
3311
|
-
import { useMemo as useMemo6 } from "react";
|
|
3312
|
-
function useOgPlaceholder(buildUrl, title, siteName = "", enabled = true, aspect = "wide") {
|
|
3313
|
-
return useMemo6(() => {
|
|
3314
|
-
if (!enabled || !title) return null;
|
|
3315
|
-
const options = {};
|
|
3316
|
-
if (siteName) options.site = siteName;
|
|
3317
|
-
if (aspect === "square") options.aspect = "square";
|
|
3318
|
-
return buildUrl(title, options);
|
|
3319
|
-
}, [buildUrl, title, siteName, enabled, aspect]);
|
|
3320
|
-
}
|
|
3321
|
-
|
|
3322
|
-
// src/hooks/use-scroll-to-hash.ts
|
|
3323
|
-
import { useEffect as useEffect19 } from "react";
|
|
3324
|
-
|
|
3325
|
-
// src/utils/scroll-into-view.ts
|
|
3326
|
-
var activeRaf = 0;
|
|
3327
|
-
var teardownActive = null;
|
|
3328
|
-
function cancelActiveScroll() {
|
|
3329
|
-
if (activeRaf) {
|
|
3330
|
-
cancelAnimationFrame(activeRaf);
|
|
3331
|
-
activeRaf = 0;
|
|
3332
|
-
}
|
|
3333
|
-
if (teardownActive) {
|
|
3334
|
-
teardownActive();
|
|
3335
|
-
teardownActive = null;
|
|
3336
|
-
}
|
|
3337
|
-
}
|
|
3338
|
-
var easeOutCubic = (t) => 1 - Math.pow(1 - t, 3);
|
|
3339
|
-
function getScrollableAncestor(el) {
|
|
3340
|
-
for (let node = el.parentElement; node; node = node.parentElement) {
|
|
3341
|
-
const overflowY = getComputedStyle(node).overflowY;
|
|
3342
|
-
if ((overflowY === "auto" || overflowY === "scroll" || overflowY === "overlay") && node.scrollHeight > node.clientHeight) {
|
|
3343
|
-
return node;
|
|
3344
|
-
}
|
|
3345
|
-
}
|
|
3346
|
-
return null;
|
|
3347
|
-
}
|
|
3348
|
-
function scrollElementIntoView(target, options = {}) {
|
|
3349
|
-
if (typeof window === "undefined" || !target) return;
|
|
3350
|
-
const { headerOffset = 0, behavior = "smooth", adjustTargetY, durationMs = 320 } = options;
|
|
3351
|
-
const container = getScrollableAncestor(target);
|
|
3352
|
-
const readCurrent = () => container ? container.scrollTop : window.scrollY;
|
|
3353
|
-
const writeTo = (y) => {
|
|
3354
|
-
if (container) container.scrollTop = y;
|
|
3355
|
-
else window.scrollTo(0, y);
|
|
3356
|
-
};
|
|
3357
|
-
const computeTarget = () => {
|
|
3358
|
-
const raw = container ? container.scrollTop + (target.getBoundingClientRect().top - container.getBoundingClientRect().top) - headerOffset : target.getBoundingClientRect().top + window.scrollY - headerOffset;
|
|
3359
|
-
const adjusted = adjustTargetY ? adjustTargetY(raw) : raw;
|
|
3360
|
-
const maxScroll = container ? Math.max(0, container.scrollHeight - container.clientHeight) : Math.max(0, document.documentElement.scrollHeight - window.innerHeight);
|
|
3361
|
-
return Math.min(Math.max(0, adjusted), maxScroll);
|
|
3362
|
-
};
|
|
3363
|
-
cancelActiveScroll();
|
|
3364
|
-
const prefersReduced = typeof window.matchMedia === "function" && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
3365
|
-
if (behavior === "instant" || behavior === "auto" || prefersReduced) {
|
|
3366
|
-
writeTo(computeTarget());
|
|
3367
|
-
return;
|
|
3368
|
-
}
|
|
3369
|
-
let startY = null;
|
|
3370
|
-
let startTime = 0;
|
|
3371
|
-
const onUserGesture = () => cancelActiveScroll();
|
|
3372
|
-
window.addEventListener("wheel", onUserGesture, { passive: true });
|
|
3373
|
-
window.addEventListener("touchmove", onUserGesture, { passive: true });
|
|
3374
|
-
teardownActive = () => {
|
|
3375
|
-
window.removeEventListener("wheel", onUserGesture);
|
|
3376
|
-
window.removeEventListener("touchmove", onUserGesture);
|
|
3377
|
-
};
|
|
3378
|
-
const step = (now) => {
|
|
3379
|
-
if (startY === null) {
|
|
3380
|
-
startY = readCurrent();
|
|
3381
|
-
startTime = now;
|
|
3382
|
-
}
|
|
3383
|
-
const targetY = computeTarget();
|
|
3384
|
-
const t = Math.min(1, (now - startTime) / durationMs);
|
|
3385
|
-
const y = startY + (targetY - startY) * easeOutCubic(t);
|
|
3386
|
-
writeTo(y);
|
|
3387
|
-
if (t < 1) {
|
|
3388
|
-
activeRaf = requestAnimationFrame(step);
|
|
3389
|
-
} else {
|
|
3390
|
-
writeTo(computeTarget());
|
|
3391
|
-
activeRaf = 0;
|
|
3392
|
-
if (teardownActive) {
|
|
3393
|
-
teardownActive();
|
|
3394
|
-
teardownActive = null;
|
|
3395
|
-
}
|
|
3396
|
-
}
|
|
3397
|
-
};
|
|
3398
|
-
activeRaf = requestAnimationFrame(step);
|
|
3399
|
-
}
|
|
3400
|
-
|
|
3401
|
-
// src/utils/same-page-hash-nav.ts
|
|
3402
|
-
var STICKY_HEADER_OFFSET_PX = 96;
|
|
3403
|
-
var HUB_HEADER_OFFSET_PX = 80;
|
|
3404
|
-
function normalizeHashFragment(hash) {
|
|
3405
|
-
if (!hash) return "";
|
|
3406
|
-
const second = hash.indexOf("#", 1);
|
|
3407
|
-
return second < 0 ? hash : hash.slice(0, second);
|
|
3408
|
-
}
|
|
3409
|
-
function navigateSamePageHash(target, options = {}) {
|
|
3410
|
-
if (typeof window === "undefined") return false;
|
|
3411
|
-
const { headerOffset = 0, history: historyMode = "push" } = options;
|
|
3412
|
-
const normalizedTarget = target.startsWith("#") ? window.location.pathname + window.location.search + target : target;
|
|
3413
|
-
let url;
|
|
3414
|
-
try {
|
|
3415
|
-
url = new URL(normalizedTarget, window.location.href);
|
|
3416
|
-
} catch {
|
|
3417
|
-
return false;
|
|
3418
|
-
}
|
|
3419
|
-
if (url.origin !== window.location.origin || url.pathname !== window.location.pathname || url.search !== window.location.search) {
|
|
3420
|
-
return false;
|
|
3421
|
-
}
|
|
3422
|
-
const current = window.location.pathname + window.location.search + window.location.hash;
|
|
3423
|
-
const normalizedHash = normalizeHashFragment(url.hash);
|
|
3424
|
-
if (process.env.NODE_ENV === "development" && normalizedHash !== url.hash) {
|
|
3425
|
-
console.warn(
|
|
3426
|
-
`[navigateSamePageHash] malformed fragment "${url.hash}" \u2192 normalizing to "${normalizedHash}". Fix the upstream composer.`
|
|
3427
|
-
);
|
|
3428
|
-
}
|
|
3429
|
-
const next = url.pathname + url.search + normalizedHash;
|
|
3430
|
-
const id = normalizedHash && normalizedHash !== "#" ? normalizedHash.slice(1) : "";
|
|
3431
|
-
if (!id && next !== current) return false;
|
|
3432
|
-
if (next !== current) {
|
|
3433
|
-
const oldURL = window.location.href;
|
|
3434
|
-
if (historyMode === "replace") {
|
|
3435
|
-
window.history.replaceState(null, "", next);
|
|
3436
|
-
} else {
|
|
3437
|
-
window.history.pushState(null, "", next);
|
|
3438
|
-
}
|
|
3439
|
-
window.dispatchEvent(new HashChangeEvent("hashchange", {
|
|
3440
|
-
oldURL,
|
|
3441
|
-
newURL: window.location.href
|
|
3442
|
-
}));
|
|
3443
|
-
}
|
|
3444
|
-
const el = id ? document.getElementById(id) : null;
|
|
3445
|
-
if (id && !el && process.env.NODE_ENV === "development") {
|
|
3446
|
-
console.warn(
|
|
3447
|
-
`[navigateSamePageHash] anchor "#${id}" not found \u2014 scrolling to top.`
|
|
3448
|
-
);
|
|
3449
|
-
}
|
|
3450
|
-
scrollElementIntoView(el ?? document.documentElement, {
|
|
3451
|
-
behavior: "smooth",
|
|
3452
|
-
headerOffset
|
|
3453
|
-
});
|
|
3454
|
-
return true;
|
|
3455
|
-
}
|
|
3456
|
-
|
|
3457
2662
|
// src/hooks/use-scroll-to-hash.ts
|
|
2663
|
+
import { useEffect as useEffect16 } from "react";
|
|
3458
2664
|
var MAX_POLL_FRAMES = 60;
|
|
3459
2665
|
function useScrollToHash(readyDep = true, options) {
|
|
3460
2666
|
const headerOffset = options?.headerOffset ?? 0;
|
|
3461
|
-
|
|
2667
|
+
useEffect16(() => {
|
|
3462
2668
|
if (typeof window === "undefined") return;
|
|
3463
2669
|
if (readyDep === null || readyDep === false) return;
|
|
3464
2670
|
let rafId = null;
|
|
@@ -3498,40 +2704,18 @@ function useScrollToHash(readyDep = true, options) {
|
|
|
3498
2704
|
}
|
|
3499
2705
|
|
|
3500
2706
|
// src/hooks/use-humanity-signals.ts
|
|
3501
|
-
import { useCallback as
|
|
3502
|
-
|
|
3503
|
-
// src/utils/humanity-signals.ts
|
|
3504
|
-
var HONEYPOT_FIELD = "contact_url_confirm";
|
|
3505
|
-
var ELAPSED_MS_FIELD = "form_elapsed_ms";
|
|
3506
|
-
var DEFAULT_MIN_FILL_MS = 700;
|
|
3507
|
-
function extractHumanitySignals(body) {
|
|
3508
|
-
const b = body ?? {};
|
|
3509
|
-
const rawHp = b[HONEYPOT_FIELD];
|
|
3510
|
-
const honeypot = rawHp == null ? "" : String(rawHp);
|
|
3511
|
-
const rawMs = b[ELAPSED_MS_FIELD];
|
|
3512
|
-
const elapsedMs = typeof rawMs === "number" && Number.isFinite(rawMs) ? rawMs : null;
|
|
3513
|
-
return { honeypot, elapsedMs };
|
|
3514
|
-
}
|
|
3515
|
-
function evaluateHumanitySignals(body, opts) {
|
|
3516
|
-
const { honeypot, elapsedMs } = extractHumanitySignals(body);
|
|
3517
|
-
if (honeypot.trim() !== "") return { ok: false, reason: "honeypot" };
|
|
3518
|
-
if (elapsedMs !== null && elapsedMs < opts.minFillMs) return { ok: false, reason: "too_fast" };
|
|
3519
|
-
return { ok: true };
|
|
3520
|
-
}
|
|
3521
|
-
var splitCsvEnv = (s) => s?.split(",").map((t) => t.trim()).filter(Boolean) ?? [];
|
|
3522
|
-
|
|
3523
|
-
// src/hooks/use-humanity-signals.ts
|
|
2707
|
+
import { useCallback as useCallback12, useRef as useRef10 } from "react";
|
|
3524
2708
|
function useHumanitySignals() {
|
|
3525
|
-
const ref =
|
|
3526
|
-
const mountedAt =
|
|
3527
|
-
const getSignals =
|
|
2709
|
+
const ref = useRef10(null);
|
|
2710
|
+
const mountedAt = useRef10(typeof performance !== "undefined" ? performance.now() : 0);
|
|
2711
|
+
const getSignals = useCallback12(
|
|
3528
2712
|
() => ({
|
|
3529
2713
|
[HONEYPOT_FIELD]: ref.current?.value ?? "",
|
|
3530
2714
|
[ELAPSED_MS_FIELD]: typeof performance !== "undefined" ? Math.round(performance.now() - mountedAt.current) : 0
|
|
3531
2715
|
}),
|
|
3532
2716
|
[]
|
|
3533
2717
|
);
|
|
3534
|
-
const resetSignals =
|
|
2718
|
+
const resetSignals = useCallback12(() => {
|
|
3535
2719
|
if (ref.current) ref.current.value = "";
|
|
3536
2720
|
if (typeof performance !== "undefined") mountedAt.current = performance.now();
|
|
3537
2721
|
}, []);
|
|
@@ -3539,8 +2723,6 @@ function useHumanitySignals() {
|
|
|
3539
2723
|
}
|
|
3540
2724
|
|
|
3541
2725
|
export {
|
|
3542
|
-
useAutoLimitTags,
|
|
3543
|
-
useDebounce,
|
|
3544
2726
|
useHeaderHeight,
|
|
3545
2727
|
useHorizontalScrollbar,
|
|
3546
2728
|
useImageEdgeColor,
|
|
@@ -3557,28 +2739,9 @@ export {
|
|
|
3557
2739
|
useTablePagination,
|
|
3558
2740
|
useThrottle,
|
|
3559
2741
|
useWindowSize,
|
|
3560
|
-
platformIcons,
|
|
3561
|
-
platformColors,
|
|
3562
|
-
platformDisplayNames,
|
|
3563
|
-
platformDescriptions,
|
|
3564
|
-
platformSlogans,
|
|
3565
|
-
platformHexColors,
|
|
3566
|
-
platformIconNames,
|
|
3567
|
-
getDefaultColorForPlatform,
|
|
3568
|
-
getDefaultIconForPlatform,
|
|
3569
|
-
transformPlatformConfigsToOptions,
|
|
3570
|
-
getPlatformIcon,
|
|
3571
|
-
getPlatformColor,
|
|
3572
|
-
getPlatformDisplayName,
|
|
3573
|
-
getPlatformDescription,
|
|
3574
|
-
getPlatformSlogan,
|
|
3575
|
-
getSmallPlatformIcon,
|
|
3576
|
-
getPlatformIconComponent,
|
|
3577
2742
|
usePlatformConfig,
|
|
3578
2743
|
usePlatformByValue,
|
|
3579
2744
|
useValidatePlatform,
|
|
3580
|
-
ToolTypeValues,
|
|
3581
|
-
toolLabels,
|
|
3582
2745
|
ToolIcon,
|
|
3583
2746
|
dotColorByVariant,
|
|
3584
2747
|
progressColorByVariant,
|
|
@@ -3589,15 +2752,6 @@ export {
|
|
|
3589
2752
|
showCommandApprovalToast,
|
|
3590
2753
|
toast,
|
|
3591
2754
|
useToast,
|
|
3592
|
-
getAppType,
|
|
3593
|
-
getEmbedProxyAuth,
|
|
3594
|
-
getPersistedProxyEmail,
|
|
3595
|
-
setEmbedProxyAuth,
|
|
3596
|
-
clearEmbedProxyAuth,
|
|
3597
|
-
applyProxyAuth,
|
|
3598
|
-
setEmbedAuthAdapter,
|
|
3599
|
-
embedAuthedFetch,
|
|
3600
|
-
contentFetch,
|
|
3601
2755
|
useContactSubmission,
|
|
3602
2756
|
useQuickActionHint,
|
|
3603
2757
|
useCopyToClipboard,
|
|
@@ -3630,24 +2784,8 @@ export {
|
|
|
3630
2784
|
createSearchParams,
|
|
3631
2785
|
useCursorPaginationState,
|
|
3632
2786
|
useNatsClient,
|
|
3633
|
-
useNearViewport,
|
|
3634
|
-
validateAccessCode,
|
|
3635
|
-
consumeAccessCode,
|
|
3636
|
-
validateAndConsumeAccessCode,
|
|
3637
2787
|
useAccessCodeIntegration,
|
|
3638
|
-
useOgPlaceholder,
|
|
3639
|
-
scrollElementIntoView,
|
|
3640
|
-
STICKY_HEADER_OFFSET_PX,
|
|
3641
|
-
HUB_HEADER_OFFSET_PX,
|
|
3642
|
-
normalizeHashFragment,
|
|
3643
|
-
navigateSamePageHash,
|
|
3644
2788
|
useScrollToHash,
|
|
3645
|
-
HONEYPOT_FIELD,
|
|
3646
|
-
ELAPSED_MS_FIELD,
|
|
3647
|
-
DEFAULT_MIN_FILL_MS,
|
|
3648
|
-
extractHumanitySignals,
|
|
3649
|
-
evaluateHumanitySignals,
|
|
3650
|
-
splitCsvEnv,
|
|
3651
2789
|
useHumanitySignals
|
|
3652
2790
|
};
|
|
3653
|
-
//# sourceMappingURL=chunk-
|
|
2791
|
+
//# sourceMappingURL=chunk-7RIYT7ZH.js.map
|