@sprintup-cms/sdk 1.8.29 → 1.8.30

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.
@@ -1,187 +0,0 @@
1
- 'use strict';
2
-
3
- var react = require('react');
4
- var jsxRuntime = require('react/jsx-runtime');
5
-
6
- function StarIcon() {
7
- return /* @__PURE__ */ jsxRuntime.jsx("svg", { className: "w-3.5 h-3.5 fill-yellow-400 text-yellow-400", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z" }) });
8
- }
9
- function GridIcon({ active }) {
10
- return /* @__PURE__ */ jsxRuntime.jsxs(
11
- "svg",
12
- {
13
- viewBox: "0 0 16 16",
14
- className: `w-4 h-4 ${active ? "text-foreground" : "text-muted-foreground"}`,
15
- fill: "currentColor",
16
- children: [
17
- /* @__PURE__ */ jsxRuntime.jsx("rect", { x: "1", y: "1", width: "6", height: "6", rx: "1" }),
18
- /* @__PURE__ */ jsxRuntime.jsx("rect", { x: "9", y: "1", width: "6", height: "6", rx: "1" }),
19
- /* @__PURE__ */ jsxRuntime.jsx("rect", { x: "1", y: "9", width: "6", height: "6", rx: "1" }),
20
- /* @__PURE__ */ jsxRuntime.jsx("rect", { x: "9", y: "9", width: "6", height: "6", rx: "1" })
21
- ]
22
- }
23
- );
24
- }
25
- function ListIcon({ active }) {
26
- return /* @__PURE__ */ jsxRuntime.jsxs(
27
- "svg",
28
- {
29
- viewBox: "0 0 16 16",
30
- className: `w-4 h-4 ${active ? "text-foreground" : "text-muted-foreground"}`,
31
- fill: "currentColor",
32
- children: [
33
- /* @__PURE__ */ jsxRuntime.jsx("rect", { x: "1", y: "2", width: "14", height: "3", rx: "1" }),
34
- /* @__PURE__ */ jsxRuntime.jsx("rect", { x: "1", y: "7", width: "14", height: "3", rx: "1" }),
35
- /* @__PURE__ */ jsxRuntime.jsx("rect", { x: "1", y: "12", width: "14", height: "3", rx: "1" })
36
- ]
37
- }
38
- );
39
- }
40
- function ProductCard({ product, cardStyle, showPrice, showRating, currency, ctaLabel, staticCtaUrl }) {
41
- const accentColor = product.color ?? "#6366f1";
42
- const href = staticCtaUrl || product.ctaUrl;
43
- return /* @__PURE__ */ jsxRuntime.jsxs(
44
- "div",
45
- {
46
- className: `overflow-hidden group transition-shadow flex flex-col ${cardStyle === "minimal" ? "border-0 shadow-none bg-transparent" : "border rounded-xl hover:shadow-lg bg-card"}`,
47
- children: [
48
- cardStyle === "color-band" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-2 w-full flex-shrink-0", style: { backgroundColor: accentColor } }),
49
- cardStyle === "filled-header" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-20 w-full flex-shrink-0 flex items-end px-5 pb-3", style: { backgroundColor: accentColor }, children: product.category && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs font-semibold text-white/80 uppercase tracking-wider", children: product.category }) }),
50
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-5 flex flex-col gap-3 flex-1", children: [
51
- cardStyle !== "filled-header" && (product.category || product.badge) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 flex-wrap", children: [
52
- product.category && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs px-2 py-0.5 rounded-full font-medium text-white", style: { backgroundColor: accentColor }, children: product.category }),
53
- product.badge && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs px-2 py-0.5 rounded-full bg-muted text-muted-foreground", children: product.badge })
54
- ] }),
55
- cardStyle === "filled-header" && product.badge && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs px-2 py-0.5 rounded-full bg-muted text-muted-foreground self-start", children: product.badge }),
56
- /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "font-semibold text-base line-clamp-2", children: product.name }),
57
- product.description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground line-clamp-2", children: product.description }),
58
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-auto pt-3 border-t border-border flex items-center justify-between gap-3", children: [
59
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
60
- showPrice && product.price > 0 && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-bold text-lg", children: [
61
- product.price.toFixed(2),
62
- " ",
63
- currency
64
- ] }),
65
- showRating && product.rating && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1 text-sm text-muted-foreground", children: [
66
- /* @__PURE__ */ jsxRuntime.jsx(StarIcon, {}),
67
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: product.rating })
68
- ] })
69
- ] }),
70
- ctaLabel && /* @__PURE__ */ jsxRuntime.jsx(
71
- "a",
72
- {
73
- href: href || "#",
74
- className: "text-xs font-semibold px-3 py-1.5 rounded-lg text-white transition-opacity hover:opacity-90 flex-shrink-0",
75
- style: { backgroundColor: accentColor },
76
- children: ctaLabel
77
- }
78
- )
79
- ] })
80
- ] })
81
- ]
82
- }
83
- );
84
- }
85
- function ProductRow({ product, showPrice, showRating, currency, ctaLabel, staticCtaUrl }) {
86
- const accentColor = product.color ?? "#6366f1";
87
- const href = staticCtaUrl || product.ctaUrl;
88
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-4 border rounded-xl bg-card px-5 py-4 hover:shadow-md transition-shadow group", children: [
89
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-1 self-stretch rounded-full flex-shrink-0", style: { backgroundColor: accentColor } }),
90
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 min-w-0", children: [
91
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 flex-wrap mb-1", children: [
92
- product.category && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs px-2 py-0.5 rounded-full font-medium text-white", style: { backgroundColor: accentColor }, children: product.category }),
93
- product.badge && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs px-2 py-0.5 rounded-full bg-muted text-muted-foreground", children: product.badge })
94
- ] }),
95
- /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "font-semibold text-sm truncate", children: product.name }),
96
- product.description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground truncate mt-0.5", children: product.description })
97
- ] }),
98
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-4 flex-shrink-0", children: [
99
- showRating && product.rating && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1 text-sm text-muted-foreground", children: [
100
- /* @__PURE__ */ jsxRuntime.jsx(StarIcon, {}),
101
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: product.rating })
102
- ] }),
103
- showPrice && product.price > 0 && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-bold text-base", children: [
104
- product.price.toFixed(2),
105
- " ",
106
- currency
107
- ] }),
108
- ctaLabel && /* @__PURE__ */ jsxRuntime.jsx(
109
- "a",
110
- {
111
- href: href || "#",
112
- className: "text-xs font-semibold px-3 py-1.5 rounded-lg text-white transition-opacity hover:opacity-90",
113
- style: { backgroundColor: accentColor },
114
- children: ctaLabel
115
- }
116
- )
117
- ] })
118
- ] });
119
- }
120
- function ProductListClient({
121
- products,
122
- defaultLayout,
123
- allowToggle,
124
- gridCols,
125
- cardStyle,
126
- showPrice,
127
- showRating,
128
- currency,
129
- ctaLabel,
130
- staticCtaUrl
131
- }) {
132
- const [layout, setLayout] = react.useState(defaultLayout);
133
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
134
- allowToggle && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-end mb-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1 border border-border rounded-lg p-1 bg-muted/30", children: [
135
- /* @__PURE__ */ jsxRuntime.jsx(
136
- "button",
137
- {
138
- type: "button",
139
- onClick: () => setLayout("grid"),
140
- className: `p-1.5 rounded-md transition-colors ${layout === "grid" ? "bg-background shadow-sm" : "hover:bg-muted"}`,
141
- "aria-label": "Grid view",
142
- "aria-pressed": layout === "grid",
143
- children: /* @__PURE__ */ jsxRuntime.jsx(GridIcon, { active: layout === "grid" })
144
- }
145
- ),
146
- /* @__PURE__ */ jsxRuntime.jsx(
147
- "button",
148
- {
149
- type: "button",
150
- onClick: () => setLayout("list"),
151
- className: `p-1.5 rounded-md transition-colors ${layout === "list" ? "bg-background shadow-sm" : "hover:bg-muted"}`,
152
- "aria-label": "List view",
153
- "aria-pressed": layout === "list",
154
- children: /* @__PURE__ */ jsxRuntime.jsx(ListIcon, { active: layout === "list" })
155
- }
156
- )
157
- ] }) }),
158
- layout === "grid" ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: `grid gap-6 grid-cols-1 ${gridCols}`, children: products.map((product) => /* @__PURE__ */ jsxRuntime.jsx(
159
- ProductCard,
160
- {
161
- product,
162
- cardStyle,
163
- showPrice,
164
- showRating,
165
- currency,
166
- ctaLabel,
167
- staticCtaUrl
168
- },
169
- product.id
170
- )) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-3", children: products.map((product) => /* @__PURE__ */ jsxRuntime.jsx(
171
- ProductRow,
172
- {
173
- product,
174
- showPrice,
175
- showRating,
176
- currency,
177
- ctaLabel,
178
- staticCtaUrl
179
- },
180
- product.id
181
- )) })
182
- ] });
183
- }
184
-
185
- exports.ProductListClient = ProductListClient;
186
- //# sourceMappingURL=product-list-client.cjs.map
187
- //# sourceMappingURL=product-list-client.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/next/product-list-client.tsx"],"names":["jsx","jsxs","useState"],"mappings":"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","file":"product-list-client.cjs","sourcesContent":["'use client'\n\nimport React, { useState } from 'react'\n\ninterface NormalisedProduct {\n id: string\n name: string\n price: number\n color?: string\n rating?: number\n category?: string\n badge?: string\n description?: string\n ctaUrl?: string\n}\n\ninterface ProductListClientProps {\n products: NormalisedProduct[]\n defaultLayout: 'grid' | 'list'\n allowToggle: boolean\n gridCols: string\n cardStyle: string\n showPrice: boolean\n showRating: boolean\n currency: string\n ctaLabel: string\n staticCtaUrl: string\n}\n\nfunction StarIcon() {\n return (\n <svg className=\"w-3.5 h-3.5 fill-yellow-400 text-yellow-400\" viewBox=\"0 0 24 24\">\n <path d=\"M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z\" />\n </svg>\n )\n}\n\nfunction GridIcon({ active }: { active: boolean }) {\n return (\n <svg\n viewBox=\"0 0 16 16\"\n className={`w-4 h-4 ${active ? 'text-foreground' : 'text-muted-foreground'}`}\n fill=\"currentColor\"\n >\n <rect x=\"1\" y=\"1\" width=\"6\" height=\"6\" rx=\"1\" />\n <rect x=\"9\" y=\"1\" width=\"6\" height=\"6\" rx=\"1\" />\n <rect x=\"1\" y=\"9\" width=\"6\" height=\"6\" rx=\"1\" />\n <rect x=\"9\" y=\"9\" width=\"6\" height=\"6\" rx=\"1\" />\n </svg>\n )\n}\n\nfunction ListIcon({ active }: { active: boolean }) {\n return (\n <svg\n viewBox=\"0 0 16 16\"\n className={`w-4 h-4 ${active ? 'text-foreground' : 'text-muted-foreground'}`}\n fill=\"currentColor\"\n >\n <rect x=\"1\" y=\"2\" width=\"14\" height=\"3\" rx=\"1\" />\n <rect x=\"1\" y=\"7\" width=\"14\" height=\"3\" rx=\"1\" />\n <rect x=\"1\" y=\"12\" width=\"14\" height=\"3\" rx=\"1\" />\n </svg>\n )\n}\n\nfunction ProductCard({ product, cardStyle, showPrice, showRating, currency, ctaLabel, staticCtaUrl }: {\n product: NormalisedProduct\n cardStyle: string\n showPrice: boolean\n showRating: boolean\n currency: string\n ctaLabel: string\n staticCtaUrl: string\n}) {\n const accentColor = product.color ?? '#6366f1'\n const href = staticCtaUrl || product.ctaUrl\n\n return (\n <div\n className={`overflow-hidden group transition-shadow flex flex-col ${\n cardStyle === 'minimal'\n ? 'border-0 shadow-none bg-transparent'\n : 'border rounded-xl hover:shadow-lg bg-card'\n }`}\n >\n {cardStyle === 'color-band' && (\n <div className=\"h-2 w-full flex-shrink-0\" style={{ backgroundColor: accentColor }} />\n )}\n {cardStyle === 'filled-header' && (\n <div className=\"h-20 w-full flex-shrink-0 flex items-end px-5 pb-3\" style={{ backgroundColor: accentColor }}>\n {product.category && (\n <span className=\"text-xs font-semibold text-white/80 uppercase tracking-wider\">{product.category}</span>\n )}\n </div>\n )}\n <div className=\"p-5 flex flex-col gap-3 flex-1\">\n {cardStyle !== 'filled-header' && (product.category || product.badge) && (\n <div className=\"flex items-center gap-2 flex-wrap\">\n {product.category && (\n <span className=\"text-xs px-2 py-0.5 rounded-full font-medium text-white\" style={{ backgroundColor: accentColor }}>\n {product.category}\n </span>\n )}\n {product.badge && (\n <span className=\"text-xs px-2 py-0.5 rounded-full bg-muted text-muted-foreground\">{product.badge}</span>\n )}\n </div>\n )}\n {cardStyle === 'filled-header' && product.badge && (\n <span className=\"text-xs px-2 py-0.5 rounded-full bg-muted text-muted-foreground self-start\">{product.badge}</span>\n )}\n <h3 className=\"font-semibold text-base line-clamp-2\">{product.name}</h3>\n {product.description && (\n <p className=\"text-xs text-muted-foreground line-clamp-2\">{product.description}</p>\n )}\n <div className=\"mt-auto pt-3 border-t border-border flex items-center justify-between gap-3\">\n <div className=\"flex items-center gap-3\">\n {showPrice && product.price > 0 && (\n <span className=\"font-bold text-lg\">{product.price.toFixed(2)} {currency}</span>\n )}\n {showRating && product.rating && (\n <div className=\"flex items-center gap-1 text-sm text-muted-foreground\">\n <StarIcon />\n <span>{product.rating}</span>\n </div>\n )}\n </div>\n {ctaLabel && (\n <a\n href={href || '#'}\n className=\"text-xs font-semibold px-3 py-1.5 rounded-lg text-white transition-opacity hover:opacity-90 flex-shrink-0\"\n style={{ backgroundColor: accentColor }}\n >\n {ctaLabel}\n </a>\n )}\n </div>\n </div>\n </div>\n )\n}\n\nfunction ProductRow({ product, showPrice, showRating, currency, ctaLabel, staticCtaUrl }: {\n product: NormalisedProduct\n showPrice: boolean\n showRating: boolean\n currency: string\n ctaLabel: string\n staticCtaUrl: string\n}) {\n const accentColor = product.color ?? '#6366f1'\n const href = staticCtaUrl || product.ctaUrl\n\n return (\n <div className=\"flex items-center gap-4 border rounded-xl bg-card px-5 py-4 hover:shadow-md transition-shadow group\">\n {/* Color dot */}\n <div className=\"w-1 self-stretch rounded-full flex-shrink-0\" style={{ backgroundColor: accentColor }} />\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-2 flex-wrap mb-1\">\n {product.category && (\n <span className=\"text-xs px-2 py-0.5 rounded-full font-medium text-white\" style={{ backgroundColor: accentColor }}>\n {product.category}\n </span>\n )}\n {product.badge && (\n <span className=\"text-xs px-2 py-0.5 rounded-full bg-muted text-muted-foreground\">{product.badge}</span>\n )}\n </div>\n <h3 className=\"font-semibold text-sm truncate\">{product.name}</h3>\n {product.description && (\n <p className=\"text-xs text-muted-foreground truncate mt-0.5\">{product.description}</p>\n )}\n </div>\n <div className=\"flex items-center gap-4 flex-shrink-0\">\n {showRating && product.rating && (\n <div className=\"flex items-center gap-1 text-sm text-muted-foreground\">\n <StarIcon />\n <span>{product.rating}</span>\n </div>\n )}\n {showPrice && product.price > 0 && (\n <span className=\"font-bold text-base\">{product.price.toFixed(2)} {currency}</span>\n )}\n {ctaLabel && (\n <a\n href={href || '#'}\n className=\"text-xs font-semibold px-3 py-1.5 rounded-lg text-white transition-opacity hover:opacity-90\"\n style={{ backgroundColor: accentColor }}\n >\n {ctaLabel}\n </a>\n )}\n </div>\n </div>\n )\n}\n\nexport function ProductListClient({\n products,\n defaultLayout,\n allowToggle,\n gridCols,\n cardStyle,\n showPrice,\n showRating,\n currency,\n ctaLabel,\n staticCtaUrl,\n}: ProductListClientProps) {\n const [layout, setLayout] = useState<'grid' | 'list'>(defaultLayout)\n\n return (\n <div>\n {allowToggle && (\n <div className=\"flex justify-end mb-4\">\n <div className=\"flex items-center gap-1 border border-border rounded-lg p-1 bg-muted/30\">\n <button\n type=\"button\"\n onClick={() => setLayout('grid')}\n className={`p-1.5 rounded-md transition-colors ${layout === 'grid' ? 'bg-background shadow-sm' : 'hover:bg-muted'}`}\n aria-label=\"Grid view\"\n aria-pressed={layout === 'grid'}\n >\n <GridIcon active={layout === 'grid'} />\n </button>\n <button\n type=\"button\"\n onClick={() => setLayout('list')}\n className={`p-1.5 rounded-md transition-colors ${layout === 'list' ? 'bg-background shadow-sm' : 'hover:bg-muted'}`}\n aria-label=\"List view\"\n aria-pressed={layout === 'list'}\n >\n <ListIcon active={layout === 'list'} />\n </button>\n </div>\n </div>\n )}\n\n {layout === 'grid' ? (\n <div className={`grid gap-6 grid-cols-1 ${gridCols}`}>\n {products.map((product) => (\n <ProductCard\n key={product.id}\n product={product}\n cardStyle={cardStyle}\n showPrice={showPrice}\n showRating={showRating}\n currency={currency}\n ctaLabel={ctaLabel}\n staticCtaUrl={staticCtaUrl}\n />\n ))}\n </div>\n ) : (\n <div className=\"flex flex-col gap-3\">\n {products.map((product) => (\n <ProductRow\n key={product.id}\n product={product}\n showPrice={showPrice}\n showRating={showRating}\n currency={currency}\n ctaLabel={ctaLabel}\n staticCtaUrl={staticCtaUrl}\n />\n ))}\n </div>\n )}\n </div>\n )\n}\n"]}
@@ -1,28 +0,0 @@
1
- import * as react_jsx_runtime from 'react/jsx-runtime';
2
-
3
- interface NormalisedProduct {
4
- id: string;
5
- name: string;
6
- price: number;
7
- color?: string;
8
- rating?: number;
9
- category?: string;
10
- badge?: string;
11
- description?: string;
12
- ctaUrl?: string;
13
- }
14
- interface ProductListClientProps {
15
- products: NormalisedProduct[];
16
- defaultLayout: 'grid' | 'list';
17
- allowToggle: boolean;
18
- gridCols: string;
19
- cardStyle: string;
20
- showPrice: boolean;
21
- showRating: boolean;
22
- currency: string;
23
- ctaLabel: string;
24
- staticCtaUrl: string;
25
- }
26
- declare function ProductListClient({ products, defaultLayout, allowToggle, gridCols, cardStyle, showPrice, showRating, currency, ctaLabel, staticCtaUrl, }: ProductListClientProps): react_jsx_runtime.JSX.Element;
27
-
28
- export { ProductListClient };
@@ -1,28 +0,0 @@
1
- import * as react_jsx_runtime from 'react/jsx-runtime';
2
-
3
- interface NormalisedProduct {
4
- id: string;
5
- name: string;
6
- price: number;
7
- color?: string;
8
- rating?: number;
9
- category?: string;
10
- badge?: string;
11
- description?: string;
12
- ctaUrl?: string;
13
- }
14
- interface ProductListClientProps {
15
- products: NormalisedProduct[];
16
- defaultLayout: 'grid' | 'list';
17
- allowToggle: boolean;
18
- gridCols: string;
19
- cardStyle: string;
20
- showPrice: boolean;
21
- showRating: boolean;
22
- currency: string;
23
- ctaLabel: string;
24
- staticCtaUrl: string;
25
- }
26
- declare function ProductListClient({ products, defaultLayout, allowToggle, gridCols, cardStyle, showPrice, showRating, currency, ctaLabel, staticCtaUrl, }: ProductListClientProps): react_jsx_runtime.JSX.Element;
27
-
28
- export { ProductListClient };
@@ -1,185 +0,0 @@
1
- import { useState } from 'react';
2
- import { jsxs, jsx } from 'react/jsx-runtime';
3
-
4
- function StarIcon() {
5
- return /* @__PURE__ */ jsx("svg", { className: "w-3.5 h-3.5 fill-yellow-400 text-yellow-400", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx("path", { d: "M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z" }) });
6
- }
7
- function GridIcon({ active }) {
8
- return /* @__PURE__ */ jsxs(
9
- "svg",
10
- {
11
- viewBox: "0 0 16 16",
12
- className: `w-4 h-4 ${active ? "text-foreground" : "text-muted-foreground"}`,
13
- fill: "currentColor",
14
- children: [
15
- /* @__PURE__ */ jsx("rect", { x: "1", y: "1", width: "6", height: "6", rx: "1" }),
16
- /* @__PURE__ */ jsx("rect", { x: "9", y: "1", width: "6", height: "6", rx: "1" }),
17
- /* @__PURE__ */ jsx("rect", { x: "1", y: "9", width: "6", height: "6", rx: "1" }),
18
- /* @__PURE__ */ jsx("rect", { x: "9", y: "9", width: "6", height: "6", rx: "1" })
19
- ]
20
- }
21
- );
22
- }
23
- function ListIcon({ active }) {
24
- return /* @__PURE__ */ jsxs(
25
- "svg",
26
- {
27
- viewBox: "0 0 16 16",
28
- className: `w-4 h-4 ${active ? "text-foreground" : "text-muted-foreground"}`,
29
- fill: "currentColor",
30
- children: [
31
- /* @__PURE__ */ jsx("rect", { x: "1", y: "2", width: "14", height: "3", rx: "1" }),
32
- /* @__PURE__ */ jsx("rect", { x: "1", y: "7", width: "14", height: "3", rx: "1" }),
33
- /* @__PURE__ */ jsx("rect", { x: "1", y: "12", width: "14", height: "3", rx: "1" })
34
- ]
35
- }
36
- );
37
- }
38
- function ProductCard({ product, cardStyle, showPrice, showRating, currency, ctaLabel, staticCtaUrl }) {
39
- const accentColor = product.color ?? "#6366f1";
40
- const href = staticCtaUrl || product.ctaUrl;
41
- return /* @__PURE__ */ jsxs(
42
- "div",
43
- {
44
- className: `overflow-hidden group transition-shadow flex flex-col ${cardStyle === "minimal" ? "border-0 shadow-none bg-transparent" : "border rounded-xl hover:shadow-lg bg-card"}`,
45
- children: [
46
- cardStyle === "color-band" && /* @__PURE__ */ jsx("div", { className: "h-2 w-full flex-shrink-0", style: { backgroundColor: accentColor } }),
47
- cardStyle === "filled-header" && /* @__PURE__ */ jsx("div", { className: "h-20 w-full flex-shrink-0 flex items-end px-5 pb-3", style: { backgroundColor: accentColor }, children: product.category && /* @__PURE__ */ jsx("span", { className: "text-xs font-semibold text-white/80 uppercase tracking-wider", children: product.category }) }),
48
- /* @__PURE__ */ jsxs("div", { className: "p-5 flex flex-col gap-3 flex-1", children: [
49
- cardStyle !== "filled-header" && (product.category || product.badge) && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 flex-wrap", children: [
50
- product.category && /* @__PURE__ */ jsx("span", { className: "text-xs px-2 py-0.5 rounded-full font-medium text-white", style: { backgroundColor: accentColor }, children: product.category }),
51
- product.badge && /* @__PURE__ */ jsx("span", { className: "text-xs px-2 py-0.5 rounded-full bg-muted text-muted-foreground", children: product.badge })
52
- ] }),
53
- cardStyle === "filled-header" && product.badge && /* @__PURE__ */ jsx("span", { className: "text-xs px-2 py-0.5 rounded-full bg-muted text-muted-foreground self-start", children: product.badge }),
54
- /* @__PURE__ */ jsx("h3", { className: "font-semibold text-base line-clamp-2", children: product.name }),
55
- product.description && /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground line-clamp-2", children: product.description }),
56
- /* @__PURE__ */ jsxs("div", { className: "mt-auto pt-3 border-t border-border flex items-center justify-between gap-3", children: [
57
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
58
- showPrice && product.price > 0 && /* @__PURE__ */ jsxs("span", { className: "font-bold text-lg", children: [
59
- product.price.toFixed(2),
60
- " ",
61
- currency
62
- ] }),
63
- showRating && product.rating && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1 text-sm text-muted-foreground", children: [
64
- /* @__PURE__ */ jsx(StarIcon, {}),
65
- /* @__PURE__ */ jsx("span", { children: product.rating })
66
- ] })
67
- ] }),
68
- ctaLabel && /* @__PURE__ */ jsx(
69
- "a",
70
- {
71
- href: href || "#",
72
- className: "text-xs font-semibold px-3 py-1.5 rounded-lg text-white transition-opacity hover:opacity-90 flex-shrink-0",
73
- style: { backgroundColor: accentColor },
74
- children: ctaLabel
75
- }
76
- )
77
- ] })
78
- ] })
79
- ]
80
- }
81
- );
82
- }
83
- function ProductRow({ product, showPrice, showRating, currency, ctaLabel, staticCtaUrl }) {
84
- const accentColor = product.color ?? "#6366f1";
85
- const href = staticCtaUrl || product.ctaUrl;
86
- return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-4 border rounded-xl bg-card px-5 py-4 hover:shadow-md transition-shadow group", children: [
87
- /* @__PURE__ */ jsx("div", { className: "w-1 self-stretch rounded-full flex-shrink-0", style: { backgroundColor: accentColor } }),
88
- /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
89
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 flex-wrap mb-1", children: [
90
- product.category && /* @__PURE__ */ jsx("span", { className: "text-xs px-2 py-0.5 rounded-full font-medium text-white", style: { backgroundColor: accentColor }, children: product.category }),
91
- product.badge && /* @__PURE__ */ jsx("span", { className: "text-xs px-2 py-0.5 rounded-full bg-muted text-muted-foreground", children: product.badge })
92
- ] }),
93
- /* @__PURE__ */ jsx("h3", { className: "font-semibold text-sm truncate", children: product.name }),
94
- product.description && /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground truncate mt-0.5", children: product.description })
95
- ] }),
96
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-4 flex-shrink-0", children: [
97
- showRating && product.rating && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1 text-sm text-muted-foreground", children: [
98
- /* @__PURE__ */ jsx(StarIcon, {}),
99
- /* @__PURE__ */ jsx("span", { children: product.rating })
100
- ] }),
101
- showPrice && product.price > 0 && /* @__PURE__ */ jsxs("span", { className: "font-bold text-base", children: [
102
- product.price.toFixed(2),
103
- " ",
104
- currency
105
- ] }),
106
- ctaLabel && /* @__PURE__ */ jsx(
107
- "a",
108
- {
109
- href: href || "#",
110
- className: "text-xs font-semibold px-3 py-1.5 rounded-lg text-white transition-opacity hover:opacity-90",
111
- style: { backgroundColor: accentColor },
112
- children: ctaLabel
113
- }
114
- )
115
- ] })
116
- ] });
117
- }
118
- function ProductListClient({
119
- products,
120
- defaultLayout,
121
- allowToggle,
122
- gridCols,
123
- cardStyle,
124
- showPrice,
125
- showRating,
126
- currency,
127
- ctaLabel,
128
- staticCtaUrl
129
- }) {
130
- const [layout, setLayout] = useState(defaultLayout);
131
- return /* @__PURE__ */ jsxs("div", { children: [
132
- allowToggle && /* @__PURE__ */ jsx("div", { className: "flex justify-end mb-4", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1 border border-border rounded-lg p-1 bg-muted/30", children: [
133
- /* @__PURE__ */ jsx(
134
- "button",
135
- {
136
- type: "button",
137
- onClick: () => setLayout("grid"),
138
- className: `p-1.5 rounded-md transition-colors ${layout === "grid" ? "bg-background shadow-sm" : "hover:bg-muted"}`,
139
- "aria-label": "Grid view",
140
- "aria-pressed": layout === "grid",
141
- children: /* @__PURE__ */ jsx(GridIcon, { active: layout === "grid" })
142
- }
143
- ),
144
- /* @__PURE__ */ jsx(
145
- "button",
146
- {
147
- type: "button",
148
- onClick: () => setLayout("list"),
149
- className: `p-1.5 rounded-md transition-colors ${layout === "list" ? "bg-background shadow-sm" : "hover:bg-muted"}`,
150
- "aria-label": "List view",
151
- "aria-pressed": layout === "list",
152
- children: /* @__PURE__ */ jsx(ListIcon, { active: layout === "list" })
153
- }
154
- )
155
- ] }) }),
156
- layout === "grid" ? /* @__PURE__ */ jsx("div", { className: `grid gap-6 grid-cols-1 ${gridCols}`, children: products.map((product) => /* @__PURE__ */ jsx(
157
- ProductCard,
158
- {
159
- product,
160
- cardStyle,
161
- showPrice,
162
- showRating,
163
- currency,
164
- ctaLabel,
165
- staticCtaUrl
166
- },
167
- product.id
168
- )) }) : /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-3", children: products.map((product) => /* @__PURE__ */ jsx(
169
- ProductRow,
170
- {
171
- product,
172
- showPrice,
173
- showRating,
174
- currency,
175
- ctaLabel,
176
- staticCtaUrl
177
- },
178
- product.id
179
- )) })
180
- ] });
181
- }
182
-
183
- export { ProductListClient };
184
- //# sourceMappingURL=product-list-client.js.map
185
- //# sourceMappingURL=product-list-client.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/next/product-list-client.tsx"],"names":[],"mappings":"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","file":"product-list-client.js","sourcesContent":["'use client'\n\nimport React, { useState } from 'react'\n\ninterface NormalisedProduct {\n id: string\n name: string\n price: number\n color?: string\n rating?: number\n category?: string\n badge?: string\n description?: string\n ctaUrl?: string\n}\n\ninterface ProductListClientProps {\n products: NormalisedProduct[]\n defaultLayout: 'grid' | 'list'\n allowToggle: boolean\n gridCols: string\n cardStyle: string\n showPrice: boolean\n showRating: boolean\n currency: string\n ctaLabel: string\n staticCtaUrl: string\n}\n\nfunction StarIcon() {\n return (\n <svg className=\"w-3.5 h-3.5 fill-yellow-400 text-yellow-400\" viewBox=\"0 0 24 24\">\n <path d=\"M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z\" />\n </svg>\n )\n}\n\nfunction GridIcon({ active }: { active: boolean }) {\n return (\n <svg\n viewBox=\"0 0 16 16\"\n className={`w-4 h-4 ${active ? 'text-foreground' : 'text-muted-foreground'}`}\n fill=\"currentColor\"\n >\n <rect x=\"1\" y=\"1\" width=\"6\" height=\"6\" rx=\"1\" />\n <rect x=\"9\" y=\"1\" width=\"6\" height=\"6\" rx=\"1\" />\n <rect x=\"1\" y=\"9\" width=\"6\" height=\"6\" rx=\"1\" />\n <rect x=\"9\" y=\"9\" width=\"6\" height=\"6\" rx=\"1\" />\n </svg>\n )\n}\n\nfunction ListIcon({ active }: { active: boolean }) {\n return (\n <svg\n viewBox=\"0 0 16 16\"\n className={`w-4 h-4 ${active ? 'text-foreground' : 'text-muted-foreground'}`}\n fill=\"currentColor\"\n >\n <rect x=\"1\" y=\"2\" width=\"14\" height=\"3\" rx=\"1\" />\n <rect x=\"1\" y=\"7\" width=\"14\" height=\"3\" rx=\"1\" />\n <rect x=\"1\" y=\"12\" width=\"14\" height=\"3\" rx=\"1\" />\n </svg>\n )\n}\n\nfunction ProductCard({ product, cardStyle, showPrice, showRating, currency, ctaLabel, staticCtaUrl }: {\n product: NormalisedProduct\n cardStyle: string\n showPrice: boolean\n showRating: boolean\n currency: string\n ctaLabel: string\n staticCtaUrl: string\n}) {\n const accentColor = product.color ?? '#6366f1'\n const href = staticCtaUrl || product.ctaUrl\n\n return (\n <div\n className={`overflow-hidden group transition-shadow flex flex-col ${\n cardStyle === 'minimal'\n ? 'border-0 shadow-none bg-transparent'\n : 'border rounded-xl hover:shadow-lg bg-card'\n }`}\n >\n {cardStyle === 'color-band' && (\n <div className=\"h-2 w-full flex-shrink-0\" style={{ backgroundColor: accentColor }} />\n )}\n {cardStyle === 'filled-header' && (\n <div className=\"h-20 w-full flex-shrink-0 flex items-end px-5 pb-3\" style={{ backgroundColor: accentColor }}>\n {product.category && (\n <span className=\"text-xs font-semibold text-white/80 uppercase tracking-wider\">{product.category}</span>\n )}\n </div>\n )}\n <div className=\"p-5 flex flex-col gap-3 flex-1\">\n {cardStyle !== 'filled-header' && (product.category || product.badge) && (\n <div className=\"flex items-center gap-2 flex-wrap\">\n {product.category && (\n <span className=\"text-xs px-2 py-0.5 rounded-full font-medium text-white\" style={{ backgroundColor: accentColor }}>\n {product.category}\n </span>\n )}\n {product.badge && (\n <span className=\"text-xs px-2 py-0.5 rounded-full bg-muted text-muted-foreground\">{product.badge}</span>\n )}\n </div>\n )}\n {cardStyle === 'filled-header' && product.badge && (\n <span className=\"text-xs px-2 py-0.5 rounded-full bg-muted text-muted-foreground self-start\">{product.badge}</span>\n )}\n <h3 className=\"font-semibold text-base line-clamp-2\">{product.name}</h3>\n {product.description && (\n <p className=\"text-xs text-muted-foreground line-clamp-2\">{product.description}</p>\n )}\n <div className=\"mt-auto pt-3 border-t border-border flex items-center justify-between gap-3\">\n <div className=\"flex items-center gap-3\">\n {showPrice && product.price > 0 && (\n <span className=\"font-bold text-lg\">{product.price.toFixed(2)} {currency}</span>\n )}\n {showRating && product.rating && (\n <div className=\"flex items-center gap-1 text-sm text-muted-foreground\">\n <StarIcon />\n <span>{product.rating}</span>\n </div>\n )}\n </div>\n {ctaLabel && (\n <a\n href={href || '#'}\n className=\"text-xs font-semibold px-3 py-1.5 rounded-lg text-white transition-opacity hover:opacity-90 flex-shrink-0\"\n style={{ backgroundColor: accentColor }}\n >\n {ctaLabel}\n </a>\n )}\n </div>\n </div>\n </div>\n )\n}\n\nfunction ProductRow({ product, showPrice, showRating, currency, ctaLabel, staticCtaUrl }: {\n product: NormalisedProduct\n showPrice: boolean\n showRating: boolean\n currency: string\n ctaLabel: string\n staticCtaUrl: string\n}) {\n const accentColor = product.color ?? '#6366f1'\n const href = staticCtaUrl || product.ctaUrl\n\n return (\n <div className=\"flex items-center gap-4 border rounded-xl bg-card px-5 py-4 hover:shadow-md transition-shadow group\">\n {/* Color dot */}\n <div className=\"w-1 self-stretch rounded-full flex-shrink-0\" style={{ backgroundColor: accentColor }} />\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-2 flex-wrap mb-1\">\n {product.category && (\n <span className=\"text-xs px-2 py-0.5 rounded-full font-medium text-white\" style={{ backgroundColor: accentColor }}>\n {product.category}\n </span>\n )}\n {product.badge && (\n <span className=\"text-xs px-2 py-0.5 rounded-full bg-muted text-muted-foreground\">{product.badge}</span>\n )}\n </div>\n <h3 className=\"font-semibold text-sm truncate\">{product.name}</h3>\n {product.description && (\n <p className=\"text-xs text-muted-foreground truncate mt-0.5\">{product.description}</p>\n )}\n </div>\n <div className=\"flex items-center gap-4 flex-shrink-0\">\n {showRating && product.rating && (\n <div className=\"flex items-center gap-1 text-sm text-muted-foreground\">\n <StarIcon />\n <span>{product.rating}</span>\n </div>\n )}\n {showPrice && product.price > 0 && (\n <span className=\"font-bold text-base\">{product.price.toFixed(2)} {currency}</span>\n )}\n {ctaLabel && (\n <a\n href={href || '#'}\n className=\"text-xs font-semibold px-3 py-1.5 rounded-lg text-white transition-opacity hover:opacity-90\"\n style={{ backgroundColor: accentColor }}\n >\n {ctaLabel}\n </a>\n )}\n </div>\n </div>\n )\n}\n\nexport function ProductListClient({\n products,\n defaultLayout,\n allowToggle,\n gridCols,\n cardStyle,\n showPrice,\n showRating,\n currency,\n ctaLabel,\n staticCtaUrl,\n}: ProductListClientProps) {\n const [layout, setLayout] = useState<'grid' | 'list'>(defaultLayout)\n\n return (\n <div>\n {allowToggle && (\n <div className=\"flex justify-end mb-4\">\n <div className=\"flex items-center gap-1 border border-border rounded-lg p-1 bg-muted/30\">\n <button\n type=\"button\"\n onClick={() => setLayout('grid')}\n className={`p-1.5 rounded-md transition-colors ${layout === 'grid' ? 'bg-background shadow-sm' : 'hover:bg-muted'}`}\n aria-label=\"Grid view\"\n aria-pressed={layout === 'grid'}\n >\n <GridIcon active={layout === 'grid'} />\n </button>\n <button\n type=\"button\"\n onClick={() => setLayout('list')}\n className={`p-1.5 rounded-md transition-colors ${layout === 'list' ? 'bg-background shadow-sm' : 'hover:bg-muted'}`}\n aria-label=\"List view\"\n aria-pressed={layout === 'list'}\n >\n <ListIcon active={layout === 'list'} />\n </button>\n </div>\n </div>\n )}\n\n {layout === 'grid' ? (\n <div className={`grid gap-6 grid-cols-1 ${gridCols}`}>\n {products.map((product) => (\n <ProductCard\n key={product.id}\n product={product}\n cardStyle={cardStyle}\n showPrice={showPrice}\n showRating={showRating}\n currency={currency}\n ctaLabel={ctaLabel}\n staticCtaUrl={staticCtaUrl}\n />\n ))}\n </div>\n ) : (\n <div className=\"flex flex-col gap-3\">\n {products.map((product) => (\n <ProductRow\n key={product.id}\n product={product}\n showPrice={showPrice}\n showRating={showRating}\n currency={currency}\n ctaLabel={ctaLabel}\n staticCtaUrl={staticCtaUrl}\n />\n ))}\n </div>\n )}\n </div>\n )\n}\n"]}
@@ -1,92 +0,0 @@
1
- import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import React from 'react';
3
-
4
- /**
5
- * @sprintup-cms/sdk — Core Client
6
- *
7
- * Zero-dependency, framework-agnostic typed API client for SprintUp Forge CMS.
8
- *
9
- * @example
10
- * import { cmsClient } from '@sprintup-cms/sdk'
11
- * const page = await cmsClient.getPage('about')
12
- *
13
- * @example Custom instance
14
- * import { createCMSClient } from '@sprintup-cms/sdk'
15
- * const cms = createCMSClient({ baseUrl: '...', apiKey: '...', appId: '...' })
16
- */
17
- interface CMSBlock {
18
- id: string;
19
- type: string;
20
- label?: string;
21
- locked?: boolean;
22
- data?: Record<string, any>;
23
- /** Legacy field — blocks created before v1.1 used `content` instead of `data` */
24
- content?: Record<string, any>;
25
- order?: number;
26
- }
27
- interface CMSPageTypeField {
28
- id: string;
29
- name: string;
30
- label: string;
31
- fieldType: 'text' | 'textarea' | 'richtext' | 'image' | 'url' | 'number' | 'boolean' | 'date' | 'select' | 'relation' | 'email' | 'phone' | 'slug' | 'color' | 'embed' | 'multi-select' | 'repeater' | 'file' | 'code';
32
- required?: boolean;
33
- options?: string[];
34
- description?: string;
35
- maxLength?: number;
36
- multiple?: boolean;
37
- targetPageTypeKey?: string;
38
- }
39
- interface CMSPageTypeSection {
40
- id: string;
41
- name: string;
42
- label: string;
43
- order: number;
44
- locked?: boolean;
45
- fields: CMSPageTypeField[];
46
- }
47
- interface CMSPageTypeVariant {
48
- key: string;
49
- label: string;
50
- description?: string;
51
- visibleSections?: string[];
52
- }
53
- interface CMSPageType {
54
- _id: string;
55
- name: string;
56
- key: string;
57
- description?: string;
58
- icon?: string;
59
- /** Used by page-type-renderers to pick a specialised React component */
60
- rendererKey?: string;
61
- /** Active variant key (set per-page) */
62
- variant?: string;
63
- category: 'singleton' | 'collection' | 'global';
64
- contentCategory: 'singleton' | 'collection' | 'global';
65
- allowedRoles?: string[];
66
- variants: CMSPageTypeVariant[];
67
- sections: CMSPageTypeSection[];
68
- }
69
-
70
- interface CMSBlocksProps {
71
- blocks: CMSBlock[];
72
- pageType?: CMSPageType | null;
73
- className?: string;
74
- /**
75
- * Custom block renderers — extend or override built-in blocks.
76
- * @example
77
- * <CMSBlocks blocks={blocks} custom={{ 'my-hero': (block) => <MyHero {...block.data} /> }} />
78
- */
79
- custom?: Record<string, (block: CMSBlock) => React.ReactNode>;
80
- }
81
- declare function CMSBlocks({ blocks, pageType, className, custom }: CMSBlocksProps): react_jsx_runtime.JSX.Element | null;
82
-
83
- interface CMSPreviewBannerProps {
84
- isPreview: boolean;
85
- status?: string;
86
- slug?: string;
87
- /** URL for the exit preview link. Defaults to /api/cms-preview/exit */
88
- exitUrl?: string;
89
- }
90
- declare function CMSPreviewBanner({ isPreview, status, slug, exitUrl }: CMSPreviewBannerProps): react_jsx_runtime.JSX.Element | null;
91
-
92
- export { CMSBlocks, type CMSBlocksProps, CMSPreviewBanner, type CMSPreviewBannerProps };