@cimplify/sdk 0.38.3 → 0.38.5
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/advanced.js +20 -20
- package/dist/advanced.mjs +1 -1
- package/dist/{chunk-ZYACIPKO.js → chunk-5VHKZTFJ.js} +35 -35
- package/dist/{chunk-HKVRUGM6.js → chunk-BAWKQRIB.js} +6 -1
- package/dist/{chunk-TFHKVQLL.mjs → chunk-EZK2FXTM.mjs} +6 -1
- package/dist/{chunk-2X6P5WJZ.mjs → chunk-JTU5P6GM.mjs} +1 -1
- package/dist/index.js +66 -66
- package/dist/index.mjs +2 -2
- package/dist/mock/cli.mjs +187 -7
- package/dist/mock/library.d.mts +2 -2
- package/dist/mock/library.d.ts +2 -2
- package/dist/mock/library.js +187 -7
- package/dist/mock/library.mjs +187 -7
- package/dist/mock/msw.d.mts +1 -1
- package/dist/mock/msw.d.ts +1 -1
- package/dist/mock/msw.js +187 -7
- package/dist/mock/msw.mjs +187 -7
- package/dist/react.js +60 -60
- package/dist/react.mjs +3 -3
- package/dist/{server-BNy6Ri-4.d.mts → server-CVEsjECc.d.mts} +27 -0
- package/dist/{server-BNy6Ri-4.d.ts → server-CVEsjECc.d.ts} +27 -0
- package/package.json +1 -1
- package/templates/storefront/README.md +1 -1
- package/templates/storefront/components/collection-strip.tsx +1 -1
- package/templates/storefront/components/store-product-card.tsx +66 -15
- package/templates/storefront/package.json +1 -1
- package/templates/storefront/tsconfig.json +1 -1
package/dist/mock/msw.js
CHANGED
|
@@ -3536,12 +3536,21 @@ function toCanonicalProductSummary(p) {
|
|
|
3536
3536
|
updated_at: p.updated_at
|
|
3537
3537
|
};
|
|
3538
3538
|
}
|
|
3539
|
-
|
|
3539
|
+
var FOOD_REGEX = /food|drink|cake|bread|pastry|dessert|coffee|tea|juice|spice|sweet|breakfast|baked/i;
|
|
3540
|
+
function deriveRenderHint(p, registry) {
|
|
3541
|
+
if (p.render_hint) return p.render_hint;
|
|
3540
3542
|
if (p.product_type === "service") return "general";
|
|
3541
|
-
|
|
3542
|
-
|
|
3543
|
-
)
|
|
3544
|
-
|
|
3543
|
+
if (p.product_type === "digital") return "general";
|
|
3544
|
+
if ((p.tags ?? []).some((t) => FOOD_REGEX.test(t))) return "food";
|
|
3545
|
+
if (registry) {
|
|
3546
|
+
for (const cid of p.category_ids) {
|
|
3547
|
+
const cat = registry.categories.get(cid);
|
|
3548
|
+
if (cat && (FOOD_REGEX.test(cat.name) || FOOD_REGEX.test(cat.slug))) {
|
|
3549
|
+
return "food";
|
|
3550
|
+
}
|
|
3551
|
+
}
|
|
3552
|
+
}
|
|
3553
|
+
return "general";
|
|
3545
3554
|
}
|
|
3546
3555
|
function toApiProduct(p, ctx) {
|
|
3547
3556
|
const { registry, priceInfo, groups, components, composite, bundle } = ctx;
|
|
@@ -3557,7 +3566,7 @@ function toApiProduct(p, ctx) {
|
|
|
3557
3566
|
images: p.images,
|
|
3558
3567
|
default_price: p.base_price,
|
|
3559
3568
|
type: p.product_type,
|
|
3560
|
-
render_hint: deriveRenderHint(p),
|
|
3569
|
+
render_hint: deriveRenderHint(p, registry),
|
|
3561
3570
|
inventory_type: "none",
|
|
3562
3571
|
variant_strategy: p.variant_ids.length > 0 ? "use_axes" : "fetch_all",
|
|
3563
3572
|
is_active: p.is_available,
|
|
@@ -3565,6 +3574,12 @@ function toApiProduct(p, ctx) {
|
|
|
3565
3574
|
tags: p.tags ?? [],
|
|
3566
3575
|
calories: p.calories,
|
|
3567
3576
|
allergies: p.allergies ?? [],
|
|
3577
|
+
display_mode: p.display_mode,
|
|
3578
|
+
digital_product_type: p.digital_product_type,
|
|
3579
|
+
quantity_pricing: p.quantity_pricing,
|
|
3580
|
+
duration_unit: p.duration_unit,
|
|
3581
|
+
duration_minutes: p.duration_minutes,
|
|
3582
|
+
billing_plans: p.billing_plans,
|
|
3568
3583
|
created_at: p.created_at,
|
|
3569
3584
|
updated_at: p.updated_at,
|
|
3570
3585
|
metadata: {
|
|
@@ -5055,6 +5070,21 @@ function makeProduct(input, categoryIds) {
|
|
|
5055
5070
|
pairings: input.pairings ?? [],
|
|
5056
5071
|
is_signature: input.isSignature ?? false,
|
|
5057
5072
|
is_new: input.isNew ?? false,
|
|
5073
|
+
render_hint: input.renderHint,
|
|
5074
|
+
display_mode: input.displayMode,
|
|
5075
|
+
digital_product_type: input.digitalProductType,
|
|
5076
|
+
quantity_pricing: input.quantityPricing,
|
|
5077
|
+
duration_unit: input.durationUnit,
|
|
5078
|
+
duration_minutes: input.durationMinutes,
|
|
5079
|
+
billing_plans: input.billingPlans?.map((b) => ({
|
|
5080
|
+
id: b.id,
|
|
5081
|
+
name: b.name,
|
|
5082
|
+
interval: b.interval,
|
|
5083
|
+
interval_count: b.interval_count,
|
|
5084
|
+
price: b.price,
|
|
5085
|
+
currency: b.currency ?? "GHS",
|
|
5086
|
+
trial_period_days: b.trial_period_days
|
|
5087
|
+
})),
|
|
5058
5088
|
created_at: ISO,
|
|
5059
5089
|
updated_at: ISO
|
|
5060
5090
|
};
|
|
@@ -5095,7 +5125,9 @@ function seedDefault(registry) {
|
|
|
5095
5125
|
{ slug: "pastries", name: "Pastries", description: "Hand-laminated croissants, danishes, brownies." },
|
|
5096
5126
|
{ slug: "cakes", name: "Cakes", description: "Slices and made-to-order showstoppers." },
|
|
5097
5127
|
{ slug: "drinks", name: "Drinks", description: "Locally roasted coffee, brewed teas, fresh juice." },
|
|
5098
|
-
{ slug: "boxes", name: "Boxes & Bundles", description: "Curated boxes for sharing." }
|
|
5128
|
+
{ slug: "boxes", name: "Boxes & Bundles", description: "Curated boxes for sharing." },
|
|
5129
|
+
{ slug: "merch", name: "Merch & More", description: "Branded goods, wholesale flour, downloadable recipes, gift cards." },
|
|
5130
|
+
{ slug: "classes", name: "Classes & Stays", description: "Hands-on baking classes, kitchen rentals, monthly bread subscriptions." }
|
|
5099
5131
|
];
|
|
5100
5132
|
const catIds = /* @__PURE__ */ new Map();
|
|
5101
5133
|
for (const c of categoryDefs) {
|
|
@@ -5409,6 +5441,154 @@ function seedDefault(registry) {
|
|
|
5409
5441
|
imageUrl: img("1486427944299-d1955d23e34d"),
|
|
5410
5442
|
tags: ["composite", "build-your-own", "gift"],
|
|
5411
5443
|
productType: "composite"
|
|
5444
|
+
},
|
|
5445
|
+
// ── Merch (Retail card — render_hint=physical) ──
|
|
5446
|
+
{
|
|
5447
|
+
id: "prod_apron",
|
|
5448
|
+
name: "Akua's Bakery Apron",
|
|
5449
|
+
slug: "apron",
|
|
5450
|
+
price: "85.00",
|
|
5451
|
+
description: "Heavy-weight cotton-canvas apron with leather neck strap, embroidered logo, and two front pockets. Made in Accra.",
|
|
5452
|
+
category: "merch",
|
|
5453
|
+
imageUrl: img("1556905055-8f358a7a47b2"),
|
|
5454
|
+
tags: ["merch", "physical"],
|
|
5455
|
+
renderHint: "physical"
|
|
5456
|
+
},
|
|
5457
|
+
{
|
|
5458
|
+
id: "prod_tote",
|
|
5459
|
+
name: "Bakery Tote Bag",
|
|
5460
|
+
slug: "tote-bag",
|
|
5461
|
+
price: "35.00",
|
|
5462
|
+
description: "12oz natural canvas tote, screen-printed with our wheat-stalk crest. Roomy enough for two loaves.",
|
|
5463
|
+
category: "merch",
|
|
5464
|
+
imageUrl: img("1591561954557-26941169b49e"),
|
|
5465
|
+
tags: ["merch", "physical", "gift"],
|
|
5466
|
+
renderHint: "physical",
|
|
5467
|
+
isNew: true
|
|
5468
|
+
},
|
|
5469
|
+
// ── Wholesale (Wholesale card — quantity_pricing tiers) ──
|
|
5470
|
+
{
|
|
5471
|
+
id: "prod_flour-wholesale",
|
|
5472
|
+
name: "Heritage Flour \u2014 25kg Sack",
|
|
5473
|
+
slug: "flour-25kg",
|
|
5474
|
+
price: "320.00",
|
|
5475
|
+
description: "Stone-milled heritage wheat flour, the same we use in our country sourdough. Tiered pricing for caf\xE9s, restaurants, and home-baking co-ops.",
|
|
5476
|
+
category: "merch",
|
|
5477
|
+
imageUrl: img("1568254183919-78a4f43a2877"),
|
|
5478
|
+
tags: ["wholesale", "physical", "trade"],
|
|
5479
|
+
renderHint: "physical",
|
|
5480
|
+
quantityPricing: [
|
|
5481
|
+
{ min_quantity: 1, unit_price: "320.00" },
|
|
5482
|
+
{ min_quantity: 5, unit_price: "295.00" },
|
|
5483
|
+
{ min_quantity: 10, unit_price: "270.00" },
|
|
5484
|
+
{ min_quantity: 25, unit_price: "245.00" }
|
|
5485
|
+
]
|
|
5486
|
+
},
|
|
5487
|
+
// ── Digital products (Digital card — type=digital) ──
|
|
5488
|
+
{
|
|
5489
|
+
id: "prod_recipe-ebook",
|
|
5490
|
+
name: "Sourdough Starter eBook",
|
|
5491
|
+
slug: "sourdough-ebook",
|
|
5492
|
+
price: "45.00",
|
|
5493
|
+
description: "PDF + EPUB walkthrough of our sourdough programme \u2014 starter, levain, autolyse, bulk fermentation, shaping, scoring. Lifetime updates.",
|
|
5494
|
+
category: "merch",
|
|
5495
|
+
imageUrl: img("1543002588-bfa74002ed7e"),
|
|
5496
|
+
tags: ["digital", "download"],
|
|
5497
|
+
productType: "digital",
|
|
5498
|
+
digitalProductType: "download"
|
|
5499
|
+
},
|
|
5500
|
+
{
|
|
5501
|
+
id: "prod_gift-card",
|
|
5502
|
+
name: "Bakery Gift Card",
|
|
5503
|
+
slug: "gift-card",
|
|
5504
|
+
price: "100.00",
|
|
5505
|
+
description: "Send instantly. Redeemable in-store and online toward any product. Choose any amount from GH\u20B550 upward.",
|
|
5506
|
+
category: "merch",
|
|
5507
|
+
imageUrl: img("1556905055-8f358a7a47b2"),
|
|
5508
|
+
tags: ["digital", "gift"],
|
|
5509
|
+
productType: "digital",
|
|
5510
|
+
digitalProductType: "gift_code",
|
|
5511
|
+
isSignature: true
|
|
5512
|
+
},
|
|
5513
|
+
// ── Services (Standard service card — type=service + duration_minutes) ──
|
|
5514
|
+
{
|
|
5515
|
+
id: "prod_baking-class",
|
|
5516
|
+
name: "Sourdough Baking Class",
|
|
5517
|
+
slug: "baking-class",
|
|
5518
|
+
price: "320.00",
|
|
5519
|
+
description: "Two-hour hands-on class: shape your own boule, score it, and take home a baked loaf and a starter jar. Held Saturdays, 10am\u201312pm.",
|
|
5520
|
+
category: "classes",
|
|
5521
|
+
imageUrl: img("1556909114-44e3e9399a2e"),
|
|
5522
|
+
tags: ["class", "service", "hands-on"],
|
|
5523
|
+
productType: "service",
|
|
5524
|
+
durationMinutes: 120
|
|
5525
|
+
},
|
|
5526
|
+
{
|
|
5527
|
+
id: "prod_pastry-workshop",
|
|
5528
|
+
name: "Lamination Workshop",
|
|
5529
|
+
slug: "pastry-workshop",
|
|
5530
|
+
price: "480.00",
|
|
5531
|
+
description: "Three-hour deep-dive on laminated dough. We cover croissants, danishes, kouign-amann. Aprons supplied; pastries to take home.",
|
|
5532
|
+
category: "classes",
|
|
5533
|
+
imageUrl: img("1517433367423-c7e5b0f35086"),
|
|
5534
|
+
tags: ["class", "service", "advanced"],
|
|
5535
|
+
productType: "service",
|
|
5536
|
+
durationMinutes: 180,
|
|
5537
|
+
isNew: true
|
|
5538
|
+
},
|
|
5539
|
+
// ── Rental service (Rental card — duration_unit=hours) ──
|
|
5540
|
+
{
|
|
5541
|
+
id: "prod_kitchen-rental",
|
|
5542
|
+
name: "Pro Kitchen Rental",
|
|
5543
|
+
slug: "kitchen-rental",
|
|
5544
|
+
price: "180.00",
|
|
5545
|
+
description: "Rent our commercial bakery after hours. Deck oven, retarder-proofer, mixers, scales \u2014 bring your team or shoot your content. Hourly.",
|
|
5546
|
+
category: "classes",
|
|
5547
|
+
imageUrl: img("1556909114-44e3e9399a2e"),
|
|
5548
|
+
tags: ["rental", "service", "commercial"],
|
|
5549
|
+
productType: "service",
|
|
5550
|
+
durationUnit: "hours"
|
|
5551
|
+
},
|
|
5552
|
+
// ── Accommodation (Accommodation card — duration_unit=nights) ──
|
|
5553
|
+
{
|
|
5554
|
+
id: "prod_loft-stay",
|
|
5555
|
+
name: "Bakery Loft \u2014 Weekend Stay",
|
|
5556
|
+
slug: "loft-stay",
|
|
5557
|
+
price: "650.00",
|
|
5558
|
+
description: "One-bedroom loft above the bakery. Wakes up to fresh croissants, ends with a private dinner. Ghana Tourism-licensed. Per night.",
|
|
5559
|
+
category: "classes",
|
|
5560
|
+
imageUrl: img("1564013799919-ab600027ffc6"),
|
|
5561
|
+
tags: ["stay", "service", "premium"],
|
|
5562
|
+
productType: "service",
|
|
5563
|
+
durationUnit: "nights"
|
|
5564
|
+
},
|
|
5565
|
+
// ── Subscription (Subscription card — billing_plans, no duration_minutes) ──
|
|
5566
|
+
{
|
|
5567
|
+
id: "prod_loaf-subscription",
|
|
5568
|
+
name: "Weekly Loaf Subscription",
|
|
5569
|
+
slug: "loaf-subscription",
|
|
5570
|
+
price: "0.00",
|
|
5571
|
+
description: "A fresh loaf delivered to your door every week. Pause or skip any time. Choose monthly or quarterly billing for a discount.",
|
|
5572
|
+
category: "classes",
|
|
5573
|
+
imageUrl: img("1509440159596-0249088772ff"),
|
|
5574
|
+
tags: ["subscription", "service", "delivery"],
|
|
5575
|
+
productType: "service",
|
|
5576
|
+
billingPlans: [
|
|
5577
|
+
{
|
|
5578
|
+
id: "plan_loaf_monthly",
|
|
5579
|
+
name: "Monthly",
|
|
5580
|
+
interval: "month",
|
|
5581
|
+
interval_count: 1,
|
|
5582
|
+
price: "90.00"
|
|
5583
|
+
},
|
|
5584
|
+
{
|
|
5585
|
+
id: "plan_loaf_quarterly",
|
|
5586
|
+
name: "Quarterly (save 10%)",
|
|
5587
|
+
interval: "month",
|
|
5588
|
+
interval_count: 3,
|
|
5589
|
+
price: "243.00"
|
|
5590
|
+
}
|
|
5591
|
+
]
|
|
5412
5592
|
}
|
|
5413
5593
|
];
|
|
5414
5594
|
for (const input of productInputs) {
|
package/dist/mock/msw.mjs
CHANGED
|
@@ -3534,12 +3534,21 @@ function toCanonicalProductSummary(p) {
|
|
|
3534
3534
|
updated_at: p.updated_at
|
|
3535
3535
|
};
|
|
3536
3536
|
}
|
|
3537
|
-
|
|
3537
|
+
var FOOD_REGEX = /food|drink|cake|bread|pastry|dessert|coffee|tea|juice|spice|sweet|breakfast|baked/i;
|
|
3538
|
+
function deriveRenderHint(p, registry) {
|
|
3539
|
+
if (p.render_hint) return p.render_hint;
|
|
3538
3540
|
if (p.product_type === "service") return "general";
|
|
3539
|
-
|
|
3540
|
-
|
|
3541
|
-
)
|
|
3542
|
-
|
|
3541
|
+
if (p.product_type === "digital") return "general";
|
|
3542
|
+
if ((p.tags ?? []).some((t) => FOOD_REGEX.test(t))) return "food";
|
|
3543
|
+
if (registry) {
|
|
3544
|
+
for (const cid of p.category_ids) {
|
|
3545
|
+
const cat = registry.categories.get(cid);
|
|
3546
|
+
if (cat && (FOOD_REGEX.test(cat.name) || FOOD_REGEX.test(cat.slug))) {
|
|
3547
|
+
return "food";
|
|
3548
|
+
}
|
|
3549
|
+
}
|
|
3550
|
+
}
|
|
3551
|
+
return "general";
|
|
3543
3552
|
}
|
|
3544
3553
|
function toApiProduct(p, ctx) {
|
|
3545
3554
|
const { registry, priceInfo, groups, components, composite, bundle } = ctx;
|
|
@@ -3555,7 +3564,7 @@ function toApiProduct(p, ctx) {
|
|
|
3555
3564
|
images: p.images,
|
|
3556
3565
|
default_price: p.base_price,
|
|
3557
3566
|
type: p.product_type,
|
|
3558
|
-
render_hint: deriveRenderHint(p),
|
|
3567
|
+
render_hint: deriveRenderHint(p, registry),
|
|
3559
3568
|
inventory_type: "none",
|
|
3560
3569
|
variant_strategy: p.variant_ids.length > 0 ? "use_axes" : "fetch_all",
|
|
3561
3570
|
is_active: p.is_available,
|
|
@@ -3563,6 +3572,12 @@ function toApiProduct(p, ctx) {
|
|
|
3563
3572
|
tags: p.tags ?? [],
|
|
3564
3573
|
calories: p.calories,
|
|
3565
3574
|
allergies: p.allergies ?? [],
|
|
3575
|
+
display_mode: p.display_mode,
|
|
3576
|
+
digital_product_type: p.digital_product_type,
|
|
3577
|
+
quantity_pricing: p.quantity_pricing,
|
|
3578
|
+
duration_unit: p.duration_unit,
|
|
3579
|
+
duration_minutes: p.duration_minutes,
|
|
3580
|
+
billing_plans: p.billing_plans,
|
|
3566
3581
|
created_at: p.created_at,
|
|
3567
3582
|
updated_at: p.updated_at,
|
|
3568
3583
|
metadata: {
|
|
@@ -5053,6 +5068,21 @@ function makeProduct(input, categoryIds) {
|
|
|
5053
5068
|
pairings: input.pairings ?? [],
|
|
5054
5069
|
is_signature: input.isSignature ?? false,
|
|
5055
5070
|
is_new: input.isNew ?? false,
|
|
5071
|
+
render_hint: input.renderHint,
|
|
5072
|
+
display_mode: input.displayMode,
|
|
5073
|
+
digital_product_type: input.digitalProductType,
|
|
5074
|
+
quantity_pricing: input.quantityPricing,
|
|
5075
|
+
duration_unit: input.durationUnit,
|
|
5076
|
+
duration_minutes: input.durationMinutes,
|
|
5077
|
+
billing_plans: input.billingPlans?.map((b) => ({
|
|
5078
|
+
id: b.id,
|
|
5079
|
+
name: b.name,
|
|
5080
|
+
interval: b.interval,
|
|
5081
|
+
interval_count: b.interval_count,
|
|
5082
|
+
price: b.price,
|
|
5083
|
+
currency: b.currency ?? "GHS",
|
|
5084
|
+
trial_period_days: b.trial_period_days
|
|
5085
|
+
})),
|
|
5056
5086
|
created_at: ISO,
|
|
5057
5087
|
updated_at: ISO
|
|
5058
5088
|
};
|
|
@@ -5093,7 +5123,9 @@ function seedDefault(registry) {
|
|
|
5093
5123
|
{ slug: "pastries", name: "Pastries", description: "Hand-laminated croissants, danishes, brownies." },
|
|
5094
5124
|
{ slug: "cakes", name: "Cakes", description: "Slices and made-to-order showstoppers." },
|
|
5095
5125
|
{ slug: "drinks", name: "Drinks", description: "Locally roasted coffee, brewed teas, fresh juice." },
|
|
5096
|
-
{ slug: "boxes", name: "Boxes & Bundles", description: "Curated boxes for sharing." }
|
|
5126
|
+
{ slug: "boxes", name: "Boxes & Bundles", description: "Curated boxes for sharing." },
|
|
5127
|
+
{ slug: "merch", name: "Merch & More", description: "Branded goods, wholesale flour, downloadable recipes, gift cards." },
|
|
5128
|
+
{ slug: "classes", name: "Classes & Stays", description: "Hands-on baking classes, kitchen rentals, monthly bread subscriptions." }
|
|
5097
5129
|
];
|
|
5098
5130
|
const catIds = /* @__PURE__ */ new Map();
|
|
5099
5131
|
for (const c of categoryDefs) {
|
|
@@ -5407,6 +5439,154 @@ function seedDefault(registry) {
|
|
|
5407
5439
|
imageUrl: img("1486427944299-d1955d23e34d"),
|
|
5408
5440
|
tags: ["composite", "build-your-own", "gift"],
|
|
5409
5441
|
productType: "composite"
|
|
5442
|
+
},
|
|
5443
|
+
// ── Merch (Retail card — render_hint=physical) ──
|
|
5444
|
+
{
|
|
5445
|
+
id: "prod_apron",
|
|
5446
|
+
name: "Akua's Bakery Apron",
|
|
5447
|
+
slug: "apron",
|
|
5448
|
+
price: "85.00",
|
|
5449
|
+
description: "Heavy-weight cotton-canvas apron with leather neck strap, embroidered logo, and two front pockets. Made in Accra.",
|
|
5450
|
+
category: "merch",
|
|
5451
|
+
imageUrl: img("1556905055-8f358a7a47b2"),
|
|
5452
|
+
tags: ["merch", "physical"],
|
|
5453
|
+
renderHint: "physical"
|
|
5454
|
+
},
|
|
5455
|
+
{
|
|
5456
|
+
id: "prod_tote",
|
|
5457
|
+
name: "Bakery Tote Bag",
|
|
5458
|
+
slug: "tote-bag",
|
|
5459
|
+
price: "35.00",
|
|
5460
|
+
description: "12oz natural canvas tote, screen-printed with our wheat-stalk crest. Roomy enough for two loaves.",
|
|
5461
|
+
category: "merch",
|
|
5462
|
+
imageUrl: img("1591561954557-26941169b49e"),
|
|
5463
|
+
tags: ["merch", "physical", "gift"],
|
|
5464
|
+
renderHint: "physical",
|
|
5465
|
+
isNew: true
|
|
5466
|
+
},
|
|
5467
|
+
// ── Wholesale (Wholesale card — quantity_pricing tiers) ──
|
|
5468
|
+
{
|
|
5469
|
+
id: "prod_flour-wholesale",
|
|
5470
|
+
name: "Heritage Flour \u2014 25kg Sack",
|
|
5471
|
+
slug: "flour-25kg",
|
|
5472
|
+
price: "320.00",
|
|
5473
|
+
description: "Stone-milled heritage wheat flour, the same we use in our country sourdough. Tiered pricing for caf\xE9s, restaurants, and home-baking co-ops.",
|
|
5474
|
+
category: "merch",
|
|
5475
|
+
imageUrl: img("1568254183919-78a4f43a2877"),
|
|
5476
|
+
tags: ["wholesale", "physical", "trade"],
|
|
5477
|
+
renderHint: "physical",
|
|
5478
|
+
quantityPricing: [
|
|
5479
|
+
{ min_quantity: 1, unit_price: "320.00" },
|
|
5480
|
+
{ min_quantity: 5, unit_price: "295.00" },
|
|
5481
|
+
{ min_quantity: 10, unit_price: "270.00" },
|
|
5482
|
+
{ min_quantity: 25, unit_price: "245.00" }
|
|
5483
|
+
]
|
|
5484
|
+
},
|
|
5485
|
+
// ── Digital products (Digital card — type=digital) ──
|
|
5486
|
+
{
|
|
5487
|
+
id: "prod_recipe-ebook",
|
|
5488
|
+
name: "Sourdough Starter eBook",
|
|
5489
|
+
slug: "sourdough-ebook",
|
|
5490
|
+
price: "45.00",
|
|
5491
|
+
description: "PDF + EPUB walkthrough of our sourdough programme \u2014 starter, levain, autolyse, bulk fermentation, shaping, scoring. Lifetime updates.",
|
|
5492
|
+
category: "merch",
|
|
5493
|
+
imageUrl: img("1543002588-bfa74002ed7e"),
|
|
5494
|
+
tags: ["digital", "download"],
|
|
5495
|
+
productType: "digital",
|
|
5496
|
+
digitalProductType: "download"
|
|
5497
|
+
},
|
|
5498
|
+
{
|
|
5499
|
+
id: "prod_gift-card",
|
|
5500
|
+
name: "Bakery Gift Card",
|
|
5501
|
+
slug: "gift-card",
|
|
5502
|
+
price: "100.00",
|
|
5503
|
+
description: "Send instantly. Redeemable in-store and online toward any product. Choose any amount from GH\u20B550 upward.",
|
|
5504
|
+
category: "merch",
|
|
5505
|
+
imageUrl: img("1556905055-8f358a7a47b2"),
|
|
5506
|
+
tags: ["digital", "gift"],
|
|
5507
|
+
productType: "digital",
|
|
5508
|
+
digitalProductType: "gift_code",
|
|
5509
|
+
isSignature: true
|
|
5510
|
+
},
|
|
5511
|
+
// ── Services (Standard service card — type=service + duration_minutes) ──
|
|
5512
|
+
{
|
|
5513
|
+
id: "prod_baking-class",
|
|
5514
|
+
name: "Sourdough Baking Class",
|
|
5515
|
+
slug: "baking-class",
|
|
5516
|
+
price: "320.00",
|
|
5517
|
+
description: "Two-hour hands-on class: shape your own boule, score it, and take home a baked loaf and a starter jar. Held Saturdays, 10am\u201312pm.",
|
|
5518
|
+
category: "classes",
|
|
5519
|
+
imageUrl: img("1556909114-44e3e9399a2e"),
|
|
5520
|
+
tags: ["class", "service", "hands-on"],
|
|
5521
|
+
productType: "service",
|
|
5522
|
+
durationMinutes: 120
|
|
5523
|
+
},
|
|
5524
|
+
{
|
|
5525
|
+
id: "prod_pastry-workshop",
|
|
5526
|
+
name: "Lamination Workshop",
|
|
5527
|
+
slug: "pastry-workshop",
|
|
5528
|
+
price: "480.00",
|
|
5529
|
+
description: "Three-hour deep-dive on laminated dough. We cover croissants, danishes, kouign-amann. Aprons supplied; pastries to take home.",
|
|
5530
|
+
category: "classes",
|
|
5531
|
+
imageUrl: img("1517433367423-c7e5b0f35086"),
|
|
5532
|
+
tags: ["class", "service", "advanced"],
|
|
5533
|
+
productType: "service",
|
|
5534
|
+
durationMinutes: 180,
|
|
5535
|
+
isNew: true
|
|
5536
|
+
},
|
|
5537
|
+
// ── Rental service (Rental card — duration_unit=hours) ──
|
|
5538
|
+
{
|
|
5539
|
+
id: "prod_kitchen-rental",
|
|
5540
|
+
name: "Pro Kitchen Rental",
|
|
5541
|
+
slug: "kitchen-rental",
|
|
5542
|
+
price: "180.00",
|
|
5543
|
+
description: "Rent our commercial bakery after hours. Deck oven, retarder-proofer, mixers, scales \u2014 bring your team or shoot your content. Hourly.",
|
|
5544
|
+
category: "classes",
|
|
5545
|
+
imageUrl: img("1556909114-44e3e9399a2e"),
|
|
5546
|
+
tags: ["rental", "service", "commercial"],
|
|
5547
|
+
productType: "service",
|
|
5548
|
+
durationUnit: "hours"
|
|
5549
|
+
},
|
|
5550
|
+
// ── Accommodation (Accommodation card — duration_unit=nights) ──
|
|
5551
|
+
{
|
|
5552
|
+
id: "prod_loft-stay",
|
|
5553
|
+
name: "Bakery Loft \u2014 Weekend Stay",
|
|
5554
|
+
slug: "loft-stay",
|
|
5555
|
+
price: "650.00",
|
|
5556
|
+
description: "One-bedroom loft above the bakery. Wakes up to fresh croissants, ends with a private dinner. Ghana Tourism-licensed. Per night.",
|
|
5557
|
+
category: "classes",
|
|
5558
|
+
imageUrl: img("1564013799919-ab600027ffc6"),
|
|
5559
|
+
tags: ["stay", "service", "premium"],
|
|
5560
|
+
productType: "service",
|
|
5561
|
+
durationUnit: "nights"
|
|
5562
|
+
},
|
|
5563
|
+
// ── Subscription (Subscription card — billing_plans, no duration_minutes) ──
|
|
5564
|
+
{
|
|
5565
|
+
id: "prod_loaf-subscription",
|
|
5566
|
+
name: "Weekly Loaf Subscription",
|
|
5567
|
+
slug: "loaf-subscription",
|
|
5568
|
+
price: "0.00",
|
|
5569
|
+
description: "A fresh loaf delivered to your door every week. Pause or skip any time. Choose monthly or quarterly billing for a discount.",
|
|
5570
|
+
category: "classes",
|
|
5571
|
+
imageUrl: img("1509440159596-0249088772ff"),
|
|
5572
|
+
tags: ["subscription", "service", "delivery"],
|
|
5573
|
+
productType: "service",
|
|
5574
|
+
billingPlans: [
|
|
5575
|
+
{
|
|
5576
|
+
id: "plan_loaf_monthly",
|
|
5577
|
+
name: "Monthly",
|
|
5578
|
+
interval: "month",
|
|
5579
|
+
interval_count: 1,
|
|
5580
|
+
price: "90.00"
|
|
5581
|
+
},
|
|
5582
|
+
{
|
|
5583
|
+
id: "plan_loaf_quarterly",
|
|
5584
|
+
name: "Quarterly (save 10%)",
|
|
5585
|
+
interval: "month",
|
|
5586
|
+
interval_count: 3,
|
|
5587
|
+
price: "243.00"
|
|
5588
|
+
}
|
|
5589
|
+
]
|
|
5410
5590
|
}
|
|
5411
5591
|
];
|
|
5412
5592
|
for (const input of productInputs) {
|