@burdenoff/website-sdk 2026.716.3 → 2026.719.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/website-switcher.d.mts +9 -1
- package/dist/components/website-switcher.d.ts +9 -1
- package/dist/components/website-switcher.js +18 -4
- package/dist/components/website-switcher.js.map +1 -1
- package/dist/components/website-switcher.mjs +18 -5
- package/dist/components/website-switcher.mjs.map +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +710 -145
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +710 -145
- package/dist/index.mjs.map +1 -1
- package/dist/product-card-Dm1zkFkm.d.mts +157 -0
- package/dist/product-card-Dm1zkFkm.d.ts +157 -0
- package/dist/store/index.d.mts +27 -154
- package/dist/store/index.d.ts +27 -154
- package/dist/store/index.js +837 -284
- package/dist/store/index.js.map +1 -1
- package/dist/store/index.mjs +838 -286
- package/dist/store/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/store/index.js
CHANGED
|
@@ -7,6 +7,196 @@ var reactHelmetAsync = require('react-helmet-async');
|
|
|
7
7
|
var __defProp = Object.defineProperty;
|
|
8
8
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
9
9
|
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
10
|
+
function formatPrice(price, currency, pricingModel) {
|
|
11
|
+
if (pricingModel === "FREE" || !price || price === 0) return "Free";
|
|
12
|
+
const curr = currency || "USD";
|
|
13
|
+
try {
|
|
14
|
+
return new Intl.NumberFormat("en-US", {
|
|
15
|
+
style: "currency",
|
|
16
|
+
currency: curr
|
|
17
|
+
}).format(price);
|
|
18
|
+
} catch {
|
|
19
|
+
return `${curr} ${price.toFixed(2)}`;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
function formatDownloads(n) {
|
|
23
|
+
if (!n) return "0";
|
|
24
|
+
if (n >= 1e6) return `${(n / 1e6).toFixed(1)}M`;
|
|
25
|
+
if (n >= 1e3) return `${(n / 1e3).toFixed(1)}K`;
|
|
26
|
+
return n.toString();
|
|
27
|
+
}
|
|
28
|
+
function StarRating({ rating }) {
|
|
29
|
+
return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex items-center gap-0.5", children: [1, 2, 3, 4, 5].map((star) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
30
|
+
"svg",
|
|
31
|
+
{
|
|
32
|
+
viewBox: "0 0 12 12",
|
|
33
|
+
className: `w-3 h-3 ${star <= Math.round(rating) ? "text-amber-400 fill-current" : "text-muted-foreground/30 fill-current"}`,
|
|
34
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M6 1l1.545 3.09L11 4.59l-2.5 2.41.59 3.41L6 8.79l-3.09 1.61L3.5 7 1 4.59l3.455-.5L6 1z" })
|
|
35
|
+
},
|
|
36
|
+
star
|
|
37
|
+
)) });
|
|
38
|
+
}
|
|
39
|
+
function TypeBadge({ type }) {
|
|
40
|
+
const labels = {
|
|
41
|
+
APP: "App",
|
|
42
|
+
NODE: "Node",
|
|
43
|
+
WORKFLOW: "Workflow",
|
|
44
|
+
TEMPLATE: "Template",
|
|
45
|
+
INTEGRATION: "Integration",
|
|
46
|
+
EXTENSION: "Extension",
|
|
47
|
+
THEME: "Theme"
|
|
48
|
+
};
|
|
49
|
+
return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "inline-block text-xs px-2 py-0.5 rounded-full bg-primary/10 text-primary font-medium", children: labels[type] ?? type });
|
|
50
|
+
}
|
|
51
|
+
function ProductCard({ product, onClick, href }) {
|
|
52
|
+
const priceLabel = formatPrice(
|
|
53
|
+
product.price,
|
|
54
|
+
product.currency,
|
|
55
|
+
product.pricingModel
|
|
56
|
+
);
|
|
57
|
+
const inner = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "group bg-card border border-border rounded-xl p-4 flex flex-col gap-3 transition-all duration-200 hover:shadow-md hover:border-primary/30 cursor-pointer h-full", children: [
|
|
58
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between gap-2", children: [
|
|
59
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-12 h-12 rounded-lg bg-muted flex-shrink-0 overflow-hidden", children: product.icon ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
60
|
+
"img",
|
|
61
|
+
{
|
|
62
|
+
src: product.icon,
|
|
63
|
+
alt: "",
|
|
64
|
+
"aria-hidden": "true",
|
|
65
|
+
className: "w-full h-full object-cover"
|
|
66
|
+
}
|
|
67
|
+
) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-full flex items-center justify-center bg-gradient-to-br from-primary/15 to-primary/5", children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
68
|
+
"svg",
|
|
69
|
+
{
|
|
70
|
+
viewBox: "0 0 32 32",
|
|
71
|
+
className: "w-8 h-8",
|
|
72
|
+
fill: "none",
|
|
73
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
74
|
+
"aria-hidden": "true",
|
|
75
|
+
children: [
|
|
76
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
77
|
+
"polygon",
|
|
78
|
+
{
|
|
79
|
+
points: "16,4 28,10 16,16 4,10",
|
|
80
|
+
className: "fill-primary/30",
|
|
81
|
+
stroke: "currentColor",
|
|
82
|
+
strokeWidth: "0.6",
|
|
83
|
+
strokeOpacity: "0.35"
|
|
84
|
+
}
|
|
85
|
+
),
|
|
86
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
87
|
+
"polygon",
|
|
88
|
+
{
|
|
89
|
+
points: "4,10 16,16 16,28 4,22",
|
|
90
|
+
className: "fill-primary/15",
|
|
91
|
+
stroke: "currentColor",
|
|
92
|
+
strokeWidth: "0.6",
|
|
93
|
+
strokeOpacity: "0.35"
|
|
94
|
+
}
|
|
95
|
+
),
|
|
96
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
97
|
+
"polygon",
|
|
98
|
+
{
|
|
99
|
+
points: "28,10 16,16 16,28 28,22",
|
|
100
|
+
className: "fill-primary/20",
|
|
101
|
+
stroke: "currentColor",
|
|
102
|
+
strokeWidth: "0.6",
|
|
103
|
+
strokeOpacity: "0.35"
|
|
104
|
+
}
|
|
105
|
+
)
|
|
106
|
+
]
|
|
107
|
+
}
|
|
108
|
+
) }) }),
|
|
109
|
+
/* @__PURE__ */ jsxRuntime.jsx(TypeBadge, { type: product.type })
|
|
110
|
+
] }),
|
|
111
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 min-w-0", children: [
|
|
112
|
+
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "font-semibold text-foreground text-sm leading-snug line-clamp-1 group-hover:text-primary transition-colors", children: product.name }),
|
|
113
|
+
product.description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground text-xs mt-1 line-clamp-2 leading-relaxed", children: product.description })
|
|
114
|
+
] }),
|
|
115
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-2", children: [
|
|
116
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-1.5", children: product.rating != null && product.rating > 0 ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
117
|
+
/* @__PURE__ */ jsxRuntime.jsx(StarRating, { rating: product.rating }),
|
|
118
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground", children: product.rating.toFixed(1) })
|
|
119
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground", children: "No reviews yet" }) }),
|
|
120
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
121
|
+
"span",
|
|
122
|
+
{
|
|
123
|
+
className: `text-xs font-semibold ${priceLabel === "Free" ? "text-emerald-500" : "text-foreground"}`,
|
|
124
|
+
children: priceLabel
|
|
125
|
+
}
|
|
126
|
+
)
|
|
127
|
+
] })
|
|
128
|
+
] });
|
|
129
|
+
if (href) {
|
|
130
|
+
return /* @__PURE__ */ jsxRuntime.jsx("a", { href, onClick, className: "block h-full no-underline", children: inner });
|
|
131
|
+
}
|
|
132
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
133
|
+
"button",
|
|
134
|
+
{
|
|
135
|
+
type: "button",
|
|
136
|
+
onClick,
|
|
137
|
+
className: "block w-full text-left h-full",
|
|
138
|
+
children: inner
|
|
139
|
+
}
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// src/store/queries.ts
|
|
144
|
+
var STORE_PRODUCT_FIELDS = `
|
|
145
|
+
fragment StoreProductFields on StoreProduct {
|
|
146
|
+
id name slug type subType nature status pricingModel
|
|
147
|
+
price currency description icon bannerUrl screenshots
|
|
148
|
+
category tags featured downloads viewCount rating reviewCount
|
|
149
|
+
publisherId authorName license compatibleProducts
|
|
150
|
+
}
|
|
151
|
+
`;
|
|
152
|
+
var HOME_GROUPED_PRODUCTS_QUERY = `
|
|
153
|
+
${STORE_PRODUCT_FIELDS}
|
|
154
|
+
query HomeGroupedProducts($compatibleWith: String) {
|
|
155
|
+
homeGroupedProducts(compatibleWith: $compatibleWith) {
|
|
156
|
+
featured { ...StoreProductFields }
|
|
157
|
+
mostDownloaded { ...StoreProductFields }
|
|
158
|
+
recentlyAdded { ...StoreProductFields }
|
|
159
|
+
freeItems { ...StoreProductFields }
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
`;
|
|
163
|
+
var BROWSE_STORE_QUERY = `
|
|
164
|
+
${STORE_PRODUCT_FIELDS}
|
|
165
|
+
query BrowseStore($input: BrowseStoreInput!) {
|
|
166
|
+
browseStore(input: $input) {
|
|
167
|
+
products { ...StoreProductFields }
|
|
168
|
+
totalCount
|
|
169
|
+
hasMore
|
|
170
|
+
nextCursor
|
|
171
|
+
facets {
|
|
172
|
+
types { value count }
|
|
173
|
+
categories { value count }
|
|
174
|
+
pricingModels { value count }
|
|
175
|
+
priceRange { min max }
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
`;
|
|
180
|
+
var STORE_PRODUCT_DETAILS_QUERY = `
|
|
181
|
+
${STORE_PRODUCT_FIELDS}
|
|
182
|
+
query StoreProductDetails($input: StoreProductDetailsInput!) {
|
|
183
|
+
storeProductDetails(input: $input) {
|
|
184
|
+
product { ...StoreProductFields longDescription videoUrls minPlatformVersion }
|
|
185
|
+
publisher { id name email websiteUrl logoUrl bio isVerified tier }
|
|
186
|
+
reviews { id rating title comment verifiedPurchase helpful createdAt }
|
|
187
|
+
reviewsCount
|
|
188
|
+
relatedProducts { ...StoreProductFields }
|
|
189
|
+
ratingDistribution { fiveStars fourStars threeStars twoStars oneStar }
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
`;
|
|
193
|
+
var CATEGORIES_QUERY = `
|
|
194
|
+
query Categories {
|
|
195
|
+
categories {
|
|
196
|
+
id name slug description icon parentId
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
`;
|
|
10
200
|
|
|
11
201
|
// src/client/security.ts
|
|
12
202
|
var LOOPBACK_HOSTS = /* @__PURE__ */ new Set(["localhost", "127.0.0.1", "::1"]);
|
|
@@ -204,155 +394,6 @@ function PageHead({
|
|
|
204
394
|
))
|
|
205
395
|
] });
|
|
206
396
|
}
|
|
207
|
-
function formatPrice(price, currency, pricingModel) {
|
|
208
|
-
if (pricingModel === "FREE" || !price || price === 0) return "Free";
|
|
209
|
-
const curr = currency || "USD";
|
|
210
|
-
try {
|
|
211
|
-
return new Intl.NumberFormat("en-US", {
|
|
212
|
-
style: "currency",
|
|
213
|
-
currency: curr
|
|
214
|
-
}).format(price);
|
|
215
|
-
} catch {
|
|
216
|
-
return `${curr} ${price.toFixed(2)}`;
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
function formatDownloads(n) {
|
|
220
|
-
if (!n) return "0";
|
|
221
|
-
if (n >= 1e6) return `${(n / 1e6).toFixed(1)}M`;
|
|
222
|
-
if (n >= 1e3) return `${(n / 1e3).toFixed(1)}K`;
|
|
223
|
-
return n.toString();
|
|
224
|
-
}
|
|
225
|
-
function StarRating({ rating }) {
|
|
226
|
-
return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex items-center gap-0.5", children: [1, 2, 3, 4, 5].map((star) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
227
|
-
"svg",
|
|
228
|
-
{
|
|
229
|
-
viewBox: "0 0 12 12",
|
|
230
|
-
className: `w-3 h-3 ${star <= Math.round(rating) ? "text-amber-400 fill-current" : "text-muted-foreground/30 fill-current"}`,
|
|
231
|
-
children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M6 1l1.545 3.09L11 4.59l-2.5 2.41.59 3.41L6 8.79l-3.09 1.61L3.5 7 1 4.59l3.455-.5L6 1z" })
|
|
232
|
-
},
|
|
233
|
-
star
|
|
234
|
-
)) });
|
|
235
|
-
}
|
|
236
|
-
function TypeBadge({ type }) {
|
|
237
|
-
const labels = {
|
|
238
|
-
APP: "App",
|
|
239
|
-
NODE: "Node",
|
|
240
|
-
WORKFLOW: "Workflow",
|
|
241
|
-
TEMPLATE: "Template",
|
|
242
|
-
INTEGRATION: "Integration",
|
|
243
|
-
EXTENSION: "Extension",
|
|
244
|
-
THEME: "Theme"
|
|
245
|
-
};
|
|
246
|
-
return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "inline-block text-xs px-2 py-0.5 rounded-full bg-primary/10 text-primary font-medium", children: labels[type] ?? type });
|
|
247
|
-
}
|
|
248
|
-
function ProductCard({ product, onClick, href }) {
|
|
249
|
-
const priceLabel = formatPrice(product.price, product.currency, product.pricingModel);
|
|
250
|
-
const inner = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "group bg-card border border-border rounded-xl p-4 flex flex-col gap-3 transition-all duration-200 hover:shadow-md hover:border-primary/30 cursor-pointer h-full", children: [
|
|
251
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between gap-2", children: [
|
|
252
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-12 h-12 rounded-lg bg-muted flex-shrink-0 overflow-hidden", children: product.icon ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
253
|
-
"img",
|
|
254
|
-
{
|
|
255
|
-
src: product.icon,
|
|
256
|
-
alt: "",
|
|
257
|
-
"aria-hidden": "true",
|
|
258
|
-
className: "w-full h-full object-cover"
|
|
259
|
-
}
|
|
260
|
-
) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-full flex items-center justify-center bg-gradient-to-br from-primary/15 to-primary/5", children: /* @__PURE__ */ jsxRuntime.jsxs("svg", { viewBox: "0 0 32 32", className: "w-8 h-8", fill: "none", xmlns: "http://www.w3.org/2000/svg", "aria-hidden": "true", children: [
|
|
261
|
-
/* @__PURE__ */ jsxRuntime.jsx("polygon", { points: "16,4 28,10 16,16 4,10", className: "fill-primary/30", stroke: "currentColor", strokeWidth: "0.6", strokeOpacity: "0.35" }),
|
|
262
|
-
/* @__PURE__ */ jsxRuntime.jsx("polygon", { points: "4,10 16,16 16,28 4,22", className: "fill-primary/15", stroke: "currentColor", strokeWidth: "0.6", strokeOpacity: "0.35" }),
|
|
263
|
-
/* @__PURE__ */ jsxRuntime.jsx("polygon", { points: "28,10 16,16 16,28 28,22", className: "fill-primary/20", stroke: "currentColor", strokeWidth: "0.6", strokeOpacity: "0.35" })
|
|
264
|
-
] }) }) }),
|
|
265
|
-
/* @__PURE__ */ jsxRuntime.jsx(TypeBadge, { type: product.type })
|
|
266
|
-
] }),
|
|
267
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 min-w-0", children: [
|
|
268
|
-
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "font-semibold text-foreground text-sm leading-snug line-clamp-1 group-hover:text-primary transition-colors", children: product.name }),
|
|
269
|
-
product.description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground text-xs mt-1 line-clamp-2 leading-relaxed", children: product.description })
|
|
270
|
-
] }),
|
|
271
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-2", children: [
|
|
272
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-1.5", children: product.rating != null && product.rating > 0 ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
273
|
-
/* @__PURE__ */ jsxRuntime.jsx(StarRating, { rating: product.rating }),
|
|
274
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground", children: product.rating.toFixed(1) })
|
|
275
|
-
] }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground", children: "No reviews yet" }) }),
|
|
276
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
277
|
-
"span",
|
|
278
|
-
{
|
|
279
|
-
className: `text-xs font-semibold ${priceLabel === "Free" ? "text-emerald-500" : "text-foreground"}`,
|
|
280
|
-
children: priceLabel
|
|
281
|
-
}
|
|
282
|
-
)
|
|
283
|
-
] })
|
|
284
|
-
] });
|
|
285
|
-
if (href) {
|
|
286
|
-
return /* @__PURE__ */ jsxRuntime.jsx("a", { href, onClick, className: "block h-full no-underline", children: inner });
|
|
287
|
-
}
|
|
288
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
289
|
-
"button",
|
|
290
|
-
{
|
|
291
|
-
type: "button",
|
|
292
|
-
onClick,
|
|
293
|
-
className: "block w-full text-left h-full",
|
|
294
|
-
children: inner
|
|
295
|
-
}
|
|
296
|
-
);
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
// src/store/queries.ts
|
|
300
|
-
var STORE_PRODUCT_FIELDS = `
|
|
301
|
-
fragment StoreProductFields on StoreProduct {
|
|
302
|
-
id name slug type subType nature status pricingModel
|
|
303
|
-
price currency description icon bannerUrl screenshots
|
|
304
|
-
category tags featured downloads viewCount rating reviewCount
|
|
305
|
-
publisherId authorName license compatibleProducts
|
|
306
|
-
}
|
|
307
|
-
`;
|
|
308
|
-
var HOME_GROUPED_PRODUCTS_QUERY = `
|
|
309
|
-
${STORE_PRODUCT_FIELDS}
|
|
310
|
-
query HomeGroupedProducts($compatibleWith: String) {
|
|
311
|
-
homeGroupedProducts(compatibleWith: $compatibleWith) {
|
|
312
|
-
featured { ...StoreProductFields }
|
|
313
|
-
mostDownloaded { ...StoreProductFields }
|
|
314
|
-
recentlyAdded { ...StoreProductFields }
|
|
315
|
-
freeItems { ...StoreProductFields }
|
|
316
|
-
}
|
|
317
|
-
}
|
|
318
|
-
`;
|
|
319
|
-
var BROWSE_STORE_QUERY = `
|
|
320
|
-
${STORE_PRODUCT_FIELDS}
|
|
321
|
-
query BrowseStore($input: BrowseStoreInput!) {
|
|
322
|
-
browseStore(input: $input) {
|
|
323
|
-
products { ...StoreProductFields }
|
|
324
|
-
totalCount
|
|
325
|
-
hasMore
|
|
326
|
-
nextCursor
|
|
327
|
-
facets {
|
|
328
|
-
types { value count }
|
|
329
|
-
categories { value count }
|
|
330
|
-
pricingModels { value count }
|
|
331
|
-
priceRange { min max }
|
|
332
|
-
}
|
|
333
|
-
}
|
|
334
|
-
}
|
|
335
|
-
`;
|
|
336
|
-
var STORE_PRODUCT_DETAILS_QUERY = `
|
|
337
|
-
${STORE_PRODUCT_FIELDS}
|
|
338
|
-
query StoreProductDetails($input: StoreProductDetailsInput!) {
|
|
339
|
-
storeProductDetails(input: $input) {
|
|
340
|
-
product { ...StoreProductFields longDescription videoUrls minPlatformVersion }
|
|
341
|
-
publisher { id name email websiteUrl logoUrl bio isVerified tier }
|
|
342
|
-
reviews { id rating title comment verifiedPurchase helpful createdAt }
|
|
343
|
-
reviewsCount
|
|
344
|
-
relatedProducts { ...StoreProductFields }
|
|
345
|
-
ratingDistribution { fiveStars fourStars threeStars twoStars oneStar }
|
|
346
|
-
}
|
|
347
|
-
}
|
|
348
|
-
`;
|
|
349
|
-
var CATEGORIES_QUERY = `
|
|
350
|
-
query Categories {
|
|
351
|
-
categories {
|
|
352
|
-
id name slug description icon parentId
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
`;
|
|
356
397
|
function dedupAcross(lists) {
|
|
357
398
|
const seen = /* @__PURE__ */ new Set();
|
|
358
399
|
return lists.map((list) => {
|
|
@@ -370,7 +411,11 @@ function FeaturedHeroCard({
|
|
|
370
411
|
product,
|
|
371
412
|
onNavigate
|
|
372
413
|
}) {
|
|
373
|
-
const priceLabel = formatPrice(
|
|
414
|
+
const priceLabel = formatPrice(
|
|
415
|
+
product.price,
|
|
416
|
+
product.currency,
|
|
417
|
+
product.pricingModel
|
|
418
|
+
);
|
|
374
419
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
375
420
|
"button",
|
|
376
421
|
{
|
|
@@ -379,28 +424,155 @@ function FeaturedHeroCard({
|
|
|
379
424
|
className: "group w-full text-left h-full rounded-2xl border border-border bg-card overflow-hidden hover:border-primary/40 transition-all duration-300 hover:shadow-xl hover:shadow-primary/10 flex flex-col",
|
|
380
425
|
children: [
|
|
381
426
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative h-44 sm:h-52 bg-gradient-to-br from-primary/20 via-primary/8 to-background overflow-hidden flex-shrink-0", children: [
|
|
382
|
-
product.bannerUrl ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
427
|
+
product.bannerUrl ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
428
|
+
"img",
|
|
429
|
+
{
|
|
430
|
+
src: product.bannerUrl,
|
|
431
|
+
alt: "",
|
|
432
|
+
"aria-hidden": "true",
|
|
433
|
+
className: "w-full h-full object-cover"
|
|
434
|
+
}
|
|
435
|
+
) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
436
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
437
|
+
"svg",
|
|
438
|
+
{
|
|
439
|
+
className: "absolute inset-0 w-full h-full opacity-[0.07]",
|
|
440
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
441
|
+
"aria-hidden": "true",
|
|
442
|
+
children: [
|
|
443
|
+
/* @__PURE__ */ jsxRuntime.jsx("defs", { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
444
|
+
"pattern",
|
|
445
|
+
{
|
|
446
|
+
id: "fg-hero-grid",
|
|
447
|
+
width: "36",
|
|
448
|
+
height: "36",
|
|
449
|
+
patternUnits: "userSpaceOnUse",
|
|
450
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
451
|
+
"path",
|
|
452
|
+
{
|
|
453
|
+
d: "M 36 0 L 0 0 0 36",
|
|
454
|
+
fill: "none",
|
|
455
|
+
stroke: "currentColor",
|
|
456
|
+
strokeWidth: "1"
|
|
457
|
+
}
|
|
458
|
+
)
|
|
459
|
+
}
|
|
460
|
+
) }),
|
|
461
|
+
/* @__PURE__ */ jsxRuntime.jsx("rect", { width: "100%", height: "100%", fill: "url(#fg-hero-grid)" })
|
|
462
|
+
]
|
|
463
|
+
}
|
|
464
|
+
),
|
|
465
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
466
|
+
"div",
|
|
467
|
+
{
|
|
468
|
+
className: "absolute inset-0 flex items-center justify-center",
|
|
469
|
+
"aria-hidden": "true",
|
|
470
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
471
|
+
"svg",
|
|
472
|
+
{
|
|
473
|
+
viewBox: "0 0 64 64",
|
|
474
|
+
className: "w-20 h-20 opacity-25",
|
|
475
|
+
fill: "none",
|
|
476
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
477
|
+
children: [
|
|
478
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
479
|
+
"polygon",
|
|
480
|
+
{
|
|
481
|
+
points: "32,8 56,20 32,32 8,20",
|
|
482
|
+
className: "fill-primary/40",
|
|
483
|
+
stroke: "currentColor",
|
|
484
|
+
strokeWidth: "1",
|
|
485
|
+
strokeOpacity: "0.5"
|
|
486
|
+
}
|
|
487
|
+
),
|
|
488
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
489
|
+
"polygon",
|
|
490
|
+
{
|
|
491
|
+
points: "8,20 32,32 32,56 8,44",
|
|
492
|
+
className: "fill-primary/20",
|
|
493
|
+
stroke: "currentColor",
|
|
494
|
+
strokeWidth: "1",
|
|
495
|
+
strokeOpacity: "0.5"
|
|
496
|
+
}
|
|
497
|
+
),
|
|
498
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
499
|
+
"polygon",
|
|
500
|
+
{
|
|
501
|
+
points: "56,20 32,32 32,56 56,44",
|
|
502
|
+
className: "fill-primary/30",
|
|
503
|
+
stroke: "currentColor",
|
|
504
|
+
strokeWidth: "1",
|
|
505
|
+
strokeOpacity: "0.5"
|
|
506
|
+
}
|
|
507
|
+
)
|
|
508
|
+
]
|
|
509
|
+
}
|
|
510
|
+
)
|
|
511
|
+
}
|
|
512
|
+
)
|
|
392
513
|
] }),
|
|
393
514
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute top-3 left-3 text-xs font-semibold px-2.5 py-1 rounded-full bg-primary text-primary-foreground shadow-sm", children: "Featured" }),
|
|
394
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute bottom-4 left-4 w-14 h-14 rounded-xl shadow-lg overflow-hidden border-2 border-background", children: product.icon ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
515
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute bottom-4 left-4 w-14 h-14 rounded-xl shadow-lg overflow-hidden border-2 border-background", children: product.icon ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
516
|
+
"img",
|
|
517
|
+
{
|
|
518
|
+
src: product.icon,
|
|
519
|
+
alt: "",
|
|
520
|
+
"aria-hidden": "true",
|
|
521
|
+
className: "w-full h-full object-cover"
|
|
522
|
+
}
|
|
523
|
+
) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-full bg-gradient-to-br from-primary/25 to-primary/10 flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
524
|
+
"svg",
|
|
525
|
+
{
|
|
526
|
+
viewBox: "0 0 32 32",
|
|
527
|
+
className: "w-8 h-8",
|
|
528
|
+
fill: "none",
|
|
529
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
530
|
+
"aria-hidden": "true",
|
|
531
|
+
children: [
|
|
532
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
533
|
+
"polygon",
|
|
534
|
+
{
|
|
535
|
+
points: "16,4 28,10 16,16 4,10",
|
|
536
|
+
className: "fill-primary/40",
|
|
537
|
+
stroke: "currentColor",
|
|
538
|
+
strokeWidth: "0.6",
|
|
539
|
+
strokeOpacity: "0.4"
|
|
540
|
+
}
|
|
541
|
+
),
|
|
542
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
543
|
+
"polygon",
|
|
544
|
+
{
|
|
545
|
+
points: "4,10 16,16 16,28 4,22",
|
|
546
|
+
className: "fill-primary/20",
|
|
547
|
+
stroke: "currentColor",
|
|
548
|
+
strokeWidth: "0.6",
|
|
549
|
+
strokeOpacity: "0.4"
|
|
550
|
+
}
|
|
551
|
+
),
|
|
552
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
553
|
+
"polygon",
|
|
554
|
+
{
|
|
555
|
+
points: "28,10 16,16 16,28 28,22",
|
|
556
|
+
className: "fill-primary/30",
|
|
557
|
+
stroke: "currentColor",
|
|
558
|
+
strokeWidth: "0.6",
|
|
559
|
+
strokeOpacity: "0.4"
|
|
560
|
+
}
|
|
561
|
+
)
|
|
562
|
+
]
|
|
563
|
+
}
|
|
564
|
+
) }) })
|
|
399
565
|
] }),
|
|
400
566
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-5 flex flex-col flex-1", children: [
|
|
401
567
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between gap-3 mb-2", children: [
|
|
402
568
|
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-base font-bold text-foreground group-hover:text-primary transition-colors line-clamp-1", children: product.name }),
|
|
403
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
569
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
570
|
+
"span",
|
|
571
|
+
{
|
|
572
|
+
className: `text-sm font-bold flex-shrink-0 ${priceLabel === "Free" ? "text-emerald-500" : "text-foreground"}`,
|
|
573
|
+
children: priceLabel
|
|
574
|
+
}
|
|
575
|
+
)
|
|
404
576
|
] }),
|
|
405
577
|
product.description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground line-clamp-2 leading-relaxed flex-1", children: product.description }),
|
|
406
578
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-3 flex items-center gap-2", children: [
|
|
@@ -421,7 +593,10 @@ function ScrollRow({
|
|
|
421
593
|
}) {
|
|
422
594
|
const ref = react.useRef(null);
|
|
423
595
|
function scroll(dir) {
|
|
424
|
-
ref.current?.scrollBy({
|
|
596
|
+
ref.current?.scrollBy({
|
|
597
|
+
left: dir === "r" ? 272 : -272,
|
|
598
|
+
behavior: "smooth"
|
|
599
|
+
});
|
|
425
600
|
}
|
|
426
601
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative group/row", children: [
|
|
427
602
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -431,7 +606,19 @@ function ScrollRow({
|
|
|
431
606
|
onClick: () => scroll("l"),
|
|
432
607
|
"aria-label": "Scroll left",
|
|
433
608
|
className: "absolute left-0 top-1/2 -translate-y-1/2 -translate-x-4 z-10 w-8 h-8 rounded-full bg-background border border-border shadow-md items-center justify-center text-muted-foreground hover:text-primary hover:border-primary/40 transition-all hidden sm:flex opacity-0 group-hover/row:opacity-100",
|
|
434
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
609
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
610
|
+
"svg",
|
|
611
|
+
{
|
|
612
|
+
viewBox: "0 0 16 16",
|
|
613
|
+
className: "w-4 h-4",
|
|
614
|
+
fill: "none",
|
|
615
|
+
stroke: "currentColor",
|
|
616
|
+
strokeWidth: "1.5",
|
|
617
|
+
strokeLinecap: "round",
|
|
618
|
+
strokeLinejoin: "round",
|
|
619
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M10 3L6 8l4 5" })
|
|
620
|
+
}
|
|
621
|
+
)
|
|
435
622
|
}
|
|
436
623
|
),
|
|
437
624
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -440,7 +627,13 @@ function ScrollRow({
|
|
|
440
627
|
ref,
|
|
441
628
|
className: "flex gap-3 overflow-x-auto pb-1 snap-x snap-mandatory",
|
|
442
629
|
style: { scrollbarWidth: "none", msOverflowStyle: "none" },
|
|
443
|
-
children: products.map((product) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-shrink-0 w-56 snap-start", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
630
|
+
children: products.map((product) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-shrink-0 w-56 snap-start", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
631
|
+
ProductCard,
|
|
632
|
+
{
|
|
633
|
+
product,
|
|
634
|
+
onClick: () => onProductClick(product)
|
|
635
|
+
}
|
|
636
|
+
) }, product.id))
|
|
444
637
|
}
|
|
445
638
|
),
|
|
446
639
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -450,7 +643,19 @@ function ScrollRow({
|
|
|
450
643
|
onClick: () => scroll("r"),
|
|
451
644
|
"aria-label": "Scroll right",
|
|
452
645
|
className: "absolute right-0 top-1/2 -translate-y-1/2 translate-x-4 z-10 w-8 h-8 rounded-full bg-background border border-border shadow-md items-center justify-center text-muted-foreground hover:text-primary hover:border-primary/40 transition-all hidden sm:flex opacity-0 group-hover/row:opacity-100",
|
|
453
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
646
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
647
|
+
"svg",
|
|
648
|
+
{
|
|
649
|
+
viewBox: "0 0 16 16",
|
|
650
|
+
className: "w-4 h-4",
|
|
651
|
+
fill: "none",
|
|
652
|
+
stroke: "currentColor",
|
|
653
|
+
strokeWidth: "1.5",
|
|
654
|
+
strokeLinecap: "round",
|
|
655
|
+
strokeLinejoin: "round",
|
|
656
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M6 3l4 5-4 5" })
|
|
657
|
+
}
|
|
658
|
+
)
|
|
454
659
|
}
|
|
455
660
|
)
|
|
456
661
|
] });
|
|
@@ -553,10 +758,8 @@ function StoreHomePage({
|
|
|
553
758
|
const [grouped, setGrouped] = react.useState(null);
|
|
554
759
|
const [loading, setLoading] = react.useState(true);
|
|
555
760
|
const [error, setError] = react.useState(null);
|
|
556
|
-
const [retryKey, setRetryKey] = react.useState(0);
|
|
557
761
|
react.useEffect(() => {
|
|
558
762
|
let cancelled = false;
|
|
559
|
-
let autoRetryTimer = null;
|
|
560
763
|
async function load() {
|
|
561
764
|
setLoading(true);
|
|
562
765
|
try {
|
|
@@ -570,15 +773,7 @@ function StoreHomePage({
|
|
|
570
773
|
setGrouped(res.data.homeGroupedProducts);
|
|
571
774
|
setError(null);
|
|
572
775
|
} catch {
|
|
573
|
-
if (!cancelled)
|
|
574
|
-
if (retryKey < 1) {
|
|
575
|
-
autoRetryTimer = setTimeout(() => {
|
|
576
|
-
if (!cancelled) setRetryKey(1);
|
|
577
|
-
}, 2e3);
|
|
578
|
-
} else {
|
|
579
|
-
setError("Failed to load store. Please try again.");
|
|
580
|
-
}
|
|
581
|
-
}
|
|
776
|
+
if (!cancelled) setError("Failed to load store. Please try again.");
|
|
582
777
|
} finally {
|
|
583
778
|
if (!cancelled) setLoading(false);
|
|
584
779
|
}
|
|
@@ -586,9 +781,8 @@ function StoreHomePage({
|
|
|
586
781
|
load();
|
|
587
782
|
return () => {
|
|
588
783
|
cancelled = true;
|
|
589
|
-
if (autoRetryTimer) clearTimeout(autoRetryTimer);
|
|
590
784
|
};
|
|
591
|
-
}, [client, compatibleWith
|
|
785
|
+
}, [client, compatibleWith]);
|
|
592
786
|
function navigate(path) {
|
|
593
787
|
if (onNavigate) {
|
|
594
788
|
onNavigate(path);
|
|
@@ -616,16 +810,65 @@ function StoreHomePage({
|
|
|
616
810
|
}
|
|
617
811
|
),
|
|
618
812
|
/* @__PURE__ */ jsxRuntime.jsxs("section", { className: "relative overflow-hidden pt-14 pb-12 sm:pt-20 sm:pb-16", children: [
|
|
619
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
813
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
814
|
+
"div",
|
|
815
|
+
{
|
|
816
|
+
className: "absolute inset-0 bg-gradient-to-b from-background via-primary/[0.06] to-background pointer-events-none",
|
|
817
|
+
"aria-hidden": "true"
|
|
818
|
+
}
|
|
819
|
+
),
|
|
820
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
821
|
+
"svg",
|
|
822
|
+
{
|
|
823
|
+
className: "absolute inset-0 w-full h-full opacity-[0.035] pointer-events-none",
|
|
824
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
825
|
+
"aria-hidden": "true",
|
|
826
|
+
children: [
|
|
827
|
+
/* @__PURE__ */ jsxRuntime.jsx("defs", { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
828
|
+
"pattern",
|
|
829
|
+
{
|
|
830
|
+
id: "store-home-grid",
|
|
831
|
+
width: "40",
|
|
832
|
+
height: "40",
|
|
833
|
+
patternUnits: "userSpaceOnUse",
|
|
834
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
835
|
+
"path",
|
|
836
|
+
{
|
|
837
|
+
d: "M 40 0 L 0 0 0 40",
|
|
838
|
+
fill: "none",
|
|
839
|
+
stroke: "currentColor",
|
|
840
|
+
strokeWidth: "1"
|
|
841
|
+
}
|
|
842
|
+
)
|
|
843
|
+
}
|
|
844
|
+
) }),
|
|
845
|
+
/* @__PURE__ */ jsxRuntime.jsx("rect", { width: "100%", height: "100%", fill: "url(#store-home-grid)" })
|
|
846
|
+
]
|
|
847
|
+
}
|
|
848
|
+
),
|
|
849
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
850
|
+
"div",
|
|
851
|
+
{
|
|
852
|
+
className: "absolute -top-16 left-1/3 w-80 h-80 rounded-full bg-primary/10 blur-3xl pointer-events-none",
|
|
853
|
+
"aria-hidden": "true"
|
|
854
|
+
}
|
|
855
|
+
),
|
|
856
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
857
|
+
"div",
|
|
858
|
+
{
|
|
859
|
+
className: "absolute top-8 right-1/4 w-56 h-56 rounded-full bg-primary/8 blur-2xl pointer-events-none",
|
|
860
|
+
"aria-hidden": "true"
|
|
861
|
+
}
|
|
862
|
+
),
|
|
626
863
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 text-center", children: [
|
|
627
864
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "inline-flex items-center gap-2 px-3 py-1 rounded-full border border-primary/30 bg-primary/10 text-xs font-semibold text-primary mb-5", children: [
|
|
628
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
865
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
866
|
+
"span",
|
|
867
|
+
{
|
|
868
|
+
className: "w-1.5 h-1.5 rounded-full bg-primary flex-shrink-0",
|
|
869
|
+
"aria-hidden": "true"
|
|
870
|
+
}
|
|
871
|
+
),
|
|
629
872
|
"Community Marketplace"
|
|
630
873
|
] }),
|
|
631
874
|
/* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-4xl sm:text-5xl md:text-6xl font-extrabold tracking-tight text-foreground mb-4 leading-[1.08]", children: resolvedTitle }),
|
|
@@ -637,7 +880,9 @@ function StoreHomePage({
|
|
|
637
880
|
onSubmit: (e) => {
|
|
638
881
|
e.preventDefault();
|
|
639
882
|
const q = new FormData(e.currentTarget).get("q");
|
|
640
|
-
navigate(
|
|
883
|
+
navigate(
|
|
884
|
+
q.trim() ? `${browsePath}?q=${encodeURIComponent(q.trim())}` : browsePath
|
|
885
|
+
);
|
|
641
886
|
},
|
|
642
887
|
children: [
|
|
643
888
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -679,9 +924,23 @@ function StoreHomePage({
|
|
|
679
924
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-4", children: [...Array(4)].map((_, i) => /* @__PURE__ */ jsxRuntime.jsx(GridCardSkeleton, {}, i)) })
|
|
680
925
|
] }) : error ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "py-16 text-center", children: [
|
|
681
926
|
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground mb-4", children: error }),
|
|
682
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
927
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
928
|
+
"button",
|
|
929
|
+
{
|
|
930
|
+
type: "button",
|
|
931
|
+
onClick: () => window.location.reload(),
|
|
932
|
+
className: "text-sm text-primary hover:underline",
|
|
933
|
+
children: "Retry"
|
|
934
|
+
}
|
|
935
|
+
)
|
|
683
936
|
] }) : featuredItems.length > 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 lg:grid-cols-[1fr_2fr] gap-4 items-start", children: [
|
|
684
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
937
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
938
|
+
FeaturedHeroCard,
|
|
939
|
+
{
|
|
940
|
+
product: featuredItems[0],
|
|
941
|
+
onNavigate: navigate
|
|
942
|
+
}
|
|
943
|
+
),
|
|
685
944
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-4", children: featuredItems.slice(1, 5).map((product) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
686
945
|
ProductCard,
|
|
687
946
|
{
|
|
@@ -702,7 +961,13 @@ function StoreHomePage({
|
|
|
702
961
|
onNavigate: navigate
|
|
703
962
|
}
|
|
704
963
|
),
|
|
705
|
-
loading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex gap-3 overflow-hidden", children: [...Array(5)].map((_, i) => /* @__PURE__ */ jsxRuntime.jsx(ScrollCardSkeleton, {}, i)) }) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
964
|
+
loading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex gap-3 overflow-hidden", children: [...Array(5)].map((_, i) => /* @__PURE__ */ jsxRuntime.jsx(ScrollCardSkeleton, {}, i)) }) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
965
|
+
ScrollRow,
|
|
966
|
+
{
|
|
967
|
+
products: popularItems,
|
|
968
|
+
onProductClick: handleProductClick
|
|
969
|
+
}
|
|
970
|
+
)
|
|
706
971
|
] }),
|
|
707
972
|
(loading || freeItems.length > 0) && /* @__PURE__ */ jsxRuntime.jsxs("section", { children: [
|
|
708
973
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -725,16 +990,35 @@ function StoreHomePage({
|
|
|
725
990
|
] })
|
|
726
991
|
] }),
|
|
727
992
|
/* @__PURE__ */ jsxRuntime.jsxs("section", { className: "relative overflow-hidden border-t border-border", children: [
|
|
728
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
729
|
-
|
|
993
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
994
|
+
"div",
|
|
995
|
+
{
|
|
996
|
+
className: "absolute inset-0 bg-gradient-to-br from-primary/8 via-background to-primary/5 pointer-events-none",
|
|
997
|
+
"aria-hidden": "true"
|
|
998
|
+
}
|
|
999
|
+
),
|
|
1000
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1001
|
+
"div",
|
|
1002
|
+
{
|
|
1003
|
+
className: "absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-80 h-40 rounded-full bg-primary/12 blur-3xl pointer-events-none",
|
|
1004
|
+
"aria-hidden": "true"
|
|
1005
|
+
}
|
|
1006
|
+
),
|
|
730
1007
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative max-w-2xl mx-auto px-4 py-16 text-center", children: [
|
|
731
1008
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "inline-flex items-center gap-2 px-3 py-1 rounded-full border border-primary/30 bg-primary/10 text-xs font-semibold text-primary mb-5", children: [
|
|
732
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1009
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1010
|
+
"span",
|
|
1011
|
+
{
|
|
1012
|
+
className: "w-1.5 h-1.5 rounded-full bg-primary flex-shrink-0",
|
|
1013
|
+
"aria-hidden": "true"
|
|
1014
|
+
}
|
|
1015
|
+
),
|
|
733
1016
|
"Become a publisher"
|
|
734
1017
|
] }),
|
|
735
1018
|
/* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-2xl sm:text-3xl font-bold text-foreground mb-3", children: "Built something useful?" }),
|
|
736
1019
|
/* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-muted-foreground mb-8 max-w-lg mx-auto leading-relaxed", children: [
|
|
737
|
-
"Share your workflows, nodes, and integrations with
|
|
1020
|
+
"Share your workflows, nodes, and integrations with",
|
|
1021
|
+
" ",
|
|
738
1022
|
productName ?? "the",
|
|
739
1023
|
" community. Earn from your work or contribute for free."
|
|
740
1024
|
] }),
|
|
@@ -790,7 +1074,14 @@ var PRICING_OPTIONS = [
|
|
|
790
1074
|
];
|
|
791
1075
|
function parseUrlParams() {
|
|
792
1076
|
if (typeof window === "undefined")
|
|
793
|
-
return {
|
|
1077
|
+
return {
|
|
1078
|
+
q: "",
|
|
1079
|
+
type: "",
|
|
1080
|
+
pricingModel: "",
|
|
1081
|
+
category: "",
|
|
1082
|
+
sortBy: "RELEVANCE",
|
|
1083
|
+
featured: false
|
|
1084
|
+
};
|
|
794
1085
|
const p = new URLSearchParams(window.location.search);
|
|
795
1086
|
return {
|
|
796
1087
|
q: p.get("q") ?? "",
|
|
@@ -842,7 +1133,9 @@ function StoreBrowsePage({
|
|
|
842
1133
|
const [featured, setFeatured] = react.useState(initial.featured);
|
|
843
1134
|
const [offset, setOffset] = react.useState(0);
|
|
844
1135
|
const [result, setResult] = react.useState(null);
|
|
845
|
-
const [allProducts, setAllProducts] = react.useState(
|
|
1136
|
+
const [allProducts, setAllProducts] = react.useState(
|
|
1137
|
+
[]
|
|
1138
|
+
);
|
|
846
1139
|
const [categories, setCategories] = react.useState([]);
|
|
847
1140
|
const [loading, setLoading] = react.useState(true);
|
|
848
1141
|
const [loadingMore, setLoadingMore] = react.useState(false);
|
|
@@ -886,7 +1179,16 @@ function StoreBrowsePage({
|
|
|
886
1179
|
return () => {
|
|
887
1180
|
cancelled = true;
|
|
888
1181
|
};
|
|
889
|
-
}, [
|
|
1182
|
+
}, [
|
|
1183
|
+
client,
|
|
1184
|
+
search,
|
|
1185
|
+
type,
|
|
1186
|
+
pricingModel,
|
|
1187
|
+
category,
|
|
1188
|
+
sortBy,
|
|
1189
|
+
compatibleWith,
|
|
1190
|
+
featured
|
|
1191
|
+
]);
|
|
890
1192
|
function loadMore() {
|
|
891
1193
|
const nextOffset = offset + PAGE_SIZE;
|
|
892
1194
|
setLoadingMore(true);
|
|
@@ -1062,7 +1364,8 @@ function StoreBrowsePage({
|
|
|
1062
1364
|
onClick: () => setFiltersOpen(!filtersOpen),
|
|
1063
1365
|
className: "lg:hidden h-10 px-4 rounded-lg border border-border bg-background text-sm text-foreground hover:bg-muted/50 transition-colors",
|
|
1064
1366
|
children: [
|
|
1065
|
-
"Filters
|
|
1367
|
+
"Filters",
|
|
1368
|
+
" ",
|
|
1066
1369
|
hasActiveFilters && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-primary", children: "\u2022" })
|
|
1067
1370
|
]
|
|
1068
1371
|
}
|
|
@@ -1076,14 +1379,32 @@ function StoreBrowsePage({
|
|
|
1076
1379
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 mb-4 flex-wrap", children: [
|
|
1077
1380
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-muted-foreground", children: loading ? "Loading\u2026" : `${result?.totalCount ?? 0} results` }),
|
|
1078
1381
|
hasActiveFilters && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap gap-1.5", children: [
|
|
1079
|
-
search && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1382
|
+
search && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1383
|
+
Chip,
|
|
1384
|
+
{
|
|
1385
|
+
label: `"${search}"`,
|
|
1386
|
+
onRemove: () => {
|
|
1387
|
+
setSearch("");
|
|
1388
|
+
setInputValue("");
|
|
1389
|
+
}
|
|
1390
|
+
}
|
|
1391
|
+
),
|
|
1083
1392
|
type && /* @__PURE__ */ jsxRuntime.jsx(Chip, { label: type, onRemove: () => setType("") }),
|
|
1084
|
-
pricingModel && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1393
|
+
pricingModel && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1394
|
+
Chip,
|
|
1395
|
+
{
|
|
1396
|
+
label: pricingModel,
|
|
1397
|
+
onRemove: () => setPricingModel("")
|
|
1398
|
+
}
|
|
1399
|
+
),
|
|
1085
1400
|
category && /* @__PURE__ */ jsxRuntime.jsx(Chip, { label: category, onRemove: () => setCategory("") }),
|
|
1086
|
-
featured && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1401
|
+
featured && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1402
|
+
Chip,
|
|
1403
|
+
{
|
|
1404
|
+
label: "Featured",
|
|
1405
|
+
onRemove: () => setFeatured(false)
|
|
1406
|
+
}
|
|
1407
|
+
)
|
|
1087
1408
|
] })
|
|
1088
1409
|
] }),
|
|
1089
1410
|
loading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-1 sm:grid-cols-2 xl:grid-cols-3 gap-4", children: [...Array(12)].map((_, i) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -1135,9 +1456,97 @@ function StoreBrowsePage({
|
|
|
1135
1456
|
function Chip({ label, onRemove }) {
|
|
1136
1457
|
return /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center gap-1 text-xs bg-primary/10 text-primary rounded-full px-2.5 py-0.5 font-medium", children: [
|
|
1137
1458
|
label,
|
|
1138
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1459
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1460
|
+
"button",
|
|
1461
|
+
{
|
|
1462
|
+
type: "button",
|
|
1463
|
+
onClick: onRemove,
|
|
1464
|
+
"aria-label": `Remove ${label}`,
|
|
1465
|
+
className: "hover:opacity-70",
|
|
1466
|
+
children: "\xD7"
|
|
1467
|
+
}
|
|
1468
|
+
)
|
|
1139
1469
|
] });
|
|
1140
1470
|
}
|
|
1471
|
+
function detectTheme() {
|
|
1472
|
+
if (typeof document === "undefined") return "light";
|
|
1473
|
+
const root = document.documentElement;
|
|
1474
|
+
return root.classList.contains("dark") || root.getAttribute("data-theme") === "dark" ? "dark" : "light";
|
|
1475
|
+
}
|
|
1476
|
+
function WorkflowEmbed({
|
|
1477
|
+
appUrl,
|
|
1478
|
+
productId,
|
|
1479
|
+
theme,
|
|
1480
|
+
clickToInteract = true,
|
|
1481
|
+
hideCta = false,
|
|
1482
|
+
className,
|
|
1483
|
+
onError
|
|
1484
|
+
}) {
|
|
1485
|
+
const iframeRef = react.useRef(null);
|
|
1486
|
+
const [status, setStatus] = react.useState("loading");
|
|
1487
|
+
const [interactive, setInteractive] = react.useState(!clickToInteract);
|
|
1488
|
+
const resolvedTheme = react.useMemo(() => theme ?? detectTheme(), [theme]);
|
|
1489
|
+
const src = react.useMemo(() => {
|
|
1490
|
+
const base = appUrl.replace(/\/+$/, "");
|
|
1491
|
+
const params = new URLSearchParams({
|
|
1492
|
+
productId,
|
|
1493
|
+
theme: resolvedTheme
|
|
1494
|
+
});
|
|
1495
|
+
if (hideCta) params.set("cta", "false");
|
|
1496
|
+
return `${base}/embed/workflow?${params.toString()}`;
|
|
1497
|
+
}, [appUrl, productId, resolvedTheme, hideCta]);
|
|
1498
|
+
react.useEffect(() => {
|
|
1499
|
+
const handler = (event) => {
|
|
1500
|
+
if (event.source !== iframeRef.current?.contentWindow) return;
|
|
1501
|
+
const data = event.data;
|
|
1502
|
+
if (data?.type === "fluidgrids:embed:loaded") setStatus("loaded");
|
|
1503
|
+
if (data?.type === "fluidgrids:embed:error") {
|
|
1504
|
+
setStatus("error");
|
|
1505
|
+
onError?.(data.message ?? "Failed to load workflow preview");
|
|
1506
|
+
}
|
|
1507
|
+
};
|
|
1508
|
+
window.addEventListener("message", handler);
|
|
1509
|
+
return () => window.removeEventListener("message", handler);
|
|
1510
|
+
}, [onError]);
|
|
1511
|
+
if (status === "error") return null;
|
|
1512
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1513
|
+
"div",
|
|
1514
|
+
{
|
|
1515
|
+
className: `relative w-full overflow-hidden rounded-xl border border-border bg-muted ${className ?? ""}`,
|
|
1516
|
+
style: { aspectRatio: "16 / 9" },
|
|
1517
|
+
children: [
|
|
1518
|
+
status === "loading" && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1519
|
+
"div",
|
|
1520
|
+
{
|
|
1521
|
+
className: "absolute inset-0 animate-pulse bg-muted",
|
|
1522
|
+
"aria-hidden": "true"
|
|
1523
|
+
}
|
|
1524
|
+
),
|
|
1525
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1526
|
+
"iframe",
|
|
1527
|
+
{
|
|
1528
|
+
ref: iframeRef,
|
|
1529
|
+
src,
|
|
1530
|
+
title: "Workflow preview",
|
|
1531
|
+
loading: "lazy",
|
|
1532
|
+
className: "h-full w-full border-0",
|
|
1533
|
+
style: interactive ? void 0 : { pointerEvents: "none" }
|
|
1534
|
+
}
|
|
1535
|
+
),
|
|
1536
|
+
clickToInteract && !interactive && status === "loaded" && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1537
|
+
"button",
|
|
1538
|
+
{
|
|
1539
|
+
type: "button",
|
|
1540
|
+
onClick: () => setInteractive(true),
|
|
1541
|
+
className: "absolute inset-0 flex items-end justify-center bg-transparent pb-4",
|
|
1542
|
+
"aria-label": "Click to explore the workflow",
|
|
1543
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "rounded-full border border-border bg-background/90 px-4 py-1.5 text-xs font-medium text-foreground shadow-sm backdrop-blur transition-colors hover:bg-background", children: "Click to explore" })
|
|
1544
|
+
}
|
|
1545
|
+
)
|
|
1546
|
+
]
|
|
1547
|
+
}
|
|
1548
|
+
);
|
|
1549
|
+
}
|
|
1141
1550
|
var ANIM_STYLES = `
|
|
1142
1551
|
@keyframes sdFadeUp {
|
|
1143
1552
|
from { opacity: 0; transform: translateY(16px); }
|
|
@@ -1170,50 +1579,11 @@ var ANIM_STYLES = `
|
|
|
1170
1579
|
.sd-d5 { animation-delay: 320ms; }
|
|
1171
1580
|
.sd-d6 { animation-delay: 400ms; }
|
|
1172
1581
|
`;
|
|
1173
|
-
function
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
) });
|
|
1179
|
-
}
|
|
1180
|
-
function MdAbout({ content }) {
|
|
1181
|
-
let key = 0;
|
|
1182
|
-
const nodes = [];
|
|
1183
|
-
let listItems = [];
|
|
1184
|
-
const flushList = () => {
|
|
1185
|
-
if (!listItems.length) return;
|
|
1186
|
-
nodes.push(
|
|
1187
|
-
/* @__PURE__ */ jsxRuntime.jsx("ul", { className: "list-disc list-inside space-y-0.5 my-2", children: listItems.map((item, i) => /* @__PURE__ */ jsxRuntime.jsx("li", { className: "text-sm leading-relaxed", children: mdInline(item) }, i)) }, key++)
|
|
1188
|
-
);
|
|
1189
|
-
listItems = [];
|
|
1190
|
-
};
|
|
1191
|
-
for (const line of content.split("\n")) {
|
|
1192
|
-
if (!line.trim()) {
|
|
1193
|
-
flushList();
|
|
1194
|
-
continue;
|
|
1195
|
-
}
|
|
1196
|
-
const hm = line.match(/^(#{1,3})\s+(.*)/);
|
|
1197
|
-
if (hm) {
|
|
1198
|
-
flushList();
|
|
1199
|
-
nodes.push(
|
|
1200
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-semibold text-foreground mt-4 first:mt-0 text-sm", children: mdInline(hm[2]) }, key++)
|
|
1201
|
-
);
|
|
1202
|
-
continue;
|
|
1203
|
-
}
|
|
1204
|
-
if (/^[-*]\s/.test(line)) {
|
|
1205
|
-
listItems.push(line.replace(/^[-*]\s+/, ""));
|
|
1206
|
-
continue;
|
|
1207
|
-
}
|
|
1208
|
-
flushList();
|
|
1209
|
-
nodes.push(
|
|
1210
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm leading-relaxed mb-1", children: mdInline(line) }, key++)
|
|
1211
|
-
);
|
|
1212
|
-
}
|
|
1213
|
-
flushList();
|
|
1214
|
-
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: nodes });
|
|
1215
|
-
}
|
|
1216
|
-
function RatingBar({ label, count, total }) {
|
|
1582
|
+
function RatingBar({
|
|
1583
|
+
label,
|
|
1584
|
+
count,
|
|
1585
|
+
total
|
|
1586
|
+
}) {
|
|
1217
1587
|
const pct = total > 0 ? Math.round(count / total * 100) : 0;
|
|
1218
1588
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 text-xs text-muted-foreground", children: [
|
|
1219
1589
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "w-12 text-right shrink-0", children: label }),
|
|
@@ -1229,12 +1599,63 @@ function RatingBar({ label, count, total }) {
|
|
|
1229
1599
|
}
|
|
1230
1600
|
function IconBlock({ src }) {
|
|
1231
1601
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex-shrink-0", children: [
|
|
1232
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1602
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1603
|
+
"div",
|
|
1604
|
+
{
|
|
1605
|
+
className: "sd-gp absolute -inset-1.5 rounded-2xl bg-primary/30 blur-md pointer-events-none",
|
|
1606
|
+
"aria-hidden": "true"
|
|
1607
|
+
}
|
|
1608
|
+
),
|
|
1609
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "sd-si relative w-20 h-20 rounded-2xl overflow-hidden shadow-lg ring-1 ring-border", children: src ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
1610
|
+
"img",
|
|
1611
|
+
{
|
|
1612
|
+
src,
|
|
1613
|
+
alt: "",
|
|
1614
|
+
"aria-hidden": true,
|
|
1615
|
+
className: "w-full h-full object-cover"
|
|
1616
|
+
}
|
|
1617
|
+
) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-full bg-gradient-to-br from-primary/25 to-primary/8 flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1618
|
+
"svg",
|
|
1619
|
+
{
|
|
1620
|
+
viewBox: "0 0 40 40",
|
|
1621
|
+
className: "w-10 h-10",
|
|
1622
|
+
fill: "none",
|
|
1623
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
1624
|
+
"aria-hidden": "true",
|
|
1625
|
+
children: [
|
|
1626
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1627
|
+
"polygon",
|
|
1628
|
+
{
|
|
1629
|
+
points: "20,4 34,11 20,18 6,11",
|
|
1630
|
+
className: "fill-primary/40",
|
|
1631
|
+
stroke: "currentColor",
|
|
1632
|
+
strokeWidth: "0.6",
|
|
1633
|
+
strokeOpacity: "0.4"
|
|
1634
|
+
}
|
|
1635
|
+
),
|
|
1636
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1637
|
+
"polygon",
|
|
1638
|
+
{
|
|
1639
|
+
points: "6,11 20,18 20,34 6,27",
|
|
1640
|
+
className: "fill-primary/20",
|
|
1641
|
+
stroke: "currentColor",
|
|
1642
|
+
strokeWidth: "0.6",
|
|
1643
|
+
strokeOpacity: "0.4"
|
|
1644
|
+
}
|
|
1645
|
+
),
|
|
1646
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1647
|
+
"polygon",
|
|
1648
|
+
{
|
|
1649
|
+
points: "34,11 20,18 20,34 34,27",
|
|
1650
|
+
className: "fill-primary/30",
|
|
1651
|
+
stroke: "currentColor",
|
|
1652
|
+
strokeWidth: "0.6",
|
|
1653
|
+
strokeOpacity: "0.4"
|
|
1654
|
+
}
|
|
1655
|
+
)
|
|
1656
|
+
]
|
|
1657
|
+
}
|
|
1658
|
+
) }) })
|
|
1238
1659
|
] });
|
|
1239
1660
|
}
|
|
1240
1661
|
function StoreProductDetailPage({
|
|
@@ -1250,6 +1671,7 @@ function StoreProductDetailPage({
|
|
|
1250
1671
|
const [error, setError] = react.useState(null);
|
|
1251
1672
|
const [activeScreenshot, setActiveScreenshot] = react.useState(0);
|
|
1252
1673
|
const [screenshotKey, setScreenshotKey] = react.useState(0);
|
|
1674
|
+
const [embedFailed, setEmbedFailed] = react.useState(false);
|
|
1253
1675
|
react.useEffect(() => {
|
|
1254
1676
|
if (!slug && !id) {
|
|
1255
1677
|
setError("Product not found.");
|
|
@@ -1303,11 +1725,30 @@ function StoreProductDetailPage({
|
|
|
1303
1725
|
if (error || !details) {
|
|
1304
1726
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-20 text-center", children: [
|
|
1305
1727
|
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground mb-4", children: error ?? "Product not found." }),
|
|
1306
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1728
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1729
|
+
"button",
|
|
1730
|
+
{
|
|
1731
|
+
type: "button",
|
|
1732
|
+
onClick: () => navigate("/store"),
|
|
1733
|
+
className: "text-sm text-primary hover:underline",
|
|
1734
|
+
children: "Back to Store"
|
|
1735
|
+
}
|
|
1736
|
+
)
|
|
1307
1737
|
] });
|
|
1308
1738
|
}
|
|
1309
|
-
const {
|
|
1310
|
-
|
|
1739
|
+
const {
|
|
1740
|
+
product,
|
|
1741
|
+
publisher,
|
|
1742
|
+
reviews,
|
|
1743
|
+
reviewsCount,
|
|
1744
|
+
relatedProducts,
|
|
1745
|
+
ratingDistribution
|
|
1746
|
+
} = details;
|
|
1747
|
+
const priceLabel = formatPrice(
|
|
1748
|
+
product.price,
|
|
1749
|
+
product.currency,
|
|
1750
|
+
product.pricingModel
|
|
1751
|
+
);
|
|
1311
1752
|
const screenshots = product.screenshots ?? [];
|
|
1312
1753
|
const totalRatings = ratingDistribution ? ratingDistribution.fiveStars + ratingDistribution.fourStars + ratingDistribution.threeStars + ratingDistribution.twoStars + ratingDistribution.oneStar : 0;
|
|
1313
1754
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full", children: [
|
|
@@ -1321,15 +1762,60 @@ function StoreProductDetailPage({
|
|
|
1321
1762
|
}
|
|
1322
1763
|
),
|
|
1323
1764
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative overflow-hidden", children: [
|
|
1324
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1765
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1766
|
+
"div",
|
|
1767
|
+
{
|
|
1768
|
+
className: "absolute inset-0 bg-gradient-to-b from-primary/[0.07] via-background to-background pointer-events-none",
|
|
1769
|
+
"aria-hidden": "true"
|
|
1770
|
+
}
|
|
1771
|
+
),
|
|
1772
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
1773
|
+
"svg",
|
|
1774
|
+
{
|
|
1775
|
+
className: "absolute inset-0 w-full h-full opacity-[0.04] pointer-events-none",
|
|
1776
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
1777
|
+
"aria-hidden": "true",
|
|
1778
|
+
children: [
|
|
1779
|
+
/* @__PURE__ */ jsxRuntime.jsx("defs", { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1780
|
+
"pattern",
|
|
1781
|
+
{
|
|
1782
|
+
id: "sd-grid",
|
|
1783
|
+
width: "40",
|
|
1784
|
+
height: "40",
|
|
1785
|
+
patternUnits: "userSpaceOnUse",
|
|
1786
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1787
|
+
"path",
|
|
1788
|
+
{
|
|
1789
|
+
d: "M 40 0 L 0 0 0 40",
|
|
1790
|
+
fill: "none",
|
|
1791
|
+
stroke: "currentColor",
|
|
1792
|
+
strokeWidth: "1"
|
|
1793
|
+
}
|
|
1794
|
+
)
|
|
1795
|
+
}
|
|
1796
|
+
) }),
|
|
1797
|
+
/* @__PURE__ */ jsxRuntime.jsx("rect", { width: "100%", height: "100%", fill: "url(#sd-grid)" })
|
|
1798
|
+
]
|
|
1799
|
+
}
|
|
1800
|
+
),
|
|
1801
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1802
|
+
"div",
|
|
1803
|
+
{
|
|
1804
|
+
className: "absolute -top-12 -left-12 w-72 h-72 rounded-full bg-primary/10 blur-3xl pointer-events-none",
|
|
1805
|
+
"aria-hidden": "true"
|
|
1806
|
+
}
|
|
1807
|
+
),
|
|
1330
1808
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 pt-6 pb-8", children: [
|
|
1331
1809
|
/* @__PURE__ */ jsxRuntime.jsxs("nav", { className: "sd-fi text-sm text-muted-foreground mb-6 flex items-center gap-1.5 flex-wrap", children: [
|
|
1332
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1810
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1811
|
+
"button",
|
|
1812
|
+
{
|
|
1813
|
+
type: "button",
|
|
1814
|
+
onClick: () => navigate("/store"),
|
|
1815
|
+
className: "hover:text-primary transition-colors",
|
|
1816
|
+
children: "Store"
|
|
1817
|
+
}
|
|
1818
|
+
),
|
|
1333
1819
|
/* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", children: "\u203A" }),
|
|
1334
1820
|
product.category && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
1335
1821
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -1395,6 +1881,14 @@ function StoreProductDetailPage({
|
|
|
1395
1881
|
}
|
|
1396
1882
|
)
|
|
1397
1883
|
] }),
|
|
1884
|
+
product.type === "WORKFLOW" && !embedFailed && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "sd-fu sd-d3 mb-8", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1885
|
+
WorkflowEmbed,
|
|
1886
|
+
{
|
|
1887
|
+
appUrl: appLoginUrl,
|
|
1888
|
+
productId: product.id,
|
|
1889
|
+
onError: () => setEmbedFailed(true)
|
|
1890
|
+
}
|
|
1891
|
+
) }),
|
|
1398
1892
|
screenshots.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "sd-fu sd-d3 mb-8", children: [
|
|
1399
1893
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-xl overflow-hidden bg-muted aspect-video mb-3 shadow-md", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1400
1894
|
"img",
|
|
@@ -1411,19 +1905,33 @@ function StoreProductDetailPage({
|
|
|
1411
1905
|
type: "button",
|
|
1412
1906
|
onClick: () => switchScreenshot(i),
|
|
1413
1907
|
className: `w-20 h-14 rounded-lg overflow-hidden flex-shrink-0 border-2 transition-all duration-200 ${i === activeScreenshot ? "border-primary shadow-sm shadow-primary/20" : "border-transparent opacity-50 hover:opacity-80"}`,
|
|
1414
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1908
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1909
|
+
"img",
|
|
1910
|
+
{
|
|
1911
|
+
src,
|
|
1912
|
+
alt: `Thumbnail ${i + 1}`,
|
|
1913
|
+
className: "w-full h-full object-cover"
|
|
1914
|
+
}
|
|
1915
|
+
)
|
|
1415
1916
|
},
|
|
1416
1917
|
i
|
|
1417
1918
|
)) })
|
|
1418
1919
|
] }),
|
|
1419
1920
|
product.longDescription && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "sd-fu sd-d4 mb-8", children: [
|
|
1420
1921
|
/* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-lg font-bold text-foreground mb-3", children: "About" }),
|
|
1421
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-muted-foreground", children:
|
|
1922
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "prose prose-sm max-w-none text-muted-foreground leading-relaxed whitespace-pre-line", children: product.longDescription })
|
|
1422
1923
|
] }),
|
|
1423
1924
|
publisher && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "sd-fu sd-d5 mb-8 p-4 rounded-xl border border-border bg-card hover:border-primary/30 transition-colors duration-300", children: [
|
|
1424
1925
|
/* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-sm font-semibold text-foreground mb-3", children: "Publisher" }),
|
|
1425
1926
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
|
|
1426
|
-
publisher.logoUrl ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
1927
|
+
publisher.logoUrl ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
1928
|
+
"img",
|
|
1929
|
+
{
|
|
1930
|
+
src: publisher.logoUrl,
|
|
1931
|
+
alt: publisher.name,
|
|
1932
|
+
className: "w-10 h-10 rounded-full object-cover"
|
|
1933
|
+
}
|
|
1934
|
+
) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-10 h-10 rounded-full bg-primary/10 flex items-center justify-center text-primary text-sm font-bold", children: publisher.name.charAt(0).toUpperCase() }),
|
|
1427
1935
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1428
1936
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
|
|
1429
1937
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-semibold text-foreground text-sm", children: publisher.name }),
|
|
@@ -1449,11 +1957,46 @@ function StoreProductDetailPage({
|
|
|
1449
1957
|
] })
|
|
1450
1958
|
] }),
|
|
1451
1959
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 space-y-1.5 pt-1", children: [
|
|
1452
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1960
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1961
|
+
RatingBar,
|
|
1962
|
+
{
|
|
1963
|
+
label: "5 \u2605",
|
|
1964
|
+
count: ratingDistribution.fiveStars,
|
|
1965
|
+
total: totalRatings
|
|
1966
|
+
}
|
|
1967
|
+
),
|
|
1968
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1969
|
+
RatingBar,
|
|
1970
|
+
{
|
|
1971
|
+
label: "4 \u2605",
|
|
1972
|
+
count: ratingDistribution.fourStars,
|
|
1973
|
+
total: totalRatings
|
|
1974
|
+
}
|
|
1975
|
+
),
|
|
1976
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1977
|
+
RatingBar,
|
|
1978
|
+
{
|
|
1979
|
+
label: "3 \u2605",
|
|
1980
|
+
count: ratingDistribution.threeStars,
|
|
1981
|
+
total: totalRatings
|
|
1982
|
+
}
|
|
1983
|
+
),
|
|
1984
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1985
|
+
RatingBar,
|
|
1986
|
+
{
|
|
1987
|
+
label: "2 \u2605",
|
|
1988
|
+
count: ratingDistribution.twoStars,
|
|
1989
|
+
total: totalRatings
|
|
1990
|
+
}
|
|
1991
|
+
),
|
|
1992
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1993
|
+
RatingBar,
|
|
1994
|
+
{
|
|
1995
|
+
label: "1 \u2605",
|
|
1996
|
+
count: ratingDistribution.oneStar,
|
|
1997
|
+
total: totalRatings
|
|
1998
|
+
}
|
|
1999
|
+
)
|
|
1457
2000
|
] })
|
|
1458
2001
|
] }),
|
|
1459
2002
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-3", children: reviews.slice(0, 5).map((review, idx) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -1468,11 +2011,14 @@ function StoreProductDetailPage({
|
|
|
1468
2011
|
] }),
|
|
1469
2012
|
review.title && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-semibold text-sm text-foreground mb-1", children: review.title }),
|
|
1470
2013
|
review.comment && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground leading-relaxed", children: review.comment }),
|
|
1471
|
-
review.createdAt && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground mt-2", children: new Date(review.createdAt).toLocaleDateString(
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
2014
|
+
review.createdAt && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground mt-2", children: new Date(review.createdAt).toLocaleDateString(
|
|
2015
|
+
"en-US",
|
|
2016
|
+
{
|
|
2017
|
+
year: "numeric",
|
|
2018
|
+
month: "short",
|
|
2019
|
+
day: "numeric"
|
|
2020
|
+
}
|
|
2021
|
+
) })
|
|
1476
2022
|
]
|
|
1477
2023
|
},
|
|
1478
2024
|
review.id
|
|
@@ -1492,7 +2038,13 @@ function StoreProductDetailPage({
|
|
|
1492
2038
|
] }),
|
|
1493
2039
|
/* @__PURE__ */ jsxRuntime.jsx("aside", { className: "lg:sticky lg:top-24 self-start", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "sd-fu sd-d4 bg-card border border-border rounded-xl p-5 space-y-4 hover:border-primary/30 transition-colors duration-300 hover:shadow-lg hover:shadow-primary/5", children: [
|
|
1494
2040
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1495
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2041
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2042
|
+
"div",
|
|
2043
|
+
{
|
|
2044
|
+
className: `text-3xl font-extrabold ${priceLabel === "Free" ? "text-emerald-500" : "text-foreground"}`,
|
|
2045
|
+
children: priceLabel
|
|
2046
|
+
}
|
|
2047
|
+
),
|
|
1496
2048
|
product.pricingModel === "SUBSCRIPTION" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs text-muted-foreground", children: "per month" })
|
|
1497
2049
|
] }),
|
|
1498
2050
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -1551,6 +2103,7 @@ exports.StoreBrowsePage = StoreBrowsePage;
|
|
|
1551
2103
|
exports.StoreHomePage = StoreHomePage;
|
|
1552
2104
|
exports.StoreProductDetailPage = StoreProductDetailPage;
|
|
1553
2105
|
exports.TypeBadge = TypeBadge;
|
|
2106
|
+
exports.WorkflowEmbed = WorkflowEmbed;
|
|
1554
2107
|
exports.formatDownloads = formatDownloads;
|
|
1555
2108
|
exports.formatPrice = formatPrice;
|
|
1556
2109
|
//# sourceMappingURL=index.js.map
|