@burdenoff/website-sdk 2026.703.2 → 2026.709.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/dist/components/electron-download.d.mts +32 -0
- package/dist/components/electron-download.d.ts +32 -0
- package/dist/components/electron-download.js +131 -0
- package/dist/components/electron-download.js.map +1 -0
- package/dist/components/electron-download.mjs +108 -0
- package/dist/components/electron-download.mjs.map +1 -0
- package/dist/components/launch-countdown.d.mts +15 -0
- package/dist/components/launch-countdown.d.ts +15 -0
- package/dist/components/launch-countdown.js +89 -0
- package/dist/components/launch-countdown.js.map +1 -0
- package/dist/components/launch-countdown.mjs +87 -0
- package/dist/components/launch-countdown.mjs.map +1 -0
- package/dist/components/problems-solved.d.mts +37 -0
- package/dist/components/problems-solved.d.ts +37 -0
- package/dist/components/problems-solved.js +157 -0
- package/dist/components/problems-solved.js.map +1 -0
- package/dist/components/problems-solved.mjs +135 -0
- package/dist/components/problems-solved.mjs.map +1 -0
- package/dist/components/website-switcher.d.mts +27 -0
- package/dist/components/website-switcher.d.ts +27 -0
- package/dist/components/website-switcher.js +168 -0
- package/dist/components/website-switcher.js.map +1 -0
- package/dist/components/website-switcher.mjs +146 -0
- package/dist/components/website-switcher.mjs.map +1 -0
- package/dist/content/index.d.mts +24 -1
- package/dist/content/index.d.ts +24 -1
- package/dist/content/index.js +459 -149
- package/dist/content/index.js.map +1 -1
- package/dist/content/index.mjs +378 -87
- package/dist/content/index.mjs.map +1 -1
- package/dist/index.d.mts +15 -2
- package/dist/index.d.ts +15 -2
- package/dist/index.js +817 -86
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +812 -88
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -1
package/dist/content/index.js
CHANGED
|
@@ -1,8 +1,33 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var React = require('react');
|
|
4
4
|
var jsxRuntime = require('react/jsx-runtime');
|
|
5
5
|
var reactHelmetAsync = require('react-helmet-async');
|
|
6
|
+
var lucideReact = require('lucide-react');
|
|
7
|
+
var reactSlot = require('@radix-ui/react-slot');
|
|
8
|
+
var classVarianceAuthority = require('class-variance-authority');
|
|
9
|
+
var clsx = require('clsx');
|
|
10
|
+
var tailwindMerge = require('tailwind-merge');
|
|
11
|
+
|
|
12
|
+
function _interopNamespace(e) {
|
|
13
|
+
if (e && e.__esModule) return e;
|
|
14
|
+
var n = Object.create(null);
|
|
15
|
+
if (e) {
|
|
16
|
+
Object.keys(e).forEach(function (k) {
|
|
17
|
+
if (k !== 'default') {
|
|
18
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
19
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
20
|
+
enumerable: true,
|
|
21
|
+
get: function () { return e[k]; }
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
n.default = e;
|
|
27
|
+
return Object.freeze(n);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
var React__namespace = /*#__PURE__*/_interopNamespace(React);
|
|
6
31
|
|
|
7
32
|
var __defProp = Object.defineProperty;
|
|
8
33
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
@@ -144,9 +169,9 @@ var _WebSDKClient = class _WebSDKClient {
|
|
|
144
169
|
__publicField(_WebSDKClient, "CACHE_TTL", 5 * 60 * 1e3);
|
|
145
170
|
// 5 minutes
|
|
146
171
|
__publicField(_WebSDKClient, "MAX_CACHE_ENTRIES", 100);
|
|
147
|
-
var WebSDKContext =
|
|
172
|
+
var WebSDKContext = React.createContext(null);
|
|
148
173
|
function useWebSDK() {
|
|
149
|
-
const client =
|
|
174
|
+
const client = React.useContext(WebSDKContext);
|
|
150
175
|
if (!client) {
|
|
151
176
|
throw new Error("useWebSDK must be used within a WebSDKProvider");
|
|
152
177
|
}
|
|
@@ -156,7 +181,7 @@ function useWebSDKConfig() {
|
|
|
156
181
|
const client = useWebSDK();
|
|
157
182
|
return client.getConfig();
|
|
158
183
|
}
|
|
159
|
-
var ProductContext =
|
|
184
|
+
var ProductContext = React.createContext({
|
|
160
185
|
product: null,
|
|
161
186
|
loading: true,
|
|
162
187
|
error: null,
|
|
@@ -165,7 +190,7 @@ var ProductContext = react.createContext({
|
|
|
165
190
|
}
|
|
166
191
|
});
|
|
167
192
|
function useProduct() {
|
|
168
|
-
return
|
|
193
|
+
return React.useContext(ProductContext);
|
|
169
194
|
}
|
|
170
195
|
var PUBLIC_CONTENT_PAGE_QUERY = `
|
|
171
196
|
query PublicContentPage($slug: String!, $productId: String) {
|
|
@@ -241,10 +266,10 @@ function useContentPage(slug, options) {
|
|
|
241
266
|
const config = useWebSDKConfig();
|
|
242
267
|
const { product } = useProduct();
|
|
243
268
|
const resolvedProductId = product?.id || config.productId;
|
|
244
|
-
const [data, setData] =
|
|
245
|
-
const [loading, setLoading] =
|
|
246
|
-
const [error, setError] =
|
|
247
|
-
const fetchPage =
|
|
269
|
+
const [data, setData] = React.useState(null);
|
|
270
|
+
const [loading, setLoading] = React.useState(true);
|
|
271
|
+
const [error, setError] = React.useState(null);
|
|
272
|
+
const fetchPage = React.useCallback(async () => {
|
|
248
273
|
if (!resolvedProductId) return;
|
|
249
274
|
setLoading(true);
|
|
250
275
|
setError(null);
|
|
@@ -271,7 +296,7 @@ function useContentPage(slug, options) {
|
|
|
271
296
|
setLoading(false);
|
|
272
297
|
}
|
|
273
298
|
}, [client, resolvedProductId, slug, options?.resolve]);
|
|
274
|
-
|
|
299
|
+
React.useEffect(() => {
|
|
275
300
|
fetchPage();
|
|
276
301
|
}, [fetchPage]);
|
|
277
302
|
return { data, loading, error, refetch: fetchPage };
|
|
@@ -279,10 +304,10 @@ function useContentPage(slug, options) {
|
|
|
279
304
|
function useContentPages(options) {
|
|
280
305
|
const client = useWebSDK();
|
|
281
306
|
const config = useWebSDKConfig();
|
|
282
|
-
const [data, setData] =
|
|
283
|
-
const [loading, setLoading] =
|
|
284
|
-
const [error, setError] =
|
|
285
|
-
const fetchPages =
|
|
307
|
+
const [data, setData] = React.useState(null);
|
|
308
|
+
const [loading, setLoading] = React.useState(true);
|
|
309
|
+
const [error, setError] = React.useState(null);
|
|
310
|
+
const fetchPages = React.useCallback(async () => {
|
|
286
311
|
setLoading(true);
|
|
287
312
|
setError(null);
|
|
288
313
|
try {
|
|
@@ -306,7 +331,7 @@ function useContentPages(options) {
|
|
|
306
331
|
setLoading(false);
|
|
307
332
|
}
|
|
308
333
|
}, [client, config.productId, options?.limit, options?.offset]);
|
|
309
|
-
|
|
334
|
+
React.useEffect(() => {
|
|
310
335
|
fetchPages();
|
|
311
336
|
}, [fetchPages]);
|
|
312
337
|
return { data, loading, error, refetch: fetchPages };
|
|
@@ -482,7 +507,7 @@ function BlogCard({
|
|
|
482
507
|
month: "long",
|
|
483
508
|
day: "numeric"
|
|
484
509
|
}) : "";
|
|
485
|
-
const [imgError, setImgError] =
|
|
510
|
+
const [imgError, setImgError] = React.useState(false);
|
|
486
511
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
487
512
|
"a",
|
|
488
513
|
{
|
|
@@ -552,13 +577,13 @@ function BlogListPage(props) {
|
|
|
552
577
|
const config = useWebSDKConfig();
|
|
553
578
|
const { product } = useProduct();
|
|
554
579
|
const resolvedProductId = product?.id || config.productId;
|
|
555
|
-
const [posts, setPosts] =
|
|
556
|
-
const [total, setTotal] =
|
|
557
|
-
const [loading, setLoading] =
|
|
558
|
-
const [error, setError] =
|
|
559
|
-
const [offset, setOffset] =
|
|
580
|
+
const [posts, setPosts] = React.useState([]);
|
|
581
|
+
const [total, setTotal] = React.useState(0);
|
|
582
|
+
const [loading, setLoading] = React.useState(true);
|
|
583
|
+
const [error, setError] = React.useState(null);
|
|
584
|
+
const [offset, setOffset] = React.useState(0);
|
|
560
585
|
const limit = 12;
|
|
561
|
-
const fetchPosts =
|
|
586
|
+
const fetchPosts = React.useCallback(async () => {
|
|
562
587
|
if (!resolvedProductId) return;
|
|
563
588
|
setLoading(true);
|
|
564
589
|
try {
|
|
@@ -583,7 +608,7 @@ function BlogListPage(props) {
|
|
|
583
608
|
setLoading(false);
|
|
584
609
|
}
|
|
585
610
|
}, [client, resolvedProductId, offset]);
|
|
586
|
-
|
|
611
|
+
React.useEffect(() => {
|
|
587
612
|
fetchPosts();
|
|
588
613
|
}, [fetchPosts]);
|
|
589
614
|
const featuredPosts = posts.filter((p) => p.featured);
|
|
@@ -668,11 +693,11 @@ function BlogPostPage(props) {
|
|
|
668
693
|
const config = useWebSDKConfig();
|
|
669
694
|
const { product } = useProduct();
|
|
670
695
|
const resolvedProductId = product?.id || config.productId;
|
|
671
|
-
const [post, setPost] =
|
|
672
|
-
const [loading, setLoading] =
|
|
673
|
-
const [error, setError] =
|
|
696
|
+
const [post, setPost] = React.useState(null);
|
|
697
|
+
const [loading, setLoading] = React.useState(true);
|
|
698
|
+
const [error, setError] = React.useState(null);
|
|
674
699
|
const slug = typeof window !== "undefined" ? window.location.pathname.split("/").pop() || "" : "";
|
|
675
|
-
|
|
700
|
+
React.useEffect(() => {
|
|
676
701
|
if (!slug || !resolvedProductId) return;
|
|
677
702
|
async function fetchPost() {
|
|
678
703
|
setLoading(true);
|
|
@@ -831,7 +856,7 @@ function CaseStudyCard({
|
|
|
831
856
|
month: "long",
|
|
832
857
|
day: "numeric"
|
|
833
858
|
}) : "";
|
|
834
|
-
const [imgError, setImgError] =
|
|
859
|
+
const [imgError, setImgError] = React.useState(false);
|
|
835
860
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
836
861
|
"a",
|
|
837
862
|
{
|
|
@@ -901,13 +926,13 @@ function CaseStudiesListPage(props) {
|
|
|
901
926
|
const config = useWebSDKConfig();
|
|
902
927
|
const { product } = useProduct();
|
|
903
928
|
const resolvedProductId = product?.id || config.productId;
|
|
904
|
-
const [posts, setPosts] =
|
|
905
|
-
const [total, setTotal] =
|
|
906
|
-
const [loading, setLoading] =
|
|
907
|
-
const [error, setError] =
|
|
908
|
-
const [offset, setOffset] =
|
|
929
|
+
const [posts, setPosts] = React.useState([]);
|
|
930
|
+
const [total, setTotal] = React.useState(0);
|
|
931
|
+
const [loading, setLoading] = React.useState(true);
|
|
932
|
+
const [error, setError] = React.useState(null);
|
|
933
|
+
const [offset, setOffset] = React.useState(0);
|
|
909
934
|
const limit = 12;
|
|
910
|
-
const fetchPosts =
|
|
935
|
+
const fetchPosts = React.useCallback(async () => {
|
|
911
936
|
if (!resolvedProductId) return;
|
|
912
937
|
setLoading(true);
|
|
913
938
|
try {
|
|
@@ -932,7 +957,7 @@ function CaseStudiesListPage(props) {
|
|
|
932
957
|
setLoading(false);
|
|
933
958
|
}
|
|
934
959
|
}, [client, resolvedProductId, offset]);
|
|
935
|
-
|
|
960
|
+
React.useEffect(() => {
|
|
936
961
|
fetchPosts();
|
|
937
962
|
}, [fetchPosts]);
|
|
938
963
|
const featuredPosts = posts.filter((p) => p.featured);
|
|
@@ -1017,11 +1042,11 @@ function CaseStudyPage(props) {
|
|
|
1017
1042
|
const config = useWebSDKConfig();
|
|
1018
1043
|
const { product } = useProduct();
|
|
1019
1044
|
const resolvedProductId = product?.id || config.productId;
|
|
1020
|
-
const [post, setPost] =
|
|
1021
|
-
const [loading, setLoading] =
|
|
1022
|
-
const [error, setError] =
|
|
1045
|
+
const [post, setPost] = React.useState(null);
|
|
1046
|
+
const [loading, setLoading] = React.useState(true);
|
|
1047
|
+
const [error, setError] = React.useState(null);
|
|
1023
1048
|
const slug = typeof window !== "undefined" ? window.location.pathname.split("/").pop() || "" : "";
|
|
1024
|
-
|
|
1049
|
+
React.useEffect(() => {
|
|
1025
1050
|
if (!slug || !resolvedProductId) return;
|
|
1026
1051
|
async function fetchPost() {
|
|
1027
1052
|
setLoading(true);
|
|
@@ -1123,6 +1148,65 @@ function CaseStudyPage(props) {
|
|
|
1123
1148
|
] })
|
|
1124
1149
|
] });
|
|
1125
1150
|
}
|
|
1151
|
+
function cn(...inputs) {
|
|
1152
|
+
return tailwindMerge.twMerge(clsx.clsx(inputs));
|
|
1153
|
+
}
|
|
1154
|
+
var buttonVariants = classVarianceAuthority.cva(
|
|
1155
|
+
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
|
|
1156
|
+
{
|
|
1157
|
+
variants: {
|
|
1158
|
+
variant: {
|
|
1159
|
+
default: "bg-primary text-primary-foreground shadow hover:bg-primary/90",
|
|
1160
|
+
destructive: "bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90",
|
|
1161
|
+
outline: "border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground",
|
|
1162
|
+
secondary: "bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80",
|
|
1163
|
+
ghost: "hover:bg-accent hover:text-accent-foreground",
|
|
1164
|
+
link: "text-primary underline-offset-4 hover:underline"
|
|
1165
|
+
},
|
|
1166
|
+
size: {
|
|
1167
|
+
default: "h-9 px-4 py-2",
|
|
1168
|
+
sm: "h-8 rounded-md px-3 text-xs",
|
|
1169
|
+
lg: "h-10 rounded-md px-8",
|
|
1170
|
+
icon: "h-9 w-9"
|
|
1171
|
+
}
|
|
1172
|
+
},
|
|
1173
|
+
defaultVariants: {
|
|
1174
|
+
variant: "default",
|
|
1175
|
+
size: "default"
|
|
1176
|
+
}
|
|
1177
|
+
}
|
|
1178
|
+
);
|
|
1179
|
+
var Button = React__namespace.forwardRef(
|
|
1180
|
+
({ className, variant, size, asChild = false, ...props }, ref) => {
|
|
1181
|
+
const Comp = asChild ? reactSlot.Slot : "button";
|
|
1182
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1183
|
+
Comp,
|
|
1184
|
+
{
|
|
1185
|
+
className: cn(buttonVariants({ variant, size, className })),
|
|
1186
|
+
ref,
|
|
1187
|
+
...props
|
|
1188
|
+
}
|
|
1189
|
+
);
|
|
1190
|
+
}
|
|
1191
|
+
);
|
|
1192
|
+
Button.displayName = "Button";
|
|
1193
|
+
var Input = React__namespace.forwardRef(
|
|
1194
|
+
({ className, type, ...props }, ref) => {
|
|
1195
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1196
|
+
"input",
|
|
1197
|
+
{
|
|
1198
|
+
type,
|
|
1199
|
+
className: cn(
|
|
1200
|
+
"flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
|
|
1201
|
+
className
|
|
1202
|
+
),
|
|
1203
|
+
ref,
|
|
1204
|
+
...props
|
|
1205
|
+
}
|
|
1206
|
+
);
|
|
1207
|
+
}
|
|
1208
|
+
);
|
|
1209
|
+
Input.displayName = "Input";
|
|
1126
1210
|
var CHANGELOG_TAG = "changelog";
|
|
1127
1211
|
var CHANGELOG_LIST_QUERY = `
|
|
1128
1212
|
query ChangelogList($productId: String!, $limit: Int, $offset: Int) {
|
|
@@ -1168,30 +1252,29 @@ function sortByDateDesc(a, b) {
|
|
|
1168
1252
|
const db = new Date(b.publishedAt || b.lastUpdated || 0).getTime();
|
|
1169
1253
|
return db - da;
|
|
1170
1254
|
}
|
|
1171
|
-
function
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
seoTitle,
|
|
1183
|
-
seoDescription,
|
|
1184
|
-
seoKeywords
|
|
1185
|
-
} = props;
|
|
1255
|
+
function normalize(value) {
|
|
1256
|
+
return value.toLowerCase().trim();
|
|
1257
|
+
}
|
|
1258
|
+
function paginate(items, page, pageSize) {
|
|
1259
|
+
const start = (page - 1) * pageSize;
|
|
1260
|
+
return items.slice(start, start + pageSize);
|
|
1261
|
+
}
|
|
1262
|
+
function parseEntryDate(date) {
|
|
1263
|
+
return new Date(date).getTime();
|
|
1264
|
+
}
|
|
1265
|
+
function useCmsChangelog() {
|
|
1186
1266
|
const client = useWebSDK();
|
|
1187
1267
|
const config = useWebSDKConfig();
|
|
1188
1268
|
const { product } = useProduct();
|
|
1189
1269
|
const resolvedProductId = product?.id || config.productId;
|
|
1190
|
-
const [entries, setEntries] =
|
|
1191
|
-
const [loading, setLoading] =
|
|
1192
|
-
const [error, setError] =
|
|
1193
|
-
const fetchEntries =
|
|
1194
|
-
if (!resolvedProductId)
|
|
1270
|
+
const [entries, setEntries] = React.useState([]);
|
|
1271
|
+
const [loading, setLoading] = React.useState(true);
|
|
1272
|
+
const [error, setError] = React.useState(null);
|
|
1273
|
+
const fetchEntries = React.useCallback(async () => {
|
|
1274
|
+
if (!resolvedProductId) {
|
|
1275
|
+
setLoading(false);
|
|
1276
|
+
return;
|
|
1277
|
+
}
|
|
1195
1278
|
setLoading(true);
|
|
1196
1279
|
try {
|
|
1197
1280
|
const listResult = await client.query(CHANGELOG_LIST_QUERY, {
|
|
@@ -1230,96 +1313,323 @@ function ChangelogPage(props) {
|
|
|
1230
1313
|
setLoading(false);
|
|
1231
1314
|
}
|
|
1232
1315
|
}, [client, resolvedProductId]);
|
|
1233
|
-
|
|
1316
|
+
React.useEffect(() => {
|
|
1234
1317
|
fetchEntries();
|
|
1235
1318
|
}, [fetchEntries]);
|
|
1319
|
+
return { entries, loading, error };
|
|
1320
|
+
}
|
|
1321
|
+
function CmsTimeline(props) {
|
|
1322
|
+
const { entries, loading, error } = props;
|
|
1323
|
+
if (loading) {
|
|
1324
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "max-w-3xl mx-auto space-y-12", children: [1, 2, 3].map((i) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
1325
|
+
"div",
|
|
1326
|
+
{
|
|
1327
|
+
className: "rounded-2xl border border-border/40 bg-card overflow-hidden animate-pulse",
|
|
1328
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-6 sm:p-8 space-y-4", children: [
|
|
1329
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-3 bg-muted rounded w-1/3" }),
|
|
1330
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-6 bg-muted rounded w-2/3" }),
|
|
1331
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-4 bg-muted rounded" }),
|
|
1332
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-4 bg-muted rounded w-5/6" })
|
|
1333
|
+
] })
|
|
1334
|
+
},
|
|
1335
|
+
i
|
|
1336
|
+
)) });
|
|
1337
|
+
}
|
|
1338
|
+
if (error) {
|
|
1339
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-center py-12", children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground", children: error }) });
|
|
1340
|
+
}
|
|
1341
|
+
if (entries.length === 0) {
|
|
1342
|
+
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!" }) });
|
|
1343
|
+
}
|
|
1344
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "max-w-3xl mx-auto space-y-12", children: entries.map((entry) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1345
|
+
"article",
|
|
1346
|
+
{
|
|
1347
|
+
id: entry.slug,
|
|
1348
|
+
className: "rounded-2xl border border-border/40 bg-card overflow-hidden scroll-mt-24",
|
|
1349
|
+
children: [
|
|
1350
|
+
entry.thumbnail && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1351
|
+
"img",
|
|
1352
|
+
{
|
|
1353
|
+
src: entry.thumbnail,
|
|
1354
|
+
alt: "",
|
|
1355
|
+
width: 1024,
|
|
1356
|
+
height: 576,
|
|
1357
|
+
loading: "lazy",
|
|
1358
|
+
decoding: "async",
|
|
1359
|
+
className: "w-full aspect-video object-cover border-b border-border/40"
|
|
1360
|
+
}
|
|
1361
|
+
),
|
|
1362
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-6 sm:p-8", children: [
|
|
1363
|
+
/* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-xs text-muted-foreground mb-2", children: [
|
|
1364
|
+
entry.publishedAt && /* @__PURE__ */ jsxRuntime.jsx("time", { dateTime: entry.publishedAt, children: formatDate(entry.publishedAt || entry.lastUpdated) }),
|
|
1365
|
+
entry.author && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
1366
|
+
" \xB7 ",
|
|
1367
|
+
entry.author
|
|
1368
|
+
] })
|
|
1369
|
+
] }),
|
|
1370
|
+
/* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-xl sm:text-2xl font-bold text-foreground mb-4", children: entry.title }),
|
|
1371
|
+
entry.content ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "prose prose-sm prose-gray dark:prose-invert max-w-none", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1372
|
+
ContentRenderer,
|
|
1373
|
+
{
|
|
1374
|
+
content: entry.content,
|
|
1375
|
+
format: entry.contentFormat
|
|
1376
|
+
}
|
|
1377
|
+
) }) : entry.excerpt && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground leading-relaxed", children: entry.excerpt })
|
|
1378
|
+
] })
|
|
1379
|
+
]
|
|
1380
|
+
},
|
|
1381
|
+
entry.id
|
|
1382
|
+
)) });
|
|
1383
|
+
}
|
|
1384
|
+
function EntryContent({ content }) {
|
|
1385
|
+
if (typeof content === "string") {
|
|
1386
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "prose prose-sm prose-gray dark:prose-invert max-w-none", children: /* @__PURE__ */ jsxRuntime.jsx(ContentRenderer, { content, format: "markdown" }) });
|
|
1387
|
+
}
|
|
1388
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "prose prose-sm max-w-none", children: content });
|
|
1389
|
+
}
|
|
1390
|
+
function EntriesTimeline(props) {
|
|
1391
|
+
const { entries, pageSize, productName } = props;
|
|
1392
|
+
const [query, setQuery] = React.useState("");
|
|
1393
|
+
const [selectedCategory, setSelectedCategory] = React.useState(null);
|
|
1394
|
+
const [page, setPage] = React.useState(1);
|
|
1395
|
+
const categories = React.useMemo(
|
|
1396
|
+
() => Array.from(new Set(entries.map((e) => e.category))).sort(),
|
|
1397
|
+
[entries]
|
|
1398
|
+
);
|
|
1399
|
+
const filtered = React.useMemo(() => {
|
|
1400
|
+
const normalized = normalize(query);
|
|
1401
|
+
return entries.filter((entry) => {
|
|
1402
|
+
if (selectedCategory && entry.category !== selectedCategory) {
|
|
1403
|
+
return false;
|
|
1404
|
+
}
|
|
1405
|
+
if (!normalized) return true;
|
|
1406
|
+
const haystack = [
|
|
1407
|
+
entry.title,
|
|
1408
|
+
entry.version,
|
|
1409
|
+
entry.category,
|
|
1410
|
+
...entry.tags ?? [],
|
|
1411
|
+
typeof entry.content === "string" ? entry.content : ""
|
|
1412
|
+
].join(" ").toLowerCase();
|
|
1413
|
+
return haystack.includes(normalized);
|
|
1414
|
+
}).sort((a, b) => parseEntryDate(b.date) - parseEntryDate(a.date));
|
|
1415
|
+
}, [entries, query, selectedCategory]);
|
|
1416
|
+
const totalPages = Math.max(1, Math.ceil(filtered.length / pageSize));
|
|
1417
|
+
const safePage = Math.min(page, totalPages);
|
|
1418
|
+
const pageItems = paginate(filtered, safePage, pageSize);
|
|
1419
|
+
React.useEffect(() => {
|
|
1420
|
+
setPage(1);
|
|
1421
|
+
}, [query, selectedCategory]);
|
|
1422
|
+
if (entries.length === 0) {
|
|
1423
|
+
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!" }) });
|
|
1424
|
+
}
|
|
1425
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "max-w-3xl mx-auto", children: [
|
|
1426
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-8 space-y-4", children: [
|
|
1427
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
|
|
1428
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1429
|
+
lucideReact.Search,
|
|
1430
|
+
{
|
|
1431
|
+
className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground",
|
|
1432
|
+
"aria-hidden": "true"
|
|
1433
|
+
}
|
|
1434
|
+
),
|
|
1435
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1436
|
+
Input,
|
|
1437
|
+
{
|
|
1438
|
+
type: "search",
|
|
1439
|
+
placeholder: "Search releases, features, fixes\u2026",
|
|
1440
|
+
value: query,
|
|
1441
|
+
onChange: (e) => setQuery(e.target.value),
|
|
1442
|
+
className: "pl-9",
|
|
1443
|
+
"aria-label": "Search changelog"
|
|
1444
|
+
}
|
|
1445
|
+
)
|
|
1446
|
+
] }),
|
|
1447
|
+
categories.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap gap-2", children: [
|
|
1448
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1449
|
+
"button",
|
|
1450
|
+
{
|
|
1451
|
+
type: "button",
|
|
1452
|
+
onClick: () => setSelectedCategory(null),
|
|
1453
|
+
className: cn(
|
|
1454
|
+
"px-3 py-1 rounded-full text-xs font-medium border transition-colors",
|
|
1455
|
+
selectedCategory === null ? "bg-primary text-primary-foreground border-primary" : "bg-background text-muted-foreground border-border/60 hover:border-primary/40"
|
|
1456
|
+
),
|
|
1457
|
+
children: "All"
|
|
1458
|
+
}
|
|
1459
|
+
),
|
|
1460
|
+
categories.map((category) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
1461
|
+
"button",
|
|
1462
|
+
{
|
|
1463
|
+
type: "button",
|
|
1464
|
+
onClick: () => setSelectedCategory(category),
|
|
1465
|
+
className: cn(
|
|
1466
|
+
"px-3 py-1 rounded-full text-xs font-medium border transition-colors",
|
|
1467
|
+
selectedCategory === category ? "bg-primary text-primary-foreground border-primary" : "bg-background text-muted-foreground border-border/60 hover:border-primary/40"
|
|
1468
|
+
),
|
|
1469
|
+
children: category
|
|
1470
|
+
},
|
|
1471
|
+
category
|
|
1472
|
+
))
|
|
1473
|
+
] })
|
|
1474
|
+
] }),
|
|
1475
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
|
|
1476
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1477
|
+
"div",
|
|
1478
|
+
{
|
|
1479
|
+
className: "absolute left-[1.125rem] top-3 bottom-3 w-px bg-border/60 hidden sm:block",
|
|
1480
|
+
"aria-hidden": "true"
|
|
1481
|
+
}
|
|
1482
|
+
),
|
|
1483
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-8", children: pageItems.map((entry) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1484
|
+
"article",
|
|
1485
|
+
{
|
|
1486
|
+
className: "relative sm:pl-12",
|
|
1487
|
+
children: [
|
|
1488
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1489
|
+
"div",
|
|
1490
|
+
{
|
|
1491
|
+
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",
|
|
1492
|
+
"aria-hidden": "true",
|
|
1493
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "h-2 w-2 rounded-full bg-primary-foreground" })
|
|
1494
|
+
}
|
|
1495
|
+
),
|
|
1496
|
+
/* @__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: [
|
|
1497
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-2 mb-3", children: [
|
|
1498
|
+
/* @__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 }),
|
|
1499
|
+
/* @__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: [
|
|
1500
|
+
"v",
|
|
1501
|
+
entry.version
|
|
1502
|
+
] }),
|
|
1503
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1504
|
+
"time",
|
|
1505
|
+
{
|
|
1506
|
+
className: "text-xs text-muted-foreground",
|
|
1507
|
+
dateTime: entry.date,
|
|
1508
|
+
children: formatDate(entry.date)
|
|
1509
|
+
}
|
|
1510
|
+
)
|
|
1511
|
+
] }),
|
|
1512
|
+
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(
|
|
1513
|
+
"span",
|
|
1514
|
+
{
|
|
1515
|
+
className: "text-[10px] uppercase tracking-wide text-muted-foreground bg-background border border-border/40 px-1.5 py-0.5 rounded",
|
|
1516
|
+
children: tag
|
|
1517
|
+
},
|
|
1518
|
+
tag
|
|
1519
|
+
)) }),
|
|
1520
|
+
/* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-xl sm:text-2xl font-bold text-foreground mb-4", children: entry.title }),
|
|
1521
|
+
/* @__PURE__ */ jsxRuntime.jsx(EntryContent, { content: entry.content })
|
|
1522
|
+
] }) })
|
|
1523
|
+
]
|
|
1524
|
+
},
|
|
1525
|
+
`${entry.version}-${entry.date}`
|
|
1526
|
+
)) })
|
|
1527
|
+
] }),
|
|
1528
|
+
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." }) }),
|
|
1529
|
+
totalPages > 1 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-10 flex items-center justify-between", children: [
|
|
1530
|
+
/* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-sm text-muted-foreground", children: [
|
|
1531
|
+
"Page ",
|
|
1532
|
+
safePage,
|
|
1533
|
+
" of ",
|
|
1534
|
+
totalPages,
|
|
1535
|
+
" \xB7 ",
|
|
1536
|
+
filtered.length,
|
|
1537
|
+
" entries"
|
|
1538
|
+
] }),
|
|
1539
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
1540
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1541
|
+
Button,
|
|
1542
|
+
{
|
|
1543
|
+
variant: "outline",
|
|
1544
|
+
size: "sm",
|
|
1545
|
+
onClick: () => setPage((p) => Math.max(1, p - 1)),
|
|
1546
|
+
disabled: safePage <= 1,
|
|
1547
|
+
"aria-label": "Previous page",
|
|
1548
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronLeft, { className: "h-4 w-4" })
|
|
1549
|
+
}
|
|
1550
|
+
),
|
|
1551
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1552
|
+
Button,
|
|
1553
|
+
{
|
|
1554
|
+
variant: "outline",
|
|
1555
|
+
size: "sm",
|
|
1556
|
+
onClick: () => setPage((p) => Math.min(totalPages, p + 1)),
|
|
1557
|
+
disabled: safePage >= totalPages,
|
|
1558
|
+
"aria-label": "Next page",
|
|
1559
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { className: "h-4 w-4" })
|
|
1560
|
+
}
|
|
1561
|
+
)
|
|
1562
|
+
] })
|
|
1563
|
+
] }),
|
|
1564
|
+
productName && pageItems.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("script", { type: "application/ld+json", children: JSON.stringify({
|
|
1565
|
+
"@context": "https://schema.org",
|
|
1566
|
+
"@type": "ItemList",
|
|
1567
|
+
name: `${productName} Changelog`,
|
|
1568
|
+
itemListElement: pageItems.map((entry, index) => ({
|
|
1569
|
+
"@type": "ListItem",
|
|
1570
|
+
position: (safePage - 1) * pageSize + index + 1,
|
|
1571
|
+
name: entry.title,
|
|
1572
|
+
description: typeof entry.content === "string" ? entry.content.slice(0, 200) : void 0,
|
|
1573
|
+
datePublished: entry.date
|
|
1574
|
+
}))
|
|
1575
|
+
}) })
|
|
1576
|
+
] });
|
|
1577
|
+
}
|
|
1578
|
+
function ChangelogPage(props) {
|
|
1579
|
+
const {
|
|
1580
|
+
productName,
|
|
1581
|
+
heroEyebrow = "What's new",
|
|
1582
|
+
heroTitle = "Changelog",
|
|
1583
|
+
heroSubtitle = "Platform updates, improvements, and announcements \u2014 newest first.",
|
|
1584
|
+
ctaTitle,
|
|
1585
|
+
ctaSubtitle,
|
|
1586
|
+
ctaHref,
|
|
1587
|
+
ctaLabel,
|
|
1588
|
+
className = "",
|
|
1589
|
+
seoTitle,
|
|
1590
|
+
seoDescription,
|
|
1591
|
+
seoKeywords,
|
|
1592
|
+
entries,
|
|
1593
|
+
pageSize = 10
|
|
1594
|
+
} = props;
|
|
1595
|
+
const { product } = useProduct();
|
|
1596
|
+
const resolvedProductName = productName || product?.name;
|
|
1597
|
+
const cms = useCmsChangelog();
|
|
1236
1598
|
const showCta = Boolean(ctaHref && ctaLabel);
|
|
1599
|
+
const isPropDriven = entries != null;
|
|
1237
1600
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `w-full ${className}`, children: [
|
|
1238
|
-
|
|
1601
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1239
1602
|
PageHead,
|
|
1240
1603
|
{
|
|
1241
|
-
title: seoTitle,
|
|
1604
|
+
title: seoTitle || heroTitle,
|
|
1242
1605
|
description: seoDescription || heroSubtitle,
|
|
1243
|
-
productName,
|
|
1606
|
+
productName: resolvedProductName,
|
|
1244
1607
|
keywords: seoKeywords
|
|
1245
1608
|
}
|
|
1246
1609
|
),
|
|
1247
1610
|
/* @__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: [
|
|
1248
1611
|
/* @__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: [
|
|
1249
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1250
|
-
"svg",
|
|
1251
|
-
{
|
|
1252
|
-
className: "h-3.5 w-3.5",
|
|
1253
|
-
fill: "none",
|
|
1254
|
-
viewBox: "0 0 24 24",
|
|
1255
|
-
stroke: "currentColor",
|
|
1256
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1257
|
-
"path",
|
|
1258
|
-
{
|
|
1259
|
-
strokeLinecap: "round",
|
|
1260
|
-
strokeLinejoin: "round",
|
|
1261
|
-
strokeWidth: 2,
|
|
1262
|
-
d: "M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"
|
|
1263
|
-
}
|
|
1264
|
-
)
|
|
1265
|
-
}
|
|
1266
|
-
),
|
|
1612
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.History, { className: "h-3.5 w-3.5", "aria-hidden": "true" }),
|
|
1267
1613
|
heroEyebrow
|
|
1268
1614
|
] }),
|
|
1269
1615
|
/* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-4xl sm:text-5xl font-bold text-foreground mb-4", children: heroTitle }),
|
|
1270
1616
|
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-lg text-muted-foreground", children: heroSubtitle })
|
|
1271
1617
|
] }) }),
|
|
1272
|
-
/* @__PURE__ */ jsxRuntime.jsx("section", { className: "px-4 sm:px-6 lg:px-8 pb-20", children:
|
|
1273
|
-
|
|
1618
|
+
/* @__PURE__ */ jsxRuntime.jsx("section", { className: "px-4 sm:px-6 lg:px-8 pb-20", children: isPropDriven ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
1619
|
+
EntriesTimeline,
|
|
1274
1620
|
{
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
] })
|
|
1282
|
-
},
|
|
1283
|
-
i
|
|
1284
|
-
)) : error ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-center py-12", children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground", children: error }) }) : entries.length === 0 ? /* @__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!" }) }) : entries.map((entry) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1285
|
-
"article",
|
|
1621
|
+
entries,
|
|
1622
|
+
pageSize,
|
|
1623
|
+
productName: resolvedProductName
|
|
1624
|
+
}
|
|
1625
|
+
) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
1626
|
+
CmsTimeline,
|
|
1286
1627
|
{
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
{
|
|
1293
|
-
src: entry.thumbnail,
|
|
1294
|
-
alt: "",
|
|
1295
|
-
width: 1024,
|
|
1296
|
-
height: 576,
|
|
1297
|
-
loading: "lazy",
|
|
1298
|
-
decoding: "async",
|
|
1299
|
-
className: "w-full aspect-video object-cover border-b border-border/40"
|
|
1300
|
-
}
|
|
1301
|
-
),
|
|
1302
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-6 sm:p-8", children: [
|
|
1303
|
-
/* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-xs text-muted-foreground mb-2", children: [
|
|
1304
|
-
entry.publishedAt && /* @__PURE__ */ jsxRuntime.jsx("time", { dateTime: entry.publishedAt, children: formatDate(entry.publishedAt || entry.lastUpdated) }),
|
|
1305
|
-
entry.author && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
1306
|
-
" \xB7 ",
|
|
1307
|
-
entry.author
|
|
1308
|
-
] })
|
|
1309
|
-
] }),
|
|
1310
|
-
/* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-xl sm:text-2xl font-bold text-foreground mb-4", children: entry.title }),
|
|
1311
|
-
entry.content ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "prose prose-sm prose-gray dark:prose-invert max-w-none", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1312
|
-
ContentRenderer,
|
|
1313
|
-
{
|
|
1314
|
-
content: entry.content,
|
|
1315
|
-
format: entry.contentFormat
|
|
1316
|
-
}
|
|
1317
|
-
) }) : entry.excerpt && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground leading-relaxed", children: entry.excerpt })
|
|
1318
|
-
] })
|
|
1319
|
-
]
|
|
1320
|
-
},
|
|
1321
|
-
entry.id
|
|
1322
|
-
)) }) }),
|
|
1628
|
+
entries: cms.entries,
|
|
1629
|
+
loading: cms.loading,
|
|
1630
|
+
error: cms.error
|
|
1631
|
+
}
|
|
1632
|
+
) }),
|
|
1323
1633
|
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: [
|
|
1324
1634
|
ctaTitle && /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-2xl font-bold text-foreground mb-3", children: ctaTitle }),
|
|
1325
1635
|
ctaSubtitle && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground mb-7", children: ctaSubtitle }),
|
|
@@ -1442,7 +1752,7 @@ function PressKitLightbox({
|
|
|
1442
1752
|
asset,
|
|
1443
1753
|
onClose
|
|
1444
1754
|
}) {
|
|
1445
|
-
|
|
1755
|
+
React.useEffect(() => {
|
|
1446
1756
|
if (!asset) return;
|
|
1447
1757
|
const onKey = (e) => {
|
|
1448
1758
|
if (e.key === "Escape") onClose();
|
|
@@ -1567,7 +1877,7 @@ function AssetCard({
|
|
|
1567
1877
|
}) : "";
|
|
1568
1878
|
const ext = (asset.mimeType || "file").split("/").pop()?.toUpperCase() || "FILE";
|
|
1569
1879
|
const size = formatBytes(asset.fileSize);
|
|
1570
|
-
const [imgError, setImgError] =
|
|
1880
|
+
const [imgError, setImgError] = React.useState(false);
|
|
1571
1881
|
const thumb = asset.thumbnailUrl && !imgError ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "aspect-[16/9] overflow-hidden bg-muted/30", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1572
1882
|
"img",
|
|
1573
1883
|
{
|
|
@@ -1680,7 +1990,7 @@ function PressReleaseCard({
|
|
|
1680
1990
|
month: "long",
|
|
1681
1991
|
day: "numeric"
|
|
1682
1992
|
}) : "";
|
|
1683
|
-
const [imgError, setImgError] =
|
|
1993
|
+
const [imgError, setImgError] = React.useState(false);
|
|
1684
1994
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1685
1995
|
"a",
|
|
1686
1996
|
{
|
|
@@ -1755,14 +2065,14 @@ function PressKitPage(props) {
|
|
|
1755
2065
|
const { product } = useProduct();
|
|
1756
2066
|
const resolvedProductId = product?.id || config.productId;
|
|
1757
2067
|
const contactEmail = mediaContactEmail || product?.contactEmail || void 0;
|
|
1758
|
-
const [assets, setAssets] =
|
|
1759
|
-
const [loading, setLoading] =
|
|
1760
|
-
const [error, setError] =
|
|
1761
|
-
const [activeCategory, setActiveCategory] =
|
|
1762
|
-
const [releases, setReleases] =
|
|
1763
|
-
const [releasesLoading, setReleasesLoading] =
|
|
1764
|
-
const [preview, setPreview] =
|
|
1765
|
-
const fetchAssets =
|
|
2068
|
+
const [assets, setAssets] = React.useState([]);
|
|
2069
|
+
const [loading, setLoading] = React.useState(true);
|
|
2070
|
+
const [error, setError] = React.useState(null);
|
|
2071
|
+
const [activeCategory, setActiveCategory] = React.useState("ALL");
|
|
2072
|
+
const [releases, setReleases] = React.useState([]);
|
|
2073
|
+
const [releasesLoading, setReleasesLoading] = React.useState(true);
|
|
2074
|
+
const [preview, setPreview] = React.useState(null);
|
|
2075
|
+
const fetchAssets = React.useCallback(async () => {
|
|
1766
2076
|
if (!resolvedProductId) {
|
|
1767
2077
|
setLoading(false);
|
|
1768
2078
|
return;
|
|
@@ -1797,10 +2107,10 @@ function PressKitPage(props) {
|
|
|
1797
2107
|
setLoading(false);
|
|
1798
2108
|
}
|
|
1799
2109
|
}, [client, resolvedProductId]);
|
|
1800
|
-
|
|
2110
|
+
React.useEffect(() => {
|
|
1801
2111
|
fetchAssets();
|
|
1802
2112
|
}, [fetchAssets]);
|
|
1803
|
-
const fetchReleases =
|
|
2113
|
+
const fetchReleases = React.useCallback(async () => {
|
|
1804
2114
|
if (!resolvedProductId || !showPressReleases) {
|
|
1805
2115
|
setReleasesLoading(false);
|
|
1806
2116
|
return;
|
|
@@ -1839,7 +2149,7 @@ function PressKitPage(props) {
|
|
|
1839
2149
|
setReleasesLoading(false);
|
|
1840
2150
|
}
|
|
1841
2151
|
}, [client, resolvedProductId, showPressReleases]);
|
|
1842
|
-
|
|
2152
|
+
React.useEffect(() => {
|
|
1843
2153
|
fetchReleases();
|
|
1844
2154
|
}, [fetchReleases]);
|
|
1845
2155
|
const presentCategories = CATEGORY_ORDER.filter(
|
|
@@ -2010,10 +2320,10 @@ function ContractsPage(props) {
|
|
|
2010
2320
|
const { product } = useProduct();
|
|
2011
2321
|
const resolvedProductId = product?.id || config.productId;
|
|
2012
2322
|
const displayName = productName ?? product?.name ?? config.productId;
|
|
2013
|
-
const [contracts, setContracts] =
|
|
2014
|
-
const [loading, setLoading] =
|
|
2015
|
-
const [error, setError] =
|
|
2016
|
-
const fetchContracts =
|
|
2323
|
+
const [contracts, setContracts] = React.useState([]);
|
|
2324
|
+
const [loading, setLoading] = React.useState(true);
|
|
2325
|
+
const [error, setError] = React.useState(null);
|
|
2326
|
+
const fetchContracts = React.useCallback(async () => {
|
|
2017
2327
|
if (!resolvedProductId) {
|
|
2018
2328
|
setLoading(false);
|
|
2019
2329
|
return;
|
|
@@ -2051,7 +2361,7 @@ function ContractsPage(props) {
|
|
|
2051
2361
|
setLoading(false);
|
|
2052
2362
|
}
|
|
2053
2363
|
}, [client, resolvedProductId]);
|
|
2054
|
-
|
|
2364
|
+
React.useEffect(() => {
|
|
2055
2365
|
fetchContracts();
|
|
2056
2366
|
}, [fetchContracts]);
|
|
2057
2367
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `min-h-screen bg-background ${className}`, children: [
|