@sprintup-cms/sdk 1.8.57 → 1.8.62

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.
@@ -1145,100 +1145,154 @@ function ServerProductListBlock({ block }) {
1145
1145
  }) })
1146
1146
  ] }) });
1147
1147
  }
1148
- function parseNavItems(html) {
1149
- if (!html) return [];
1150
- const text = html.replace(/<[^>]*>/g, "").replace(/&nbsp;/g, " ");
1151
- return text.split(/\r?\n/).filter(Boolean).map((line) => {
1152
- const [label, url] = line.split("|").map((s) => s.trim());
1153
- return { label: label || "", url: url || "#" };
1154
- });
1148
+ function getSD(doc) {
1149
+ const structuredBlock = Array.isArray(doc?.blocks) && doc.blocks[0]?.type === "__structured__" ? doc.blocks[0].content : null;
1150
+ return doc?.sectionData ?? structuredBlock ?? null;
1155
1151
  }
1156
1152
  function CMSHeader({ nav }) {
1157
- if (!nav) return null;
1158
- const structuredBlock = Array.isArray(nav.blocks) && nav.blocks[0]?.type === "__structured__" ? nav.blocks[0].content : null;
1159
- const sd = nav.sectionData ?? structuredBlock;
1153
+ const sd = getSD(nav);
1160
1154
  if (!sd) return null;
1161
- const primary = sd.primary ?? {};
1162
- const navItems = parseNavItems(primary.nav_items || "");
1163
- const logoUrl = primary.logo_url || "";
1164
- const logoAlt = primary.logo_alt || "";
1165
- if (!logoUrl && !logoAlt && navItems.length === 0) return null;
1166
- return /* @__PURE__ */ jsx("header", { className: "w-full border-b border-border bg-background/95 backdrop-blur sticky top-0 z-50", children: /* @__PURE__ */ jsxs("div", { className: "max-w-6xl mx-auto px-4 h-16 flex items-center justify-between gap-4", children: [
1167
- /* @__PURE__ */ jsxs("a", { href: "/", className: "flex items-center gap-2 shrink-0", children: [
1168
- logoUrl && /* @__PURE__ */ jsx("img", { src: logoUrl, alt: logoAlt || "Logo", className: "h-8 w-auto" }),
1169
- !logoUrl && logoAlt && /* @__PURE__ */ jsx("span", { className: "font-bold text-base", children: logoAlt })
1170
- ] }),
1171
- navItems.length > 0 && /* @__PURE__ */ jsx("nav", { className: "hidden md:flex items-center gap-6", children: navItems.map((item, i) => /* @__PURE__ */ jsx("a", { href: item.url, className: "text-sm text-muted-foreground hover:text-foreground transition-colors", children: item.label }, i)) })
1155
+ const logoUrl = sd.logo_url?.trim() || "";
1156
+ const logoAlt = sd.logo_alt?.trim() || "";
1157
+ const items = Array.isArray(sd.items) ? sd.items : [];
1158
+ if (!logoUrl && !logoAlt && items.length === 0) return null;
1159
+ const links = items.filter((i) => i.type === "link" || i.type === "dropdown");
1160
+ const buttons = items.filter((i) => i.type === "button");
1161
+ const btnBase = { textDecoration: "none", padding: "0.4rem 1rem", borderRadius: "6px", fontWeight: 600, fontSize: "0.875rem", whiteSpace: "nowrap", transition: "opacity 0.15s" };
1162
+ const btnVariant = (v) => ({
1163
+ primary: { ...btnBase, background: "var(--foreground, #111)", color: "#fff", border: "1px solid transparent" },
1164
+ outline: { ...btnBase, background: "transparent", color: "var(--foreground, #111)", border: "1px solid var(--border, #e5e7eb)" },
1165
+ ghost: { ...btnBase, background: "transparent", color: "var(--muted-foreground, #6b7280)", border: "none", fontWeight: 500 }
1166
+ })[v] ?? btnBase;
1167
+ return /* @__PURE__ */ jsx("header", { style: { position: "sticky", top: 0, zIndex: 50, width: "100%", borderBottom: "1px solid var(--border, #e5e7eb)", background: "rgba(255,255,255,0.97)", backdropFilter: "blur(8px)", WebkitBackdropFilter: "blur(8px)" }, children: /* @__PURE__ */ jsxs("div", { style: { maxWidth: "1200px", margin: "0 auto", padding: "0 1.5rem", height: "64px", display: "flex", alignItems: "center", justifyContent: "space-between", gap: "2rem" }, children: [
1168
+ /* @__PURE__ */ jsx("a", { href: "/", style: { display: "flex", alignItems: "center", gap: "0.5rem", textDecoration: "none", flexShrink: 0 }, children: logoUrl ? /* @__PURE__ */ jsx("img", { src: logoUrl, alt: logoAlt || "Logo", style: { height: "32px", width: "auto", display: "block" } }) : /* @__PURE__ */ jsx("span", { style: { fontWeight: 700, fontSize: "1.125rem", color: "var(--foreground, #111)" }, children: logoAlt }) }),
1169
+ links.length > 0 && /* @__PURE__ */ jsx("nav", { style: { display: "flex", alignItems: "center", gap: "1.75rem", flex: 1 }, children: links.map((item) => /* @__PURE__ */ jsx(
1170
+ "a",
1171
+ {
1172
+ href: item.url || "#",
1173
+ target: item.openInNewTab ? "_blank" : void 0,
1174
+ rel: item.openInNewTab ? "noopener noreferrer" : void 0,
1175
+ style: { fontSize: "0.9rem", color: "var(--muted-foreground, #6b7280)", textDecoration: "none", fontWeight: 500 },
1176
+ children: item.label
1177
+ },
1178
+ item.id
1179
+ )) }),
1180
+ buttons.length > 0 && /* @__PURE__ */ jsx("div", { style: { display: "flex", alignItems: "center", gap: "0.625rem", flexShrink: 0 }, children: buttons.map((item) => /* @__PURE__ */ jsx(
1181
+ "a",
1182
+ {
1183
+ href: item.url || "#",
1184
+ target: item.openInNewTab ? "_blank" : void 0,
1185
+ rel: item.openInNewTab ? "noopener noreferrer" : void 0,
1186
+ style: btnVariant(item.variant || "ghost"),
1187
+ children: item.label
1188
+ },
1189
+ item.id
1190
+ )) })
1172
1191
  ] }) });
1173
1192
  }
1174
- function parseFooterColumns(html) {
1175
- if (!html) return [];
1176
- const text = html.replace(/<[^>]*>/g, "").replace(/&nbsp;/g, " ");
1177
- const lines = text.split(/\r?\n/).filter(Boolean);
1178
- const cols = [];
1179
- let current = null;
1180
- for (const line of lines) {
1181
- const parts = line.split("|").map((s) => s.trim());
1182
- if (parts.length === 1) {
1183
- if (current) cols.push(current);
1184
- current = { title: parts[0], links: [] };
1185
- } else if (parts.length >= 2) {
1186
- if (!current) current = { title: "", links: [] };
1187
- current.links.push({ label: parts[0], url: parts[1] || "#" });
1188
- }
1193
+ var SOCIAL_ICONS = [
1194
+ { key: "facebook", label: "Facebook", d: "M18 2h-3a5 5 0 0 0-5 5v3H7v4h3v8h4v-8h3l1-4h-4V7a1 1 0 0 1 1-1h3z" },
1195
+ { key: "twitter", label: "X", d: "M18 6L6 18M6 6l12 12" },
1196
+ { key: "instagram", label: "Instagram", d: "M16 11.37A4 4 0 1 1 12.63 8 4 4 0 0 1 16 11.37zm1.5-4.87h.01M6.5 2h11A4.5 4.5 0 0 1 22 6.5v11A4.5 4.5 0 0 1 17.5 22h-11A4.5 4.5 0 0 1 2 17.5v-11A4.5 4.5 0 0 1 6.5 2z" },
1197
+ { key: "linkedin", label: "LinkedIn", d: "M16 8a6 6 0 0 1 6 6v7h-4v-7a2 2 0 0 0-4 0v7h-4v-7a6 6 0 0 1 6-6zM2 9h4v12H2zm2-3a2 2 0 1 1 0-4 2 2 0 0 1 0 4z" },
1198
+ { key: "youtube", label: "YouTube", d: "M22.54 6.42a2.78 2.78 0 0 0-1.94-1.96C18.88 4 12 4 12 4s-6.88 0-8.6.46a2.78 2.78 0 0 0-1.94 1.96A29 29 0 0 0 1 12a29 29 0 0 0 .46 5.58 2.78 2.78 0 0 0 1.94 1.96C5.12 20 12 20 12 20s6.88 0 8.6-.46a2.78 2.78 0 0 0 1.94-1.96A29 29 0 0 0 23 12a29 29 0 0 0-.46-5.58zM9.75 15.02V8.98L15.5 12l-5.75 3.02z" }
1199
+ ];
1200
+ function renderFooterSection(sec, mutedLink) {
1201
+ if (sec.type === "brand") {
1202
+ if (!sec.logo_url && !sec.tagline) return null;
1203
+ return /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "0.75rem" }, children: [
1204
+ sec.logo_url && /* @__PURE__ */ jsx("img", { src: sec.logo_url, alt: "Logo", style: { height: "32px", width: "auto", objectFit: "contain" } }),
1205
+ sec.tagline && /* @__PURE__ */ jsx("p", { style: { fontSize: "0.875rem", color: "var(--muted-foreground, #6b7280)", lineHeight: 1.6, margin: 0 }, children: sec.tagline })
1206
+ ] });
1189
1207
  }
1190
- if (current) cols.push(current);
1191
- return cols;
1192
- }
1193
- function parseLegalLinks(html) {
1194
- if (!html) return [];
1195
- const text = html.replace(/<[^>]*>/g, "").replace(/&nbsp;/g, " ");
1196
- return text.split(/\r?\n/).filter(Boolean).map((line) => {
1197
- const [label, url] = line.split("|").map((s) => s.trim());
1198
- return { label: label || "", url: url || "#" };
1199
- });
1208
+ if (sec.type === "links") {
1209
+ const links = (sec.links || []).filter((l) => l.label);
1210
+ if (!links.length && !sec.title) return null;
1211
+ return /* @__PURE__ */ jsxs("div", { children: [
1212
+ sec.title && /* @__PURE__ */ jsx("h4", { style: { fontWeight: 600, fontSize: "0.875rem", margin: "0 0 0.875rem", color: "var(--foreground, #111)" }, children: sec.title }),
1213
+ /* @__PURE__ */ jsx("ul", { style: { listStyle: "none", margin: 0, padding: 0, display: "flex", flexDirection: "column", gap: "0.5rem" }, children: links.map((link) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(
1214
+ "a",
1215
+ {
1216
+ href: link.url || "#",
1217
+ target: link.external ? "_blank" : void 0,
1218
+ rel: link.external ? "noopener noreferrer" : void 0,
1219
+ style: mutedLink,
1220
+ children: link.label
1221
+ }
1222
+ ) }, link.id || link.label)) })
1223
+ ] });
1224
+ }
1225
+ if (sec.type === "contact") {
1226
+ if (!sec.email && !sec.phone && !sec.address) return null;
1227
+ return /* @__PURE__ */ jsxs("div", { children: [
1228
+ sec.title && /* @__PURE__ */ jsx("h4", { style: { fontWeight: 600, fontSize: "0.875rem", margin: "0 0 0.875rem", color: "var(--foreground, #111)" }, children: sec.title }),
1229
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "0.4rem" }, children: [
1230
+ sec.email && /* @__PURE__ */ jsx("a", { href: `mailto:${sec.email}`, style: mutedLink, children: sec.email }),
1231
+ sec.phone && /* @__PURE__ */ jsx("a", { href: `tel:${sec.phone}`, style: mutedLink, children: sec.phone }),
1232
+ sec.address && /* @__PURE__ */ jsx("p", { style: { ...mutedLink, whiteSpace: "pre-line", margin: 0 }, children: sec.address })
1233
+ ] })
1234
+ ] });
1235
+ }
1236
+ if (sec.type === "social") {
1237
+ const active = SOCIAL_ICONS.filter((s) => sec[s.key]?.trim());
1238
+ if (!active.length) return null;
1239
+ return /* @__PURE__ */ jsxs("div", { children: [
1240
+ sec.title && /* @__PURE__ */ jsx("h4", { style: { fontWeight: 600, fontSize: "0.875rem", margin: "0 0 0.875rem", color: "var(--foreground, #111)" }, children: sec.title }),
1241
+ /* @__PURE__ */ jsx("div", { style: { display: "flex", flexWrap: "wrap", gap: "0.625rem" }, children: active.map((s) => /* @__PURE__ */ jsx(
1242
+ "a",
1243
+ {
1244
+ href: sec[s.key],
1245
+ target: "_blank",
1246
+ rel: "noopener noreferrer",
1247
+ "aria-label": s.label,
1248
+ style: { display: "flex", alignItems: "center", justifyContent: "center", width: "34px", height: "34px", borderRadius: "8px", border: "1px solid var(--border, #e5e7eb)", color: "var(--muted-foreground, #6b7280)", textDecoration: "none" },
1249
+ children: /* @__PURE__ */ jsx("svg", { width: "15", height: "15", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx("path", { d: s.d }) })
1250
+ },
1251
+ s.key
1252
+ )) })
1253
+ ] });
1254
+ }
1255
+ return null;
1200
1256
  }
