@burdenoff/website-sdk 2026.521.2 → 2026.521.3
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/partners.d.mts +78 -0
- package/dist/components/partners.d.ts +78 -0
- package/dist/components/partners.js +1147 -0
- package/dist/components/partners.js.map +1 -0
- package/dist/components/partners.mjs +1122 -0
- package/dist/components/partners.mjs.map +1 -0
- package/dist/index.d.mts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +503 -207
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +504 -209
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -978,6 +978,508 @@ function ContactPage({
|
|
|
978
978
|
] }) })
|
|
979
979
|
] });
|
|
980
980
|
}
|
|
981
|
+
var PUBLIC_CONTENT_PAGE_QUERY = `
|
|
982
|
+
query PublicContentPage($slug: String!, $productId: String) {
|
|
983
|
+
publicContentPage(slug: $slug, productId: $productId) {
|
|
984
|
+
id
|
|
985
|
+
title
|
|
986
|
+
slug
|
|
987
|
+
content
|
|
988
|
+
contentFormat
|
|
989
|
+
seoTitle
|
|
990
|
+
seoDescription
|
|
991
|
+
seoKeywords
|
|
992
|
+
lastUpdated
|
|
993
|
+
version
|
|
994
|
+
excerpt
|
|
995
|
+
thumbnail
|
|
996
|
+
author
|
|
997
|
+
publishedAt
|
|
998
|
+
readingTime
|
|
999
|
+
featured
|
|
1000
|
+
category
|
|
1001
|
+
}
|
|
1002
|
+
}
|
|
1003
|
+
`;
|
|
1004
|
+
var PUBLIC_RESOLVED_CONTENT_PAGE_QUERY = `
|
|
1005
|
+
query PublicResolvedContentPage($slug: String!, $productId: String!) {
|
|
1006
|
+
publicResolvedContentPage(slug: $slug, productId: $productId) {
|
|
1007
|
+
id
|
|
1008
|
+
title
|
|
1009
|
+
slug
|
|
1010
|
+
content
|
|
1011
|
+
contentFormat
|
|
1012
|
+
seoTitle
|
|
1013
|
+
seoDescription
|
|
1014
|
+
seoKeywords
|
|
1015
|
+
lastUpdated
|
|
1016
|
+
version
|
|
1017
|
+
excerpt
|
|
1018
|
+
thumbnail
|
|
1019
|
+
author
|
|
1020
|
+
publishedAt
|
|
1021
|
+
readingTime
|
|
1022
|
+
featured
|
|
1023
|
+
category
|
|
1024
|
+
}
|
|
1025
|
+
}
|
|
1026
|
+
`;
|
|
1027
|
+
var PUBLIC_CONTENT_PAGES_QUERY = `
|
|
1028
|
+
query PublicContentPages($productId: String!, $limit: Int, $offset: Int) {
|
|
1029
|
+
publicContentPages(productId: $productId, limit: $limit, offset: $offset) {
|
|
1030
|
+
items {
|
|
1031
|
+
id
|
|
1032
|
+
title
|
|
1033
|
+
slug
|
|
1034
|
+
lastUpdated
|
|
1035
|
+
tags
|
|
1036
|
+
seoDescription
|
|
1037
|
+
excerpt
|
|
1038
|
+
thumbnail
|
|
1039
|
+
author
|
|
1040
|
+
publishedAt
|
|
1041
|
+
readingTime
|
|
1042
|
+
featured
|
|
1043
|
+
category
|
|
1044
|
+
}
|
|
1045
|
+
total
|
|
1046
|
+
hasMore
|
|
1047
|
+
}
|
|
1048
|
+
}
|
|
1049
|
+
`;
|
|
1050
|
+
function useContentPage(slug, options) {
|
|
1051
|
+
const client = useWebSDK();
|
|
1052
|
+
const config = useWebSDKConfig();
|
|
1053
|
+
const { product } = useProduct();
|
|
1054
|
+
const resolvedProductId = product?.id || config.productId;
|
|
1055
|
+
const [data, setData] = React.useState(null);
|
|
1056
|
+
const [loading, setLoading] = React.useState(true);
|
|
1057
|
+
const [error, setError] = React.useState(null);
|
|
1058
|
+
const fetchPage = React.useCallback(async () => {
|
|
1059
|
+
if (!resolvedProductId) return;
|
|
1060
|
+
setLoading(true);
|
|
1061
|
+
setError(null);
|
|
1062
|
+
try {
|
|
1063
|
+
const query = options?.resolve ? PUBLIC_RESOLVED_CONTENT_PAGE_QUERY : PUBLIC_CONTENT_PAGE_QUERY;
|
|
1064
|
+
const queryName = options?.resolve ? "publicResolvedContentPage" : "publicContentPage";
|
|
1065
|
+
const result = await client.query(
|
|
1066
|
+
query,
|
|
1067
|
+
{
|
|
1068
|
+
slug,
|
|
1069
|
+
productId: resolvedProductId
|
|
1070
|
+
}
|
|
1071
|
+
);
|
|
1072
|
+
if (result.errors?.length) {
|
|
1073
|
+
setError(result.errors[0]?.message ?? "Unknown error");
|
|
1074
|
+
setData(null);
|
|
1075
|
+
} else {
|
|
1076
|
+
setData(result.data?.[queryName] ?? null);
|
|
1077
|
+
}
|
|
1078
|
+
} catch (err) {
|
|
1079
|
+
setError(err instanceof Error ? err.message : "Failed to fetch content");
|
|
1080
|
+
setData(null);
|
|
1081
|
+
} finally {
|
|
1082
|
+
setLoading(false);
|
|
1083
|
+
}
|
|
1084
|
+
}, [client, resolvedProductId, slug, options?.resolve]);
|
|
1085
|
+
React.useEffect(() => {
|
|
1086
|
+
fetchPage();
|
|
1087
|
+
}, [fetchPage]);
|
|
1088
|
+
return { data, loading, error, refetch: fetchPage };
|
|
1089
|
+
}
|
|
1090
|
+
function useContentPages(options) {
|
|
1091
|
+
const client = useWebSDK();
|
|
1092
|
+
const config = useWebSDKConfig();
|
|
1093
|
+
const [data, setData] = React.useState(null);
|
|
1094
|
+
const [loading, setLoading] = React.useState(true);
|
|
1095
|
+
const [error, setError] = React.useState(null);
|
|
1096
|
+
const fetchPages = React.useCallback(async () => {
|
|
1097
|
+
setLoading(true);
|
|
1098
|
+
setError(null);
|
|
1099
|
+
try {
|
|
1100
|
+
const result = await client.query(PUBLIC_CONTENT_PAGES_QUERY, {
|
|
1101
|
+
productId: config.productId,
|
|
1102
|
+
limit: options?.limit ?? 50,
|
|
1103
|
+
offset: options?.offset ?? 0
|
|
1104
|
+
});
|
|
1105
|
+
if (result.errors?.length) {
|
|
1106
|
+
setError(result.errors[0]?.message ?? "Unknown error");
|
|
1107
|
+
setData(null);
|
|
1108
|
+
} else {
|
|
1109
|
+
setData(result.data?.publicContentPages ?? null);
|
|
1110
|
+
}
|
|
1111
|
+
} catch (err) {
|
|
1112
|
+
setError(
|
|
1113
|
+
err instanceof Error ? err.message : "Failed to fetch content pages"
|
|
1114
|
+
);
|
|
1115
|
+
setData(null);
|
|
1116
|
+
} finally {
|
|
1117
|
+
setLoading(false);
|
|
1118
|
+
}
|
|
1119
|
+
}, [client, config.productId, options?.limit, options?.offset]);
|
|
1120
|
+
React.useEffect(() => {
|
|
1121
|
+
fetchPages();
|
|
1122
|
+
}, [fetchPages]);
|
|
1123
|
+
return { data, loading, error, refetch: fetchPages };
|
|
1124
|
+
}
|
|
1125
|
+
function renderMarkdown(md) {
|
|
1126
|
+
let html = md;
|
|
1127
|
+
html = html.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
1128
|
+
html = html.replace(/```(\w*)\n([\s\S]*?)```/g, (_m, _lang, code) => {
|
|
1129
|
+
return `<pre><code>${code.trim()}</code></pre>`;
|
|
1130
|
+
});
|
|
1131
|
+
html = html.replace(/`([^`]+)`/g, "<code>$1</code>");
|
|
1132
|
+
html = html.replace(/^###### (.+)$/gm, "<h6>$1</h6>");
|
|
1133
|
+
html = html.replace(/^##### (.+)$/gm, "<h5>$1</h5>");
|
|
1134
|
+
html = html.replace(/^#### (.+)$/gm, "<h4>$1</h4>");
|
|
1135
|
+
html = html.replace(/^### (.+)$/gm, "<h3>$1</h3>");
|
|
1136
|
+
html = html.replace(/^## (.+)$/gm, "<h2>$1</h2>");
|
|
1137
|
+
html = html.replace(/^# (.+)$/gm, "<h1>$1</h1>");
|
|
1138
|
+
html = html.replace(/\*\*\*(.+?)\*\*\*/g, "<strong><em>$1</em></strong>");
|
|
1139
|
+
html = html.replace(/\*\*(.+?)\*\*/g, "<strong>$1</strong>");
|
|
1140
|
+
html = html.replace(/\*(.+?)\*/g, "<em>$1</em>");
|
|
1141
|
+
html = html.replace(
|
|
1142
|
+
/\[([^\]]+)\]\(([^)]+)\)/g,
|
|
1143
|
+
'<a href="$2" target="_blank" rel="noopener noreferrer">$1</a>'
|
|
1144
|
+
);
|
|
1145
|
+
html = html.replace(/^> (.+)$/gm, "<blockquote>$1</blockquote>");
|
|
1146
|
+
html = html.replace(/(^- .+$(\n^- .+$)*)/gm, (block) => {
|
|
1147
|
+
const items = block.split("\n").map((line) => `<li>${line.replace(/^- /, "")}</li>`).join("");
|
|
1148
|
+
return `<ul>${items}</ul>`;
|
|
1149
|
+
});
|
|
1150
|
+
html = html.replace(/(^\d+\. .+$(\n^\d+\. .+$)*)/gm, (block) => {
|
|
1151
|
+
const items = block.split("\n").map((line) => `<li>${line.replace(/^\d+\. /, "")}</li>`).join("");
|
|
1152
|
+
return `<ol>${items}</ol>`;
|
|
1153
|
+
});
|
|
1154
|
+
html = html.replace(/^---$/gm, "<hr />");
|
|
1155
|
+
html = html.split(/\n\n+/).map((block) => {
|
|
1156
|
+
const trimmed = block.trim();
|
|
1157
|
+
if (!trimmed) return "";
|
|
1158
|
+
if (/^<(h[1-6]|ul|ol|pre|blockquote|hr)/.test(trimmed)) return trimmed;
|
|
1159
|
+
return `<p>${trimmed.replace(/\n/g, "<br />")}</p>`;
|
|
1160
|
+
}).join("\n");
|
|
1161
|
+
return html;
|
|
1162
|
+
}
|
|
1163
|
+
function ContentRenderer({
|
|
1164
|
+
content,
|
|
1165
|
+
format = "markdown",
|
|
1166
|
+
className
|
|
1167
|
+
}) {
|
|
1168
|
+
if (format === "markdown") {
|
|
1169
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1170
|
+
"div",
|
|
1171
|
+
{
|
|
1172
|
+
className,
|
|
1173
|
+
dangerouslySetInnerHTML: { __html: renderMarkdown(content) }
|
|
1174
|
+
}
|
|
1175
|
+
);
|
|
1176
|
+
}
|
|
1177
|
+
if (format === "html") {
|
|
1178
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1179
|
+
"div",
|
|
1180
|
+
{
|
|
1181
|
+
className,
|
|
1182
|
+
dangerouslySetInnerHTML: { __html: content }
|
|
1183
|
+
}
|
|
1184
|
+
);
|
|
1185
|
+
}
|
|
1186
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className, children: /* @__PURE__ */ jsxRuntime.jsx("pre", { style: { whiteSpace: "pre-wrap", fontFamily: "inherit" }, children: content }) });
|
|
1187
|
+
}
|
|
1188
|
+
var PARTNER_CONTENT_QUERY = `
|
|
1189
|
+
query PartnerContent($productId: String!, $limit: Int) {
|
|
1190
|
+
publicContentPages(productId: $productId, limit: $limit, offset: 0) {
|
|
1191
|
+
items {
|
|
1192
|
+
id
|
|
1193
|
+
title
|
|
1194
|
+
slug
|
|
1195
|
+
excerpt
|
|
1196
|
+
content
|
|
1197
|
+
contentFormat
|
|
1198
|
+
thumbnail
|
|
1199
|
+
tags
|
|
1200
|
+
publishedAt
|
|
1201
|
+
lastUpdated
|
|
1202
|
+
}
|
|
1203
|
+
}
|
|
1204
|
+
}
|
|
1205
|
+
`;
|
|
1206
|
+
var PARTNER_DOCUMENTS_QUERY = `
|
|
1207
|
+
query PartnerDocuments($productId: String!, $limit: Int) {
|
|
1208
|
+
publicPressKitAssets(productId: $productId, limit: $limit, offset: 0) {
|
|
1209
|
+
items {
|
|
1210
|
+
id
|
|
1211
|
+
category
|
|
1212
|
+
title
|
|
1213
|
+
description
|
|
1214
|
+
fileUrl
|
|
1215
|
+
fileName
|
|
1216
|
+
fileSize
|
|
1217
|
+
mimeType
|
|
1218
|
+
version
|
|
1219
|
+
tags
|
|
1220
|
+
sortOrder
|
|
1221
|
+
updatedAt
|
|
1222
|
+
}
|
|
1223
|
+
}
|
|
1224
|
+
}
|
|
1225
|
+
`;
|
|
1226
|
+
function formatFileSize(bytes) {
|
|
1227
|
+
if (!bytes || bytes <= 0) return "";
|
|
1228
|
+
const units = ["B", "KB", "MB", "GB"];
|
|
1229
|
+
let i = 0;
|
|
1230
|
+
let n = bytes;
|
|
1231
|
+
while (n >= 1024 && i < units.length - 1) {
|
|
1232
|
+
n /= 1024;
|
|
1233
|
+
i++;
|
|
1234
|
+
}
|
|
1235
|
+
return `${n.toFixed(n >= 10 || i === 0 ? 0 : 1)} ${units[i]}`;
|
|
1236
|
+
}
|
|
1237
|
+
async function downloadDocument(e, doc) {
|
|
1238
|
+
e.preventDefault();
|
|
1239
|
+
const name = doc.fileName || doc.fileUrl.split("/").pop()?.split("?")[0] || doc.title || "partner-document";
|
|
1240
|
+
const openInTab = () => window.open(doc.fileUrl, "_blank", "noopener,noreferrer");
|
|
1241
|
+
try {
|
|
1242
|
+
const res = await fetch(doc.fileUrl, { mode: "cors" });
|
|
1243
|
+
if (!res.ok) {
|
|
1244
|
+
openInTab();
|
|
1245
|
+
return;
|
|
1246
|
+
}
|
|
1247
|
+
const blob = await res.blob();
|
|
1248
|
+
const objUrl = URL.createObjectURL(blob);
|
|
1249
|
+
const a = document.createElement("a");
|
|
1250
|
+
a.href = objUrl;
|
|
1251
|
+
a.download = name;
|
|
1252
|
+
document.body.appendChild(a);
|
|
1253
|
+
a.click();
|
|
1254
|
+
a.remove();
|
|
1255
|
+
URL.revokeObjectURL(objUrl);
|
|
1256
|
+
} catch {
|
|
1257
|
+
openInTab();
|
|
1258
|
+
}
|
|
1259
|
+
}
|
|
1260
|
+
function PartnerHero({
|
|
1261
|
+
title,
|
|
1262
|
+
subtitle
|
|
1263
|
+
}) {
|
|
1264
|
+
return /* @__PURE__ */ jsxRuntime.jsx("section", { className: "bg-gradient-to-b from-background to-muted/20 py-16 md:py-24", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "container mx-auto px-4 max-w-4xl text-center", children: [
|
|
1265
|
+
/* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-4xl md:text-5xl font-bold tracking-tight text-foreground mb-4", children: title }),
|
|
1266
|
+
subtitle && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-lg md:text-xl text-muted-foreground max-w-2xl mx-auto", children: subtitle })
|
|
1267
|
+
] }) });
|
|
1268
|
+
}
|
|
1269
|
+
function PartnerContentSection({
|
|
1270
|
+
page
|
|
1271
|
+
}) {
|
|
1272
|
+
return /* @__PURE__ */ jsxRuntime.jsx("section", { className: "py-12 md:py-16", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1273
|
+
"div",
|
|
1274
|
+
{
|
|
1275
|
+
className: [
|
|
1276
|
+
"mx-auto max-w-3xl px-4",
|
|
1277
|
+
// Headings
|
|
1278
|
+
"[&_h1]:text-3xl [&_h1]:font-bold [&_h1]:tracking-tight [&_h1]:mt-0 [&_h1]:mb-6",
|
|
1279
|
+
"[&_h2]:text-2xl [&_h2]:font-bold [&_h2]:tracking-tight [&_h2]:mt-10 [&_h2]:mb-4",
|
|
1280
|
+
"[&_h3]:text-xl [&_h3]:font-semibold [&_h3]:mt-7 [&_h3]:mb-3",
|
|
1281
|
+
"[&_h4]:text-lg [&_h4]:font-semibold [&_h4]:mt-6 [&_h4]:mb-2",
|
|
1282
|
+
// Block elements
|
|
1283
|
+
"[&_p]:my-4 [&_p]:leading-relaxed [&_p]:text-base",
|
|
1284
|
+
"[&_ul]:my-4 [&_ul]:pl-6 [&_ul]:list-disc [&_ul]:space-y-1",
|
|
1285
|
+
"[&_ol]:my-4 [&_ol]:pl-6 [&_ol]:list-decimal [&_ol]:space-y-1",
|
|
1286
|
+
"[&_li]:leading-relaxed",
|
|
1287
|
+
"[&_li>p]:my-1",
|
|
1288
|
+
"[&_blockquote]:border-l-4 [&_blockquote]:border-border [&_blockquote]:pl-4 [&_blockquote]:italic [&_blockquote]:my-4 [&_blockquote]:text-muted-foreground",
|
|
1289
|
+
"[&_hr]:my-8 [&_hr]:border-border",
|
|
1290
|
+
// Inline elements
|
|
1291
|
+
"[&_strong]:font-semibold [&_strong]:text-foreground",
|
|
1292
|
+
"[&_em]:italic",
|
|
1293
|
+
"[&_a]:underline [&_a]:underline-offset-2 [&_a]:text-accent hover:[&_a]:text-accent/80 [&_a]:transition-colors",
|
|
1294
|
+
"[&_code]:rounded [&_code]:bg-muted [&_code]:px-1.5 [&_code]:py-0.5 [&_code]:text-sm [&_code]:font-mono",
|
|
1295
|
+
"[&_pre]:my-4 [&_pre]:overflow-x-auto [&_pre]:rounded-lg [&_pre]:bg-muted [&_pre]:p-4 [&_pre]:text-sm",
|
|
1296
|
+
"[&_pre>code]:bg-transparent [&_pre>code]:p-0"
|
|
1297
|
+
].join(" "),
|
|
1298
|
+
children: page.content && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1299
|
+
ContentRenderer,
|
|
1300
|
+
{
|
|
1301
|
+
content: page.content,
|
|
1302
|
+
format: (
|
|
1303
|
+
// Validate before passing; unknown formats fall through to
|
|
1304
|
+
// ContentRenderer's default behavior (markdown rendering)
|
|
1305
|
+
// rather than getting silently force-cast to an
|
|
1306
|
+
// unsupported variant.
|
|
1307
|
+
page.contentFormat === "markdown" || page.contentFormat === "html" ? page.contentFormat : void 0
|
|
1308
|
+
)
|
|
1309
|
+
}
|
|
1310
|
+
)
|
|
1311
|
+
}
|
|
1312
|
+
) });
|
|
1313
|
+
}
|
|
1314
|
+
function PartnerDocumentCard({ doc }) {
|
|
1315
|
+
const sizeLabel = formatFileSize(doc.fileSize);
|
|
1316
|
+
const ext = doc.fileName?.split(".").pop()?.toUpperCase();
|
|
1317
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("article", { className: "flex flex-col gap-3 rounded-xl border border-border bg-card p-5 shadow-sm hover:shadow-md transition-shadow", children: [
|
|
1318
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start gap-3", children: [
|
|
1319
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-lg bg-muted p-2.5 shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.FileText, { size: 20, className: "text-muted-foreground" }) }),
|
|
1320
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 flex-1", children: [
|
|
1321
|
+
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "font-semibold text-foreground truncate", children: doc.title }),
|
|
1322
|
+
doc.version && /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-xs text-muted-foreground mt-0.5", children: [
|
|
1323
|
+
"Version ",
|
|
1324
|
+
doc.version
|
|
1325
|
+
] })
|
|
1326
|
+
] })
|
|
1327
|
+
] }),
|
|
1328
|
+
doc.description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground line-clamp-3", children: doc.description }),
|
|
1329
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-3 mt-auto pt-2 border-t border-border/60", children: [
|
|
1330
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-xs text-muted-foreground flex items-center gap-2", children: [
|
|
1331
|
+
ext && /* @__PURE__ */ jsxRuntime.jsx("span", { children: ext }),
|
|
1332
|
+
sizeLabel && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
1333
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": true, children: "\xB7" }),
|
|
1334
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: sizeLabel })
|
|
1335
|
+
] })
|
|
1336
|
+
] }),
|
|
1337
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
1338
|
+
"a",
|
|
1339
|
+
{
|
|
1340
|
+
href: doc.fileUrl,
|
|
1341
|
+
download: doc.fileName ?? void 0,
|
|
1342
|
+
onClick: (e) => void downloadDocument(e, doc),
|
|
1343
|
+
className: "inline-flex items-center gap-1.5 rounded-md border border-border bg-background px-3 py-1.5 text-sm font-medium text-foreground hover:bg-muted transition-colors",
|
|
1344
|
+
children: [
|
|
1345
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Download, { size: 14 }),
|
|
1346
|
+
"Download"
|
|
1347
|
+
]
|
|
1348
|
+
}
|
|
1349
|
+
)
|
|
1350
|
+
] })
|
|
1351
|
+
] });
|
|
1352
|
+
}
|
|
1353
|
+
function PartnerDocumentsSection({
|
|
1354
|
+
title,
|
|
1355
|
+
subtitle,
|
|
1356
|
+
docs
|
|
1357
|
+
}) {
|
|
1358
|
+
return /* @__PURE__ */ jsxRuntime.jsx("section", { className: "py-12 md:py-16 bg-muted/20", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "container mx-auto px-4 max-w-5xl", children: [
|
|
1359
|
+
/* @__PURE__ */ jsxRuntime.jsxs("header", { className: "mb-8 md:mb-10 text-center", children: [
|
|
1360
|
+
/* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-2xl md:text-3xl font-bold text-foreground mb-2", children: title }),
|
|
1361
|
+
subtitle && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground max-w-2xl mx-auto", children: subtitle })
|
|
1362
|
+
] }),
|
|
1363
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4", children: docs.map((doc) => /* @__PURE__ */ jsxRuntime.jsx(PartnerDocumentCard, { doc }, doc.id)) })
|
|
1364
|
+
] }) });
|
|
1365
|
+
}
|
|
1366
|
+
var DEFAULT_PARTNER_CATEGORY = {
|
|
1367
|
+
value: "partnership",
|
|
1368
|
+
label: "Partner program"
|
|
1369
|
+
};
|
|
1370
|
+
function PartnersPage(props) {
|
|
1371
|
+
const {
|
|
1372
|
+
productName: productNameProp,
|
|
1373
|
+
heroTitle = "Partner with us",
|
|
1374
|
+
heroSubtitle,
|
|
1375
|
+
contentTag = "partner",
|
|
1376
|
+
contentSlug,
|
|
1377
|
+
documentsTag = "partner",
|
|
1378
|
+
documentsTitle = "Partner Documents",
|
|
1379
|
+
documentsSubtitle,
|
|
1380
|
+
showContactForm = true,
|
|
1381
|
+
contactCategory,
|
|
1382
|
+
formTitle = "Become a partner",
|
|
1383
|
+
formSubtitle,
|
|
1384
|
+
contactEmail,
|
|
1385
|
+
contactPhone,
|
|
1386
|
+
officeAddress,
|
|
1387
|
+
responseTime,
|
|
1388
|
+
recaptchaSiteKey,
|
|
1389
|
+
additionalOptions,
|
|
1390
|
+
seoTitle,
|
|
1391
|
+
seoDescription,
|
|
1392
|
+
seoKeywords,
|
|
1393
|
+
className
|
|
1394
|
+
} = props;
|
|
1395
|
+
const client = useWebSDK();
|
|
1396
|
+
const config = useWebSDKConfig();
|
|
1397
|
+
const { product } = useProduct();
|
|
1398
|
+
const resolvedProductId = product?.id ?? config?.productId ?? productNameProp ?? "";
|
|
1399
|
+
const resolvedProductName = productNameProp ?? product?.name ?? config?.productId ?? "our team";
|
|
1400
|
+
const [contentPage, setContentPage] = React.useState(null);
|
|
1401
|
+
const [docs, setDocs] = React.useState([]);
|
|
1402
|
+
const [loading, setLoading] = React.useState(true);
|
|
1403
|
+
React.useEffect(() => {
|
|
1404
|
+
if (!client || !resolvedProductId) {
|
|
1405
|
+
setContentPage(null);
|
|
1406
|
+
setDocs([]);
|
|
1407
|
+
setLoading(false);
|
|
1408
|
+
return;
|
|
1409
|
+
}
|
|
1410
|
+
let cancelled = false;
|
|
1411
|
+
setLoading(true);
|
|
1412
|
+
void Promise.allSettled([
|
|
1413
|
+
client.query(PARTNER_CONTENT_QUERY, { productId: resolvedProductId, limit: 50 }),
|
|
1414
|
+
client.query(
|
|
1415
|
+
PARTNER_DOCUMENTS_QUERY,
|
|
1416
|
+
{ productId: resolvedProductId, limit: 50 }
|
|
1417
|
+
)
|
|
1418
|
+
]).then(([contentResult, docsResult]) => {
|
|
1419
|
+
if (cancelled) return;
|
|
1420
|
+
if (contentResult.status === "rejected") {
|
|
1421
|
+
setContentPage(null);
|
|
1422
|
+
} else if (contentResult.status === "fulfilled") {
|
|
1423
|
+
const items = contentResult.value.data?.publicContentPages?.items ?? [];
|
|
1424
|
+
const match = contentSlug ? items.find((p) => p.slug === contentSlug) : items.find((p) => p.tags?.includes(contentTag));
|
|
1425
|
+
setContentPage(match ?? null);
|
|
1426
|
+
}
|
|
1427
|
+
if (docsResult.status === "rejected") {
|
|
1428
|
+
setDocs([]);
|
|
1429
|
+
} else if (docsResult.status === "fulfilled") {
|
|
1430
|
+
const items = docsResult.value.data?.publicPressKitAssets?.items ?? [];
|
|
1431
|
+
const filtered = items.filter(
|
|
1432
|
+
(d) => d.category === "DOCUMENT" && d.tags?.includes(documentsTag) && !!d.fileUrl
|
|
1433
|
+
).sort(
|
|
1434
|
+
(a, b) => a.sortOrder - b.sortOrder
|
|
1435
|
+
);
|
|
1436
|
+
setDocs(filtered);
|
|
1437
|
+
}
|
|
1438
|
+
setLoading(false);
|
|
1439
|
+
});
|
|
1440
|
+
return () => {
|
|
1441
|
+
cancelled = true;
|
|
1442
|
+
};
|
|
1443
|
+
}, [client, resolvedProductId, contentSlug, contentTag, documentsTag]);
|
|
1444
|
+
const lockedCategory = contactCategory === false ? null : contactCategory ?? DEFAULT_PARTNER_CATEGORY;
|
|
1445
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className, children: [
|
|
1446
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1447
|
+
PageHead,
|
|
1448
|
+
{
|
|
1449
|
+
title: seoTitle ?? `${heroTitle} \u2014 ${resolvedProductName}`,
|
|
1450
|
+
description: seoDescription ?? heroSubtitle ?? `Join the ${resolvedProductName} partner programme.`,
|
|
1451
|
+
keywords: seoKeywords
|
|
1452
|
+
}
|
|
1453
|
+
),
|
|
1454
|
+
/* @__PURE__ */ jsxRuntime.jsx(PartnerHero, { title: heroTitle, subtitle: heroSubtitle }),
|
|
1455
|
+
!loading && contentPage && /* @__PURE__ */ jsxRuntime.jsx(PartnerContentSection, { page: contentPage }),
|
|
1456
|
+
!loading && docs.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1457
|
+
PartnerDocumentsSection,
|
|
1458
|
+
{
|
|
1459
|
+
title: documentsTitle,
|
|
1460
|
+
subtitle: documentsSubtitle,
|
|
1461
|
+
docs
|
|
1462
|
+
}
|
|
1463
|
+
),
|
|
1464
|
+
showContactForm && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1465
|
+
ContactPage,
|
|
1466
|
+
{
|
|
1467
|
+
productName: resolvedProductName,
|
|
1468
|
+
heroTitle: formTitle,
|
|
1469
|
+
heroDescription: formSubtitle ?? `Tell us about your organisation and a partner manager from ${resolvedProductName} will be in touch.`,
|
|
1470
|
+
contactEmail,
|
|
1471
|
+
contactPhone,
|
|
1472
|
+
officeAddress,
|
|
1473
|
+
responseTime,
|
|
1474
|
+
recaptchaSiteKey,
|
|
1475
|
+
additionalOptions,
|
|
1476
|
+
categories: lockedCategory ? [lockedCategory] : [],
|
|
1477
|
+
categoryLabel: "Partnership type",
|
|
1478
|
+
categoryRequired: !!lockedCategory
|
|
1479
|
+
}
|
|
1480
|
+
)
|
|
1481
|
+
] });
|
|
1482
|
+
}
|
|
981
1483
|
var newsletterSchema = zod.z.object({
|
|
982
1484
|
email: zod.z.string().email("Please enter a valid email address")
|
|
983
1485
|
});
|
|
@@ -2936,213 +3438,6 @@ function RybbitAnalytics({
|
|
|
2936
3438
|
}, [siteId, scriptUrl, enabled]);
|
|
2937
3439
|
return null;
|
|
2938
3440
|
}
|
|
2939
|
-
var PUBLIC_CONTENT_PAGE_QUERY = `
|
|
2940
|
-
query PublicContentPage($slug: String!, $productId: String) {
|
|
2941
|
-
publicContentPage(slug: $slug, productId: $productId) {
|
|
2942
|
-
id
|
|
2943
|
-
title
|
|
2944
|
-
slug
|
|
2945
|
-
content
|
|
2946
|
-
contentFormat
|
|
2947
|
-
seoTitle
|
|
2948
|
-
seoDescription
|
|
2949
|
-
seoKeywords
|
|
2950
|
-
lastUpdated
|
|
2951
|
-
version
|
|
2952
|
-
excerpt
|
|
2953
|
-
thumbnail
|
|
2954
|
-
author
|
|
2955
|
-
publishedAt
|
|
2956
|
-
readingTime
|
|
2957
|
-
featured
|
|
2958
|
-
category
|
|
2959
|
-
}
|
|
2960
|
-
}
|
|
2961
|
-
`;
|
|
2962
|
-
var PUBLIC_RESOLVED_CONTENT_PAGE_QUERY = `
|
|
2963
|
-
query PublicResolvedContentPage($slug: String!, $productId: String!) {
|
|
2964
|
-
publicResolvedContentPage(slug: $slug, productId: $productId) {
|
|
2965
|
-
id
|
|
2966
|
-
title
|
|
2967
|
-
slug
|
|
2968
|
-
content
|
|
2969
|
-
contentFormat
|
|
2970
|
-
seoTitle
|
|
2971
|
-
seoDescription
|
|
2972
|
-
seoKeywords
|
|
2973
|
-
lastUpdated
|
|
2974
|
-
version
|
|
2975
|
-
excerpt
|
|
2976
|
-
thumbnail
|
|
2977
|
-
author
|
|
2978
|
-
publishedAt
|
|
2979
|
-
readingTime
|
|
2980
|
-
featured
|
|
2981
|
-
category
|
|
2982
|
-
}
|
|
2983
|
-
}
|
|
2984
|
-
`;
|
|
2985
|
-
var PUBLIC_CONTENT_PAGES_QUERY = `
|
|
2986
|
-
query PublicContentPages($productId: String!, $limit: Int, $offset: Int) {
|
|
2987
|
-
publicContentPages(productId: $productId, limit: $limit, offset: $offset) {
|
|
2988
|
-
items {
|
|
2989
|
-
id
|
|
2990
|
-
title
|
|
2991
|
-
slug
|
|
2992
|
-
lastUpdated
|
|
2993
|
-
tags
|
|
2994
|
-
seoDescription
|
|
2995
|
-
excerpt
|
|
2996
|
-
thumbnail
|
|
2997
|
-
author
|
|
2998
|
-
publishedAt
|
|
2999
|
-
readingTime
|
|
3000
|
-
featured
|
|
3001
|
-
category
|
|
3002
|
-
}
|
|
3003
|
-
total
|
|
3004
|
-
hasMore
|
|
3005
|
-
}
|
|
3006
|
-
}
|
|
3007
|
-
`;
|
|
3008
|
-
function useContentPage(slug, options) {
|
|
3009
|
-
const client = useWebSDK();
|
|
3010
|
-
const config = useWebSDKConfig();
|
|
3011
|
-
const { product } = useProduct();
|
|
3012
|
-
const resolvedProductId = product?.id || config.productId;
|
|
3013
|
-
const [data, setData] = React.useState(null);
|
|
3014
|
-
const [loading, setLoading] = React.useState(true);
|
|
3015
|
-
const [error, setError] = React.useState(null);
|
|
3016
|
-
const fetchPage = React.useCallback(async () => {
|
|
3017
|
-
if (!resolvedProductId) return;
|
|
3018
|
-
setLoading(true);
|
|
3019
|
-
setError(null);
|
|
3020
|
-
try {
|
|
3021
|
-
const query = options?.resolve ? PUBLIC_RESOLVED_CONTENT_PAGE_QUERY : PUBLIC_CONTENT_PAGE_QUERY;
|
|
3022
|
-
const queryName = options?.resolve ? "publicResolvedContentPage" : "publicContentPage";
|
|
3023
|
-
const result = await client.query(
|
|
3024
|
-
query,
|
|
3025
|
-
{
|
|
3026
|
-
slug,
|
|
3027
|
-
productId: resolvedProductId
|
|
3028
|
-
}
|
|
3029
|
-
);
|
|
3030
|
-
if (result.errors?.length) {
|
|
3031
|
-
setError(result.errors[0]?.message ?? "Unknown error");
|
|
3032
|
-
setData(null);
|
|
3033
|
-
} else {
|
|
3034
|
-
setData(result.data?.[queryName] ?? null);
|
|
3035
|
-
}
|
|
3036
|
-
} catch (err) {
|
|
3037
|
-
setError(err instanceof Error ? err.message : "Failed to fetch content");
|
|
3038
|
-
setData(null);
|
|
3039
|
-
} finally {
|
|
3040
|
-
setLoading(false);
|
|
3041
|
-
}
|
|
3042
|
-
}, [client, resolvedProductId, slug, options?.resolve]);
|
|
3043
|
-
React.useEffect(() => {
|
|
3044
|
-
fetchPage();
|
|
3045
|
-
}, [fetchPage]);
|
|
3046
|
-
return { data, loading, error, refetch: fetchPage };
|
|
3047
|
-
}
|
|
3048
|
-
function useContentPages(options) {
|
|
3049
|
-
const client = useWebSDK();
|
|
3050
|
-
const config = useWebSDKConfig();
|
|
3051
|
-
const [data, setData] = React.useState(null);
|
|
3052
|
-
const [loading, setLoading] = React.useState(true);
|
|
3053
|
-
const [error, setError] = React.useState(null);
|
|
3054
|
-
const fetchPages = React.useCallback(async () => {
|
|
3055
|
-
setLoading(true);
|
|
3056
|
-
setError(null);
|
|
3057
|
-
try {
|
|
3058
|
-
const result = await client.query(PUBLIC_CONTENT_PAGES_QUERY, {
|
|
3059
|
-
productId: config.productId,
|
|
3060
|
-
limit: options?.limit ?? 50,
|
|
3061
|
-
offset: options?.offset ?? 0
|
|
3062
|
-
});
|
|
3063
|
-
if (result.errors?.length) {
|
|
3064
|
-
setError(result.errors[0]?.message ?? "Unknown error");
|
|
3065
|
-
setData(null);
|
|
3066
|
-
} else {
|
|
3067
|
-
setData(result.data?.publicContentPages ?? null);
|
|
3068
|
-
}
|
|
3069
|
-
} catch (err) {
|
|
3070
|
-
setError(
|
|
3071
|
-
err instanceof Error ? err.message : "Failed to fetch content pages"
|
|
3072
|
-
);
|
|
3073
|
-
setData(null);
|
|
3074
|
-
} finally {
|
|
3075
|
-
setLoading(false);
|
|
3076
|
-
}
|
|
3077
|
-
}, [client, config.productId, options?.limit, options?.offset]);
|
|
3078
|
-
React.useEffect(() => {
|
|
3079
|
-
fetchPages();
|
|
3080
|
-
}, [fetchPages]);
|
|
3081
|
-
return { data, loading, error, refetch: fetchPages };
|
|
3082
|
-
}
|
|
3083
|
-
function renderMarkdown(md) {
|
|
3084
|
-
let html = md;
|
|
3085
|
-
html = html.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
3086
|
-
html = html.replace(/```(\w*)\n([\s\S]*?)```/g, (_m, _lang, code) => {
|
|
3087
|
-
return `<pre><code>${code.trim()}</code></pre>`;
|
|
3088
|
-
});
|
|
3089
|
-
html = html.replace(/`([^`]+)`/g, "<code>$1</code>");
|
|
3090
|
-
html = html.replace(/^###### (.+)$/gm, "<h6>$1</h6>");
|
|
3091
|
-
html = html.replace(/^##### (.+)$/gm, "<h5>$1</h5>");
|
|
3092
|
-
html = html.replace(/^#### (.+)$/gm, "<h4>$1</h4>");
|
|
3093
|
-
html = html.replace(/^### (.+)$/gm, "<h3>$1</h3>");
|
|
3094
|
-
html = html.replace(/^## (.+)$/gm, "<h2>$1</h2>");
|
|
3095
|
-
html = html.replace(/^# (.+)$/gm, "<h1>$1</h1>");
|
|
3096
|
-
html = html.replace(/\*\*\*(.+?)\*\*\*/g, "<strong><em>$1</em></strong>");
|
|
3097
|
-
html = html.replace(/\*\*(.+?)\*\*/g, "<strong>$1</strong>");
|
|
3098
|
-
html = html.replace(/\*(.+?)\*/g, "<em>$1</em>");
|
|
3099
|
-
html = html.replace(
|
|
3100
|
-
/\[([^\]]+)\]\(([^)]+)\)/g,
|
|
3101
|
-
'<a href="$2" target="_blank" rel="noopener noreferrer">$1</a>'
|
|
3102
|
-
);
|
|
3103
|
-
html = html.replace(/^> (.+)$/gm, "<blockquote>$1</blockquote>");
|
|
3104
|
-
html = html.replace(/(^- .+$(\n^- .+$)*)/gm, (block) => {
|
|
3105
|
-
const items = block.split("\n").map((line) => `<li>${line.replace(/^- /, "")}</li>`).join("");
|
|
3106
|
-
return `<ul>${items}</ul>`;
|
|
3107
|
-
});
|
|
3108
|
-
html = html.replace(/(^\d+\. .+$(\n^\d+\. .+$)*)/gm, (block) => {
|
|
3109
|
-
const items = block.split("\n").map((line) => `<li>${line.replace(/^\d+\. /, "")}</li>`).join("");
|
|
3110
|
-
return `<ol>${items}</ol>`;
|
|
3111
|
-
});
|
|
3112
|
-
html = html.replace(/^---$/gm, "<hr />");
|
|
3113
|
-
html = html.split(/\n\n+/).map((block) => {
|
|
3114
|
-
const trimmed = block.trim();
|
|
3115
|
-
if (!trimmed) return "";
|
|
3116
|
-
if (/^<(h[1-6]|ul|ol|pre|blockquote|hr)/.test(trimmed)) return trimmed;
|
|
3117
|
-
return `<p>${trimmed.replace(/\n/g, "<br />")}</p>`;
|
|
3118
|
-
}).join("\n");
|
|
3119
|
-
return html;
|
|
3120
|
-
}
|
|
3121
|
-
function ContentRenderer({
|
|
3122
|
-
content,
|
|
3123
|
-
format = "markdown",
|
|
3124
|
-
className
|
|
3125
|
-
}) {
|
|
3126
|
-
if (format === "markdown") {
|
|
3127
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
3128
|
-
"div",
|
|
3129
|
-
{
|
|
3130
|
-
className,
|
|
3131
|
-
dangerouslySetInnerHTML: { __html: renderMarkdown(content) }
|
|
3132
|
-
}
|
|
3133
|
-
);
|
|
3134
|
-
}
|
|
3135
|
-
if (format === "html") {
|
|
3136
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
3137
|
-
"div",
|
|
3138
|
-
{
|
|
3139
|
-
className,
|
|
3140
|
-
dangerouslySetInnerHTML: { __html: content }
|
|
3141
|
-
}
|
|
3142
|
-
);
|
|
3143
|
-
}
|
|
3144
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className, children: /* @__PURE__ */ jsxRuntime.jsx("pre", { style: { whiteSpace: "pre-wrap", fontFamily: "inherit" }, children: content }) });
|
|
3145
|
-
}
|
|
3146
3441
|
var BLOG_POSTS_QUERY = `
|
|
3147
3442
|
query BlogPosts($productId: String!, $limit: Int, $offset: Int) {
|
|
3148
3443
|
publicContentPages(productId: $productId, limit: $limit, offset: $offset) {
|
|
@@ -4135,6 +4430,7 @@ exports.Label = Label;
|
|
|
4135
4430
|
exports.NewsletterForm = NewsletterForm;
|
|
4136
4431
|
exports.NewsletterPage = NewsletterPage;
|
|
4137
4432
|
exports.PageHead = PageHead;
|
|
4433
|
+
exports.PartnersPage = PartnersPage;
|
|
4138
4434
|
exports.PressKitPage = PressKitPage;
|
|
4139
4435
|
exports.PricingPage = PricingPage;
|
|
4140
4436
|
exports.PricingSection = PricingSection;
|