@burdenoff/website-sdk 2026.1101.1 → 2026.1101.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +42 -8
- package/dist/analytics/index.js +19 -69
- package/dist/analytics/index.js.map +1 -1
- package/dist/analytics/index.mjs +3 -69
- package/dist/analytics/index.mjs.map +1 -1
- package/dist/avatar-live/index.js +1 -0
- package/dist/avatar-live/index.js.map +1 -1
- package/dist/avatar-live/index.mjs +1 -0
- package/dist/avatar-live/index.mjs.map +1 -1
- package/dist/avatar-live-view/index.js +10 -30
- package/dist/avatar-live-view/index.js.map +1 -1
- package/dist/avatar-live-view/index.mjs +4 -24
- package/dist/avatar-live-view/index.mjs.map +1 -1
- package/dist/chunk-23H4JUL4.js +41 -0
- package/dist/chunk-23H4JUL4.js.map +1 -0
- package/dist/chunk-34RX5P75.mjs +25 -0
- package/dist/chunk-34RX5P75.mjs.map +1 -0
- package/dist/chunk-3LFFY7AZ.js +184 -0
- package/dist/chunk-3LFFY7AZ.js.map +1 -0
- package/dist/chunk-3X26GE4S.js +2794 -0
- package/dist/chunk-3X26GE4S.js.map +1 -0
- package/dist/chunk-45GCA4GG.js +85 -0
- package/dist/chunk-45GCA4GG.js.map +1 -0
- package/dist/chunk-4SAGVLHN.js +876 -0
- package/dist/chunk-4SAGVLHN.js.map +1 -0
- package/dist/chunk-4U6YAII5.js +218 -0
- package/dist/chunk-4U6YAII5.js.map +1 -0
- package/dist/chunk-5GMTBOO6.js +21 -0
- package/dist/chunk-5GMTBOO6.js.map +1 -0
- package/dist/chunk-5JRJ57CL.mjs +329 -0
- package/dist/chunk-5JRJ57CL.mjs.map +1 -0
- package/dist/chunk-6C2DKIC7.js +4 -0
- package/dist/chunk-6C2DKIC7.js.map +1 -0
- package/dist/chunk-6IBFBWC5.mjs +17 -0
- package/dist/chunk-6IBFBWC5.mjs.map +1 -0
- package/dist/chunk-6KY2ZRVI.js +116 -0
- package/dist/chunk-6KY2ZRVI.js.map +1 -0
- package/dist/chunk-6VJT3SM4.mjs +182 -0
- package/dist/chunk-6VJT3SM4.mjs.map +1 -0
- package/dist/chunk-6YZUFMK2.mjs +40 -0
- package/dist/chunk-6YZUFMK2.mjs.map +1 -0
- package/dist/chunk-7A6R7CGG.js +47 -0
- package/dist/chunk-7A6R7CGG.js.map +1 -0
- package/dist/chunk-7PWL4V2R.js +4 -0
- package/dist/chunk-7PWL4V2R.js.map +1 -0
- package/dist/chunk-AA33WDYS.js +161 -0
- package/dist/chunk-AA33WDYS.js.map +1 -0
- package/dist/chunk-AHRGFXV2.js +525 -0
- package/dist/chunk-AHRGFXV2.js.map +1 -0
- package/dist/chunk-B63XLDZH.mjs +109 -0
- package/dist/chunk-B63XLDZH.mjs.map +1 -0
- package/dist/chunk-BX2USEWF.mjs +35 -0
- package/dist/chunk-BX2USEWF.mjs.map +1 -0
- package/dist/chunk-BYSZT35R.js +150 -0
- package/dist/chunk-BYSZT35R.js.map +1 -0
- package/dist/chunk-C6OJIHNO.js +12 -0
- package/dist/chunk-C6OJIHNO.js.map +1 -0
- package/dist/chunk-COOELBX7.mjs +63 -0
- package/dist/chunk-COOELBX7.mjs.map +1 -0
- package/dist/chunk-D2TW7MNC.mjs +2771 -0
- package/dist/chunk-D2TW7MNC.mjs.map +1 -0
- package/dist/chunk-D5KEZ6V6.mjs +3 -0
- package/dist/chunk-D5KEZ6V6.mjs.map +1 -0
- package/dist/chunk-E3GUGJMY.js +46 -0
- package/dist/chunk-E3GUGJMY.js.map +1 -0
- package/dist/chunk-EBZ2HGJ2.mjs +52 -0
- package/dist/chunk-EBZ2HGJ2.mjs.map +1 -0
- package/dist/chunk-EDLTUOIA.mjs +210 -0
- package/dist/chunk-EDLTUOIA.mjs.map +1 -0
- package/dist/chunk-EJQSOT4X.js +4 -0
- package/dist/chunk-EJQSOT4X.js.map +1 -0
- package/dist/chunk-EUPFS6MZ.mjs +2019 -0
- package/dist/chunk-EUPFS6MZ.mjs.map +1 -0
- package/dist/chunk-F3XWDC3B.js +77 -0
- package/dist/chunk-F3XWDC3B.js.map +1 -0
- package/dist/chunk-FFADMVIK.mjs +5127 -0
- package/dist/chunk-FFADMVIK.mjs.map +1 -0
- package/dist/chunk-FJWS7BKT.mjs +3 -0
- package/dist/chunk-FJWS7BKT.mjs.map +1 -0
- package/dist/chunk-FJZJDUOR.mjs +3 -0
- package/dist/chunk-FJZJDUOR.mjs.map +1 -0
- package/dist/chunk-GCFLCO2Z.mjs +145 -0
- package/dist/chunk-GCFLCO2Z.mjs.map +1 -0
- package/dist/chunk-GEXC4LRP.js +61 -0
- package/dist/chunk-GEXC4LRP.js.map +1 -0
- package/dist/chunk-GTRAXQGC.mjs +3 -0
- package/dist/chunk-GTRAXQGC.mjs.map +1 -0
- package/dist/chunk-IKOIRUKW.js +270 -0
- package/dist/chunk-IKOIRUKW.js.map +1 -0
- package/dist/chunk-IXTWOPRN.js +45 -0
- package/dist/chunk-IXTWOPRN.js.map +1 -0
- package/dist/chunk-JDXOXGOK.js +547 -0
- package/dist/chunk-JDXOXGOK.js.map +1 -0
- package/dist/chunk-JSLDWYV7.mjs +558 -0
- package/dist/chunk-JSLDWYV7.mjs.map +1 -0
- package/dist/chunk-JXLSTVBK.js +336 -0
- package/dist/chunk-JXLSTVBK.js.map +1 -0
- package/dist/chunk-KHYXK7FG.mjs +49 -0
- package/dist/chunk-KHYXK7FG.mjs.map +1 -0
- package/dist/chunk-KSMBOWQQ.js +2034 -0
- package/dist/chunk-KSMBOWQQ.js.map +1 -0
- package/dist/chunk-KU2PXHGB.mjs +83 -0
- package/dist/chunk-KU2PXHGB.mjs.map +1 -0
- package/dist/chunk-KZANIV3S.mjs +37 -0
- package/dist/chunk-KZANIV3S.mjs.map +1 -0
- package/dist/chunk-L4BP6YOB.js +20 -0
- package/dist/chunk-L4BP6YOB.js.map +1 -0
- package/dist/chunk-MRKA2OAF.mjs +75 -0
- package/dist/chunk-MRKA2OAF.mjs.map +1 -0
- package/dist/chunk-N5EC53MH.mjs +80 -0
- package/dist/chunk-N5EC53MH.mjs.map +1 -0
- package/dist/chunk-NZANQGDM.mjs +34 -0
- package/dist/chunk-NZANQGDM.mjs.map +1 -0
- package/dist/chunk-O4GS3XPZ.js +10 -0
- package/dist/chunk-O4GS3XPZ.js.map +1 -0
- package/dist/chunk-O76QDGRM.js +5154 -0
- package/dist/chunk-O76QDGRM.js.map +1 -0
- package/dist/chunk-OYEUNZJY.js +114 -0
- package/dist/chunk-OYEUNZJY.js.map +1 -0
- package/dist/chunk-PHXAGQNB.js +74 -0
- package/dist/chunk-PHXAGQNB.js.map +1 -0
- package/dist/chunk-PIHHPP7J.mjs +16 -0
- package/dist/chunk-PIHHPP7J.mjs.map +1 -0
- package/dist/chunk-PXRHVVOU.mjs +499 -0
- package/dist/chunk-PXRHVVOU.mjs.map +1 -0
- package/dist/chunk-QMA6U6AU.js +36 -0
- package/dist/chunk-QMA6U6AU.js.map +1 -0
- package/dist/chunk-R6J7IULF.js +44 -0
- package/dist/chunk-R6J7IULF.js.map +1 -0
- package/dist/chunk-R7G6TWIS.mjs +10 -0
- package/dist/chunk-R7G6TWIS.mjs.map +1 -0
- package/dist/chunk-RUMGFI6L.mjs +544 -0
- package/dist/chunk-RUMGFI6L.mjs.map +1 -0
- package/dist/chunk-S54JWSJF.js +565 -0
- package/dist/chunk-S54JWSJF.js.map +1 -0
- package/dist/chunk-SK5UGG6A.js +2041 -0
- package/dist/chunk-SK5UGG6A.js.map +1 -0
- package/dist/chunk-SKIYDKIS.mjs +70 -0
- package/dist/chunk-SKIYDKIS.mjs.map +1 -0
- package/dist/chunk-SZNS5IK6.mjs +322 -0
- package/dist/chunk-SZNS5IK6.mjs.map +1 -0
- package/dist/chunk-T7JIPZAC.js +66 -0
- package/dist/chunk-T7JIPZAC.js.map +1 -0
- package/dist/chunk-TGYQHO2E.mjs +864 -0
- package/dist/chunk-TGYQHO2E.mjs.map +1 -0
- package/dist/chunk-TT3MHN42.mjs +8 -0
- package/dist/chunk-TT3MHN42.mjs.map +1 -0
- package/dist/chunk-UM55U65W.mjs +268 -0
- package/dist/chunk-UM55U65W.mjs.map +1 -0
- package/dist/chunk-UQ2HALUD.js +72 -0
- package/dist/chunk-UQ2HALUD.js.map +1 -0
- package/dist/chunk-UXWT7G77.js +82 -0
- package/dist/chunk-UXWT7G77.js.map +1 -0
- package/dist/chunk-VNS5WDWO.mjs +7 -0
- package/dist/chunk-VNS5WDWO.mjs.map +1 -0
- package/dist/chunk-VRWZLGR7.js +4 -0
- package/dist/chunk-VRWZLGR7.js.map +1 -0
- package/dist/chunk-VZLDSNH4.mjs +22 -0
- package/dist/chunk-VZLDSNH4.mjs.map +1 -0
- package/dist/chunk-W6P3YETJ.js +92 -0
- package/dist/chunk-W6P3YETJ.js.map +1 -0
- package/dist/chunk-WPKFFQCR.mjs +90 -0
- package/dist/chunk-WPKFFQCR.mjs.map +1 -0
- package/dist/chunk-WTVTI5TO.mjs +22 -0
- package/dist/chunk-WTVTI5TO.mjs.map +1 -0
- package/dist/chunk-XJOBZ4RJ.js +44 -0
- package/dist/chunk-XJOBZ4RJ.js.map +1 -0
- package/dist/chunk-XP2JDNDU.js +325 -0
- package/dist/chunk-XP2JDNDU.js.map +1 -0
- package/dist/chunk-Y4V5CEWD.mjs +112 -0
- package/dist/chunk-Y4V5CEWD.mjs.map +1 -0
- package/dist/chunk-YERN2UWM.js +116 -0
- package/dist/chunk-YERN2UWM.js.map +1 -0
- package/dist/chunk-ZKJQWFAA.mjs +114 -0
- package/dist/chunk-ZKJQWFAA.mjs.map +1 -0
- package/dist/chunk-ZOON3S3Y.mjs +138 -0
- package/dist/chunk-ZOON3S3Y.mjs.map +1 -0
- package/dist/chunk-ZP6QRAYC.mjs +2024 -0
- package/dist/chunk-ZP6QRAYC.mjs.map +1 -0
- package/dist/chunk-ZSTFX7FV.js +9 -0
- package/dist/chunk-ZSTFX7FV.js.map +1 -0
- package/dist/client/index.js +23 -331
- package/dist/client/index.js.map +1 -1
- package/dist/client/index.mjs +3 -330
- package/dist/client/index.mjs.map +1 -1
- package/dist/comparison/index.js +28 -111
- package/dist/comparison/index.js.map +1 -1
- package/dist/comparison/index.mjs +2 -107
- package/dist/comparison/index.mjs.map +1 -1
- package/dist/components/contact.js +21 -931
- package/dist/components/contact.js.map +1 -1
- package/dist/components/contact.mjs +12 -909
- package/dist/components/contact.mjs.map +1 -1
- package/dist/components/electron-download.js +12 -124
- package/dist/components/electron-download.js.map +1 -1
- package/dist/components/electron-download.mjs +4 -106
- package/dist/components/electron-download.mjs.map +1 -1
- package/dist/components/explore-cta.js +8 -112
- package/dist/components/explore-cta.js.map +1 -1
- package/dist/components/explore-cta.mjs +3 -114
- package/dist/components/explore-cta.mjs.map +1 -1
- package/dist/components/explore.js +62 -7833
- package/dist/components/explore.js.map +1 -1
- package/dist/components/explore.mjs +13 -7800
- package/dist/components/explore.mjs.map +1 -1
- package/dist/components/launch-countdown.js +8 -83
- package/dist/components/launch-countdown.js.map +1 -1
- package/dist/components/launch-countdown.mjs +3 -85
- package/dist/components/launch-countdown.mjs.map +1 -1
- package/dist/components/newsletter.js +20 -993
- package/dist/components/newsletter.js.map +1 -1
- package/dist/components/newsletter.mjs +11 -971
- package/dist/components/newsletter.mjs.map +1 -1
- package/dist/components/partners.js +24 -1302
- package/dist/components/partners.js.map +1 -1
- package/dist/components/partners.mjs +15 -1276
- package/dist/components/partners.mjs.map +1 -1
- package/dist/components/pricing.js +49 -1249
- package/dist/components/pricing.js.map +1 -1
- package/dist/components/pricing.mjs +8 -1226
- package/dist/components/pricing.mjs.map +1 -1
- package/dist/components/problems-solved.js +8 -150
- package/dist/components/problems-solved.js.map +1 -1
- package/dist/components/problems-solved.mjs +4 -133
- package/dist/components/problems-solved.mjs.map +1 -1
- package/dist/components/resource-links.js +8 -304
- package/dist/components/resource-links.js.map +1 -1
- package/dist/components/resource-links.mjs +5 -308
- package/dist/components/resource-links.mjs.map +1 -1
- package/dist/components/social-links.js +8 -343
- package/dist/components/social-links.js.map +1 -1
- package/dist/components/social-links.mjs +5 -347
- package/dist/components/social-links.mjs.map +1 -1
- package/dist/components/unsubscribe.js +10 -627
- package/dist/components/unsubscribe.js.map +1 -1
- package/dist/components/unsubscribe.mjs +6 -611
- package/dist/components/unsubscribe.mjs.map +1 -1
- package/dist/components/waitlist.js +21 -1001
- package/dist/components/waitlist.js.map +1 -1
- package/dist/components/waitlist.mjs +12 -982
- package/dist/components/waitlist.mjs.map +1 -1
- package/dist/components/website-switcher.js +12 -175
- package/dist/components/website-switcher.js.map +1 -1
- package/dist/components/website-switcher.mjs +4 -157
- package/dist/components/website-switcher.mjs.map +1 -1
- package/dist/content/index.js +118 -3616
- package/dist/content/index.js.map +1 -1
- package/dist/content/index.mjs +12 -3567
- package/dist/content/index.mjs.map +1 -1
- package/dist/hooks/index.js +37 -2321
- package/dist/hooks/index.js.map +1 -1
- package/dist/hooks/index.mjs +6 -2318
- package/dist/hooks/index.mjs.map +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +4145 -20599
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +3766 -20567
- package/dist/index.mjs.map +1 -1
- package/dist/product/index.js +20 -393
- package/dist/product/index.js.map +1 -1
- package/dist/product/index.mjs +5 -394
- package/dist/product/index.mjs.map +1 -1
- package/dist/seo/index.js +8 -76
- package/dist/seo/index.js.map +1 -1
- package/dist/seo/index.mjs +3 -78
- package/dist/seo/index.mjs.map +1 -1
- package/dist/store/index.js +51 -2650
- package/dist/store/index.js.map +1 -1
- package/dist/store/index.mjs +13 -2619
- package/dist/store/index.mjs.map +1 -1
- package/dist/utils/index.js +69 -134
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/index.mjs +5 -122
- package/dist/utils/index.mjs.map +1 -1
- package/package.json +2 -1
|
@@ -0,0 +1,2794 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunk4U6YAII5_js = require('./chunk-4U6YAII5.js');
|
|
4
|
+
var chunk3LFFY7AZ_js = require('./chunk-3LFFY7AZ.js');
|
|
5
|
+
var chunk7A6R7CGG_js = require('./chunk-7A6R7CGG.js');
|
|
6
|
+
var chunkUXWT7G77_js = require('./chunk-UXWT7G77.js');
|
|
7
|
+
var chunkUQ2HALUD_js = require('./chunk-UQ2HALUD.js');
|
|
8
|
+
var chunkC6OJIHNO_js = require('./chunk-C6OJIHNO.js');
|
|
9
|
+
var chunkBYSZT35R_js = require('./chunk-BYSZT35R.js');
|
|
10
|
+
var chunkJXLSTVBK_js = require('./chunk-JXLSTVBK.js');
|
|
11
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
12
|
+
var react = require('react');
|
|
13
|
+
var lucideReact = require('lucide-react');
|
|
14
|
+
|
|
15
|
+
var LEGAL_DOCUMENTS = {
|
|
16
|
+
privacy: {
|
|
17
|
+
key: "privacy",
|
|
18
|
+
slug: "privacy-policy",
|
|
19
|
+
title: "Privacy Policy",
|
|
20
|
+
description: "How we collect, use, share and protect your personal information."
|
|
21
|
+
},
|
|
22
|
+
terms: {
|
|
23
|
+
key: "terms",
|
|
24
|
+
slug: "terms-of-service",
|
|
25
|
+
title: "Terms of Service",
|
|
26
|
+
description: "The terms that govern your use of the service."
|
|
27
|
+
},
|
|
28
|
+
cookies: {
|
|
29
|
+
key: "cookies",
|
|
30
|
+
slug: "cookie-policy",
|
|
31
|
+
title: "Cookie Policy",
|
|
32
|
+
description: "The cookies and similar technologies we use, and why."
|
|
33
|
+
},
|
|
34
|
+
refunds: {
|
|
35
|
+
key: "refunds",
|
|
36
|
+
slug: "refund-policy",
|
|
37
|
+
title: "Refund Policy",
|
|
38
|
+
description: "How cancellations and refunds work for paid plans."
|
|
39
|
+
},
|
|
40
|
+
aup: {
|
|
41
|
+
key: "aup",
|
|
42
|
+
slug: "acceptable-use-policy",
|
|
43
|
+
title: "Acceptable Use Policy",
|
|
44
|
+
description: "What you may and may not do with the service."
|
|
45
|
+
},
|
|
46
|
+
dpa: {
|
|
47
|
+
key: "dpa",
|
|
48
|
+
slug: "data-processing-addendum",
|
|
49
|
+
title: "Data Processing Addendum",
|
|
50
|
+
description: "Our obligations as a processor of personal data on your behalf."
|
|
51
|
+
},
|
|
52
|
+
"ai-terms": {
|
|
53
|
+
key: "ai-terms",
|
|
54
|
+
slug: "ai-product-terms",
|
|
55
|
+
title: "AI Product Terms",
|
|
56
|
+
description: "The terms that apply to AI features, including how your data is and is not used."
|
|
57
|
+
},
|
|
58
|
+
subprocessors: {
|
|
59
|
+
key: "subprocessors",
|
|
60
|
+
slug: "subprocessors",
|
|
61
|
+
title: "Subprocessors",
|
|
62
|
+
description: "The third parties that help us host, secure and support the service."
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
var LEGAL_DOCUMENT_KEYS = Object.keys(
|
|
66
|
+
LEGAL_DOCUMENTS
|
|
67
|
+
);
|
|
68
|
+
function findLegalDocument(keyOrSlug) {
|
|
69
|
+
if (Object.prototype.hasOwnProperty.call(LEGAL_DOCUMENTS, keyOrSlug)) {
|
|
70
|
+
return LEGAL_DOCUMENTS[keyOrSlug];
|
|
71
|
+
}
|
|
72
|
+
return Object.values(LEGAL_DOCUMENTS).find((doc) => doc.slug === keyOrSlug) ?? null;
|
|
73
|
+
}
|
|
74
|
+
var LEGAL_CONTENT_QUERY = `
|
|
75
|
+
query PublicLegalContentPage($slug: String!, $productId: String!) {
|
|
76
|
+
publicResolvedContentPage(slug: $slug, productId: $productId) {
|
|
77
|
+
title
|
|
78
|
+
slug
|
|
79
|
+
content
|
|
80
|
+
contentFormat
|
|
81
|
+
seoTitle
|
|
82
|
+
seoDescription
|
|
83
|
+
seoKeywords
|
|
84
|
+
lastUpdated
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
`;
|
|
88
|
+
async function fetchLegalContentPage(client, slug, productId) {
|
|
89
|
+
const result = await client.query(LEGAL_CONTENT_QUERY, { slug, productId }, { cache: false });
|
|
90
|
+
if (result.errors?.length) {
|
|
91
|
+
throw new Error(result.errors[0]?.message ?? "Unknown error");
|
|
92
|
+
}
|
|
93
|
+
return result.data?.publicResolvedContentPage ?? null;
|
|
94
|
+
}
|
|
95
|
+
async function fetchLegalContent(client, options) {
|
|
96
|
+
const docs = (options.documents ?? LEGAL_DOCUMENT_KEYS).map(
|
|
97
|
+
(key) => LEGAL_DOCUMENTS[key]
|
|
98
|
+
);
|
|
99
|
+
const entries = await Promise.all(
|
|
100
|
+
docs.map(
|
|
101
|
+
async (doc) => [
|
|
102
|
+
doc.slug,
|
|
103
|
+
await fetchLegalContentPage(client, doc.slug, options.productId)
|
|
104
|
+
]
|
|
105
|
+
)
|
|
106
|
+
);
|
|
107
|
+
return Object.fromEntries(entries);
|
|
108
|
+
}
|
|
109
|
+
function splitLeadingHeading(content, format) {
|
|
110
|
+
if (format.toLowerCase() !== "markdown")
|
|
111
|
+
return { heading: null, body: content };
|
|
112
|
+
const match = /^\s*#[ \t]+([^\n]+?)[ \t#]*(?:\n|$)/.exec(content);
|
|
113
|
+
if (!match?.[1]) return { heading: null, body: content };
|
|
114
|
+
return {
|
|
115
|
+
heading: match[1].trim(),
|
|
116
|
+
body: content.slice(match[0].length).replace(/^\s+/, "")
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
function formatLegalDate(iso) {
|
|
120
|
+
if (!iso) return null;
|
|
121
|
+
const date = new Date(iso);
|
|
122
|
+
if (Number.isNaN(date.getTime())) return null;
|
|
123
|
+
return date.toLocaleDateString("en-US", {
|
|
124
|
+
year: "numeric",
|
|
125
|
+
month: "long",
|
|
126
|
+
day: "numeric",
|
|
127
|
+
timeZone: "UTC"
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
function LegalPage(props) {
|
|
131
|
+
const {
|
|
132
|
+
document: document2,
|
|
133
|
+
slug: slugProp,
|
|
134
|
+
initialContent,
|
|
135
|
+
fallbackTitle,
|
|
136
|
+
fallbackDescription,
|
|
137
|
+
productName,
|
|
138
|
+
canonicalUrl,
|
|
139
|
+
contactEmail,
|
|
140
|
+
className = ""
|
|
141
|
+
} = props;
|
|
142
|
+
const registered = document2 ? LEGAL_DOCUMENTS[document2] : slugProp ? findLegalDocument(slugProp) : null;
|
|
143
|
+
const slug = registered?.slug ?? slugProp ?? "";
|
|
144
|
+
const prefetched = initialContent !== void 0;
|
|
145
|
+
const { data: fetched, loading } = chunk4U6YAII5_js.useContentPage(slug, {
|
|
146
|
+
resolve: true,
|
|
147
|
+
enabled: !prefetched && slug !== ""
|
|
148
|
+
});
|
|
149
|
+
const page = prefetched ? initialContent ?? null : fetched;
|
|
150
|
+
const isLoading = !prefetched && slug !== "" && loading;
|
|
151
|
+
const defaultTitle = fallbackTitle ?? registered?.title ?? "Legal";
|
|
152
|
+
const defaultDescription = fallbackDescription ?? registered?.description ?? "";
|
|
153
|
+
const { heading, body } = page ? splitLeadingHeading(page.content, page.contentFormat) : { heading: null, body: "" };
|
|
154
|
+
const title = page?.title || heading || defaultTitle;
|
|
155
|
+
const updated = formatLegalDate(page?.lastUpdated);
|
|
156
|
+
const unavailable = !isLoading && !page;
|
|
157
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `w-full ${className}`, children: [
|
|
158
|
+
/* @__PURE__ */ jsxRuntime.jsx(chunk3LFFY7AZ_js.ProseStyles, {}),
|
|
159
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
160
|
+
chunkUXWT7G77_js.PageHead,
|
|
161
|
+
{
|
|
162
|
+
title: page?.seoTitle || title,
|
|
163
|
+
description: page?.seoDescription?.trim() || defaultDescription,
|
|
164
|
+
keywords: page?.seoKeywords ?? void 0,
|
|
165
|
+
productName,
|
|
166
|
+
url: canonicalUrl,
|
|
167
|
+
robots: unavailable ? "noindex, follow" : void 0
|
|
168
|
+
}
|
|
169
|
+
),
|
|
170
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
171
|
+
"article",
|
|
172
|
+
{
|
|
173
|
+
className: "max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 py-16 sm:py-24",
|
|
174
|
+
"aria-busy": isLoading,
|
|
175
|
+
children: [
|
|
176
|
+
/* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-3xl sm:text-4xl font-bold tracking-tight text-foreground mb-3", children: title }),
|
|
177
|
+
updated && /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-sm text-muted-foreground mb-10", children: [
|
|
178
|
+
"Last updated:",
|
|
179
|
+
" ",
|
|
180
|
+
/* @__PURE__ */ jsxRuntime.jsx("time", { dateTime: page?.lastUpdated ?? void 0, children: updated })
|
|
181
|
+
] }),
|
|
182
|
+
isLoading ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", "data-testid": "legal-page-loading", children: [
|
|
183
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-4 w-3/4 rounded bg-muted animate-pulse" }),
|
|
184
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-4 w-full rounded bg-muted animate-pulse" }),
|
|
185
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-4 w-5/6 rounded bg-muted animate-pulse" })
|
|
186
|
+
] }) : page ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "boff-prose max-w-none", children: /* @__PURE__ */ jsxRuntime.jsx(chunk4U6YAII5_js.ContentRenderer, { content: body, format: page.contentFormat }) }) : /* @__PURE__ */ jsxRuntime.jsxs(
|
|
187
|
+
"div",
|
|
188
|
+
{
|
|
189
|
+
role: "status",
|
|
190
|
+
className: "rounded-xl border border-border bg-muted/30 p-6",
|
|
191
|
+
children: [
|
|
192
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-base text-foreground", children: "This document is not available right now." }),
|
|
193
|
+
contactEmail && /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "mt-2 text-sm text-muted-foreground", children: [
|
|
194
|
+
"For a copy, contact",
|
|
195
|
+
" ",
|
|
196
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
197
|
+
"a",
|
|
198
|
+
{
|
|
199
|
+
className: "text-primary underline",
|
|
200
|
+
href: `mailto:${contactEmail}`,
|
|
201
|
+
children: contactEmail
|
|
202
|
+
}
|
|
203
|
+
),
|
|
204
|
+
"."
|
|
205
|
+
] })
|
|
206
|
+
]
|
|
207
|
+
}
|
|
208
|
+
)
|
|
209
|
+
]
|
|
210
|
+
}
|
|
211
|
+
)
|
|
212
|
+
] });
|
|
213
|
+
}
|
|
214
|
+
var PUBLIC_JOB_POSTING_FIELDS = (
|
|
215
|
+
/* GraphQL */
|
|
216
|
+
`
|
|
217
|
+
id
|
|
218
|
+
slug
|
|
219
|
+
title
|
|
220
|
+
department
|
|
221
|
+
location
|
|
222
|
+
employmentType
|
|
223
|
+
openings
|
|
224
|
+
description
|
|
225
|
+
overview
|
|
226
|
+
responsibilities
|
|
227
|
+
learnings
|
|
228
|
+
qualifications
|
|
229
|
+
rounds {
|
|
230
|
+
roundNumber
|
|
231
|
+
name
|
|
232
|
+
roundType
|
|
233
|
+
isRequired
|
|
234
|
+
description
|
|
235
|
+
}
|
|
236
|
+
`
|
|
237
|
+
);
|
|
238
|
+
var PUBLIC_JOB_POSTINGS_QUERY = (
|
|
239
|
+
/* GraphQL */
|
|
240
|
+
`
|
|
241
|
+
query PublicJobPostings($productId: ID, $limit: Int, $offset: Int) {
|
|
242
|
+
publicJobPostings(productId: $productId, limit: $limit, offset: $offset) {
|
|
243
|
+
${PUBLIC_JOB_POSTING_FIELDS}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
`
|
|
247
|
+
);
|
|
248
|
+
var PUBLIC_JOB_POSTING_QUERY = (
|
|
249
|
+
/* GraphQL */
|
|
250
|
+
`
|
|
251
|
+
query PublicJobPosting($slug: String!, $productId: ID) {
|
|
252
|
+
publicJobPosting(slug: $slug, productId: $productId) {
|
|
253
|
+
${PUBLIC_JOB_POSTING_FIELDS}
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
`
|
|
257
|
+
);
|
|
258
|
+
var PUBLIC_JOB_POSTINGS_FOR_SUBMISSION_QUERY = (
|
|
259
|
+
/* GraphQL */
|
|
260
|
+
`
|
|
261
|
+
query PublicJobPostingsForSubmission(
|
|
262
|
+
$productId: ID
|
|
263
|
+
$limit: Int
|
|
264
|
+
$offset: Int
|
|
265
|
+
) {
|
|
266
|
+
publicJobPostingsForSubmission(
|
|
267
|
+
productId: $productId
|
|
268
|
+
limit: $limit
|
|
269
|
+
offset: $offset
|
|
270
|
+
) {
|
|
271
|
+
id
|
|
272
|
+
title
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
`
|
|
276
|
+
);
|
|
277
|
+
async function fetchPublicJobPostings(client, options) {
|
|
278
|
+
const result = await client.query(PUBLIC_JOB_POSTINGS_QUERY, {
|
|
279
|
+
productId: options?.productId,
|
|
280
|
+
limit: options?.limit ?? 50,
|
|
281
|
+
offset: options?.offset ?? 0
|
|
282
|
+
});
|
|
283
|
+
if (result.errors?.length) {
|
|
284
|
+
throw new Error(result.errors[0]?.message ?? "Unknown error");
|
|
285
|
+
}
|
|
286
|
+
return result.data?.publicJobPostings ?? [];
|
|
287
|
+
}
|
|
288
|
+
async function fetchPublicJobPosting(client, slug, options) {
|
|
289
|
+
const result = await client.query(PUBLIC_JOB_POSTING_QUERY, {
|
|
290
|
+
slug,
|
|
291
|
+
productId: options?.productId
|
|
292
|
+
});
|
|
293
|
+
if (result.errors?.length) {
|
|
294
|
+
throw new Error(result.errors[0]?.message ?? "Unknown error");
|
|
295
|
+
}
|
|
296
|
+
return result.data?.publicJobPosting ?? null;
|
|
297
|
+
}
|
|
298
|
+
async function fetchPublicJobPostingsForSubmission(client, options) {
|
|
299
|
+
const result = await client.query(PUBLIC_JOB_POSTINGS_FOR_SUBMISSION_QUERY, {
|
|
300
|
+
productId: options?.productId,
|
|
301
|
+
limit: options?.limit ?? 50,
|
|
302
|
+
offset: options?.offset ?? 0
|
|
303
|
+
});
|
|
304
|
+
if (result.errors?.length) {
|
|
305
|
+
throw new Error(result.errors[0]?.message ?? "Unknown error");
|
|
306
|
+
}
|
|
307
|
+
return result.data?.publicJobPostingsForSubmission ?? [];
|
|
308
|
+
}
|
|
309
|
+
function usePublicJobPostings(options) {
|
|
310
|
+
const client = chunkJXLSTVBK_js.useWebSDK();
|
|
311
|
+
const config = chunkJXLSTVBK_js.useWebSDKConfig();
|
|
312
|
+
const { product } = chunkBYSZT35R_js.useProduct();
|
|
313
|
+
const resolvedProductId = options?.productId ?? product?.id ?? config.productId;
|
|
314
|
+
const [postings, setPostings] = react.useState([]);
|
|
315
|
+
const [loading, setLoading] = react.useState(true);
|
|
316
|
+
const [error, setError] = react.useState(null);
|
|
317
|
+
const fetchPostings = react.useCallback(async () => {
|
|
318
|
+
setLoading(true);
|
|
319
|
+
setError(null);
|
|
320
|
+
try {
|
|
321
|
+
const items = await fetchPublicJobPostings(client, {
|
|
322
|
+
productId: resolvedProductId,
|
|
323
|
+
limit: options?.limit,
|
|
324
|
+
offset: options?.offset
|
|
325
|
+
});
|
|
326
|
+
setPostings(items);
|
|
327
|
+
} catch (err) {
|
|
328
|
+
setError(
|
|
329
|
+
err instanceof Error ? err.message : "Failed to fetch job postings"
|
|
330
|
+
);
|
|
331
|
+
setPostings([]);
|
|
332
|
+
} finally {
|
|
333
|
+
setLoading(false);
|
|
334
|
+
}
|
|
335
|
+
}, [client, resolvedProductId, options?.limit, options?.offset]);
|
|
336
|
+
react.useEffect(() => {
|
|
337
|
+
fetchPostings();
|
|
338
|
+
}, [fetchPostings]);
|
|
339
|
+
return { postings, loading, error, refetch: fetchPostings };
|
|
340
|
+
}
|
|
341
|
+
function usePublicJobPostingsForSubmission(options) {
|
|
342
|
+
const client = chunkJXLSTVBK_js.useWebSDK();
|
|
343
|
+
const config = chunkJXLSTVBK_js.useWebSDKConfig();
|
|
344
|
+
const { product } = chunkBYSZT35R_js.useProduct();
|
|
345
|
+
const resolvedProductId = options?.productId ?? product?.id ?? config.productId;
|
|
346
|
+
const [postings, setPostings] = react.useState([]);
|
|
347
|
+
const [loading, setLoading] = react.useState(true);
|
|
348
|
+
const [error, setError] = react.useState(null);
|
|
349
|
+
const fetchPostings = react.useCallback(async () => {
|
|
350
|
+
setLoading(true);
|
|
351
|
+
setError(null);
|
|
352
|
+
try {
|
|
353
|
+
const items = await fetchPublicJobPostingsForSubmission(client, {
|
|
354
|
+
productId: resolvedProductId,
|
|
355
|
+
limit: options?.limit,
|
|
356
|
+
offset: options?.offset
|
|
357
|
+
});
|
|
358
|
+
setPostings(items);
|
|
359
|
+
} catch (err) {
|
|
360
|
+
setError(
|
|
361
|
+
err instanceof Error ? err.message : "Failed to fetch job postings"
|
|
362
|
+
);
|
|
363
|
+
setPostings([]);
|
|
364
|
+
} finally {
|
|
365
|
+
setLoading(false);
|
|
366
|
+
}
|
|
367
|
+
}, [client, resolvedProductId, options?.limit, options?.offset]);
|
|
368
|
+
react.useEffect(() => {
|
|
369
|
+
fetchPostings();
|
|
370
|
+
}, [fetchPostings]);
|
|
371
|
+
return { postings, loading, error, refetch: fetchPostings };
|
|
372
|
+
}
|
|
373
|
+
function usePublicJobPosting(slug, options) {
|
|
374
|
+
const client = chunkJXLSTVBK_js.useWebSDK();
|
|
375
|
+
const config = chunkJXLSTVBK_js.useWebSDKConfig();
|
|
376
|
+
const { product } = chunkBYSZT35R_js.useProduct();
|
|
377
|
+
const resolvedProductId = options?.productId ?? product?.id ?? config.productId;
|
|
378
|
+
const [posting, setPosting] = react.useState(null);
|
|
379
|
+
const [loading, setLoading] = react.useState(true);
|
|
380
|
+
const [error, setError] = react.useState(null);
|
|
381
|
+
const fetchPosting = react.useCallback(async () => {
|
|
382
|
+
if (!slug) {
|
|
383
|
+
setPosting(null);
|
|
384
|
+
setLoading(false);
|
|
385
|
+
return;
|
|
386
|
+
}
|
|
387
|
+
setLoading(true);
|
|
388
|
+
setError(null);
|
|
389
|
+
try {
|
|
390
|
+
const item = await fetchPublicJobPosting(client, slug, {
|
|
391
|
+
productId: resolvedProductId
|
|
392
|
+
});
|
|
393
|
+
setPosting(item);
|
|
394
|
+
} catch (err) {
|
|
395
|
+
setError(
|
|
396
|
+
err instanceof Error ? err.message : "Failed to fetch job posting"
|
|
397
|
+
);
|
|
398
|
+
setPosting(null);
|
|
399
|
+
} finally {
|
|
400
|
+
setLoading(false);
|
|
401
|
+
}
|
|
402
|
+
}, [client, resolvedProductId, slug]);
|
|
403
|
+
react.useEffect(() => {
|
|
404
|
+
fetchPosting();
|
|
405
|
+
}, [fetchPosting]);
|
|
406
|
+
return { posting, loading, error, refetch: fetchPosting };
|
|
407
|
+
}
|
|
408
|
+
var BLOG_POSTS_QUERY = `
|
|
409
|
+
query BlogPosts($productId: String!, $limit: Int, $offset: Int) {
|
|
410
|
+
publicContentPages(productId: $productId, limit: $limit, offset: $offset) {
|
|
411
|
+
items {
|
|
412
|
+
id
|
|
413
|
+
title
|
|
414
|
+
slug
|
|
415
|
+
lastUpdated
|
|
416
|
+
tags
|
|
417
|
+
seoDescription
|
|
418
|
+
excerpt
|
|
419
|
+
thumbnail
|
|
420
|
+
author
|
|
421
|
+
publishedAt
|
|
422
|
+
readingTime
|
|
423
|
+
featured
|
|
424
|
+
category
|
|
425
|
+
}
|
|
426
|
+
total
|
|
427
|
+
hasMore
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
`;
|
|
431
|
+
var BLOG_POST_QUERY = `
|
|
432
|
+
query BlogPost($slug: String!, $productId: String) {
|
|
433
|
+
publicContentPage(slug: $slug, productId: $productId) {
|
|
434
|
+
id
|
|
435
|
+
title
|
|
436
|
+
slug
|
|
437
|
+
content
|
|
438
|
+
contentFormat
|
|
439
|
+
seoTitle
|
|
440
|
+
seoDescription
|
|
441
|
+
seoKeywords
|
|
442
|
+
lastUpdated
|
|
443
|
+
tags
|
|
444
|
+
excerpt
|
|
445
|
+
thumbnail
|
|
446
|
+
author
|
|
447
|
+
publishedAt
|
|
448
|
+
readingTime
|
|
449
|
+
featured
|
|
450
|
+
category
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
`;
|
|
454
|
+
function BlogCard({
|
|
455
|
+
post,
|
|
456
|
+
basePath = "/blog"
|
|
457
|
+
}) {
|
|
458
|
+
const date = post.publishedAt || post.lastUpdated;
|
|
459
|
+
const formattedDate = date ? new Date(date).toLocaleDateString("en-US", {
|
|
460
|
+
year: "numeric",
|
|
461
|
+
month: "long",
|
|
462
|
+
day: "numeric"
|
|
463
|
+
}) : "";
|
|
464
|
+
const [imgError, setImgError] = react.useState(false);
|
|
465
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
466
|
+
"a",
|
|
467
|
+
{
|
|
468
|
+
href: `${basePath}/${post.slug}`,
|
|
469
|
+
className: "group block bg-card border rounded-xl overflow-hidden hover:shadow-lg hover:border-primary/30 transition-all duration-300",
|
|
470
|
+
children: [
|
|
471
|
+
post.thumbnail && !imgError ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "aspect-[16/9] overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
472
|
+
"img",
|
|
473
|
+
{
|
|
474
|
+
src: post.thumbnail,
|
|
475
|
+
alt: post.title,
|
|
476
|
+
className: "w-full h-full object-cover group-hover:scale-105 transition-transform duration-300",
|
|
477
|
+
loading: "lazy",
|
|
478
|
+
onError: () => setImgError(true)
|
|
479
|
+
}
|
|
480
|
+
) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "aspect-[16/9] bg-muted/50 flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
481
|
+
"svg",
|
|
482
|
+
{
|
|
483
|
+
className: "w-12 h-12 text-muted-foreground/20",
|
|
484
|
+
fill: "none",
|
|
485
|
+
viewBox: "0 0 24 24",
|
|
486
|
+
stroke: "currentColor",
|
|
487
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
488
|
+
"path",
|
|
489
|
+
{
|
|
490
|
+
strokeLinecap: "round",
|
|
491
|
+
strokeLinejoin: "round",
|
|
492
|
+
strokeWidth: 1.5,
|
|
493
|
+
d: "M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253"
|
|
494
|
+
}
|
|
495
|
+
)
|
|
496
|
+
}
|
|
497
|
+
) }),
|
|
498
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-5 sm:p-6", children: [
|
|
499
|
+
post.category && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "inline-block text-xs font-medium text-primary bg-primary/10 px-2.5 py-1 rounded-full mb-3", children: post.category }),
|
|
500
|
+
/* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-lg font-semibold text-foreground mb-2 group-hover:text-primary transition-colors line-clamp-2", children: post.title }),
|
|
501
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground mb-4 line-clamp-3", children: post.excerpt || post.seoDescription || "" }),
|
|
502
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3 text-xs text-muted-foreground", children: [
|
|
503
|
+
post.author && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: post.author }),
|
|
504
|
+
post.author && formattedDate && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground/40", children: "\xB7" }),
|
|
505
|
+
formattedDate && /* @__PURE__ */ jsxRuntime.jsx("span", { children: formattedDate }),
|
|
506
|
+
post.readingTime && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
507
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground/40", children: "\xB7" }),
|
|
508
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
509
|
+
post.readingTime,
|
|
510
|
+
" min read"
|
|
511
|
+
] })
|
|
512
|
+
] })
|
|
513
|
+
] })
|
|
514
|
+
] })
|
|
515
|
+
]
|
|
516
|
+
}
|
|
517
|
+
);
|
|
518
|
+
}
|
|
519
|
+
function BlogListPage(props) {
|
|
520
|
+
const {
|
|
521
|
+
productName,
|
|
522
|
+
heroTitle = "Blog",
|
|
523
|
+
heroSubtitle = "Latest updates, engineering insights, and product news",
|
|
524
|
+
blogPostBasePath = "/blog",
|
|
525
|
+
className = "",
|
|
526
|
+
seoTitle,
|
|
527
|
+
seoDescription,
|
|
528
|
+
seoKeywords
|
|
529
|
+
} = props;
|
|
530
|
+
const client = chunkJXLSTVBK_js.useWebSDK();
|
|
531
|
+
const config = chunkJXLSTVBK_js.useWebSDKConfig();
|
|
532
|
+
const { product } = chunkBYSZT35R_js.useProduct();
|
|
533
|
+
const resolvedProductId = product?.id || config.productId;
|
|
534
|
+
const [posts, setPosts] = react.useState([]);
|
|
535
|
+
const [total, setTotal] = react.useState(0);
|
|
536
|
+
const [loading, setLoading] = react.useState(true);
|
|
537
|
+
const [error, setError] = react.useState(null);
|
|
538
|
+
const [offset, setOffset] = react.useState(0);
|
|
539
|
+
const limit = 12;
|
|
540
|
+
const fetchPosts = react.useCallback(async () => {
|
|
541
|
+
if (!resolvedProductId) return;
|
|
542
|
+
setLoading(true);
|
|
543
|
+
try {
|
|
544
|
+
const result = await client.query(BLOG_POSTS_QUERY, {
|
|
545
|
+
productId: resolvedProductId,
|
|
546
|
+
limit,
|
|
547
|
+
offset
|
|
548
|
+
});
|
|
549
|
+
if (result.errors?.length) {
|
|
550
|
+
setError(result.errors[0]?.message ?? "Failed to load posts");
|
|
551
|
+
return;
|
|
552
|
+
}
|
|
553
|
+
const blogPosts = (result.data?.publicContentPages?.items || []).filter(
|
|
554
|
+
(p) => p.tags?.includes("blog")
|
|
555
|
+
);
|
|
556
|
+
setPosts(blogPosts);
|
|
557
|
+
setTotal(result.data?.publicContentPages?.total || 0);
|
|
558
|
+
setError(null);
|
|
559
|
+
} catch {
|
|
560
|
+
setError("Failed to load blog posts");
|
|
561
|
+
} finally {
|
|
562
|
+
setLoading(false);
|
|
563
|
+
}
|
|
564
|
+
}, [client, resolvedProductId, offset]);
|
|
565
|
+
react.useEffect(() => {
|
|
566
|
+
fetchPosts();
|
|
567
|
+
}, [fetchPosts]);
|
|
568
|
+
const featuredPosts = posts.filter((p) => p.featured);
|
|
569
|
+
const regularPosts = posts.filter((p) => !p.featured);
|
|
570
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `w-full ${className}`, children: [
|
|
571
|
+
seoTitle && /* @__PURE__ */ jsxRuntime.jsx(
|
|
572
|
+
chunkUXWT7G77_js.PageHead,
|
|
573
|
+
{
|
|
574
|
+
title: seoTitle,
|
|
575
|
+
description: seoDescription || heroSubtitle,
|
|
576
|
+
productName,
|
|
577
|
+
keywords: seoKeywords,
|
|
578
|
+
url: typeof window !== "undefined" ? window.location.origin + window.location.pathname : void 0
|
|
579
|
+
}
|
|
580
|
+
),
|
|
581
|
+
/* @__PURE__ */ jsxRuntime.jsx("section", { className: "py-16 sm:py-20 md:py-24", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-center max-w-3xl mx-auto", children: [
|
|
582
|
+
/* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-3xl sm:text-4xl md:text-5xl font-bold tracking-tight text-foreground", children: heroTitle }),
|
|
583
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-4 text-lg text-muted-foreground", children: heroSubtitle })
|
|
584
|
+
] }) }) }),
|
|
585
|
+
/* @__PURE__ */ jsxRuntime.jsx("section", { className: "pb-16 sm:pb-20", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8", children: loading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid md:grid-cols-2 lg:grid-cols-3 gap-6 sm:gap-8", children: [1, 2, 3].map((i) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
586
|
+
"div",
|
|
587
|
+
{
|
|
588
|
+
className: "bg-card border rounded-xl overflow-hidden animate-pulse",
|
|
589
|
+
children: [
|
|
590
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "aspect-[16/9] bg-muted" }),
|
|
591
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-6 space-y-3", children: [
|
|
592
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-4 bg-muted rounded w-1/4" }),
|
|
593
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-6 bg-muted rounded w-3/4" }),
|
|
594
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-4 bg-muted rounded" }),
|
|
595
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-4 bg-muted rounded w-1/2" })
|
|
596
|
+
] })
|
|
597
|
+
]
|
|
598
|
+
},
|
|
599
|
+
i
|
|
600
|
+
)) }) : error ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-center py-12", children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground", children: error }) }) : posts.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-center py-12", children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground", children: "No blog posts yet. Check back soon!" }) }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
601
|
+
featuredPosts.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid md:grid-cols-2 gap-6 sm:gap-8 mb-8", children: featuredPosts.map((post) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
602
|
+
BlogCard,
|
|
603
|
+
{
|
|
604
|
+
post,
|
|
605
|
+
basePath: blogPostBasePath
|
|
606
|
+
},
|
|
607
|
+
post.id
|
|
608
|
+
)) }),
|
|
609
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid md:grid-cols-2 lg:grid-cols-3 gap-6 sm:gap-8", children: regularPosts.map((post) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
610
|
+
BlogCard,
|
|
611
|
+
{
|
|
612
|
+
post,
|
|
613
|
+
basePath: blogPostBasePath
|
|
614
|
+
},
|
|
615
|
+
post.id
|
|
616
|
+
)) }),
|
|
617
|
+
total > limit && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-center gap-4 mt-12", children: [
|
|
618
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
619
|
+
"button",
|
|
620
|
+
{
|
|
621
|
+
onClick: () => setOffset(Math.max(0, offset - limit)),
|
|
622
|
+
disabled: offset === 0,
|
|
623
|
+
className: "px-5 py-2.5 text-sm font-medium border rounded-lg disabled:opacity-40 hover:bg-muted transition-colors",
|
|
624
|
+
children: "Previous"
|
|
625
|
+
}
|
|
626
|
+
),
|
|
627
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
628
|
+
"button",
|
|
629
|
+
{
|
|
630
|
+
onClick: () => setOffset(offset + limit),
|
|
631
|
+
disabled: offset + limit >= total,
|
|
632
|
+
className: "px-5 py-2.5 text-sm font-medium border rounded-lg disabled:opacity-40 hover:bg-muted transition-colors",
|
|
633
|
+
children: "Next"
|
|
634
|
+
}
|
|
635
|
+
)
|
|
636
|
+
] })
|
|
637
|
+
] }) }) })
|
|
638
|
+
] });
|
|
639
|
+
}
|
|
640
|
+
function BlogPostPage(props) {
|
|
641
|
+
const {
|
|
642
|
+
productName,
|
|
643
|
+
blogListUrl = "/blog",
|
|
644
|
+
backLabel = "Back to Blog",
|
|
645
|
+
className = ""
|
|
646
|
+
} = props;
|
|
647
|
+
const client = chunkJXLSTVBK_js.useWebSDK();
|
|
648
|
+
const config = chunkJXLSTVBK_js.useWebSDKConfig();
|
|
649
|
+
const { product } = chunkBYSZT35R_js.useProduct();
|
|
650
|
+
const resolvedProductId = product?.id || config.productId;
|
|
651
|
+
const [post, setPost] = react.useState(null);
|
|
652
|
+
const [loading, setLoading] = react.useState(true);
|
|
653
|
+
const [error, setError] = react.useState(null);
|
|
654
|
+
const slug = typeof window !== "undefined" ? window.location.pathname.split("/").pop() || "" : "";
|
|
655
|
+
react.useEffect(() => {
|
|
656
|
+
if (!slug || !resolvedProductId) return;
|
|
657
|
+
async function fetchPost() {
|
|
658
|
+
setLoading(true);
|
|
659
|
+
try {
|
|
660
|
+
const result = await client.query(BLOG_POST_QUERY, {
|
|
661
|
+
slug,
|
|
662
|
+
productId: resolvedProductId
|
|
663
|
+
});
|
|
664
|
+
if (result.errors?.length) {
|
|
665
|
+
setError(result.errors[0]?.message ?? "Failed to load post");
|
|
666
|
+
return;
|
|
667
|
+
}
|
|
668
|
+
setPost(result.data?.publicContentPage ?? null);
|
|
669
|
+
setError(null);
|
|
670
|
+
} catch {
|
|
671
|
+
setError("Failed to load blog post");
|
|
672
|
+
} finally {
|
|
673
|
+
setLoading(false);
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
fetchPost();
|
|
677
|
+
}, [client, slug, resolvedProductId]);
|
|
678
|
+
if (loading) {
|
|
679
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `w-full ${className}`, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 py-24", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "animate-pulse space-y-6", children: [
|
|
680
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-8 bg-muted rounded w-2/3" }),
|
|
681
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-4 bg-muted rounded w-1/3" }),
|
|
682
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "aspect-[16/9] bg-muted rounded-xl" }),
|
|
683
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-3", children: [1, 2, 3, 4, 5].map((i) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-4 bg-muted rounded" }, i)) })
|
|
684
|
+
] }) }) });
|
|
685
|
+
}
|
|
686
|
+
if (error || !post) {
|
|
687
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `w-full ${className}`, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 py-24 text-center", children: [
|
|
688
|
+
/* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-2xl font-bold mb-4", children: "Post not found" }),
|
|
689
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground mb-6", children: error || "This blog post doesn't exist or has been removed." }),
|
|
690
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
691
|
+
"a",
|
|
692
|
+
{
|
|
693
|
+
href: blogListUrl,
|
|
694
|
+
className: "text-primary hover:underline font-medium",
|
|
695
|
+
children: [
|
|
696
|
+
"\u2190 ",
|
|
697
|
+
backLabel
|
|
698
|
+
]
|
|
699
|
+
}
|
|
700
|
+
)
|
|
701
|
+
] }) });
|
|
702
|
+
}
|
|
703
|
+
const date = post.publishedAt || post.lastUpdated;
|
|
704
|
+
const formattedDate = date ? new Date(date).toLocaleDateString("en-US", {
|
|
705
|
+
year: "numeric",
|
|
706
|
+
month: "long",
|
|
707
|
+
day: "numeric"
|
|
708
|
+
}) : "";
|
|
709
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `w-full ${className}`, children: [
|
|
710
|
+
/* @__PURE__ */ jsxRuntime.jsx(chunk3LFFY7AZ_js.ProseStyles, {}),
|
|
711
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
712
|
+
chunkUXWT7G77_js.PageHead,
|
|
713
|
+
{
|
|
714
|
+
title: post.seoTitle || post.title,
|
|
715
|
+
description: post.seoDescription || post.excerpt || "",
|
|
716
|
+
productName,
|
|
717
|
+
keywords: post.seoKeywords || "",
|
|
718
|
+
image: post.thumbnail || void 0,
|
|
719
|
+
url: typeof window !== "undefined" ? window.location.origin + window.location.pathname : void 0
|
|
720
|
+
}
|
|
721
|
+
),
|
|
722
|
+
/* @__PURE__ */ jsxRuntime.jsxs("article", { className: "max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 py-16 sm:py-20", children: [
|
|
723
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
724
|
+
"a",
|
|
725
|
+
{
|
|
726
|
+
href: blogListUrl,
|
|
727
|
+
className: "inline-flex items-center gap-1 text-sm text-muted-foreground hover:text-foreground mb-8 transition-colors",
|
|
728
|
+
children: [
|
|
729
|
+
"\u2190 ",
|
|
730
|
+
backLabel
|
|
731
|
+
]
|
|
732
|
+
}
|
|
733
|
+
),
|
|
734
|
+
post.category && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "inline-block text-xs font-medium text-primary bg-primary/10 px-2.5 py-1 rounded-full mb-4", children: post.category }),
|
|
735
|
+
/* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-3xl sm:text-4xl md:text-5xl font-bold tracking-tight text-foreground mb-4", children: post.title }),
|
|
736
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3 text-sm text-muted-foreground mb-8", children: [
|
|
737
|
+
post.author && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-foreground", children: post.author }),
|
|
738
|
+
post.author && formattedDate && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground/40", children: "\xB7" }),
|
|
739
|
+
formattedDate && /* @__PURE__ */ jsxRuntime.jsx("span", { children: formattedDate }),
|
|
740
|
+
post.readingTime && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
741
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground/40", children: "\xB7" }),
|
|
742
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
743
|
+
post.readingTime,
|
|
744
|
+
" min read"
|
|
745
|
+
] })
|
|
746
|
+
] })
|
|
747
|
+
] }),
|
|
748
|
+
post.thumbnail && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "aspect-[16/9] rounded-xl overflow-hidden mb-10", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
749
|
+
"img",
|
|
750
|
+
{
|
|
751
|
+
src: post.thumbnail,
|
|
752
|
+
alt: post.title,
|
|
753
|
+
className: "w-full h-full object-cover"
|
|
754
|
+
}
|
|
755
|
+
) }),
|
|
756
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "boff-prose max-w-none", children: /* @__PURE__ */ jsxRuntime.jsx(chunk4U6YAII5_js.ContentRenderer, { content: post.content, format: post.contentFormat }) })
|
|
757
|
+
] })
|
|
758
|
+
] });
|
|
759
|
+
}
|
|
760
|
+
var CASE_STUDY_TAG = "case-study";
|
|
761
|
+
function hasCustomerSignOff(page) {
|
|
762
|
+
const signedAt = page.customerSignOff?.signedAt;
|
|
763
|
+
return typeof signedAt === "string" && !Number.isNaN(new Date(signedAt).getTime());
|
|
764
|
+
}
|
|
765
|
+
var ANIMATION_STYLES = `
|
|
766
|
+
@keyframes csFadeUp { from { opacity: 0; transform: translateY(16px); } to { opacity: 1; transform: translateY(0); } }
|
|
767
|
+
@keyframes csFloat { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-14px); } }
|
|
768
|
+
.cs-fade-up { animation: csFadeUp 0.5s cubic-bezier(0.16, 1, 0.3, 1) both; }
|
|
769
|
+
.cs-float { animation: csFloat 7s ease-in-out infinite; }
|
|
770
|
+
@media (prefers-reduced-motion: reduce) {
|
|
771
|
+
.cs-fade-up, .cs-float { animation: none !important; }
|
|
772
|
+
}
|
|
773
|
+
`;
|
|
774
|
+
function AnimationStyles() {
|
|
775
|
+
return /* @__PURE__ */ jsxRuntime.jsx("style", { dangerouslySetInnerHTML: { __html: ANIMATION_STYLES } });
|
|
776
|
+
}
|
|
777
|
+
var CASE_STUDIES_QUERY = `
|
|
778
|
+
query CaseStudies($productId: String!, $tag: String, $limit: Int, $offset: Int) {
|
|
779
|
+
publicContentPages(productId: $productId, tag: $tag, limit: $limit, offset: $offset) {
|
|
780
|
+
items {
|
|
781
|
+
id
|
|
782
|
+
title
|
|
783
|
+
slug
|
|
784
|
+
lastUpdated
|
|
785
|
+
tags
|
|
786
|
+
seoDescription
|
|
787
|
+
excerpt
|
|
788
|
+
thumbnail
|
|
789
|
+
author
|
|
790
|
+
publishedAt
|
|
791
|
+
readingTime
|
|
792
|
+
featured
|
|
793
|
+
category
|
|
794
|
+
customerSignOff {
|
|
795
|
+
signedAt
|
|
796
|
+
}
|
|
797
|
+
}
|
|
798
|
+
total
|
|
799
|
+
hasMore
|
|
800
|
+
}
|
|
801
|
+
}
|
|
802
|
+
`;
|
|
803
|
+
var CASE_STUDY_QUERY = `
|
|
804
|
+
query CaseStudy($slug: String!, $productId: String) {
|
|
805
|
+
publicContentPage(slug: $slug, productId: $productId) {
|
|
806
|
+
id
|
|
807
|
+
title
|
|
808
|
+
slug
|
|
809
|
+
content
|
|
810
|
+
contentFormat
|
|
811
|
+
seoTitle
|
|
812
|
+
seoDescription
|
|
813
|
+
seoKeywords
|
|
814
|
+
lastUpdated
|
|
815
|
+
tags
|
|
816
|
+
excerpt
|
|
817
|
+
thumbnail
|
|
818
|
+
author
|
|
819
|
+
publishedAt
|
|
820
|
+
readingTime
|
|
821
|
+
featured
|
|
822
|
+
category
|
|
823
|
+
customerSignOff {
|
|
824
|
+
signedAt
|
|
825
|
+
}
|
|
826
|
+
}
|
|
827
|
+
}
|
|
828
|
+
`;
|
|
829
|
+
function formatDate(value) {
|
|
830
|
+
if (!value) return "";
|
|
831
|
+
const d = new Date(value);
|
|
832
|
+
if (Number.isNaN(d.getTime())) return "";
|
|
833
|
+
return d.toLocaleDateString("en-US", {
|
|
834
|
+
year: "numeric",
|
|
835
|
+
month: "long",
|
|
836
|
+
day: "numeric"
|
|
837
|
+
});
|
|
838
|
+
}
|
|
839
|
+
function Thumbnail({
|
|
840
|
+
src,
|
|
841
|
+
alt,
|
|
842
|
+
className = ""
|
|
843
|
+
}) {
|
|
844
|
+
const [imgError, setImgError] = react.useState(false);
|
|
845
|
+
if (src && !imgError) {
|
|
846
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
847
|
+
"img",
|
|
848
|
+
{
|
|
849
|
+
src,
|
|
850
|
+
alt,
|
|
851
|
+
className,
|
|
852
|
+
loading: "lazy",
|
|
853
|
+
onError: () => setImgError(true)
|
|
854
|
+
}
|
|
855
|
+
);
|
|
856
|
+
}
|
|
857
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
858
|
+
"div",
|
|
859
|
+
{
|
|
860
|
+
className: `flex items-center justify-center bg-gradient-to-br from-muted/60 to-muted ${className}`,
|
|
861
|
+
"aria-hidden": "true",
|
|
862
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
863
|
+
"svg",
|
|
864
|
+
{
|
|
865
|
+
className: "w-12 h-12 text-muted-foreground/25",
|
|
866
|
+
fill: "none",
|
|
867
|
+
viewBox: "0 0 24 24",
|
|
868
|
+
stroke: "currentColor",
|
|
869
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
870
|
+
"path",
|
|
871
|
+
{
|
|
872
|
+
strokeLinecap: "round",
|
|
873
|
+
strokeLinejoin: "round",
|
|
874
|
+
strokeWidth: 1.5,
|
|
875
|
+
d: "M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253"
|
|
876
|
+
}
|
|
877
|
+
)
|
|
878
|
+
}
|
|
879
|
+
)
|
|
880
|
+
}
|
|
881
|
+
);
|
|
882
|
+
}
|
|
883
|
+
function MetaRow({
|
|
884
|
+
post,
|
|
885
|
+
className = ""
|
|
886
|
+
}) {
|
|
887
|
+
const formattedDate = formatDate(post.publishedAt || post.lastUpdated);
|
|
888
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
889
|
+
"div",
|
|
890
|
+
{
|
|
891
|
+
className: `flex flex-wrap items-center gap-x-3 gap-y-1 text-xs text-muted-foreground ${className}`,
|
|
892
|
+
children: [
|
|
893
|
+
post.author && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: post.author }),
|
|
894
|
+
post.author && formattedDate && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground/40", children: "\xB7" }),
|
|
895
|
+
formattedDate && /* @__PURE__ */ jsxRuntime.jsx("span", { children: formattedDate }),
|
|
896
|
+
post.readingTime ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
897
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground/40", children: "\xB7" }),
|
|
898
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
899
|
+
post.readingTime,
|
|
900
|
+
" min read"
|
|
901
|
+
] })
|
|
902
|
+
] }) : null
|
|
903
|
+
]
|
|
904
|
+
}
|
|
905
|
+
);
|
|
906
|
+
}
|
|
907
|
+
function FeaturedCard({
|
|
908
|
+
post,
|
|
909
|
+
basePath
|
|
910
|
+
}) {
|
|
911
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
912
|
+
"a",
|
|
913
|
+
{
|
|
914
|
+
href: `${basePath}/${post.slug}`,
|
|
915
|
+
className: "group relative grid md:grid-cols-2 gap-0 overflow-hidden rounded-2xl border bg-card shadow-sm transition-all duration-300 hover:-translate-y-1 hover:shadow-xl hover:border-primary/40",
|
|
916
|
+
children: [
|
|
917
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative aspect-[16/10] md:aspect-auto md:h-full overflow-hidden", children: [
|
|
918
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
919
|
+
Thumbnail,
|
|
920
|
+
{
|
|
921
|
+
src: post.thumbnail,
|
|
922
|
+
alt: post.title,
|
|
923
|
+
className: "w-full h-full min-h-[220px] object-cover transition-transform duration-500 group-hover:scale-[1.04]"
|
|
924
|
+
}
|
|
925
|
+
),
|
|
926
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "absolute top-4 left-4 inline-flex items-center gap-1 rounded-full bg-primary px-2.5 py-1 text-xs font-semibold text-primary-foreground shadow-sm", children: [
|
|
927
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
928
|
+
"svg",
|
|
929
|
+
{
|
|
930
|
+
className: "h-3 w-3",
|
|
931
|
+
viewBox: "0 0 20 20",
|
|
932
|
+
fill: "currentColor",
|
|
933
|
+
"aria-hidden": "true",
|
|
934
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.286 3.957a1 1 0 00.95.69h4.162c.969 0 1.371 1.24.588 1.81l-3.368 2.447a1 1 0 00-.364 1.118l1.287 3.957c.3.921-.755 1.688-1.54 1.118l-3.367-2.447a1 1 0 00-1.176 0l-3.367 2.447c-.784.57-1.838-.197-1.539-1.118l1.286-3.957a1 1 0 00-.363-1.118L2.98 9.384c-.783-.57-.38-1.81.588-1.81h4.162a1 1 0 00.95-.69l1.286-3.957z" })
|
|
935
|
+
}
|
|
936
|
+
),
|
|
937
|
+
"Featured"
|
|
938
|
+
] })
|
|
939
|
+
] }),
|
|
940
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col justify-center p-6 sm:p-8", children: [
|
|
941
|
+
post.category && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "mb-3 inline-block w-fit rounded-full bg-primary/10 px-2.5 py-1 text-xs font-medium text-primary", children: post.category }),
|
|
942
|
+
/* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-xl sm:text-2xl font-bold text-foreground transition-colors group-hover:text-primary line-clamp-3", children: post.title }),
|
|
943
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-3 text-sm sm:text-base text-muted-foreground line-clamp-3", children: post.excerpt || post.seoDescription || "" }),
|
|
944
|
+
/* @__PURE__ */ jsxRuntime.jsx(MetaRow, { post, className: "mt-5" }),
|
|
945
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "mt-5 inline-flex items-center gap-1 text-sm font-semibold text-primary", children: [
|
|
946
|
+
"Read the story",
|
|
947
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
948
|
+
"svg",
|
|
949
|
+
{
|
|
950
|
+
className: "h-4 w-4 transition-transform duration-300 group-hover:translate-x-1",
|
|
951
|
+
viewBox: "0 0 20 20",
|
|
952
|
+
fill: "currentColor",
|
|
953
|
+
"aria-hidden": "true",
|
|
954
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
955
|
+
"path",
|
|
956
|
+
{
|
|
957
|
+
fillRule: "evenodd",
|
|
958
|
+
d: "M7.293 4.293a1 1 0 011.414 0l5 5a1 1 0 010 1.414l-5 5a1 1 0 01-1.414-1.414L11.586 10 7.293 5.707a1 1 0 010-1.414z",
|
|
959
|
+
clipRule: "evenodd"
|
|
960
|
+
}
|
|
961
|
+
)
|
|
962
|
+
}
|
|
963
|
+
)
|
|
964
|
+
] })
|
|
965
|
+
] })
|
|
966
|
+
]
|
|
967
|
+
}
|
|
968
|
+
);
|
|
969
|
+
}
|
|
970
|
+
function CaseStudyCard({
|
|
971
|
+
post,
|
|
972
|
+
basePath = "/case-studies"
|
|
973
|
+
}) {
|
|
974
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
975
|
+
"a",
|
|
976
|
+
{
|
|
977
|
+
href: `${basePath}/${post.slug}`,
|
|
978
|
+
className: "group flex flex-col overflow-hidden rounded-xl border bg-card transition-all duration-300 hover:-translate-y-1 hover:shadow-lg hover:border-primary/40",
|
|
979
|
+
children: [
|
|
980
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "aspect-[16/9] overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
981
|
+
Thumbnail,
|
|
982
|
+
{
|
|
983
|
+
src: post.thumbnail,
|
|
984
|
+
alt: post.title,
|
|
985
|
+
className: "w-full h-full object-cover transition-transform duration-500 group-hover:scale-105"
|
|
986
|
+
}
|
|
987
|
+
) }),
|
|
988
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-1 flex-col p-5 sm:p-6", children: [
|
|
989
|
+
post.category && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "mb-3 inline-block w-fit rounded-full bg-primary/10 px-2.5 py-1 text-xs font-medium text-primary", children: post.category }),
|
|
990
|
+
/* @__PURE__ */ jsxRuntime.jsx("h2", { className: "mb-2 text-lg font-semibold text-foreground transition-colors group-hover:text-primary line-clamp-2", children: post.title }),
|
|
991
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "mb-4 text-sm text-muted-foreground line-clamp-3", children: post.excerpt || post.seoDescription || "" }),
|
|
992
|
+
/* @__PURE__ */ jsxRuntime.jsx(MetaRow, { post, className: "mt-auto" })
|
|
993
|
+
] })
|
|
994
|
+
]
|
|
995
|
+
}
|
|
996
|
+
);
|
|
997
|
+
}
|
|
998
|
+
function EmptyState({
|
|
999
|
+
productLabel,
|
|
1000
|
+
title,
|
|
1001
|
+
subtitle,
|
|
1002
|
+
contactHref,
|
|
1003
|
+
contactLabel,
|
|
1004
|
+
exploreHref,
|
|
1005
|
+
exploreLabel
|
|
1006
|
+
}) {
|
|
1007
|
+
const highlights = [
|
|
1008
|
+
{
|
|
1009
|
+
title: "Real outcomes, real teams",
|
|
1010
|
+
body: `We're partnering with our earliest adopters right now. As they ship results with ${productLabel}, their stories will land here \u2014 measured and unembellished.`,
|
|
1011
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1012
|
+
"path",
|
|
1013
|
+
{
|
|
1014
|
+
strokeLinecap: "round",
|
|
1015
|
+
strokeLinejoin: "round",
|
|
1016
|
+
strokeWidth: 1.5,
|
|
1017
|
+
d: "M3 13.125C3 12.504 3.504 12 4.125 12h2.25c.621 0 1.125.504 1.125 1.125v6.75C7.5 20.496 6.996 21 6.375 21h-2.25A1.125 1.125 0 013 19.875v-6.75zM9.75 8.625c0-.621.504-1.125 1.125-1.125h2.25c.621 0 1.125.504 1.125 1.125v11.25c0 .621-.504 1.125-1.125 1.125h-2.25a1.125 1.125 0 01-1.125-1.125V8.625zM16.5 4.125c0-.621.504-1.125 1.125-1.125h2.25C20.496 3 21 3.504 21 4.125v15.75c0 .621-.504 1.125-1.125 1.125h-2.25a1.125 1.125 0 01-1.125-1.125V4.125z"
|
|
1018
|
+
}
|
|
1019
|
+
)
|
|
1020
|
+
},
|
|
1021
|
+
{
|
|
1022
|
+
title: "See it on your use case",
|
|
1023
|
+
body: `Want to know how ${productLabel} would work for your team? We'll walk you through exactly what to expect \u2014 no pitch, just specifics.`,
|
|
1024
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1025
|
+
"path",
|
|
1026
|
+
{
|
|
1027
|
+
strokeLinecap: "round",
|
|
1028
|
+
strokeLinejoin: "round",
|
|
1029
|
+
strokeWidth: 1.5,
|
|
1030
|
+
d: "M2.036 12.322a1.012 1.012 0 010-.639C3.423 7.51 7.36 4.5 12 4.5c4.638 0 8.573 3.007 9.963 7.178.07.207.07.431 0 .639C20.577 16.49 16.64 19.5 12 19.5c-4.638 0-8.573-3.007-9.963-7.178z M15 12a3 3 0 11-6 0 3 3 0 016 0z"
|
|
1031
|
+
}
|
|
1032
|
+
)
|
|
1033
|
+
},
|
|
1034
|
+
{
|
|
1035
|
+
title: "Be the first story",
|
|
1036
|
+
body: `Building something with ${productLabel} worth talking about? Tell us \u2014 the best early stories become the case studies featured on this page.`,
|
|
1037
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1038
|
+
"path",
|
|
1039
|
+
{
|
|
1040
|
+
strokeLinecap: "round",
|
|
1041
|
+
strokeLinejoin: "round",
|
|
1042
|
+
strokeWidth: 1.5,
|
|
1043
|
+
d: "M11.48 3.499a.562.562 0 011.04 0l2.125 5.111a.563.563 0 00.475.345l5.518.442c.499.04.701.663.321.988l-4.204 3.602a.563.563 0 00-.182.557l1.285 5.385a.562.562 0 01-.84.61l-4.725-2.885a.562.562 0 00-.586 0L6.982 20.54a.562.562 0 01-.84-.61l1.285-5.386a.562.562 0 00-.182-.557l-4.204-3.602a.562.562 0 01.321-.988l5.518-.442a.563.563 0 00.475-.345L11.48 3.5z"
|
|
1044
|
+
}
|
|
1045
|
+
)
|
|
1046
|
+
}
|
|
1047
|
+
];
|
|
1048
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "cs-fade-up mx-auto max-w-4xl", children: [
|
|
1049
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative overflow-hidden rounded-3xl border bg-card px-6 py-14 text-center sm:px-12 sm:py-16", children: [
|
|
1050
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1051
|
+
"div",
|
|
1052
|
+
{
|
|
1053
|
+
className: "pointer-events-none absolute -top-24 -right-16 h-64 w-64 rounded-full bg-primary/10 blur-3xl",
|
|
1054
|
+
"aria-hidden": "true"
|
|
1055
|
+
}
|
|
1056
|
+
),
|
|
1057
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1058
|
+
"div",
|
|
1059
|
+
{
|
|
1060
|
+
className: "pointer-events-none absolute -bottom-24 -left-16 h-64 w-64 rounded-full bg-primary/5 blur-3xl",
|
|
1061
|
+
"aria-hidden": "true"
|
|
1062
|
+
}
|
|
1063
|
+
),
|
|
1064
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
|
|
1065
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "cs-float mx-auto flex h-20 w-20 items-center justify-center rounded-2xl bg-primary/10 text-primary ring-1 ring-primary/20", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1066
|
+
"svg",
|
|
1067
|
+
{
|
|
1068
|
+
className: "h-10 w-10",
|
|
1069
|
+
fill: "none",
|
|
1070
|
+
viewBox: "0 0 24 24",
|
|
1071
|
+
stroke: "currentColor",
|
|
1072
|
+
"aria-hidden": "true",
|
|
1073
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1074
|
+
"path",
|
|
1075
|
+
{
|
|
1076
|
+
strokeLinecap: "round",
|
|
1077
|
+
strokeLinejoin: "round",
|
|
1078
|
+
strokeWidth: 1.5,
|
|
1079
|
+
d: "M19.5 14.25v-2.625a3.375 3.375 0 00-3.375-3.375h-1.5A1.125 1.125 0 0113.5 7.125v-1.5a3.375 3.375 0 00-3.375-3.375H8.25m2.25 0H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 00-9-9z"
|
|
1080
|
+
}
|
|
1081
|
+
)
|
|
1082
|
+
}
|
|
1083
|
+
) }),
|
|
1084
|
+
/* @__PURE__ */ jsxRuntime.jsx("h2", { className: "mt-8 text-2xl font-bold tracking-tight text-foreground sm:text-3xl", children: title }),
|
|
1085
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "mx-auto mt-4 max-w-2xl text-base leading-relaxed text-muted-foreground sm:text-lg", children: subtitle }),
|
|
1086
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-8 flex flex-col items-center justify-center gap-3 sm:flex-row", children: [
|
|
1087
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
1088
|
+
"a",
|
|
1089
|
+
{
|
|
1090
|
+
href: contactHref,
|
|
1091
|
+
className: "inline-flex w-full items-center justify-center gap-2 rounded-lg bg-primary px-6 py-3 text-sm font-semibold text-primary-foreground shadow-sm transition-all hover:opacity-90 hover:shadow-md sm:w-auto",
|
|
1092
|
+
children: [
|
|
1093
|
+
contactLabel,
|
|
1094
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1095
|
+
"svg",
|
|
1096
|
+
{
|
|
1097
|
+
className: "h-4 w-4",
|
|
1098
|
+
viewBox: "0 0 20 20",
|
|
1099
|
+
fill: "currentColor",
|
|
1100
|
+
"aria-hidden": "true",
|
|
1101
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1102
|
+
"path",
|
|
1103
|
+
{
|
|
1104
|
+
fillRule: "evenodd",
|
|
1105
|
+
d: "M7.293 4.293a1 1 0 011.414 0l5 5a1 1 0 010 1.414l-5 5a1 1 0 01-1.414-1.414L11.586 10 7.293 5.707a1 1 0 010-1.414z",
|
|
1106
|
+
clipRule: "evenodd"
|
|
1107
|
+
}
|
|
1108
|
+
)
|
|
1109
|
+
}
|
|
1110
|
+
)
|
|
1111
|
+
]
|
|
1112
|
+
}
|
|
1113
|
+
),
|
|
1114
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1115
|
+
"a",
|
|
1116
|
+
{
|
|
1117
|
+
href: exploreHref,
|
|
1118
|
+
className: "inline-flex w-full items-center justify-center gap-2 rounded-lg border border-border bg-background px-6 py-3 text-sm font-semibold text-foreground transition-colors hover:bg-muted sm:w-auto",
|
|
1119
|
+
children: exploreLabel
|
|
1120
|
+
}
|
|
1121
|
+
)
|
|
1122
|
+
] })
|
|
1123
|
+
] })
|
|
1124
|
+
] }),
|
|
1125
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-8 grid gap-4 sm:grid-cols-3", children: highlights.map((h) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1126
|
+
"div",
|
|
1127
|
+
{
|
|
1128
|
+
className: "rounded-2xl border bg-card/60 p-5 text-left transition-colors hover:border-primary/30",
|
|
1129
|
+
children: [
|
|
1130
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex h-10 w-10 items-center justify-center rounded-lg bg-primary/10 text-primary", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1131
|
+
"svg",
|
|
1132
|
+
{
|
|
1133
|
+
className: "h-5 w-5",
|
|
1134
|
+
fill: "none",
|
|
1135
|
+
viewBox: "0 0 24 24",
|
|
1136
|
+
stroke: "currentColor",
|
|
1137
|
+
"aria-hidden": "true",
|
|
1138
|
+
children: h.icon
|
|
1139
|
+
}
|
|
1140
|
+
) }),
|
|
1141
|
+
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "mt-4 text-sm font-semibold text-foreground", children: h.title }),
|
|
1142
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-1.5 text-sm leading-relaxed text-muted-foreground", children: h.body })
|
|
1143
|
+
]
|
|
1144
|
+
},
|
|
1145
|
+
h.title
|
|
1146
|
+
)) })
|
|
1147
|
+
] });
|
|
1148
|
+
}
|
|
1149
|
+
function CaseStudiesListPage(props) {
|
|
1150
|
+
const {
|
|
1151
|
+
productName,
|
|
1152
|
+
eyebrow = "Customer Stories",
|
|
1153
|
+
heroTitle = "Case Studies",
|
|
1154
|
+
heroSubtitle = "Real-world stories of teams building with our platform.",
|
|
1155
|
+
caseStudyBasePath = "/case-studies",
|
|
1156
|
+
className = "",
|
|
1157
|
+
seoTitle,
|
|
1158
|
+
seoDescription,
|
|
1159
|
+
seoKeywords,
|
|
1160
|
+
contactHref = "/contact",
|
|
1161
|
+
contactLabel = "Get in touch",
|
|
1162
|
+
exploreHref = "/features",
|
|
1163
|
+
exploreLabel = "Explore the product",
|
|
1164
|
+
emptyTitle,
|
|
1165
|
+
emptySubtitle
|
|
1166
|
+
} = props;
|
|
1167
|
+
const client = chunkJXLSTVBK_js.useWebSDK();
|
|
1168
|
+
const config = chunkJXLSTVBK_js.useWebSDKConfig();
|
|
1169
|
+
const { product } = chunkBYSZT35R_js.useProduct();
|
|
1170
|
+
const resolvedProductId = product?.id || config.productId;
|
|
1171
|
+
const productLabel = product?.name || productName || "our platform";
|
|
1172
|
+
const [posts, setPosts] = react.useState([]);
|
|
1173
|
+
const [total, setTotal] = react.useState(0);
|
|
1174
|
+
const [loading, setLoading] = react.useState(true);
|
|
1175
|
+
const [error, setError] = react.useState(null);
|
|
1176
|
+
const [offset, setOffset] = react.useState(0);
|
|
1177
|
+
const [activeCategory, setActiveCategory] = react.useState("All");
|
|
1178
|
+
const limit = 12;
|
|
1179
|
+
const fetchPosts = react.useCallback(async () => {
|
|
1180
|
+
if (!resolvedProductId) return;
|
|
1181
|
+
setLoading(true);
|
|
1182
|
+
try {
|
|
1183
|
+
const result = await client.query(CASE_STUDIES_QUERY, {
|
|
1184
|
+
productId: resolvedProductId,
|
|
1185
|
+
// Filter server-side: an unfiltered page of `limit` rows is mostly blog/legal pages, so
|
|
1186
|
+
// real case studies past it were never listed and the page fell back to the empty state.
|
|
1187
|
+
tag: CASE_STUDY_TAG,
|
|
1188
|
+
limit,
|
|
1189
|
+
offset
|
|
1190
|
+
});
|
|
1191
|
+
if (result.errors?.length) {
|
|
1192
|
+
setError(result.errors[0]?.message ?? "Failed to load case studies");
|
|
1193
|
+
setPosts([]);
|
|
1194
|
+
return;
|
|
1195
|
+
}
|
|
1196
|
+
const items = result.data?.publicContentPages?.items || [];
|
|
1197
|
+
const caseStudies = items.filter(
|
|
1198
|
+
(p) => p.tags?.includes(CASE_STUDY_TAG) && hasCustomerSignOff(p)
|
|
1199
|
+
);
|
|
1200
|
+
setPosts(caseStudies);
|
|
1201
|
+
const dropped = items.length - caseStudies.length;
|
|
1202
|
+
setTotal(
|
|
1203
|
+
Math.max(0, (result.data?.publicContentPages?.total || 0) - dropped)
|
|
1204
|
+
);
|
|
1205
|
+
setError(null);
|
|
1206
|
+
} catch {
|
|
1207
|
+
setError("load-failed");
|
|
1208
|
+
setPosts([]);
|
|
1209
|
+
} finally {
|
|
1210
|
+
setLoading(false);
|
|
1211
|
+
}
|
|
1212
|
+
}, [client, resolvedProductId, offset]);
|
|
1213
|
+
react.useEffect(() => {
|
|
1214
|
+
fetchPosts();
|
|
1215
|
+
}, [fetchPosts]);
|
|
1216
|
+
const categories = react.useMemo(() => {
|
|
1217
|
+
const set = /* @__PURE__ */ new Set();
|
|
1218
|
+
posts.forEach((p) => {
|
|
1219
|
+
if (p.category) set.add(p.category);
|
|
1220
|
+
});
|
|
1221
|
+
return ["All", ...Array.from(set)];
|
|
1222
|
+
}, [posts]);
|
|
1223
|
+
const visiblePosts = react.useMemo(() => {
|
|
1224
|
+
if (activeCategory === "All") return posts;
|
|
1225
|
+
return posts.filter((p) => p.category === activeCategory);
|
|
1226
|
+
}, [posts, activeCategory]);
|
|
1227
|
+
const featuredPosts = visiblePosts.filter((p) => p.featured);
|
|
1228
|
+
const regularPosts = visiblePosts.filter((p) => !p.featured);
|
|
1229
|
+
const hasContent = !loading && !error && posts.length > 0;
|
|
1230
|
+
const showEmpty = !loading && (error !== null || posts.length === 0);
|
|
1231
|
+
const resolvedEmptyTitle = emptyTitle ?? "Case studies are on the way";
|
|
1232
|
+
const resolvedEmptySubtitle = emptySubtitle ?? `${productLabel} is early in its journey, and we'd rather show you real, measurable results than filler. We're working closely with our first teams now \u2014 their stories will be published here soon. In the meantime, we'd love to show you what's possible.`;
|
|
1233
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `w-full ${className}`, "data-cs": "case-studies-v2", children: [
|
|
1234
|
+
/* @__PURE__ */ jsxRuntime.jsx(chunk3LFFY7AZ_js.ProseStyles, {}),
|
|
1235
|
+
/* @__PURE__ */ jsxRuntime.jsx(AnimationStyles, {}),
|
|
1236
|
+
seoTitle && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1237
|
+
chunkUXWT7G77_js.PageHead,
|
|
1238
|
+
{
|
|
1239
|
+
title: seoTitle,
|
|
1240
|
+
description: seoDescription || heroSubtitle,
|
|
1241
|
+
productName,
|
|
1242
|
+
keywords: seoKeywords
|
|
1243
|
+
}
|
|
1244
|
+
),
|
|
1245
|
+
/* @__PURE__ */ jsxRuntime.jsxs("section", { className: "relative overflow-hidden", children: [
|
|
1246
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1247
|
+
"div",
|
|
1248
|
+
{
|
|
1249
|
+
className: "pointer-events-none absolute inset-x-0 -top-32 mx-auto h-72 max-w-3xl rounded-full bg-primary/10 blur-3xl",
|
|
1250
|
+
"aria-hidden": "true"
|
|
1251
|
+
}
|
|
1252
|
+
),
|
|
1253
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative mx-auto max-w-7xl px-4 py-16 sm:px-6 sm:py-20 md:py-24 lg:px-8", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mx-auto max-w-3xl text-center", children: [
|
|
1254
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center gap-2 rounded-full border border-primary/20 bg-primary/10 px-3 py-1 text-xs font-semibold uppercase tracking-wide text-primary", children: [
|
|
1255
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "h-1.5 w-1.5 rounded-full bg-primary" }),
|
|
1256
|
+
eyebrow
|
|
1257
|
+
] }),
|
|
1258
|
+
/* @__PURE__ */ jsxRuntime.jsx("h1", { className: "mt-5 text-3xl font-bold tracking-tight text-foreground sm:text-4xl md:text-5xl", children: heroTitle }),
|
|
1259
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-4 text-lg text-muted-foreground", children: heroSubtitle })
|
|
1260
|
+
] }) })
|
|
1261
|
+
] }),
|
|
1262
|
+
/* @__PURE__ */ jsxRuntime.jsx("section", { className: "pb-20 sm:pb-24", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mx-auto max-w-7xl px-4 sm:px-6 lg:px-8", children: loading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid gap-6 sm:gap-8 md:grid-cols-2 lg:grid-cols-3", children: [1, 2, 3, 4, 5, 6].map((i) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1263
|
+
"div",
|
|
1264
|
+
{
|
|
1265
|
+
className: "overflow-hidden rounded-xl border bg-card animate-pulse",
|
|
1266
|
+
children: [
|
|
1267
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "aspect-[16/9] bg-muted" }),
|
|
1268
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3 p-6", children: [
|
|
1269
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-4 w-1/4 rounded bg-muted" }),
|
|
1270
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-6 w-3/4 rounded bg-muted" }),
|
|
1271
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-4 rounded bg-muted" }),
|
|
1272
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-4 w-1/2 rounded bg-muted" })
|
|
1273
|
+
] })
|
|
1274
|
+
]
|
|
1275
|
+
},
|
|
1276
|
+
i
|
|
1277
|
+
)) }) : showEmpty ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
1278
|
+
EmptyState,
|
|
1279
|
+
{
|
|
1280
|
+
productLabel,
|
|
1281
|
+
title: resolvedEmptyTitle,
|
|
1282
|
+
subtitle: resolvedEmptySubtitle,
|
|
1283
|
+
contactHref,
|
|
1284
|
+
contactLabel,
|
|
1285
|
+
exploreHref,
|
|
1286
|
+
exploreLabel
|
|
1287
|
+
}
|
|
1288
|
+
) : hasContent ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
1289
|
+
categories.length > 2 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-10 flex flex-wrap justify-center gap-2", children: categories.map((cat) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
1290
|
+
"button",
|
|
1291
|
+
{
|
|
1292
|
+
type: "button",
|
|
1293
|
+
onClick: () => setActiveCategory(cat),
|
|
1294
|
+
className: `rounded-full border px-4 py-1.5 text-sm font-medium transition-colors ${activeCategory === cat ? "border-primary bg-primary text-primary-foreground" : "border-border bg-background text-muted-foreground hover:border-primary/40 hover:text-foreground"}`,
|
|
1295
|
+
children: cat
|
|
1296
|
+
},
|
|
1297
|
+
cat
|
|
1298
|
+
)) }),
|
|
1299
|
+
featuredPosts.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-10 grid gap-6 sm:gap-8 lg:grid-cols-2", children: featuredPosts.map((post) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
1300
|
+
FeaturedCard,
|
|
1301
|
+
{
|
|
1302
|
+
post,
|
|
1303
|
+
basePath: caseStudyBasePath
|
|
1304
|
+
},
|
|
1305
|
+
post.id
|
|
1306
|
+
)) }),
|
|
1307
|
+
regularPosts.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid gap-6 sm:gap-8 md:grid-cols-2 lg:grid-cols-3", children: regularPosts.map((post) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
1308
|
+
CaseStudyCard,
|
|
1309
|
+
{
|
|
1310
|
+
post,
|
|
1311
|
+
basePath: caseStudyBasePath
|
|
1312
|
+
},
|
|
1313
|
+
post.id
|
|
1314
|
+
)) }),
|
|
1315
|
+
activeCategory === "All" && total > limit && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-14 flex justify-center gap-4", children: [
|
|
1316
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1317
|
+
"button",
|
|
1318
|
+
{
|
|
1319
|
+
onClick: () => setOffset(Math.max(0, offset - limit)),
|
|
1320
|
+
disabled: offset === 0,
|
|
1321
|
+
className: "rounded-lg border px-5 py-2.5 text-sm font-medium transition-colors hover:bg-muted disabled:opacity-40",
|
|
1322
|
+
children: "Previous"
|
|
1323
|
+
}
|
|
1324
|
+
),
|
|
1325
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1326
|
+
"button",
|
|
1327
|
+
{
|
|
1328
|
+
onClick: () => setOffset(offset + limit),
|
|
1329
|
+
disabled: offset + limit >= total,
|
|
1330
|
+
className: "rounded-lg border px-5 py-2.5 text-sm font-medium transition-colors hover:bg-muted disabled:opacity-40",
|
|
1331
|
+
children: "Next"
|
|
1332
|
+
}
|
|
1333
|
+
)
|
|
1334
|
+
] }),
|
|
1335
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-16 overflow-hidden rounded-2xl border bg-gradient-to-br from-primary/10 via-card to-card p-8 text-center sm:p-10", children: [
|
|
1336
|
+
/* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-xl font-bold text-foreground sm:text-2xl", children: "Want results like these?" }),
|
|
1337
|
+
/* @__PURE__ */ jsxRuntime.jsxs("p", { className: "mx-auto mt-2 max-w-xl text-sm text-muted-foreground sm:text-base", children: [
|
|
1338
|
+
"Tell us about your goals and we\u2019ll show you exactly how",
|
|
1339
|
+
" ",
|
|
1340
|
+
productLabel,
|
|
1341
|
+
" can help."
|
|
1342
|
+
] }),
|
|
1343
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1344
|
+
"a",
|
|
1345
|
+
{
|
|
1346
|
+
href: contactHref,
|
|
1347
|
+
className: "mt-6 inline-flex items-center justify-center gap-2 rounded-lg bg-primary px-6 py-3 text-sm font-semibold text-primary-foreground shadow-sm transition-all hover:opacity-90 hover:shadow-md",
|
|
1348
|
+
children: contactLabel
|
|
1349
|
+
}
|
|
1350
|
+
)
|
|
1351
|
+
] })
|
|
1352
|
+
] }) : null }) })
|
|
1353
|
+
] });
|
|
1354
|
+
}
|
|
1355
|
+
function CaseStudyPage(props) {
|
|
1356
|
+
const {
|
|
1357
|
+
productName,
|
|
1358
|
+
caseStudiesListUrl = "/case-studies",
|
|
1359
|
+
backLabel = "Back to Case Studies",
|
|
1360
|
+
contactHref = "/contact",
|
|
1361
|
+
contactLabel = "Get in touch",
|
|
1362
|
+
className = ""
|
|
1363
|
+
} = props;
|
|
1364
|
+
const client = chunkJXLSTVBK_js.useWebSDK();
|
|
1365
|
+
const config = chunkJXLSTVBK_js.useWebSDKConfig();
|
|
1366
|
+
const { product } = chunkBYSZT35R_js.useProduct();
|
|
1367
|
+
const resolvedProductId = product?.id || config.productId;
|
|
1368
|
+
const productLabel = product?.name || productName || "our team";
|
|
1369
|
+
const [post, setPost] = react.useState(null);
|
|
1370
|
+
const [loading, setLoading] = react.useState(true);
|
|
1371
|
+
const [error, setError] = react.useState(null);
|
|
1372
|
+
const slug = typeof window !== "undefined" ? window.location.pathname.split("/").pop() || "" : "";
|
|
1373
|
+
react.useEffect(() => {
|
|
1374
|
+
if (!slug || !resolvedProductId) return;
|
|
1375
|
+
async function fetchPost() {
|
|
1376
|
+
setLoading(true);
|
|
1377
|
+
try {
|
|
1378
|
+
const result = await client.query(CASE_STUDY_QUERY, {
|
|
1379
|
+
slug,
|
|
1380
|
+
productId: resolvedProductId
|
|
1381
|
+
});
|
|
1382
|
+
if (result.errors?.length) {
|
|
1383
|
+
setError(result.errors[0]?.message ?? "Failed to load case study");
|
|
1384
|
+
return;
|
|
1385
|
+
}
|
|
1386
|
+
const page = result.data?.publicContentPage ?? null;
|
|
1387
|
+
setPost(page && hasCustomerSignOff(page) ? page : null);
|
|
1388
|
+
setError(null);
|
|
1389
|
+
} catch {
|
|
1390
|
+
setError("Failed to load case study");
|
|
1391
|
+
} finally {
|
|
1392
|
+
setLoading(false);
|
|
1393
|
+
}
|
|
1394
|
+
}
|
|
1395
|
+
fetchPost();
|
|
1396
|
+
}, [client, slug, resolvedProductId]);
|
|
1397
|
+
if (loading) {
|
|
1398
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `w-full ${className}`, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mx-auto max-w-4xl px-4 py-24 sm:px-6 lg:px-8", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "animate-pulse space-y-6", children: [
|
|
1399
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-8 w-2/3 rounded bg-muted" }),
|
|
1400
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-4 w-1/3 rounded bg-muted" }),
|
|
1401
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "aspect-[16/9] rounded-xl bg-muted" }),
|
|
1402
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-3", children: [1, 2, 3, 4, 5].map((i) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-4 rounded bg-muted" }, i)) })
|
|
1403
|
+
] }) }) });
|
|
1404
|
+
}
|
|
1405
|
+
if (error || !post) {
|
|
1406
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `w-full ${className}`, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mx-auto max-w-2xl px-4 py-24 text-center sm:px-6 lg:px-8", children: [
|
|
1407
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mx-auto flex h-16 w-16 items-center justify-center rounded-2xl bg-primary/10 text-primary", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1408
|
+
"svg",
|
|
1409
|
+
{
|
|
1410
|
+
className: "h-8 w-8",
|
|
1411
|
+
fill: "none",
|
|
1412
|
+
viewBox: "0 0 24 24",
|
|
1413
|
+
stroke: "currentColor",
|
|
1414
|
+
"aria-hidden": "true",
|
|
1415
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1416
|
+
"path",
|
|
1417
|
+
{
|
|
1418
|
+
strokeLinecap: "round",
|
|
1419
|
+
strokeLinejoin: "round",
|
|
1420
|
+
strokeWidth: 1.5,
|
|
1421
|
+
d: "M9.879 7.519c1.171-1.025 3.071-1.025 4.242 0 1.172 1.025 1.172 2.687 0 3.712-.203.179-.43.326-.67.442-.745.361-1.45.999-1.45 1.827v.75M21 12a9 9 0 11-18 0 9 9 0 0118 0zm-9 5.25h.008v.008H12v-.008z"
|
|
1422
|
+
}
|
|
1423
|
+
)
|
|
1424
|
+
}
|
|
1425
|
+
) }),
|
|
1426
|
+
/* @__PURE__ */ jsxRuntime.jsx("h1", { className: "mt-6 text-2xl font-bold text-foreground", children: "Case study not found" }),
|
|
1427
|
+
/* @__PURE__ */ jsxRuntime.jsxs("p", { className: "mx-auto mt-3 max-w-md text-muted-foreground", children: [
|
|
1428
|
+
"This story isn\u2019t available yet \u2014 but there\u2019s plenty more to explore, and we\u2019re always happy to talk through what ",
|
|
1429
|
+
productLabel,
|
|
1430
|
+
" can do."
|
|
1431
|
+
] }),
|
|
1432
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-8 flex flex-col items-center justify-center gap-3 sm:flex-row", children: [
|
|
1433
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
1434
|
+
"a",
|
|
1435
|
+
{
|
|
1436
|
+
href: caseStudiesListUrl,
|
|
1437
|
+
className: "inline-flex items-center justify-center rounded-lg border px-5 py-2.5 text-sm font-semibold text-foreground transition-colors hover:bg-muted",
|
|
1438
|
+
children: [
|
|
1439
|
+
"\u2190 ",
|
|
1440
|
+
backLabel
|
|
1441
|
+
]
|
|
1442
|
+
}
|
|
1443
|
+
),
|
|
1444
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1445
|
+
"a",
|
|
1446
|
+
{
|
|
1447
|
+
href: contactHref,
|
|
1448
|
+
className: "inline-flex items-center justify-center rounded-lg bg-primary px-5 py-2.5 text-sm font-semibold text-primary-foreground transition-all hover:opacity-90",
|
|
1449
|
+
children: contactLabel
|
|
1450
|
+
}
|
|
1451
|
+
)
|
|
1452
|
+
] })
|
|
1453
|
+
] }) });
|
|
1454
|
+
}
|
|
1455
|
+
const formattedDate = formatDate(post.publishedAt || post.lastUpdated);
|
|
1456
|
+
const approvedDate = formatDate(post.customerSignOff?.signedAt);
|
|
1457
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `w-full ${className}`, children: [
|
|
1458
|
+
/* @__PURE__ */ jsxRuntime.jsx(chunk3LFFY7AZ_js.ProseStyles, {}),
|
|
1459
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1460
|
+
chunkUXWT7G77_js.PageHead,
|
|
1461
|
+
{
|
|
1462
|
+
title: post.seoTitle || post.title,
|
|
1463
|
+
description: post.seoDescription || post.excerpt || "",
|
|
1464
|
+
productName,
|
|
1465
|
+
keywords: post.seoKeywords || ""
|
|
1466
|
+
}
|
|
1467
|
+
),
|
|
1468
|
+
/* @__PURE__ */ jsxRuntime.jsxs("article", { className: "mx-auto max-w-4xl px-4 py-16 sm:px-6 sm:py-20 lg:px-8", children: [
|
|
1469
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
1470
|
+
"a",
|
|
1471
|
+
{
|
|
1472
|
+
href: caseStudiesListUrl,
|
|
1473
|
+
className: "mb-8 inline-flex items-center gap-1 text-sm text-muted-foreground transition-colors hover:text-foreground",
|
|
1474
|
+
children: [
|
|
1475
|
+
"\u2190 ",
|
|
1476
|
+
backLabel
|
|
1477
|
+
]
|
|
1478
|
+
}
|
|
1479
|
+
),
|
|
1480
|
+
post.category && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "mb-4 inline-block rounded-full bg-primary/10 px-2.5 py-1 text-xs font-medium text-primary", children: post.category }),
|
|
1481
|
+
/* @__PURE__ */ jsxRuntime.jsx("h1", { className: "mb-4 text-3xl font-bold tracking-tight text-foreground sm:text-4xl md:text-5xl", children: post.title }),
|
|
1482
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-8 flex flex-wrap items-center gap-3 text-sm text-muted-foreground", children: [
|
|
1483
|
+
post.author && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-foreground", children: post.author }),
|
|
1484
|
+
post.author && formattedDate && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground/40", children: "\xB7" }),
|
|
1485
|
+
formattedDate && /* @__PURE__ */ jsxRuntime.jsx("span", { children: formattedDate }),
|
|
1486
|
+
post.readingTime ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
1487
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground/40", children: "\xB7" }),
|
|
1488
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
1489
|
+
post.readingTime,
|
|
1490
|
+
" min read"
|
|
1491
|
+
] })
|
|
1492
|
+
] }) : null
|
|
1493
|
+
] }),
|
|
1494
|
+
approvedDate && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1495
|
+
"p",
|
|
1496
|
+
{
|
|
1497
|
+
className: "-mt-4 mb-8 text-xs text-muted-foreground",
|
|
1498
|
+
"data-cs": "customer-signoff",
|
|
1499
|
+
children: [
|
|
1500
|
+
"Approved for publication by the customer on ",
|
|
1501
|
+
approvedDate
|
|
1502
|
+
]
|
|
1503
|
+
}
|
|
1504
|
+
),
|
|
1505
|
+
post.thumbnail && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-10 aspect-[16/9] overflow-hidden rounded-xl", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1506
|
+
"img",
|
|
1507
|
+
{
|
|
1508
|
+
src: post.thumbnail,
|
|
1509
|
+
alt: post.title,
|
|
1510
|
+
className: "h-full w-full object-cover"
|
|
1511
|
+
}
|
|
1512
|
+
) }),
|
|
1513
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "boff-prose max-w-none", children: /* @__PURE__ */ jsxRuntime.jsx(chunk4U6YAII5_js.ContentRenderer, { content: post.content, format: post.contentFormat }) }),
|
|
1514
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-14 rounded-2xl border bg-gradient-to-br from-primary/10 via-card to-card p-8 text-center", children: [
|
|
1515
|
+
/* @__PURE__ */ jsxRuntime.jsxs("h2", { className: "text-xl font-bold text-foreground", children: [
|
|
1516
|
+
"Curious what ",
|
|
1517
|
+
productLabel,
|
|
1518
|
+
" could do for you?"
|
|
1519
|
+
] }),
|
|
1520
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "mx-auto mt-2 max-w-lg text-sm text-muted-foreground", children: "We\u2019re happy to walk you through it \u2014 no pressure, just a conversation about your goals." }),
|
|
1521
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1522
|
+
"a",
|
|
1523
|
+
{
|
|
1524
|
+
href: contactHref,
|
|
1525
|
+
className: "mt-6 inline-flex items-center justify-center rounded-lg bg-primary px-6 py-3 text-sm font-semibold text-primary-foreground shadow-sm transition-all hover:opacity-90 hover:shadow-md",
|
|
1526
|
+
children: contactLabel
|
|
1527
|
+
}
|
|
1528
|
+
)
|
|
1529
|
+
] })
|
|
1530
|
+
] })
|
|
1531
|
+
] });
|
|
1532
|
+
}
|
|
1533
|
+
var CHANGELOG_TAG = "changelog";
|
|
1534
|
+
var CHANGELOG_LIST_QUERY = `
|
|
1535
|
+
query ChangelogList($productId: String!, $limit: Int, $offset: Int) {
|
|
1536
|
+
publicContentPages(productId: $productId, limit: $limit, offset: $offset) {
|
|
1537
|
+
items {
|
|
1538
|
+
id
|
|
1539
|
+
title
|
|
1540
|
+
slug
|
|
1541
|
+
lastUpdated
|
|
1542
|
+
tags
|
|
1543
|
+
excerpt
|
|
1544
|
+
seoDescription
|
|
1545
|
+
thumbnail
|
|
1546
|
+
author
|
|
1547
|
+
publishedAt
|
|
1548
|
+
readingTime
|
|
1549
|
+
featured
|
|
1550
|
+
category
|
|
1551
|
+
}
|
|
1552
|
+
total
|
|
1553
|
+
hasMore
|
|
1554
|
+
}
|
|
1555
|
+
}
|
|
1556
|
+
`;
|
|
1557
|
+
var CHANGELOG_ENTRY_QUERY = `
|
|
1558
|
+
query ChangelogEntry($slug: String!, $productId: String) {
|
|
1559
|
+
publicContentPage(slug: $slug, productId: $productId) {
|
|
1560
|
+
content
|
|
1561
|
+
contentFormat
|
|
1562
|
+
}
|
|
1563
|
+
}
|
|
1564
|
+
`;
|
|
1565
|
+
function formatDate2(value) {
|
|
1566
|
+
if (!value) return "";
|
|
1567
|
+
return new Date(value).toLocaleDateString("en-US", {
|
|
1568
|
+
year: "numeric",
|
|
1569
|
+
month: "long",
|
|
1570
|
+
day: "numeric"
|
|
1571
|
+
});
|
|
1572
|
+
}
|
|
1573
|
+
function sortByDateDesc(a, b) {
|
|
1574
|
+
const da = new Date(a.publishedAt || a.lastUpdated || 0).getTime();
|
|
1575
|
+
const db = new Date(b.publishedAt || b.lastUpdated || 0).getTime();
|
|
1576
|
+
return db - da;
|
|
1577
|
+
}
|
|
1578
|
+
function normalize(value) {
|
|
1579
|
+
return value.toLowerCase().trim();
|
|
1580
|
+
}
|
|
1581
|
+
function paginate(items, page, pageSize) {
|
|
1582
|
+
const start = (page - 1) * pageSize;
|
|
1583
|
+
return items.slice(start, start + pageSize);
|
|
1584
|
+
}
|
|
1585
|
+
function parseEntryDate(date) {
|
|
1586
|
+
return new Date(date).getTime();
|
|
1587
|
+
}
|
|
1588
|
+
function useCmsChangelog() {
|
|
1589
|
+
const client = chunkJXLSTVBK_js.useWebSDK();
|
|
1590
|
+
const config = chunkJXLSTVBK_js.useWebSDKConfig();
|
|
1591
|
+
const { product } = chunkBYSZT35R_js.useProduct();
|
|
1592
|
+
const resolvedProductId = product?.id || config.productId;
|
|
1593
|
+
const [entries, setEntries] = react.useState([]);
|
|
1594
|
+
const [loading, setLoading] = react.useState(true);
|
|
1595
|
+
const [error, setError] = react.useState(null);
|
|
1596
|
+
const fetchEntries = react.useCallback(async () => {
|
|
1597
|
+
if (!resolvedProductId) {
|
|
1598
|
+
setLoading(false);
|
|
1599
|
+
return;
|
|
1600
|
+
}
|
|
1601
|
+
setLoading(true);
|
|
1602
|
+
try {
|
|
1603
|
+
const listResult = await client.query(CHANGELOG_LIST_QUERY, {
|
|
1604
|
+
productId: resolvedProductId,
|
|
1605
|
+
limit: 50,
|
|
1606
|
+
offset: 0
|
|
1607
|
+
});
|
|
1608
|
+
if (listResult.errors?.length) {
|
|
1609
|
+
setError(listResult.errors[0]?.message ?? "Failed to load changelog");
|
|
1610
|
+
return;
|
|
1611
|
+
}
|
|
1612
|
+
const changelogItems = (listResult.data?.publicContentPages?.items || []).filter((p) => p.tags?.includes(CHANGELOG_TAG)).sort(sortByDateDesc);
|
|
1613
|
+
const resolved = await Promise.all(
|
|
1614
|
+
changelogItems.map(async (item) => {
|
|
1615
|
+
try {
|
|
1616
|
+
const detail = await client.query(CHANGELOG_ENTRY_QUERY, {
|
|
1617
|
+
slug: item.slug,
|
|
1618
|
+
productId: resolvedProductId
|
|
1619
|
+
});
|
|
1620
|
+
const page = detail.data?.publicContentPage;
|
|
1621
|
+
return {
|
|
1622
|
+
...item,
|
|
1623
|
+
content: page?.content,
|
|
1624
|
+
contentFormat: page?.contentFormat
|
|
1625
|
+
};
|
|
1626
|
+
} catch {
|
|
1627
|
+
return { ...item };
|
|
1628
|
+
}
|
|
1629
|
+
})
|
|
1630
|
+
);
|
|
1631
|
+
setEntries(resolved);
|
|
1632
|
+
setError(null);
|
|
1633
|
+
} catch {
|
|
1634
|
+
setError("Failed to load changelog");
|
|
1635
|
+
} finally {
|
|
1636
|
+
setLoading(false);
|
|
1637
|
+
}
|
|
1638
|
+
}, [client, resolvedProductId]);
|
|
1639
|
+
react.useEffect(() => {
|
|
1640
|
+
fetchEntries();
|
|
1641
|
+
}, [fetchEntries]);
|
|
1642
|
+
return { entries, loading, error };
|
|
1643
|
+
}
|
|
1644
|
+
function CmsTimeline(props) {
|
|
1645
|
+
const { entries, loading, error } = props;
|
|
1646
|
+
if (loading) {
|
|
1647
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "max-w-3xl mx-auto space-y-12", children: [1, 2, 3].map((i) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
1648
|
+
"div",
|
|
1649
|
+
{
|
|
1650
|
+
className: "rounded-2xl border border-border/40 bg-card overflow-hidden animate-pulse",
|
|
1651
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-6 sm:p-8 space-y-4", children: [
|
|
1652
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-3 bg-muted rounded w-1/3" }),
|
|
1653
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-6 bg-muted rounded w-2/3" }),
|
|
1654
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-4 bg-muted rounded" }),
|
|
1655
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-4 bg-muted rounded w-5/6" })
|
|
1656
|
+
] })
|
|
1657
|
+
},
|
|
1658
|
+
i
|
|
1659
|
+
)) });
|
|
1660
|
+
}
|
|
1661
|
+
if (error) {
|
|
1662
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-center py-12", children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground", children: error }) });
|
|
1663
|
+
}
|
|
1664
|
+
if (entries.length === 0) {
|
|
1665
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-center py-12", children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground", children: "No changelog entries yet. Check back soon!" }) });
|
|
1666
|
+
}
|
|
1667
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "max-w-3xl mx-auto space-y-12", children: entries.map((entry) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1668
|
+
"article",
|
|
1669
|
+
{
|
|
1670
|
+
id: entry.slug,
|
|
1671
|
+
className: "rounded-2xl border border-border/40 bg-card overflow-hidden scroll-mt-24",
|
|
1672
|
+
children: [
|
|
1673
|
+
entry.thumbnail && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1674
|
+
"img",
|
|
1675
|
+
{
|
|
1676
|
+
src: entry.thumbnail,
|
|
1677
|
+
alt: "",
|
|
1678
|
+
width: 1024,
|
|
1679
|
+
height: 576,
|
|
1680
|
+
loading: "lazy",
|
|
1681
|
+
decoding: "async",
|
|
1682
|
+
className: "w-full aspect-video object-cover border-b border-border/40"
|
|
1683
|
+
}
|
|
1684
|
+
),
|
|
1685
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-6 sm:p-8", children: [
|
|
1686
|
+
/* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-xs text-muted-foreground mb-2", children: [
|
|
1687
|
+
entry.publishedAt && /* @__PURE__ */ jsxRuntime.jsx("time", { dateTime: entry.publishedAt, children: formatDate2(entry.publishedAt || entry.lastUpdated) }),
|
|
1688
|
+
entry.author && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
1689
|
+
" \xB7 ",
|
|
1690
|
+
entry.author
|
|
1691
|
+
] })
|
|
1692
|
+
] }),
|
|
1693
|
+
/* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-xl sm:text-2xl font-bold text-foreground mb-4", children: entry.title }),
|
|
1694
|
+
entry.content ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "boff-prose boff-prose-sm max-w-none", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1695
|
+
chunk4U6YAII5_js.ContentRenderer,
|
|
1696
|
+
{
|
|
1697
|
+
content: entry.content,
|
|
1698
|
+
format: entry.contentFormat
|
|
1699
|
+
}
|
|
1700
|
+
) }) : entry.excerpt && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground leading-relaxed", children: entry.excerpt })
|
|
1701
|
+
] })
|
|
1702
|
+
]
|
|
1703
|
+
},
|
|
1704
|
+
entry.id
|
|
1705
|
+
)) });
|
|
1706
|
+
}
|
|
1707
|
+
function EntryContent({ content }) {
|
|
1708
|
+
if (typeof content === "string") {
|
|
1709
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "boff-prose boff-prose-sm max-w-none", children: /* @__PURE__ */ jsxRuntime.jsx(chunk4U6YAII5_js.ContentRenderer, { content, format: "markdown" }) });
|
|
1710
|
+
}
|
|
1711
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "boff-prose boff-prose-sm max-w-none", children: content });
|
|
1712
|
+
}
|
|
1713
|
+
function EntriesTimeline(props) {
|
|
1714
|
+
const { entries, pageSize, productName } = props;
|
|
1715
|
+
const [query, setQuery] = react.useState("");
|
|
1716
|
+
const [selectedCategory, setSelectedCategory] = react.useState(null);
|
|
1717
|
+
const [page, setPage] = react.useState(1);
|
|
1718
|
+
const categories = react.useMemo(
|
|
1719
|
+
() => Array.from(new Set(entries.map((e) => e.category))).sort(),
|
|
1720
|
+
[entries]
|
|
1721
|
+
);
|
|
1722
|
+
const filtered = react.useMemo(() => {
|
|
1723
|
+
const normalized = normalize(query);
|
|
1724
|
+
return entries.filter((entry) => {
|
|
1725
|
+
if (selectedCategory && entry.category !== selectedCategory) {
|
|
1726
|
+
return false;
|
|
1727
|
+
}
|
|
1728
|
+
if (!normalized) return true;
|
|
1729
|
+
const haystack = [
|
|
1730
|
+
entry.title,
|
|
1731
|
+
entry.version,
|
|
1732
|
+
entry.category,
|
|
1733
|
+
...entry.tags ?? [],
|
|
1734
|
+
typeof entry.content === "string" ? entry.content : ""
|
|
1735
|
+
].join(" ").toLowerCase();
|
|
1736
|
+
return haystack.includes(normalized);
|
|
1737
|
+
}).sort((a, b) => parseEntryDate(b.date) - parseEntryDate(a.date));
|
|
1738
|
+
}, [entries, query, selectedCategory]);
|
|
1739
|
+
const totalPages = Math.max(1, Math.ceil(filtered.length / pageSize));
|
|
1740
|
+
const safePage = Math.min(page, totalPages);
|
|
1741
|
+
const pageItems = paginate(filtered, safePage, pageSize);
|
|
1742
|
+
react.useEffect(() => {
|
|
1743
|
+
setPage(1);
|
|
1744
|
+
}, [query, selectedCategory]);
|
|
1745
|
+
if (entries.length === 0) {
|
|
1746
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-center py-12", children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground", children: "No changelog entries yet. Check back soon!" }) });
|
|
1747
|
+
}
|
|
1748
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "max-w-3xl mx-auto", children: [
|
|
1749
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-8 space-y-4", children: [
|
|
1750
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
|
|
1751
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1752
|
+
lucideReact.Search,
|
|
1753
|
+
{
|
|
1754
|
+
className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground",
|
|
1755
|
+
"aria-hidden": "true"
|
|
1756
|
+
}
|
|
1757
|
+
),
|
|
1758
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1759
|
+
chunk7A6R7CGG_js.Input,
|
|
1760
|
+
{
|
|
1761
|
+
type: "search",
|
|
1762
|
+
placeholder: "Search releases, features, fixes\u2026",
|
|
1763
|
+
value: query,
|
|
1764
|
+
onChange: (e) => setQuery(e.target.value),
|
|
1765
|
+
className: "pl-9",
|
|
1766
|
+
"aria-label": "Search changelog"
|
|
1767
|
+
}
|
|
1768
|
+
)
|
|
1769
|
+
] }),
|
|
1770
|
+
categories.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap gap-2", children: [
|
|
1771
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1772
|
+
"button",
|
|
1773
|
+
{
|
|
1774
|
+
type: "button",
|
|
1775
|
+
onClick: () => setSelectedCategory(null),
|
|
1776
|
+
className: chunkC6OJIHNO_js.cn(
|
|
1777
|
+
"px-3 py-1 rounded-full text-xs font-medium border transition-colors",
|
|
1778
|
+
selectedCategory === null ? "bg-primary text-primary-foreground border-primary" : "bg-background text-muted-foreground border-border/60 hover:border-primary/40"
|
|
1779
|
+
),
|
|
1780
|
+
children: "All"
|
|
1781
|
+
}
|
|
1782
|
+
),
|
|
1783
|
+
categories.map((category) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
1784
|
+
"button",
|
|
1785
|
+
{
|
|
1786
|
+
type: "button",
|
|
1787
|
+
onClick: () => setSelectedCategory(category),
|
|
1788
|
+
className: chunkC6OJIHNO_js.cn(
|
|
1789
|
+
"px-3 py-1 rounded-full text-xs font-medium border transition-colors",
|
|
1790
|
+
selectedCategory === category ? "bg-primary text-primary-foreground border-primary" : "bg-background text-muted-foreground border-border/60 hover:border-primary/40"
|
|
1791
|
+
),
|
|
1792
|
+
children: category
|
|
1793
|
+
},
|
|
1794
|
+
category
|
|
1795
|
+
))
|
|
1796
|
+
] })
|
|
1797
|
+
] }),
|
|
1798
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
|
|
1799
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1800
|
+
"div",
|
|
1801
|
+
{
|
|
1802
|
+
className: "absolute left-[1.125rem] top-3 bottom-3 w-px bg-border/60 hidden sm:block",
|
|
1803
|
+
"aria-hidden": "true"
|
|
1804
|
+
}
|
|
1805
|
+
),
|
|
1806
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-8", children: pageItems.map((entry) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1807
|
+
"article",
|
|
1808
|
+
{
|
|
1809
|
+
className: "relative sm:pl-12",
|
|
1810
|
+
children: [
|
|
1811
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1812
|
+
"div",
|
|
1813
|
+
{
|
|
1814
|
+
className: "hidden sm:flex absolute left-2 top-2 h-5 w-5 items-center justify-center rounded-full border-2 border-background bg-primary ring-1 ring-border/40",
|
|
1815
|
+
"aria-hidden": "true",
|
|
1816
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "h-2 w-2 rounded-full bg-primary-foreground" })
|
|
1817
|
+
}
|
|
1818
|
+
),
|
|
1819
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-2xl border border-border/40 bg-card overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-6 sm:p-8", children: [
|
|
1820
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-2 mb-3", children: [
|
|
1821
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "inline-flex items-center rounded-md bg-primary/10 px-2 py-1 text-xs font-medium text-primary", children: entry.category }),
|
|
1822
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center rounded-md bg-muted px-2 py-1 text-xs font-mono font-medium text-muted-foreground", children: [
|
|
1823
|
+
"v",
|
|
1824
|
+
entry.version
|
|
1825
|
+
] }),
|
|
1826
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1827
|
+
"time",
|
|
1828
|
+
{
|
|
1829
|
+
className: "text-xs text-muted-foreground",
|
|
1830
|
+
dateTime: entry.date,
|
|
1831
|
+
children: formatDate2(entry.date)
|
|
1832
|
+
}
|
|
1833
|
+
)
|
|
1834
|
+
] }),
|
|
1835
|
+
entry.tags && entry.tags.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap gap-1.5 mb-3", children: entry.tags.map((tag) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
1836
|
+
"span",
|
|
1837
|
+
{
|
|
1838
|
+
className: "text-[10px] uppercase tracking-wide text-muted-foreground bg-background border border-border/40 px-1.5 py-0.5 rounded",
|
|
1839
|
+
children: tag
|
|
1840
|
+
},
|
|
1841
|
+
tag
|
|
1842
|
+
)) }),
|
|
1843
|
+
/* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-xl sm:text-2xl font-bold text-foreground mb-4", children: entry.title }),
|
|
1844
|
+
/* @__PURE__ */ jsxRuntime.jsx(EntryContent, { content: entry.content })
|
|
1845
|
+
] }) })
|
|
1846
|
+
]
|
|
1847
|
+
},
|
|
1848
|
+
`${entry.version}-${entry.date}`
|
|
1849
|
+
)) })
|
|
1850
|
+
] }),
|
|
1851
|
+
pageItems.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-center py-12", children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground", children: "No entries match your filters." }) }),
|
|
1852
|
+
totalPages > 1 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-10 flex items-center justify-between", children: [
|
|
1853
|
+
/* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-sm text-muted-foreground", children: [
|
|
1854
|
+
"Page ",
|
|
1855
|
+
safePage,
|
|
1856
|
+
" of ",
|
|
1857
|
+
totalPages,
|
|
1858
|
+
" \xB7 ",
|
|
1859
|
+
filtered.length,
|
|
1860
|
+
" entries"
|
|
1861
|
+
] }),
|
|
1862
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
1863
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1864
|
+
chunkUQ2HALUD_js.Button,
|
|
1865
|
+
{
|
|
1866
|
+
variant: "outline",
|
|
1867
|
+
size: "sm",
|
|
1868
|
+
onClick: () => setPage((p) => Math.max(1, p - 1)),
|
|
1869
|
+
disabled: safePage <= 1,
|
|
1870
|
+
"aria-label": "Previous page",
|
|
1871
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronLeft, { className: "h-4 w-4" })
|
|
1872
|
+
}
|
|
1873
|
+
),
|
|
1874
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1875
|
+
chunkUQ2HALUD_js.Button,
|
|
1876
|
+
{
|
|
1877
|
+
variant: "outline",
|
|
1878
|
+
size: "sm",
|
|
1879
|
+
onClick: () => setPage((p) => Math.min(totalPages, p + 1)),
|
|
1880
|
+
disabled: safePage >= totalPages,
|
|
1881
|
+
"aria-label": "Next page",
|
|
1882
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { className: "h-4 w-4" })
|
|
1883
|
+
}
|
|
1884
|
+
)
|
|
1885
|
+
] })
|
|
1886
|
+
] }),
|
|
1887
|
+
productName && pageItems.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("script", { type: "application/ld+json", children: JSON.stringify({
|
|
1888
|
+
"@context": "https://schema.org",
|
|
1889
|
+
"@type": "ItemList",
|
|
1890
|
+
name: `${productName} Changelog`,
|
|
1891
|
+
itemListElement: pageItems.map((entry, index) => ({
|
|
1892
|
+
"@type": "ListItem",
|
|
1893
|
+
position: (safePage - 1) * pageSize + index + 1,
|
|
1894
|
+
name: entry.title,
|
|
1895
|
+
description: typeof entry.content === "string" ? entry.content.slice(0, 200) : void 0,
|
|
1896
|
+
datePublished: entry.date
|
|
1897
|
+
}))
|
|
1898
|
+
}) })
|
|
1899
|
+
] });
|
|
1900
|
+
}
|
|
1901
|
+
function ChangelogPage(props) {
|
|
1902
|
+
const {
|
|
1903
|
+
productName,
|
|
1904
|
+
heroEyebrow = "What's new",
|
|
1905
|
+
heroTitle = "Changelog",
|
|
1906
|
+
heroSubtitle = "Platform updates, improvements, and announcements \u2014 newest first.",
|
|
1907
|
+
ctaTitle,
|
|
1908
|
+
ctaSubtitle,
|
|
1909
|
+
ctaHref,
|
|
1910
|
+
ctaLabel,
|
|
1911
|
+
className = "",
|
|
1912
|
+
seoTitle,
|
|
1913
|
+
seoDescription,
|
|
1914
|
+
seoKeywords,
|
|
1915
|
+
entries,
|
|
1916
|
+
pageSize = 10
|
|
1917
|
+
} = props;
|
|
1918
|
+
const { product } = chunkBYSZT35R_js.useProduct();
|
|
1919
|
+
const resolvedProductName = productName || product?.name;
|
|
1920
|
+
const cms = useCmsChangelog();
|
|
1921
|
+
const showCta = Boolean(ctaHref && ctaLabel);
|
|
1922
|
+
const isPropDriven = entries != null;
|
|
1923
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `w-full ${className}`, children: [
|
|
1924
|
+
/* @__PURE__ */ jsxRuntime.jsx(chunk3LFFY7AZ_js.ProseStyles, {}),
|
|
1925
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1926
|
+
chunkUXWT7G77_js.PageHead,
|
|
1927
|
+
{
|
|
1928
|
+
title: seoTitle || heroTitle,
|
|
1929
|
+
description: seoDescription || heroSubtitle,
|
|
1930
|
+
productName: resolvedProductName,
|
|
1931
|
+
keywords: seoKeywords
|
|
1932
|
+
}
|
|
1933
|
+
),
|
|
1934
|
+
/* @__PURE__ */ jsxRuntime.jsx("section", { className: "py-16 md:py-20 px-4 sm:px-6 lg:px-8 text-center", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "max-w-3xl mx-auto", children: [
|
|
1935
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "inline-flex items-center gap-2 px-3 py-1.5 rounded-full bg-primary/10 border border-primary/20 text-xs font-medium text-primary mb-6", children: [
|
|
1936
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.History, { className: "h-3.5 w-3.5", "aria-hidden": "true" }),
|
|
1937
|
+
heroEyebrow
|
|
1938
|
+
] }),
|
|
1939
|
+
/* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-4xl sm:text-5xl font-bold text-foreground mb-4", children: heroTitle }),
|
|
1940
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-lg text-muted-foreground", children: heroSubtitle })
|
|
1941
|
+
] }) }),
|
|
1942
|
+
/* @__PURE__ */ jsxRuntime.jsx("section", { className: "px-4 sm:px-6 lg:px-8 pb-20", children: isPropDriven ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
1943
|
+
EntriesTimeline,
|
|
1944
|
+
{
|
|
1945
|
+
entries,
|
|
1946
|
+
pageSize,
|
|
1947
|
+
productName: resolvedProductName
|
|
1948
|
+
}
|
|
1949
|
+
) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
1950
|
+
CmsTimeline,
|
|
1951
|
+
{
|
|
1952
|
+
entries: cms.entries,
|
|
1953
|
+
loading: cms.loading,
|
|
1954
|
+
error: cms.error
|
|
1955
|
+
}
|
|
1956
|
+
) }),
|
|
1957
|
+
showCta && /* @__PURE__ */ jsxRuntime.jsx("section", { className: "py-14 px-4 sm:px-6 lg:px-8 bg-primary/5 border-t border-border/40", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "max-w-2xl mx-auto text-center", children: [
|
|
1958
|
+
ctaTitle && /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-2xl font-bold text-foreground mb-3", children: ctaTitle }),
|
|
1959
|
+
ctaSubtitle && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground mb-7", children: ctaSubtitle }),
|
|
1960
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1961
|
+
"a",
|
|
1962
|
+
{
|
|
1963
|
+
href: ctaHref,
|
|
1964
|
+
className: "inline-flex items-center justify-center rounded-lg bg-primary px-6 py-3 text-sm font-medium text-primary-foreground hover:opacity-90 transition-opacity",
|
|
1965
|
+
children: ctaLabel
|
|
1966
|
+
}
|
|
1967
|
+
)
|
|
1968
|
+
] }) })
|
|
1969
|
+
] });
|
|
1970
|
+
}
|
|
1971
|
+
|
|
1972
|
+
// src/content/utils.ts
|
|
1973
|
+
function formatBytes(bytes) {
|
|
1974
|
+
if (bytes == null) return "";
|
|
1975
|
+
if (bytes < 1024) return `${bytes} B`;
|
|
1976
|
+
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(0)} KB`;
|
|
1977
|
+
return `${(bytes / 1024 / 1024).toFixed(1)} MB`;
|
|
1978
|
+
}
|
|
1979
|
+
function fileExt(file) {
|
|
1980
|
+
const name = file.fileName || file.fileUrl.split("/").pop()?.split("?")[0] || "";
|
|
1981
|
+
const ext = name.split(".").pop();
|
|
1982
|
+
return ext && ext !== name ? ext.toUpperCase() : "FILE";
|
|
1983
|
+
}
|
|
1984
|
+
async function downloadFile(e, file) {
|
|
1985
|
+
e.preventDefault();
|
|
1986
|
+
const openInTab = () => window.open(file.fileUrl, "_blank", "noopener,noreferrer");
|
|
1987
|
+
const name = file.fileName || file.fileUrl.split("/").pop()?.split("?")[0] || file.title || "download";
|
|
1988
|
+
try {
|
|
1989
|
+
const res = await fetch(file.fileUrl, { mode: "cors" });
|
|
1990
|
+
if (!res.ok) {
|
|
1991
|
+
openInTab();
|
|
1992
|
+
return;
|
|
1993
|
+
}
|
|
1994
|
+
const blob = await res.blob();
|
|
1995
|
+
const objUrl = URL.createObjectURL(blob);
|
|
1996
|
+
const a = document.createElement("a");
|
|
1997
|
+
a.href = objUrl;
|
|
1998
|
+
a.download = name;
|
|
1999
|
+
document.body.appendChild(a);
|
|
2000
|
+
a.click();
|
|
2001
|
+
a.remove();
|
|
2002
|
+
URL.revokeObjectURL(objUrl);
|
|
2003
|
+
} catch {
|
|
2004
|
+
openInTab();
|
|
2005
|
+
}
|
|
2006
|
+
}
|
|
2007
|
+
var PRESS_KIT_QUERY = `
|
|
2008
|
+
query PublicPressKit($productId: String!, $limit: Int, $offset: Int) {
|
|
2009
|
+
publicPressKitAssets(productId: $productId, limit: $limit, offset: $offset) {
|
|
2010
|
+
items {
|
|
2011
|
+
id
|
|
2012
|
+
category
|
|
2013
|
+
title
|
|
2014
|
+
slug
|
|
2015
|
+
description
|
|
2016
|
+
fileUrl
|
|
2017
|
+
fileName
|
|
2018
|
+
fileSize
|
|
2019
|
+
mimeType
|
|
2020
|
+
thumbnailUrl
|
|
2021
|
+
version
|
|
2022
|
+
tags
|
|
2023
|
+
sortOrder
|
|
2024
|
+
updatedAt
|
|
2025
|
+
}
|
|
2026
|
+
total
|
|
2027
|
+
hasMore
|
|
2028
|
+
}
|
|
2029
|
+
}
|
|
2030
|
+
`;
|
|
2031
|
+
var PRESS_RELEASES_QUERY = `
|
|
2032
|
+
query PublicPressReleases($productId: String!, $limit: Int, $offset: Int) {
|
|
2033
|
+
publicContentPages(productId: $productId, limit: $limit, offset: $offset) {
|
|
2034
|
+
items {
|
|
2035
|
+
id
|
|
2036
|
+
title
|
|
2037
|
+
slug
|
|
2038
|
+
lastUpdated
|
|
2039
|
+
tags
|
|
2040
|
+
seoDescription
|
|
2041
|
+
excerpt
|
|
2042
|
+
thumbnail
|
|
2043
|
+
author
|
|
2044
|
+
publishedAt
|
|
2045
|
+
readingTime
|
|
2046
|
+
featured
|
|
2047
|
+
category
|
|
2048
|
+
}
|
|
2049
|
+
total
|
|
2050
|
+
hasMore
|
|
2051
|
+
}
|
|
2052
|
+
}
|
|
2053
|
+
`;
|
|
2054
|
+
var CATEGORY_ORDER = [
|
|
2055
|
+
"LOGO",
|
|
2056
|
+
"BANNER",
|
|
2057
|
+
"SCREENSHOT",
|
|
2058
|
+
"BRAND_GUIDE",
|
|
2059
|
+
"BROCHURE",
|
|
2060
|
+
"DOCUMENT",
|
|
2061
|
+
"PRESS_RELEASE"
|
|
2062
|
+
];
|
|
2063
|
+
var CATEGORY_LABELS = {
|
|
2064
|
+
LOGO: "Logos",
|
|
2065
|
+
BANNER: "Banners",
|
|
2066
|
+
SCREENSHOT: "Screenshots",
|
|
2067
|
+
BRAND_GUIDE: "Brand Guides",
|
|
2068
|
+
BROCHURE: "Brochures",
|
|
2069
|
+
DOCUMENT: "Documents",
|
|
2070
|
+
PRESS_RELEASE: "Press Releases"
|
|
2071
|
+
};
|
|
2072
|
+
function isImageAsset(a) {
|
|
2073
|
+
return (a.mimeType || "").startsWith("image/");
|
|
2074
|
+
}
|
|
2075
|
+
function PressKitLightbox({
|
|
2076
|
+
asset,
|
|
2077
|
+
onClose
|
|
2078
|
+
}) {
|
|
2079
|
+
react.useEffect(() => {
|
|
2080
|
+
if (!asset) return;
|
|
2081
|
+
const onKey = (e) => {
|
|
2082
|
+
if (e.key === "Escape") onClose();
|
|
2083
|
+
};
|
|
2084
|
+
document.addEventListener("keydown", onKey);
|
|
2085
|
+
const prevOverflow = document.body.style.overflow;
|
|
2086
|
+
document.body.style.overflow = "hidden";
|
|
2087
|
+
return () => {
|
|
2088
|
+
document.removeEventListener("keydown", onKey);
|
|
2089
|
+
document.body.style.overflow = prevOverflow;
|
|
2090
|
+
};
|
|
2091
|
+
}, [asset, onClose]);
|
|
2092
|
+
if (!asset) return null;
|
|
2093
|
+
const ext = (asset.mimeType || "file").split("/").pop()?.toUpperCase() || "FILE";
|
|
2094
|
+
const size = formatBytes(asset.fileSize);
|
|
2095
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2096
|
+
"div",
|
|
2097
|
+
{
|
|
2098
|
+
role: "dialog",
|
|
2099
|
+
"aria-modal": "true",
|
|
2100
|
+
"aria-label": `${asset.title} preview`,
|
|
2101
|
+
onClick: onClose,
|
|
2102
|
+
className: "fixed inset-0 z-50 flex items-center justify-center bg-black/80 p-4 sm:p-8",
|
|
2103
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2104
|
+
"div",
|
|
2105
|
+
{
|
|
2106
|
+
onClick: (e) => e.stopPropagation(),
|
|
2107
|
+
className: "relative flex max-h-full w-full max-w-4xl flex-col overflow-hidden rounded-xl border bg-card shadow-2xl",
|
|
2108
|
+
children: [
|
|
2109
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between gap-4 border-b p-4", children: [
|
|
2110
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0", children: [
|
|
2111
|
+
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "truncate text-sm font-semibold text-foreground", children: asset.title }),
|
|
2112
|
+
/* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-xs text-muted-foreground", children: [
|
|
2113
|
+
ext,
|
|
2114
|
+
size ? ` \xB7 ${size}` : ""
|
|
2115
|
+
] })
|
|
2116
|
+
] }),
|
|
2117
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2118
|
+
"button",
|
|
2119
|
+
{
|
|
2120
|
+
type: "button",
|
|
2121
|
+
onClick: onClose,
|
|
2122
|
+
"aria-label": "Close preview",
|
|
2123
|
+
className: "shrink-0 rounded-md p-1.5 text-muted-foreground transition-colors hover:bg-muted hover:text-foreground",
|
|
2124
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2125
|
+
"svg",
|
|
2126
|
+
{
|
|
2127
|
+
className: "h-5 w-5",
|
|
2128
|
+
fill: "none",
|
|
2129
|
+
viewBox: "0 0 24 24",
|
|
2130
|
+
stroke: "currentColor",
|
|
2131
|
+
strokeWidth: 2,
|
|
2132
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2133
|
+
"path",
|
|
2134
|
+
{
|
|
2135
|
+
strokeLinecap: "round",
|
|
2136
|
+
strokeLinejoin: "round",
|
|
2137
|
+
d: "M6 18L18 6M6 6l12 12"
|
|
2138
|
+
}
|
|
2139
|
+
)
|
|
2140
|
+
}
|
|
2141
|
+
)
|
|
2142
|
+
}
|
|
2143
|
+
)
|
|
2144
|
+
] }),
|
|
2145
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-1 items-center justify-center overflow-auto bg-muted/20 p-4", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2146
|
+
"img",
|
|
2147
|
+
{
|
|
2148
|
+
src: asset.fileUrl,
|
|
2149
|
+
alt: asset.title,
|
|
2150
|
+
className: "max-h-[70vh] w-auto max-w-full object-contain"
|
|
2151
|
+
}
|
|
2152
|
+
) }),
|
|
2153
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-end border-t p-4", children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2154
|
+
"a",
|
|
2155
|
+
{
|
|
2156
|
+
href: asset.fileUrl,
|
|
2157
|
+
target: "_blank",
|
|
2158
|
+
rel: "noopener noreferrer",
|
|
2159
|
+
download: true,
|
|
2160
|
+
onClick: (e) => {
|
|
2161
|
+
void downloadFile(e, asset);
|
|
2162
|
+
},
|
|
2163
|
+
className: "inline-flex items-center gap-1.5 rounded-lg bg-primary px-4 py-2 text-sm font-medium text-primary-foreground transition-opacity hover:opacity-90",
|
|
2164
|
+
children: [
|
|
2165
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2166
|
+
"svg",
|
|
2167
|
+
{
|
|
2168
|
+
className: "h-4 w-4",
|
|
2169
|
+
fill: "none",
|
|
2170
|
+
viewBox: "0 0 24 24",
|
|
2171
|
+
stroke: "currentColor",
|
|
2172
|
+
strokeWidth: 2,
|
|
2173
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2174
|
+
"path",
|
|
2175
|
+
{
|
|
2176
|
+
strokeLinecap: "round",
|
|
2177
|
+
strokeLinejoin: "round",
|
|
2178
|
+
d: "M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4"
|
|
2179
|
+
}
|
|
2180
|
+
)
|
|
2181
|
+
}
|
|
2182
|
+
),
|
|
2183
|
+
"Download"
|
|
2184
|
+
]
|
|
2185
|
+
}
|
|
2186
|
+
) })
|
|
2187
|
+
]
|
|
2188
|
+
}
|
|
2189
|
+
)
|
|
2190
|
+
}
|
|
2191
|
+
);
|
|
2192
|
+
}
|
|
2193
|
+
function AssetCard({
|
|
2194
|
+
asset,
|
|
2195
|
+
onPreview
|
|
2196
|
+
}) {
|
|
2197
|
+
const date = asset.updatedAt ? new Date(asset.updatedAt).toLocaleDateString("en-US", {
|
|
2198
|
+
year: "numeric",
|
|
2199
|
+
month: "short",
|
|
2200
|
+
day: "numeric"
|
|
2201
|
+
}) : "";
|
|
2202
|
+
const ext = (asset.mimeType || "file").split("/").pop()?.toUpperCase() || "FILE";
|
|
2203
|
+
const size = formatBytes(asset.fileSize);
|
|
2204
|
+
const [imgError, setImgError] = react.useState(false);
|
|
2205
|
+
const thumb = asset.thumbnailUrl && !imgError ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "aspect-[16/9] overflow-hidden bg-muted/30", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2206
|
+
"img",
|
|
2207
|
+
{
|
|
2208
|
+
src: asset.thumbnailUrl,
|
|
2209
|
+
alt: asset.title,
|
|
2210
|
+
className: "w-full h-full object-contain group-hover:scale-105 transition-transform duration-300",
|
|
2211
|
+
loading: "lazy",
|
|
2212
|
+
onError: () => setImgError(true)
|
|
2213
|
+
}
|
|
2214
|
+
) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "aspect-[16/9] bg-muted/50 flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2215
|
+
"svg",
|
|
2216
|
+
{
|
|
2217
|
+
className: "w-12 h-12 text-muted-foreground/20",
|
|
2218
|
+
fill: "none",
|
|
2219
|
+
viewBox: "0 0 24 24",
|
|
2220
|
+
stroke: "currentColor",
|
|
2221
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2222
|
+
"path",
|
|
2223
|
+
{
|
|
2224
|
+
strokeLinecap: "round",
|
|
2225
|
+
strokeLinejoin: "round",
|
|
2226
|
+
strokeWidth: 1.5,
|
|
2227
|
+
d: "M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z"
|
|
2228
|
+
}
|
|
2229
|
+
)
|
|
2230
|
+
}
|
|
2231
|
+
) });
|
|
2232
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "group flex flex-col bg-card border rounded-xl overflow-hidden hover:shadow-lg hover:border-primary/30 transition-all duration-300", children: [
|
|
2233
|
+
onPreview && isImageAsset(asset) ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
2234
|
+
"button",
|
|
2235
|
+
{
|
|
2236
|
+
type: "button",
|
|
2237
|
+
onClick: () => onPreview(asset),
|
|
2238
|
+
"aria-label": `Preview ${asset.title}`,
|
|
2239
|
+
className: "block w-full text-left cursor-zoom-in",
|
|
2240
|
+
children: thumb
|
|
2241
|
+
}
|
|
2242
|
+
) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
2243
|
+
"a",
|
|
2244
|
+
{
|
|
2245
|
+
href: asset.fileUrl,
|
|
2246
|
+
target: "_blank",
|
|
2247
|
+
rel: "noopener noreferrer",
|
|
2248
|
+
"aria-label": `Open ${asset.title}`,
|
|
2249
|
+
className: "block",
|
|
2250
|
+
children: thumb
|
|
2251
|
+
}
|
|
2252
|
+
),
|
|
2253
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col flex-1 p-5", children: [
|
|
2254
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "inline-block self-start text-xs font-medium text-primary bg-primary/10 px-2.5 py-1 rounded-full mb-3", children: CATEGORY_LABELS[asset.category] ?? asset.category }),
|
|
2255
|
+
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-base font-semibold text-foreground mb-1 line-clamp-2", children: asset.title }),
|
|
2256
|
+
asset.description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground mb-3 line-clamp-2", children: asset.description }),
|
|
2257
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-auto flex items-center justify-between pt-3", children: [
|
|
2258
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 text-xs text-muted-foreground", children: [
|
|
2259
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: ext }),
|
|
2260
|
+
size && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2261
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground/40", children: "\xB7" }),
|
|
2262
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: size })
|
|
2263
|
+
] }),
|
|
2264
|
+
date && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2265
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground/40", children: "\xB7" }),
|
|
2266
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: date })
|
|
2267
|
+
] })
|
|
2268
|
+
] }),
|
|
2269
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
2270
|
+
"a",
|
|
2271
|
+
{
|
|
2272
|
+
href: asset.fileUrl,
|
|
2273
|
+
target: "_blank",
|
|
2274
|
+
rel: "noopener noreferrer",
|
|
2275
|
+
download: true,
|
|
2276
|
+
onClick: (e) => {
|
|
2277
|
+
void downloadFile(e, asset);
|
|
2278
|
+
},
|
|
2279
|
+
className: "inline-flex items-center gap-1.5 text-sm font-medium text-primary hover:underline",
|
|
2280
|
+
children: [
|
|
2281
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2282
|
+
"svg",
|
|
2283
|
+
{
|
|
2284
|
+
className: "w-4 h-4",
|
|
2285
|
+
fill: "none",
|
|
2286
|
+
viewBox: "0 0 24 24",
|
|
2287
|
+
stroke: "currentColor",
|
|
2288
|
+
strokeWidth: 2,
|
|
2289
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2290
|
+
"path",
|
|
2291
|
+
{
|
|
2292
|
+
strokeLinecap: "round",
|
|
2293
|
+
strokeLinejoin: "round",
|
|
2294
|
+
d: "M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4"
|
|
2295
|
+
}
|
|
2296
|
+
)
|
|
2297
|
+
}
|
|
2298
|
+
),
|
|
2299
|
+
"Download"
|
|
2300
|
+
]
|
|
2301
|
+
}
|
|
2302
|
+
)
|
|
2303
|
+
] })
|
|
2304
|
+
] })
|
|
2305
|
+
] });
|
|
2306
|
+
}
|
|
2307
|
+
function PressReleaseCard({
|
|
2308
|
+
release,
|
|
2309
|
+
basePath
|
|
2310
|
+
}) {
|
|
2311
|
+
const date = release.publishedAt || release.lastUpdated;
|
|
2312
|
+
const formattedDate = date ? new Date(date).toLocaleDateString("en-US", {
|
|
2313
|
+
year: "numeric",
|
|
2314
|
+
month: "long",
|
|
2315
|
+
day: "numeric"
|
|
2316
|
+
}) : "";
|
|
2317
|
+
const [imgError, setImgError] = react.useState(false);
|
|
2318
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2319
|
+
"a",
|
|
2320
|
+
{
|
|
2321
|
+
href: `${basePath}/${release.slug}`,
|
|
2322
|
+
className: "group flex flex-col bg-card border rounded-xl overflow-hidden hover:shadow-lg hover:border-primary/30 transition-all duration-300",
|
|
2323
|
+
children: [
|
|
2324
|
+
release.thumbnail && !imgError ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "aspect-[16/9] overflow-hidden bg-muted/30", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2325
|
+
"img",
|
|
2326
|
+
{
|
|
2327
|
+
src: release.thumbnail,
|
|
2328
|
+
alt: release.title,
|
|
2329
|
+
className: "w-full h-full object-cover group-hover:scale-105 transition-transform duration-300",
|
|
2330
|
+
loading: "lazy",
|
|
2331
|
+
onError: () => setImgError(true)
|
|
2332
|
+
}
|
|
2333
|
+
) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "aspect-[16/9] bg-muted/50 flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2334
|
+
"svg",
|
|
2335
|
+
{
|
|
2336
|
+
className: "w-12 h-12 text-muted-foreground/20",
|
|
2337
|
+
fill: "none",
|
|
2338
|
+
viewBox: "0 0 24 24",
|
|
2339
|
+
stroke: "currentColor",
|
|
2340
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2341
|
+
"path",
|
|
2342
|
+
{
|
|
2343
|
+
strokeLinecap: "round",
|
|
2344
|
+
strokeLinejoin: "round",
|
|
2345
|
+
strokeWidth: 1.5,
|
|
2346
|
+
d: "M19 20H5a2 2 0 01-2-2V6a2 2 0 012-2h10a2 2 0 012 2v1m-1 13a2 2 0 01-2-2V7m3 13a2 2 0 002-2V9a2 2 0 00-2-2h-2m-4-3H9M7 16h6M7 8h6v4H7V8z"
|
|
2347
|
+
}
|
|
2348
|
+
)
|
|
2349
|
+
}
|
|
2350
|
+
) }),
|
|
2351
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col flex-1 p-5 sm:p-6", children: [
|
|
2352
|
+
release.category && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "inline-block self-start text-xs font-medium text-primary bg-primary/10 px-2.5 py-1 rounded-full mb-3", children: release.category }),
|
|
2353
|
+
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-lg font-semibold text-foreground mb-2 group-hover:text-primary transition-colors line-clamp-2", children: release.title }),
|
|
2354
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground mb-4 line-clamp-3", children: release.excerpt || release.seoDescription || "" }),
|
|
2355
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-auto flex items-center gap-3 text-xs text-muted-foreground", children: [
|
|
2356
|
+
release.author && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: release.author }),
|
|
2357
|
+
release.author && formattedDate && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground/40", children: "\xB7" }),
|
|
2358
|
+
formattedDate && /* @__PURE__ */ jsxRuntime.jsx("span", { children: formattedDate }),
|
|
2359
|
+
release.readingTime ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2360
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground/40", children: "\xB7" }),
|
|
2361
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
2362
|
+
release.readingTime,
|
|
2363
|
+
" min read"
|
|
2364
|
+
] })
|
|
2365
|
+
] }) : null
|
|
2366
|
+
] })
|
|
2367
|
+
] })
|
|
2368
|
+
]
|
|
2369
|
+
}
|
|
2370
|
+
);
|
|
2371
|
+
}
|
|
2372
|
+
function PressKitPage(props) {
|
|
2373
|
+
const {
|
|
2374
|
+
productName,
|
|
2375
|
+
heroTitle = "Press & Media Kit",
|
|
2376
|
+
heroSubtitle = "Official logos, brand assets, and media resources. Everything you need to write about us.",
|
|
2377
|
+
mediaContactEmail,
|
|
2378
|
+
brandKitUrl,
|
|
2379
|
+
className = "",
|
|
2380
|
+
seoTitle,
|
|
2381
|
+
seoDescription,
|
|
2382
|
+
seoKeywords,
|
|
2383
|
+
showPressReleases = true,
|
|
2384
|
+
pressReleaseBasePath = "/press",
|
|
2385
|
+
pressReleasesTitle = "Press Releases"
|
|
2386
|
+
} = props;
|
|
2387
|
+
const client = chunkJXLSTVBK_js.useWebSDK();
|
|
2388
|
+
const config = chunkJXLSTVBK_js.useWebSDKConfig();
|
|
2389
|
+
const { product } = chunkBYSZT35R_js.useProduct();
|
|
2390
|
+
const resolvedProductId = product?.id || config.productId;
|
|
2391
|
+
const contactEmail = mediaContactEmail || product?.contactEmail || void 0;
|
|
2392
|
+
const [assets, setAssets] = react.useState([]);
|
|
2393
|
+
const [loading, setLoading] = react.useState(true);
|
|
2394
|
+
const [error, setError] = react.useState(null);
|
|
2395
|
+
const [activeCategory, setActiveCategory] = react.useState("ALL");
|
|
2396
|
+
const [releases, setReleases] = react.useState([]);
|
|
2397
|
+
const [releasesLoading, setReleasesLoading] = react.useState(true);
|
|
2398
|
+
const [preview, setPreview] = react.useState(null);
|
|
2399
|
+
const fetchAssets = react.useCallback(async () => {
|
|
2400
|
+
if (!resolvedProductId) {
|
|
2401
|
+
setLoading(false);
|
|
2402
|
+
return;
|
|
2403
|
+
}
|
|
2404
|
+
setLoading(true);
|
|
2405
|
+
try {
|
|
2406
|
+
const PAGE_SIZE = 100;
|
|
2407
|
+
const MAX_PAGES = 10;
|
|
2408
|
+
const all = [];
|
|
2409
|
+
let offset = 0;
|
|
2410
|
+
for (let pageNum = 0; pageNum < MAX_PAGES; pageNum++) {
|
|
2411
|
+
const result = await client.query(PRESS_KIT_QUERY, {
|
|
2412
|
+
productId: resolvedProductId,
|
|
2413
|
+
limit: PAGE_SIZE,
|
|
2414
|
+
offset
|
|
2415
|
+
});
|
|
2416
|
+
if (result.errors?.length) {
|
|
2417
|
+
setError(result.errors[0]?.message ?? "Failed to load press kit");
|
|
2418
|
+
return;
|
|
2419
|
+
}
|
|
2420
|
+
const page = result.data?.publicPressKitAssets;
|
|
2421
|
+
const items = page?.items || [];
|
|
2422
|
+
all.push(...items);
|
|
2423
|
+
if (!page?.hasMore || items.length === 0) break;
|
|
2424
|
+
offset += PAGE_SIZE;
|
|
2425
|
+
}
|
|
2426
|
+
setAssets(all);
|
|
2427
|
+
setError(null);
|
|
2428
|
+
} catch {
|
|
2429
|
+
setError("Failed to load press kit");
|
|
2430
|
+
} finally {
|
|
2431
|
+
setLoading(false);
|
|
2432
|
+
}
|
|
2433
|
+
}, [client, resolvedProductId]);
|
|
2434
|
+
react.useEffect(() => {
|
|
2435
|
+
fetchAssets();
|
|
2436
|
+
}, [fetchAssets]);
|
|
2437
|
+
const fetchReleases = react.useCallback(async () => {
|
|
2438
|
+
if (!resolvedProductId || !showPressReleases) {
|
|
2439
|
+
setReleasesLoading(false);
|
|
2440
|
+
return;
|
|
2441
|
+
}
|
|
2442
|
+
setReleasesLoading(true);
|
|
2443
|
+
try {
|
|
2444
|
+
const PAGE_SIZE = 100;
|
|
2445
|
+
const MAX_PAGES = 10;
|
|
2446
|
+
const all = [];
|
|
2447
|
+
let offset = 0;
|
|
2448
|
+
for (let pageNum = 0; pageNum < MAX_PAGES; pageNum++) {
|
|
2449
|
+
const result = await client.query(PRESS_RELEASES_QUERY, {
|
|
2450
|
+
productId: resolvedProductId,
|
|
2451
|
+
limit: PAGE_SIZE,
|
|
2452
|
+
offset
|
|
2453
|
+
});
|
|
2454
|
+
if (result.errors?.length) {
|
|
2455
|
+
setReleases([]);
|
|
2456
|
+
return;
|
|
2457
|
+
}
|
|
2458
|
+
const page = result.data?.publicContentPages;
|
|
2459
|
+
const items = page?.items || [];
|
|
2460
|
+
all.push(...items);
|
|
2461
|
+
if (!page?.hasMore || items.length === 0) break;
|
|
2462
|
+
offset += PAGE_SIZE;
|
|
2463
|
+
}
|
|
2464
|
+
const pressOnly = all.filter((p) => p.tags?.includes("press")).sort((a, b) => {
|
|
2465
|
+
const da = new Date(a.publishedAt || a.lastUpdated || 0).getTime();
|
|
2466
|
+
const db = new Date(b.publishedAt || b.lastUpdated || 0).getTime();
|
|
2467
|
+
return db - da;
|
|
2468
|
+
});
|
|
2469
|
+
setReleases(pressOnly);
|
|
2470
|
+
} catch {
|
|
2471
|
+
setReleases([]);
|
|
2472
|
+
} finally {
|
|
2473
|
+
setReleasesLoading(false);
|
|
2474
|
+
}
|
|
2475
|
+
}, [client, resolvedProductId, showPressReleases]);
|
|
2476
|
+
react.useEffect(() => {
|
|
2477
|
+
fetchReleases();
|
|
2478
|
+
}, [fetchReleases]);
|
|
2479
|
+
const presentCategories = CATEGORY_ORDER.filter(
|
|
2480
|
+
(c) => assets.some((a) => a.category === c)
|
|
2481
|
+
);
|
|
2482
|
+
const visibleAssets = activeCategory === "ALL" ? assets : assets.filter((a) => a.category === activeCategory);
|
|
2483
|
+
const grouped = (activeCategory === "ALL" ? presentCategories : [activeCategory]).map((cat) => ({
|
|
2484
|
+
cat,
|
|
2485
|
+
items: visibleAssets.filter((a) => a.category === cat).sort((a, b) => a.sortOrder - b.sortOrder)
|
|
2486
|
+
})).filter((g) => g.items.length > 0);
|
|
2487
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `w-full ${className}`, children: [
|
|
2488
|
+
seoTitle && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2489
|
+
chunkUXWT7G77_js.PageHead,
|
|
2490
|
+
{
|
|
2491
|
+
title: seoTitle,
|
|
2492
|
+
description: seoDescription || heroSubtitle,
|
|
2493
|
+
productName,
|
|
2494
|
+
keywords: seoKeywords
|
|
2495
|
+
}
|
|
2496
|
+
),
|
|
2497
|
+
/* @__PURE__ */ jsxRuntime.jsx("section", { className: "py-16 sm:py-20 md:py-24", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-center max-w-3xl mx-auto", children: [
|
|
2498
|
+
/* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-3xl sm:text-4xl md:text-5xl font-bold tracking-tight text-foreground", children: heroTitle }),
|
|
2499
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-4 text-lg text-muted-foreground", children: heroSubtitle }),
|
|
2500
|
+
(brandKitUrl || contactEmail) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-8 flex flex-wrap items-center justify-center gap-4", children: [
|
|
2501
|
+
brandKitUrl && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2502
|
+
"a",
|
|
2503
|
+
{
|
|
2504
|
+
href: brandKitUrl,
|
|
2505
|
+
target: "_blank",
|
|
2506
|
+
rel: "noopener noreferrer",
|
|
2507
|
+
className: "inline-flex items-center gap-2 px-6 py-3 rounded-lg bg-primary text-primary-foreground font-medium hover:opacity-90 transition-opacity",
|
|
2508
|
+
children: "Download brand kit"
|
|
2509
|
+
}
|
|
2510
|
+
),
|
|
2511
|
+
contactEmail && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2512
|
+
"a",
|
|
2513
|
+
{
|
|
2514
|
+
href: `mailto:${contactEmail}`,
|
|
2515
|
+
className: "inline-flex items-center gap-2 px-6 py-3 rounded-lg border font-medium text-foreground hover:bg-muted transition-colors",
|
|
2516
|
+
children: "Media inquiries"
|
|
2517
|
+
}
|
|
2518
|
+
)
|
|
2519
|
+
] })
|
|
2520
|
+
] }) }) }),
|
|
2521
|
+
showPressReleases && (releasesLoading || releases.length > 0) && /* @__PURE__ */ jsxRuntime.jsx("section", { className: "pb-16 sm:pb-20", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8", children: [
|
|
2522
|
+
/* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-xl font-semibold text-foreground mb-6", children: pressReleasesTitle }),
|
|
2523
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid sm:grid-cols-2 lg:grid-cols-3 gap-6", children: releasesLoading ? [1, 2, 3].map((i) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2524
|
+
"div",
|
|
2525
|
+
{
|
|
2526
|
+
className: "bg-card border rounded-xl overflow-hidden animate-pulse",
|
|
2527
|
+
children: [
|
|
2528
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "aspect-[16/9] bg-muted" }),
|
|
2529
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-5 space-y-3", children: [
|
|
2530
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-4 bg-muted rounded w-1/4" }),
|
|
2531
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-5 bg-muted rounded w-3/4" }),
|
|
2532
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-4 bg-muted rounded w-1/2" })
|
|
2533
|
+
] })
|
|
2534
|
+
]
|
|
2535
|
+
},
|
|
2536
|
+
i
|
|
2537
|
+
)) : releases.map((r) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
2538
|
+
PressReleaseCard,
|
|
2539
|
+
{
|
|
2540
|
+
release: r,
|
|
2541
|
+
basePath: pressReleaseBasePath
|
|
2542
|
+
},
|
|
2543
|
+
r.id
|
|
2544
|
+
)) })
|
|
2545
|
+
] }) }),
|
|
2546
|
+
/* @__PURE__ */ jsxRuntime.jsx("section", { className: "pb-16 sm:pb-20", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8", children: loading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid sm:grid-cols-2 lg:grid-cols-3 gap-6", children: [1, 2, 3, 4, 5, 6].map((i) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2547
|
+
"div",
|
|
2548
|
+
{
|
|
2549
|
+
className: "bg-card border rounded-xl overflow-hidden animate-pulse",
|
|
2550
|
+
children: [
|
|
2551
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "aspect-[16/9] bg-muted" }),
|
|
2552
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-5 space-y-3", children: [
|
|
2553
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-4 bg-muted rounded w-1/4" }),
|
|
2554
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-5 bg-muted rounded w-3/4" }),
|
|
2555
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-4 bg-muted rounded w-1/2" })
|
|
2556
|
+
] })
|
|
2557
|
+
]
|
|
2558
|
+
},
|
|
2559
|
+
i
|
|
2560
|
+
)) }) : error ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-center py-12", children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground", children: error }) }) : assets.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-center py-12", children: /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-muted-foreground", children: [
|
|
2561
|
+
"Press materials are coming soon. For media inquiries",
|
|
2562
|
+
contactEmail ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2563
|
+
", contact ",
|
|
2564
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2565
|
+
"a",
|
|
2566
|
+
{
|
|
2567
|
+
href: `mailto:${contactEmail}`,
|
|
2568
|
+
className: "text-primary underline underline-offset-4 hover:no-underline",
|
|
2569
|
+
children: contactEmail
|
|
2570
|
+
}
|
|
2571
|
+
)
|
|
2572
|
+
] }) : " please reach out to our team",
|
|
2573
|
+
"."
|
|
2574
|
+
] }) }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2575
|
+
presentCategories.length > 1 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap gap-2 mb-10 justify-center", children: ["ALL", ...presentCategories].map((c) => {
|
|
2576
|
+
const active = activeCategory === c;
|
|
2577
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2578
|
+
"button",
|
|
2579
|
+
{
|
|
2580
|
+
type: "button",
|
|
2581
|
+
onClick: () => setActiveCategory(c),
|
|
2582
|
+
className: `px-4 py-2 rounded-full text-sm font-medium transition-colors ${active ? "bg-primary text-primary-foreground" : "bg-muted text-muted-foreground hover:text-foreground"}`,
|
|
2583
|
+
children: c === "ALL" ? "All" : CATEGORY_LABELS[c] ?? c
|
|
2584
|
+
},
|
|
2585
|
+
c
|
|
2586
|
+
);
|
|
2587
|
+
}) }),
|
|
2588
|
+
grouped.map((group) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-12", children: [
|
|
2589
|
+
/* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-xl font-semibold text-foreground mb-5", children: CATEGORY_LABELS[group.cat] ?? group.cat }),
|
|
2590
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid sm:grid-cols-2 lg:grid-cols-3 gap-6", children: group.items.map((a) => /* @__PURE__ */ jsxRuntime.jsx(AssetCard, { asset: a, onPreview: setPreview }, a.id)) })
|
|
2591
|
+
] }, group.cat)),
|
|
2592
|
+
contactEmail && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-8 border-t pt-10 text-center", children: [
|
|
2593
|
+
/* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-lg font-semibold text-foreground mb-2", children: "Media Contact" }),
|
|
2594
|
+
/* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-muted-foreground", children: [
|
|
2595
|
+
"For interviews, partnerships, and press inquiries:",
|
|
2596
|
+
" ",
|
|
2597
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2598
|
+
"a",
|
|
2599
|
+
{
|
|
2600
|
+
href: `mailto:${contactEmail}`,
|
|
2601
|
+
className: "text-primary underline underline-offset-4 hover:no-underline",
|
|
2602
|
+
children: contactEmail
|
|
2603
|
+
}
|
|
2604
|
+
)
|
|
2605
|
+
] })
|
|
2606
|
+
] })
|
|
2607
|
+
] }) }) }),
|
|
2608
|
+
/* @__PURE__ */ jsxRuntime.jsx(PressKitLightbox, { asset: preview, onClose: () => setPreview(null) })
|
|
2609
|
+
] });
|
|
2610
|
+
}
|
|
2611
|
+
var CONTRACTS_QUERY = `
|
|
2612
|
+
query PublicContracts($productId: String!, $limit: Int, $offset: Int) {
|
|
2613
|
+
publicPressKitAssets(productId: $productId, category: CONTRACT, limit: $limit, offset: $offset) {
|
|
2614
|
+
items {
|
|
2615
|
+
id
|
|
2616
|
+
title
|
|
2617
|
+
slug
|
|
2618
|
+
description
|
|
2619
|
+
fileUrl
|
|
2620
|
+
fileName
|
|
2621
|
+
fileSize
|
|
2622
|
+
mimeType
|
|
2623
|
+
version
|
|
2624
|
+
tags
|
|
2625
|
+
sortOrder
|
|
2626
|
+
updatedAt
|
|
2627
|
+
}
|
|
2628
|
+
hasMore
|
|
2629
|
+
}
|
|
2630
|
+
}
|
|
2631
|
+
`;
|
|
2632
|
+
function ContractsPage(props) {
|
|
2633
|
+
const {
|
|
2634
|
+
productName,
|
|
2635
|
+
heroTitle = "Contracts & Legal Agreements",
|
|
2636
|
+
heroSubtitle = "Download our standard legal agreements and policies.",
|
|
2637
|
+
className = "",
|
|
2638
|
+
seoTitle,
|
|
2639
|
+
seoDescription,
|
|
2640
|
+
seoKeywords
|
|
2641
|
+
} = props;
|
|
2642
|
+
const client = chunkJXLSTVBK_js.useWebSDK();
|
|
2643
|
+
const config = chunkJXLSTVBK_js.useWebSDKConfig();
|
|
2644
|
+
const { product } = chunkBYSZT35R_js.useProduct();
|
|
2645
|
+
const resolvedProductId = product?.id || config.productId;
|
|
2646
|
+
const displayName = productName ?? product?.name ?? config.productId;
|
|
2647
|
+
const [contracts, setContracts] = react.useState([]);
|
|
2648
|
+
const [loading, setLoading] = react.useState(true);
|
|
2649
|
+
const [error, setError] = react.useState(null);
|
|
2650
|
+
const fetchContracts = react.useCallback(async () => {
|
|
2651
|
+
if (!resolvedProductId) {
|
|
2652
|
+
setLoading(false);
|
|
2653
|
+
return;
|
|
2654
|
+
}
|
|
2655
|
+
setLoading(true);
|
|
2656
|
+
try {
|
|
2657
|
+
const PAGE_SIZE = 100;
|
|
2658
|
+
const MAX_PAGES = 10;
|
|
2659
|
+
const all = [];
|
|
2660
|
+
let offset = 0;
|
|
2661
|
+
for (let pageNum = 0; pageNum < MAX_PAGES; pageNum++) {
|
|
2662
|
+
const result = await client.query(CONTRACTS_QUERY, {
|
|
2663
|
+
productId: resolvedProductId,
|
|
2664
|
+
limit: PAGE_SIZE,
|
|
2665
|
+
offset
|
|
2666
|
+
});
|
|
2667
|
+
if (result.errors?.length) {
|
|
2668
|
+
setError(result.errors[0]?.message ?? "Failed to load contracts");
|
|
2669
|
+
return;
|
|
2670
|
+
}
|
|
2671
|
+
const page = result.data?.publicPressKitAssets;
|
|
2672
|
+
const items = page?.items || [];
|
|
2673
|
+
all.push(...items);
|
|
2674
|
+
if (!page?.hasMore || items.length === 0) break;
|
|
2675
|
+
offset += PAGE_SIZE;
|
|
2676
|
+
}
|
|
2677
|
+
all.sort(
|
|
2678
|
+
(a, b) => a.sortOrder - b.sortOrder || a.title.localeCompare(b.title)
|
|
2679
|
+
);
|
|
2680
|
+
setContracts(all);
|
|
2681
|
+
setError(null);
|
|
2682
|
+
} catch {
|
|
2683
|
+
setError("Failed to load contracts");
|
|
2684
|
+
} finally {
|
|
2685
|
+
setLoading(false);
|
|
2686
|
+
}
|
|
2687
|
+
}, [client, resolvedProductId]);
|
|
2688
|
+
react.useEffect(() => {
|
|
2689
|
+
fetchContracts();
|
|
2690
|
+
}, [fetchContracts]);
|
|
2691
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `min-h-screen bg-background ${className}`, children: [
|
|
2692
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2693
|
+
chunkUXWT7G77_js.PageHead,
|
|
2694
|
+
{
|
|
2695
|
+
title: seoTitle || `Contracts \u2014 ${displayName}`,
|
|
2696
|
+
description: seoDescription || heroSubtitle,
|
|
2697
|
+
productName,
|
|
2698
|
+
keywords: seoKeywords
|
|
2699
|
+
}
|
|
2700
|
+
),
|
|
2701
|
+
/* @__PURE__ */ jsxRuntime.jsx("section", { className: "border-b border-border bg-muted/30", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "max-w-5xl mx-auto px-4 sm:px-6 lg:px-8 py-16 text-center", children: [
|
|
2702
|
+
/* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-4xl md:text-5xl font-bold text-foreground mb-4", children: heroTitle }),
|
|
2703
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-lg text-muted-foreground max-w-2xl mx-auto", children: heroSubtitle })
|
|
2704
|
+
] }) }),
|
|
2705
|
+
/* @__PURE__ */ jsxRuntime.jsx("section", { className: "max-w-5xl mx-auto px-4 sm:px-6 lg:px-8 py-12", children: loading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center py-20", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-8 w-8 animate-spin rounded-full border-2 border-primary border-t-transparent" }) }) : error ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-center py-16", children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground", children: error }) }) : contracts.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-center py-16", children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-base text-muted-foreground", children: "No contracts are available yet." }) }) : /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "divide-y divide-border rounded-xl border border-border overflow-hidden bg-card", children: contracts.map((c) => {
|
|
2706
|
+
const ext = fileExt(c);
|
|
2707
|
+
const size = formatBytes(c.fileSize);
|
|
2708
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2709
|
+
"li",
|
|
2710
|
+
{
|
|
2711
|
+
className: "flex items-center justify-between gap-4 p-5 hover:bg-muted/40 transition-colors",
|
|
2712
|
+
children: [
|
|
2713
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0", children: [
|
|
2714
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 flex-wrap", children: [
|
|
2715
|
+
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-base font-semibold text-foreground truncate", children: c.title }),
|
|
2716
|
+
c.version && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs font-medium text-primary bg-primary/10 px-2 py-0.5 rounded-full", children: c.version })
|
|
2717
|
+
] }),
|
|
2718
|
+
c.description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground mt-1 line-clamp-2", children: c.description }),
|
|
2719
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-1 flex items-center gap-2 text-xs text-muted-foreground", children: [
|
|
2720
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: ext }),
|
|
2721
|
+
size && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2722
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground/40", children: "\xB7" }),
|
|
2723
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: size })
|
|
2724
|
+
] })
|
|
2725
|
+
] })
|
|
2726
|
+
] }),
|
|
2727
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
2728
|
+
"a",
|
|
2729
|
+
{
|
|
2730
|
+
href: c.fileUrl,
|
|
2731
|
+
target: "_blank",
|
|
2732
|
+
rel: "noopener noreferrer",
|
|
2733
|
+
download: true,
|
|
2734
|
+
"aria-label": `Download ${c.title}`,
|
|
2735
|
+
onClick: (e) => {
|
|
2736
|
+
void downloadFile(e, c);
|
|
2737
|
+
},
|
|
2738
|
+
className: "flex-shrink-0 inline-flex items-center gap-1.5 text-sm font-medium text-primary-foreground bg-primary hover:opacity-90 px-4 py-2 rounded-lg transition-opacity",
|
|
2739
|
+
children: [
|
|
2740
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2741
|
+
"svg",
|
|
2742
|
+
{
|
|
2743
|
+
className: "w-4 h-4",
|
|
2744
|
+
fill: "none",
|
|
2745
|
+
viewBox: "0 0 24 24",
|
|
2746
|
+
stroke: "currentColor",
|
|
2747
|
+
"aria-hidden": "true",
|
|
2748
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2749
|
+
"path",
|
|
2750
|
+
{
|
|
2751
|
+
strokeLinecap: "round",
|
|
2752
|
+
strokeLinejoin: "round",
|
|
2753
|
+
strokeWidth: 2,
|
|
2754
|
+
d: "M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4"
|
|
2755
|
+
}
|
|
2756
|
+
)
|
|
2757
|
+
}
|
|
2758
|
+
),
|
|
2759
|
+
"Download"
|
|
2760
|
+
]
|
|
2761
|
+
}
|
|
2762
|
+
)
|
|
2763
|
+
]
|
|
2764
|
+
},
|
|
2765
|
+
c.id
|
|
2766
|
+
);
|
|
2767
|
+
}) }) })
|
|
2768
|
+
] });
|
|
2769
|
+
}
|
|
2770
|
+
|
|
2771
|
+
exports.BlogListPage = BlogListPage;
|
|
2772
|
+
exports.BlogPostPage = BlogPostPage;
|
|
2773
|
+
exports.CaseStudiesListPage = CaseStudiesListPage;
|
|
2774
|
+
exports.CaseStudyPage = CaseStudyPage;
|
|
2775
|
+
exports.ChangelogPage = ChangelogPage;
|
|
2776
|
+
exports.ContractsPage = ContractsPage;
|
|
2777
|
+
exports.LEGAL_DOCUMENTS = LEGAL_DOCUMENTS;
|
|
2778
|
+
exports.LEGAL_DOCUMENT_KEYS = LEGAL_DOCUMENT_KEYS;
|
|
2779
|
+
exports.LegalPage = LegalPage;
|
|
2780
|
+
exports.PressKitPage = PressKitPage;
|
|
2781
|
+
exports.fetchLegalContent = fetchLegalContent;
|
|
2782
|
+
exports.fetchLegalContentPage = fetchLegalContentPage;
|
|
2783
|
+
exports.fetchPublicJobPosting = fetchPublicJobPosting;
|
|
2784
|
+
exports.fetchPublicJobPostings = fetchPublicJobPostings;
|
|
2785
|
+
exports.fetchPublicJobPostingsForSubmission = fetchPublicJobPostingsForSubmission;
|
|
2786
|
+
exports.findLegalDocument = findLegalDocument;
|
|
2787
|
+
exports.formatLegalDate = formatLegalDate;
|
|
2788
|
+
exports.hasCustomerSignOff = hasCustomerSignOff;
|
|
2789
|
+
exports.splitLeadingHeading = splitLeadingHeading;
|
|
2790
|
+
exports.usePublicJobPosting = usePublicJobPosting;
|
|
2791
|
+
exports.usePublicJobPostings = usePublicJobPostings;
|
|
2792
|
+
exports.usePublicJobPostingsForSubmission = usePublicJobPostingsForSubmission;
|
|
2793
|
+
//# sourceMappingURL=chunk-3X26GE4S.js.map
|
|
2794
|
+
//# sourceMappingURL=chunk-3X26GE4S.js.map
|