1201
1257
  function CMSFooter({ footer }) {
1202
- if (!footer) return null;
1203
- const structuredBlock = Array.isArray(footer.blocks) && footer.blocks[0]?.type === "__structured__" ? footer.blocks[0].content : null;
1204
- const sd = footer.sectionData ?? structuredBlock;
1258
+ const sd = getSD(footer);
1205
1259
  if (!sd) return null;
1206
- const c = sd.content ?? {};
1207
- const contact = sd.contact ?? {};
1208
- const social = sd.social ?? {};
1209
- const legal = sd.legal ?? {};
1210
- const columns = parseFooterColumns(c.columns || "");
1211
- const legalLinks = parseLegalLinks(legal.legal_links || "");
1212
- const hasSocial = social.facebook || social.twitter || social.instagram || social.linkedin || social.youtube;
1213
- const isEmpty = !c.tagline && !c.logo_url && columns.length === 0 && !contact.email && !contact.phone && !hasSocial && !legal.copyright && legalLinks.length === 0;
1214
- if (isEmpty) return null;
1215
- return /* @__PURE__ */ jsx("footer", { className: "border-t border-border bg-muted/30 pt-12 pb-6 mt-16", children: /* @__PURE__ */ jsxs("div", { className: "max-w-6xl mx-auto px-4", children: [
1216
- (c.tagline || c.logo_url || columns.length > 0 || contact.email) && /* @__PURE__ */ jsxs("div", { className: `grid gap-8 mb-10 grid-cols-1 sm:grid-cols-2 ${columns.length > 0 ? "lg:grid-cols-4" : "lg:grid-cols-2"}`, children: [
1217
- (c.logo_url || c.tagline) && /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
1218
- c.logo_url && /* @__PURE__ */ jsx("img", { src: c.logo_url, alt: "Logo", className: "h-8 w-auto" }),
1219
- c.tagline && /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground leading-relaxed", children: c.tagline })
1220
- ] }),
1221
- columns.map((col, i) => /* @__PURE__ */ jsxs("div", { children: [
1222
- col.title && /* @__PURE__ */ jsx("h4", { className: "font-semibold text-sm mb-3", children: col.title }),
1223
- /* @__PURE__ */ jsx("ul", { className: "space-y-2", children: col.links.map((link, j) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx("a", { href: link.url, className: "text-sm text-muted-foreground hover:text-foreground transition-colors", children: link.label }) }, j)) })
1224
- ] }, i)),
1225
- (contact.email || contact.phone || contact.address) && /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
1226
- /* @__PURE__ */ jsx("h4", { className: "font-semibold text-sm mb-3", children: "Contact" }),
1227
- contact.email && /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: contact.email }),
1228
- contact.phone && /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: contact.phone }),
1229
- contact.address && /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground whitespace-pre-line", children: contact.address })
1230
- ] })
1231
- ] }),
1232
- hasSocial && /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap gap-4 mb-6", children: [
1233
- social.facebook && /* @__PURE__ */ jsx("a", { href: social.facebook, className: "text-sm text-muted-foreground hover:text-foreground transition-colors", children: "Facebook" }),
1234
- social.twitter && /* @__PURE__ */ jsx("a", { href: social.twitter, className: "text-sm text-muted-foreground hover:text-foreground transition-colors", children: "X" }),
1235
- social.instagram && /* @__PURE__ */ jsx("a", { href: social.instagram, className: "text-sm text-muted-foreground hover:text-foreground transition-colors", children: "Instagram" }),
1236
- social.linkedin && /* @__PURE__ */ jsx("a", { href: social.linkedin, className: "text-sm text-muted-foreground hover:text-foreground transition-colors", children: "LinkedIn" }),
1237
- social.youtube && /* @__PURE__ */ jsx("a", { href: social.youtube, className: "text-sm text-muted-foreground hover:text-foreground transition-colors", children: "YouTube" })
1238
- ] }),
1239
- (legal.copyright || legalLinks.length > 0) && /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center justify-between gap-4 pt-6 border-t border-border", children: [
1240
- legal.copyright && /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: legal.copyright }),
1241
- legalLinks.length > 0 && /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-4", children: legalLinks.map((link, i) => /* @__PURE__ */ jsx("a", { href: link.url, className: "text-xs text-muted-foreground hover:text-foreground transition-colors", children: link.label }, i)) })
1260
+ const sections = Array.isArray(sd.sections) ? sd.sections : [];
1261
+ let renderSections = sections;
1262
+ if (renderSections.length === 0 && (sd.brand || sd.columns || sd.contact || sd.social || sd.legal)) {
1263
+ renderSections = [];
1264
+ if (sd.brand?.logo_url || sd.brand?.tagline) renderSections.push({ id: "b", type: "brand", ...sd.brand });
1265
+ (sd.columns || []).forEach((col) => renderSections.push({ id: col.id || col.title, type: "links", title: col.title, links: col.links }));
1266
+ if (sd.contact?.email || sd.contact?.phone) renderSections.push({ id: "c", type: "contact", ...sd.contact });
1267
+ if (Object.values(sd.social || {}).some(Boolean)) renderSections.push({ id: "s", type: "social", ...sd.social });
1268
+ }
1269
+ const legalSec = sd.sections ? sd.sections.find((s) => s.type === "legal") : sd.legal;
1270
+ const mainSections = renderSections.filter((s) => s.type !== "legal");
1271
+ if (mainSections.length === 0 && !legalSec) return null;
1272
+ const gridCount = mainSections.length;
1273
+ const gridCols = gridCount <= 1 ? "1fr" : gridCount === 2 ? "repeat(2,1fr)" : gridCount === 3 ? "repeat(3,1fr)" : "repeat(4,1fr)";
1274
+ const mutedLink = { fontSize: "0.875rem", color: "var(--muted-foreground, #6b7280)", textDecoration: "none" };
1275
+ const copyright = legalSec?.copyright || "";
1276
+ const legalLinks = legalSec?.legal_links || legalSec?.links || [];
1277
+ const hasBottom = copyright || legalLinks.filter((l) => l.label).length > 0;
1278
+ return /* @__PURE__ */ jsx("footer", { style: { borderTop: "1px solid var(--border, #e5e7eb)", background: "var(--muted, #f9fafb)", marginTop: "4rem" }, children: /* @__PURE__ */ jsxs("div", { style: { maxWidth: "1200px", margin: "0 auto", padding: "3rem 1.5rem 1.5rem" }, children: [
1279
+ mainSections.length > 0 && /* @__PURE__ */ jsx("div", { style: { display: "grid", gridTemplateColumns: gridCols, gap: "2.5rem", marginBottom: hasBottom ? "2.5rem" : 0 }, children: mainSections.map((sec) => {
1280
+ const rendered = renderFooterSection(sec, mutedLink);
1281
+ return rendered ? /* @__PURE__ */ jsx("div", { children: rendered }, sec.id) : null;
1282
+ }) }),
1283
+ hasBottom && /* @__PURE__ */ jsxs("div", { style: { borderTop: "1px solid var(--border, #e5e7eb)", paddingTop: "1.25rem", display: "flex", flexWrap: "wrap", alignItems: "center", justifyContent: "space-between", gap: "1rem" }, children: [
1284
+ copyright && /* @__PURE__ */ jsx("p", { style: { fontSize: "0.8rem", color: "var(--muted-foreground, #6b7280)", margin: 0 }, children: copyright }),
1285
+ legalLinks.filter((l) => l.label).length > 0 && /* @__PURE__ */ jsx("div", { style: { display: "flex", flexWrap: "wrap", gap: "1.25rem" }, children: legalLinks.filter((l) => l.label).map((link) => /* @__PURE__ */ jsx(
1286
+ "a",
1287
+ {
1288
+ href: link.url || "#",
1289
+ target: link.external ? "_blank" : void 0,
1290
+ rel: link.external ? "noopener noreferrer" : void 0,
1291
+ style: { fontSize: "0.8rem", color: "var(--muted-foreground, #6b7280)", textDecoration: "none" },
1292
+ children: link.label
1293
+ },
1294
+ link.id || link.label
1295
+ )) })
1242
1296
  ] })
1243
1297
  ] }) });
1244
1298
  }