@neowhale/storefront 0.2.7 → 0.2.8
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/react/index.cjs +235 -67
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +0 -13
- package/dist/react/index.d.ts +0 -13
- package/dist/react/index.js +235 -67
- package/dist/react/index.js.map +1 -1
- package/package.json +1 -1
package/dist/react/index.d.cts
CHANGED
|
@@ -381,19 +381,6 @@ interface QRLandingPageProps {
|
|
|
381
381
|
/** Called on error */
|
|
382
382
|
onError?: (error: Error) => void;
|
|
383
383
|
}
|
|
384
|
-
/**
|
|
385
|
-
* QR Landing Page — drop-in component that renders a branded landing page
|
|
386
|
-
* for any QR code. Fetches data from the gateway's public endpoint.
|
|
387
|
-
*
|
|
388
|
-
* Usage:
|
|
389
|
-
* ```tsx
|
|
390
|
-
* // In app/qr/[code]/page.tsx:
|
|
391
|
-
* import { QRLandingPage } from '@neowhale/storefront/react'
|
|
392
|
-
* export default function Page({ params }: { params: { code: string } }) {
|
|
393
|
-
* return <QRLandingPage code={params.code} />
|
|
394
|
-
* }
|
|
395
|
-
* ```
|
|
396
|
-
*/
|
|
397
384
|
declare function QRLandingPage({ code, gatewayUrl, renderProduct, renderCOA, renderPage, onDataLoaded, onError, }: QRLandingPageProps): react_jsx_runtime.JSX.Element | null;
|
|
398
385
|
|
|
399
386
|
interface LandingPageProps {
|
package/dist/react/index.d.ts
CHANGED
|
@@ -381,19 +381,6 @@ interface QRLandingPageProps {
|
|
|
381
381
|
/** Called on error */
|
|
382
382
|
onError?: (error: Error) => void;
|
|
383
383
|
}
|
|
384
|
-
/**
|
|
385
|
-
* QR Landing Page — drop-in component that renders a branded landing page
|
|
386
|
-
* for any QR code. Fetches data from the gateway's public endpoint.
|
|
387
|
-
*
|
|
388
|
-
* Usage:
|
|
389
|
-
* ```tsx
|
|
390
|
-
* // In app/qr/[code]/page.tsx:
|
|
391
|
-
* import { QRLandingPage } from '@neowhale/storefront/react'
|
|
392
|
-
* export default function Page({ params }: { params: { code: string } }) {
|
|
393
|
-
* return <QRLandingPage code={params.code} />
|
|
394
|
-
* }
|
|
395
|
-
* ```
|
|
396
|
-
*/
|
|
397
384
|
declare function QRLandingPage({ code, gatewayUrl, renderProduct, renderCOA, renderPage, onDataLoaded, onError, }: QRLandingPageProps): react_jsx_runtime.JSX.Element | null;
|
|
398
385
|
|
|
399
386
|
interface LandingPageProps {
|
package/dist/react/index.js
CHANGED
|
@@ -1275,69 +1275,171 @@ function DefaultLayout({
|
|
|
1275
1275
|
const bg = lp.background_color || store?.theme?.background || "#050505";
|
|
1276
1276
|
const fg = lp.text_color || store?.theme?.foreground || "#fafafa";
|
|
1277
1277
|
const accent = store?.theme?.accent || qr.brand_color || "#E8E2D9";
|
|
1278
|
-
const surface = store?.theme?.surface || "#
|
|
1278
|
+
const surface = store?.theme?.surface || "#0C0C0C";
|
|
1279
|
+
const surfaceLight = store?.theme?.surfaceLight || "#141414";
|
|
1279
1280
|
const muted = store?.theme?.muted || "#888";
|
|
1281
|
+
const border = store?.theme?.border || "#1C1C1C";
|
|
1282
|
+
const fontDisplay = store?.theme?.fontDisplay || "system-ui, -apple-system, sans-serif";
|
|
1283
|
+
const fontBody = store?.theme?.fontBody || "system-ui, -apple-system, sans-serif";
|
|
1280
1284
|
const logoUrl = qr.logo_url || store?.logo_url;
|
|
1281
|
-
const productImage = lp.image_url || product?.featured_image ||
|
|
1285
|
+
const productImage = lp.image_url || product?.featured_image || null;
|
|
1282
1286
|
const productName = lp.title || product?.name || qr.name;
|
|
1283
1287
|
const description = lp.description || product?.description || "";
|
|
1284
|
-
const ctaText = lp.cta_text || (coa ? "View Lab Results" : "Learn More");
|
|
1285
1288
|
const ctaUrl = lp.cta_url || qr.destination_url;
|
|
1289
|
+
const categoryName = product?.category_name ?? null;
|
|
1286
1290
|
const cf = product?.custom_fields;
|
|
1287
1291
|
const thca = cf?.thca_percentage ?? null;
|
|
1288
1292
|
const thc = cf?.d9_percentage ?? null;
|
|
1289
1293
|
const cbd = cf?.cbd_total ?? null;
|
|
1290
1294
|
const strainType = cf?.strain_type ?? null;
|
|
1291
|
-
const
|
|
1295
|
+
const batchNumber = cf?.batch_number ?? null;
|
|
1296
|
+
const dateTested = cf?.date_tested ?? null;
|
|
1297
|
+
const terpenes = cf?.terpenes ?? null;
|
|
1298
|
+
const effects = cf?.effects ?? null;
|
|
1299
|
+
const genetics = cf?.genetics ?? null;
|
|
1300
|
+
const tagline = cf?.tagline ?? null;
|
|
1301
|
+
const pricingData = product?.pricing_data;
|
|
1302
|
+
const tiers = pricingData?.tiers?.sort((a, b) => (a.sort_order ?? 0) - (b.sort_order ?? 0)) ?? [];
|
|
1303
|
+
const lowestPrice = tiers.length > 0 ? Math.min(...tiers.map((t) => t.default_price)) : null;
|
|
1292
1304
|
const handleCOAClick = useCallback(() => {
|
|
1293
1305
|
if (coa) setShowCOA(true);
|
|
1294
1306
|
}, [coa]);
|
|
1295
|
-
return /* @__PURE__ */ jsxs("div", { style: { minHeight: "100dvh", background: bg, color: fg, fontFamily:
|
|
1296
|
-
/* @__PURE__ */
|
|
1297
|
-
"
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
/* @__PURE__ */
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1307
|
+
return /* @__PURE__ */ jsxs("div", { style: { minHeight: "100dvh", background: bg, color: fg, fontFamily: fontBody }, children: [
|
|
1308
|
+
/* @__PURE__ */ jsxs("header", { style: {
|
|
1309
|
+
padding: "1rem 1.5rem",
|
|
1310
|
+
display: "flex",
|
|
1311
|
+
alignItems: "center",
|
|
1312
|
+
justifyContent: "space-between",
|
|
1313
|
+
borderBottom: `1px solid ${border}`
|
|
1314
|
+
}, children: [
|
|
1315
|
+
logoUrl ? /* @__PURE__ */ jsx("img", { src: logoUrl, alt: store?.name || "Store", style: { height: 32, objectFit: "contain" } }) : /* @__PURE__ */ jsx("span", { style: { fontFamily: fontDisplay, fontWeight: 600, fontSize: "1.1rem" }, children: store?.name || "" }),
|
|
1316
|
+
store?.name && logoUrl && /* @__PURE__ */ jsx("span", { style: { fontSize: "0.75rem", color: muted, fontWeight: 500 }, children: store.name })
|
|
1317
|
+
] }),
|
|
1318
|
+
/* @__PURE__ */ jsxs("div", { style: {
|
|
1319
|
+
display: "flex",
|
|
1320
|
+
flexDirection: "column",
|
|
1321
|
+
maxWidth: 640,
|
|
1322
|
+
margin: "0 auto",
|
|
1323
|
+
padding: "0 1.5rem"
|
|
1324
|
+
}, children: [
|
|
1325
|
+
productImage && /* @__PURE__ */ jsx("div", { style: {
|
|
1326
|
+
marginTop: "1.5rem",
|
|
1327
|
+
borderRadius: 8,
|
|
1328
|
+
overflow: "hidden",
|
|
1329
|
+
background: surface,
|
|
1330
|
+
aspectRatio: "4/3",
|
|
1331
|
+
maxHeight: 320,
|
|
1332
|
+
display: "flex",
|
|
1333
|
+
alignItems: "center",
|
|
1334
|
+
justifyContent: "center"
|
|
1335
|
+
}, children: /* @__PURE__ */ jsx(
|
|
1336
|
+
"img",
|
|
1337
|
+
{
|
|
1338
|
+
src: productImage,
|
|
1339
|
+
alt: productName,
|
|
1340
|
+
style: { width: "100%", height: "100%", objectFit: "cover" }
|
|
1341
|
+
}
|
|
1342
|
+
) }),
|
|
1343
|
+
/* @__PURE__ */ jsxs("div", { style: { display: "flex", gap: "0.5rem", marginTop: "1.25rem", flexWrap: "wrap", alignItems: "center" }, children: [
|
|
1344
|
+
categoryName && /* @__PURE__ */ jsx(Badge, { text: categoryName, bg: surfaceLight, color: accent }),
|
|
1345
|
+
strainType && /* @__PURE__ */ jsx(Badge, { text: strainType, bg: strainBadgeColor(strainType), color: "#fff", bold: true }),
|
|
1346
|
+
coa && /* @__PURE__ */ jsx(Badge, { text: "Lab Tested", bg: "rgba(34,197,94,0.15)", color: "#22c55e" })
|
|
1347
|
+
] }),
|
|
1348
|
+
/* @__PURE__ */ jsxs("div", { style: { marginTop: "0.75rem" }, children: [
|
|
1349
|
+
/* @__PURE__ */ jsx("h1", { style: {
|
|
1350
|
+
fontFamily: fontDisplay,
|
|
1351
|
+
fontSize: "1.75rem",
|
|
1318
1352
|
fontWeight: 600,
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1353
|
+
margin: 0,
|
|
1354
|
+
lineHeight: 1.2,
|
|
1355
|
+
letterSpacing: "-0.02em"
|
|
1356
|
+
}, children: productName }),
|
|
1357
|
+
lowestPrice != null && /* @__PURE__ */ jsxs("p", { style: {
|
|
1358
|
+
fontSize: "1.25rem",
|
|
1359
|
+
fontWeight: 500,
|
|
1360
|
+
color: accent,
|
|
1361
|
+
margin: "0.375rem 0 0"
|
|
1362
|
+
}, children: [
|
|
1363
|
+
"From $",
|
|
1364
|
+
lowestPrice.toFixed(2)
|
|
1365
|
+
] }),
|
|
1366
|
+
tagline && /* @__PURE__ */ jsx("p", { style: { color: muted, fontSize: "0.9rem", margin: "0.5rem 0 0", fontStyle: "italic" }, children: tagline })
|
|
1331
1367
|
] }),
|
|
1332
|
-
/* @__PURE__ */ jsx("
|
|
1333
|
-
description && /* @__PURE__ */ jsx("p", { style: { color: muted, lineHeight: 1.6, margin: "0 0 1.5rem", fontSize: "0.95rem" }, children: description }),
|
|
1368
|
+
description && /* @__PURE__ */ jsx("p", { style: { color: muted, lineHeight: 1.6, margin: "1rem 0 0", fontSize: "0.9rem" }, children: description }),
|
|
1334
1369
|
renderProduct ? renderProduct(data) : null,
|
|
1335
|
-
(thca || thc || cbd) && /* @__PURE__ */ jsxs("div", { style: {
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1370
|
+
(thca != null || thc != null || cbd != null) && /* @__PURE__ */ jsxs("div", { style: {
|
|
1371
|
+
marginTop: "1.25rem",
|
|
1372
|
+
background: surface,
|
|
1373
|
+
border: `1px solid ${border}`,
|
|
1374
|
+
borderRadius: 8,
|
|
1375
|
+
padding: "1rem"
|
|
1376
|
+
}, children: [
|
|
1377
|
+
/* @__PURE__ */ jsx("div", { style: {
|
|
1378
|
+
fontSize: "0.65rem",
|
|
1379
|
+
fontWeight: 600,
|
|
1380
|
+
textTransform: "uppercase",
|
|
1381
|
+
letterSpacing: "0.08em",
|
|
1382
|
+
color: muted,
|
|
1383
|
+
marginBottom: "0.75rem"
|
|
1384
|
+
}, children: "Potency" }),
|
|
1385
|
+
/* @__PURE__ */ jsxs("div", { style: { display: "grid", gridTemplateColumns: `repeat(${[thca, thc, cbd].filter((v) => v != null).length}, 1fr)`, gap: "0.5rem" }, children: [
|
|
1386
|
+
thca != null && /* @__PURE__ */ jsx(PotencyStat, { label: "THCa", value: thca, accent, fg }),
|
|
1387
|
+
thc != null && /* @__PURE__ */ jsx(PotencyStat, { label: "\u03949 THC", value: thc, accent, fg }),
|
|
1388
|
+
cbd != null && /* @__PURE__ */ jsx(PotencyStat, { label: "CBD", value: cbd, accent, fg })
|
|
1389
|
+
] })
|
|
1390
|
+
] }),
|
|
1391
|
+
(batchNumber || dateTested || genetics || terpenes || effects) && /* @__PURE__ */ jsxs("div", { style: {
|
|
1392
|
+
marginTop: "0.75rem",
|
|
1393
|
+
background: surface,
|
|
1394
|
+
border: `1px solid ${border}`,
|
|
1395
|
+
borderRadius: 8,
|
|
1396
|
+
padding: "1rem"
|
|
1397
|
+
}, children: [
|
|
1398
|
+
/* @__PURE__ */ jsx("div", { style: {
|
|
1399
|
+
fontSize: "0.65rem",
|
|
1400
|
+
fontWeight: 600,
|
|
1401
|
+
textTransform: "uppercase",
|
|
1402
|
+
letterSpacing: "0.08em",
|
|
1403
|
+
color: muted,
|
|
1404
|
+
marginBottom: "0.75rem"
|
|
1405
|
+
}, children: "Details" }),
|
|
1406
|
+
/* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "0.5rem" }, children: [
|
|
1407
|
+
genetics && /* @__PURE__ */ jsx(DetailRow, { label: "Genetics", value: genetics, fg, muted }),
|
|
1408
|
+
terpenes && /* @__PURE__ */ jsx(DetailRow, { label: "Terpenes", value: terpenes, fg, muted }),
|
|
1409
|
+
effects && /* @__PURE__ */ jsx(DetailRow, { label: "Effects", value: effects, fg, muted }),
|
|
1410
|
+
batchNumber && /* @__PURE__ */ jsx(DetailRow, { label: "Batch", value: batchNumber, fg, muted }),
|
|
1411
|
+
dateTested && /* @__PURE__ */ jsx(DetailRow, { label: "Tested", value: formatDate(dateTested), fg, muted })
|
|
1412
|
+
] })
|
|
1339
1413
|
] }),
|
|
1340
|
-
/* @__PURE__ */ jsxs("div", { style: {
|
|
1414
|
+
tiers.length > 1 && /* @__PURE__ */ jsxs("div", { style: {
|
|
1415
|
+
marginTop: "0.75rem",
|
|
1416
|
+
background: surface,
|
|
1417
|
+
border: `1px solid ${border}`,
|
|
1418
|
+
borderRadius: 8,
|
|
1419
|
+
padding: "1rem"
|
|
1420
|
+
}, children: [
|
|
1421
|
+
/* @__PURE__ */ jsx("div", { style: {
|
|
1422
|
+
fontSize: "0.65rem",
|
|
1423
|
+
fontWeight: 600,
|
|
1424
|
+
textTransform: "uppercase",
|
|
1425
|
+
letterSpacing: "0.08em",
|
|
1426
|
+
color: muted,
|
|
1427
|
+
marginBottom: "0.75rem"
|
|
1428
|
+
}, children: "Pricing" }),
|
|
1429
|
+
/* @__PURE__ */ jsx("div", { style: { display: "grid", gridTemplateColumns: "repeat(auto-fill, minmax(100px, 1fr))", gap: "0.5rem" }, children: tiers.map((tier) => /* @__PURE__ */ jsxs("div", { style: {
|
|
1430
|
+
background: surfaceLight,
|
|
1431
|
+
borderRadius: 6,
|
|
1432
|
+
padding: "0.625rem",
|
|
1433
|
+
textAlign: "center"
|
|
1434
|
+
}, children: [
|
|
1435
|
+
/* @__PURE__ */ jsxs("div", { style: { fontSize: "1rem", fontWeight: 600, color: fg }, children: [
|
|
1436
|
+
"$",
|
|
1437
|
+
tier.default_price.toFixed(2)
|
|
1438
|
+
] }),
|
|
1439
|
+
/* @__PURE__ */ jsx("div", { style: { fontSize: "0.7rem", color: muted, marginTop: "0.125rem" }, children: tier.label })
|
|
1440
|
+
] }, tier.id)) })
|
|
1441
|
+
] }),
|
|
1442
|
+
/* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "0.625rem", marginTop: "1.5rem" }, children: [
|
|
1341
1443
|
coa && /* @__PURE__ */ jsx(
|
|
1342
1444
|
"button",
|
|
1343
1445
|
{
|
|
@@ -1348,10 +1450,12 @@ function DefaultLayout({
|
|
|
1348
1450
|
background: accent,
|
|
1349
1451
|
color: bg,
|
|
1350
1452
|
border: "none",
|
|
1351
|
-
fontSize: "0.
|
|
1453
|
+
fontSize: "0.9rem",
|
|
1352
1454
|
fontWeight: 600,
|
|
1455
|
+
fontFamily: fontDisplay,
|
|
1353
1456
|
cursor: "pointer",
|
|
1354
|
-
borderRadius:
|
|
1457
|
+
borderRadius: 6,
|
|
1458
|
+
letterSpacing: "-0.01em"
|
|
1355
1459
|
},
|
|
1356
1460
|
children: "View Lab Results"
|
|
1357
1461
|
}
|
|
@@ -1367,26 +1471,33 @@ function DefaultLayout({
|
|
|
1367
1471
|
padding: "0.875rem",
|
|
1368
1472
|
background: "transparent",
|
|
1369
1473
|
color: fg,
|
|
1370
|
-
border: `1px solid ${
|
|
1371
|
-
fontSize: "0.
|
|
1474
|
+
border: `1px solid ${border}`,
|
|
1475
|
+
fontSize: "0.9rem",
|
|
1372
1476
|
fontWeight: 500,
|
|
1477
|
+
fontFamily: fontDisplay,
|
|
1373
1478
|
textAlign: "center",
|
|
1374
1479
|
textDecoration: "none",
|
|
1375
1480
|
boxSizing: "border-box",
|
|
1376
|
-
borderRadius:
|
|
1481
|
+
borderRadius: 6
|
|
1377
1482
|
},
|
|
1378
|
-
children:
|
|
1483
|
+
children: "Shop Online"
|
|
1379
1484
|
}
|
|
1380
1485
|
)
|
|
1381
1486
|
] }),
|
|
1382
|
-
/* @__PURE__ */ jsxs("
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1487
|
+
/* @__PURE__ */ jsxs("footer", { style: {
|
|
1488
|
+
marginTop: "2rem",
|
|
1489
|
+
paddingTop: "1.25rem",
|
|
1490
|
+
paddingBottom: "2rem",
|
|
1491
|
+
borderTop: `1px solid ${border}`,
|
|
1492
|
+
textAlign: "center"
|
|
1493
|
+
}, children: [
|
|
1494
|
+
/* @__PURE__ */ jsxs("div", { style: { display: "flex", justifyContent: "center", gap: "1.5rem", marginBottom: "0.5rem" }, children: [
|
|
1495
|
+
coa && /* @__PURE__ */ jsx(FooterBadge, { icon: "\u2713", text: "Lab Verified", muted }),
|
|
1496
|
+
/* @__PURE__ */ jsx(FooterBadge, { icon: "\u2726", text: "Authentic Product", muted })
|
|
1386
1497
|
] }),
|
|
1387
|
-
store?.name && /* @__PURE__ */ jsxs("p", { style: { fontSize: "0.
|
|
1388
|
-
|
|
1389
|
-
store.
|
|
1498
|
+
store?.name && /* @__PURE__ */ jsxs("p", { style: { fontSize: "0.7rem", color: muted, margin: "0.5rem 0 0" }, children: [
|
|
1499
|
+
store.name,
|
|
1500
|
+
store?.tagline ? ` \u2014 ${store.tagline}` : ""
|
|
1390
1501
|
] })
|
|
1391
1502
|
] })
|
|
1392
1503
|
] }),
|
|
@@ -1397,18 +1508,32 @@ function DefaultLayout({
|
|
|
1397
1508
|
position: "fixed",
|
|
1398
1509
|
inset: 0,
|
|
1399
1510
|
zIndex: 9999,
|
|
1400
|
-
background: "rgba(0,0,0,0.
|
|
1511
|
+
background: "rgba(0,0,0,0.92)",
|
|
1401
1512
|
display: "flex",
|
|
1402
1513
|
flexDirection: "column"
|
|
1403
1514
|
},
|
|
1404
1515
|
children: [
|
|
1405
|
-
/* @__PURE__ */ jsxs("div", { style: {
|
|
1406
|
-
|
|
1516
|
+
/* @__PURE__ */ jsxs("div", { style: {
|
|
1517
|
+
display: "flex",
|
|
1518
|
+
justifyContent: "space-between",
|
|
1519
|
+
alignItems: "center",
|
|
1520
|
+
padding: "0.75rem 1rem",
|
|
1521
|
+
borderBottom: "1px solid #222"
|
|
1522
|
+
}, children: [
|
|
1523
|
+
/* @__PURE__ */ jsx("span", { style: { color: "#fff", fontWeight: 600, fontSize: "0.9rem", fontFamily: fontDisplay }, children: coa.document_name || "Lab Results" }),
|
|
1407
1524
|
/* @__PURE__ */ jsx(
|
|
1408
1525
|
"button",
|
|
1409
1526
|
{
|
|
1410
1527
|
onClick: () => setShowCOA(false),
|
|
1411
|
-
style: {
|
|
1528
|
+
style: {
|
|
1529
|
+
background: "rgba(255,255,255,0.1)",
|
|
1530
|
+
border: "none",
|
|
1531
|
+
color: "#fff",
|
|
1532
|
+
fontSize: "1rem",
|
|
1533
|
+
cursor: "pointer",
|
|
1534
|
+
padding: "0.375rem 0.75rem",
|
|
1535
|
+
borderRadius: 4
|
|
1536
|
+
},
|
|
1412
1537
|
children: "\u2715"
|
|
1413
1538
|
}
|
|
1414
1539
|
)
|
|
@@ -1426,10 +1551,45 @@ function DefaultLayout({
|
|
|
1426
1551
|
)
|
|
1427
1552
|
] });
|
|
1428
1553
|
}
|
|
1429
|
-
function
|
|
1430
|
-
return /* @__PURE__ */
|
|
1431
|
-
|
|
1432
|
-
|
|
1554
|
+
function Badge({ text, bg, color, bold }) {
|
|
1555
|
+
return /* @__PURE__ */ jsx("span", { style: {
|
|
1556
|
+
padding: "0.25rem 0.625rem",
|
|
1557
|
+
borderRadius: 4,
|
|
1558
|
+
fontSize: "0.7rem",
|
|
1559
|
+
fontWeight: bold ? 700 : 500,
|
|
1560
|
+
textTransform: "uppercase",
|
|
1561
|
+
letterSpacing: "0.04em",
|
|
1562
|
+
background: bg,
|
|
1563
|
+
color
|
|
1564
|
+
}, children: text });
|
|
1565
|
+
}
|
|
1566
|
+
function PotencyStat({ label, value, accent, fg }) {
|
|
1567
|
+
return /* @__PURE__ */ jsxs("div", { style: { textAlign: "center", padding: "0.25rem 0" }, children: [
|
|
1568
|
+
/* @__PURE__ */ jsxs("div", { style: { fontSize: "1.5rem", fontWeight: 700, color: fg, lineHeight: 1.1 }, children: [
|
|
1569
|
+
value.toFixed(value >= 1 ? 1 : 2),
|
|
1570
|
+
"%"
|
|
1571
|
+
] }),
|
|
1572
|
+
/* @__PURE__ */ jsx("div", { style: {
|
|
1573
|
+
fontSize: "0.65rem",
|
|
1574
|
+
color: accent,
|
|
1575
|
+
textTransform: "uppercase",
|
|
1576
|
+
letterSpacing: "0.06em",
|
|
1577
|
+
marginTop: "0.25rem",
|
|
1578
|
+
fontWeight: 600
|
|
1579
|
+
}, children: label })
|
|
1580
|
+
] });
|
|
1581
|
+
}
|
|
1582
|
+
function DetailRow({ label, value, fg, muted }) {
|
|
1583
|
+
return /* @__PURE__ */ jsxs("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "baseline" }, children: [
|
|
1584
|
+
/* @__PURE__ */ jsx("span", { style: { fontSize: "0.8rem", color: muted }, children: label }),
|
|
1585
|
+
/* @__PURE__ */ jsx("span", { style: { fontSize: "0.8rem", color: fg, fontWeight: 500 }, children: value })
|
|
1586
|
+
] });
|
|
1587
|
+
}
|
|
1588
|
+
function FooterBadge({ icon, text, muted }) {
|
|
1589
|
+
return /* @__PURE__ */ jsxs("span", { style: { fontSize: "0.7rem", color: muted, display: "flex", alignItems: "center", gap: "0.25rem" }, children: [
|
|
1590
|
+
/* @__PURE__ */ jsx("span", { style: { fontSize: "0.6rem" }, children: icon }),
|
|
1591
|
+
" ",
|
|
1592
|
+
text
|
|
1433
1593
|
] });
|
|
1434
1594
|
}
|
|
1435
1595
|
function strainBadgeColor(strain) {
|
|
@@ -1439,6 +1599,14 @@ function strainBadgeColor(strain) {
|
|
|
1439
1599
|
if (s === "hybrid") return "#f59e0b";
|
|
1440
1600
|
return "#6b7280";
|
|
1441
1601
|
}
|
|
1602
|
+
function formatDate(dateStr) {
|
|
1603
|
+
try {
|
|
1604
|
+
const d = /* @__PURE__ */ new Date(dateStr + "T00:00:00");
|
|
1605
|
+
return d.toLocaleDateString("en-US", { month: "short", day: "numeric", year: "numeric" });
|
|
1606
|
+
} catch {
|
|
1607
|
+
return dateStr;
|
|
1608
|
+
}
|
|
1609
|
+
}
|
|
1442
1610
|
var containerStyle = {
|
|
1443
1611
|
minHeight: "100dvh",
|
|
1444
1612
|
display: "flex",
|