PB-driven editorial copy + Hampers & Boxes category (Q1a, Q2, Q5)

- collection_rows: hampers-boxes row (seed default + ensure-row migration);
  /chocolate shows the button, /collections/hampers-boxes gets the two-tone
  hero (last-word script rule) + live Shopify hampers + row blurb as lead
- gifting_page: tabs/hampers/seasonal heading fields (seed + fill-missing
  migration, never overwrites admin edits); gifting.tsx consumes them
- site_settings: home seasonal + universe copy keys (seed + ensure-keys
  migration); index loader passes them to SeasonalTeaser/UniverseSection
- hero lead on collection pages falls back to the PB row blurb
This commit is contained in:
2026-09-06 15:22:50 +05:30
parent 06f6e75b57
commit 296c05cf88
7 changed files with 256 additions and 21 deletions
+108
View File
@@ -205,6 +205,15 @@ const COLLECTION_ROWS = [
sort: 7,
visible: true,
},
{
shopify_handle: "hampers-boxes",
name_override: "Hampers & Boxes",
blurb: "Celebration hampers and keepsake boxes, composed to order",
carousel_urls:
"/products/mozi20.jpg\n/products/mozi-33.jpg\n/products/mozi21.jpg",
sort: 8,
visible: true,
},
];
const GIFTING_PAGE = [
@@ -214,6 +223,14 @@ const GIFTING_PAGE = [
hero_script: "giving",
hero_lead:
"Some gifts are opened. Others are remembered. Every Mozimo hamper is composed by hand — chocolate first, packaging worthy of it second.",
tabs_eyebrow: "Who is it for?",
tabs_title: "Gifts,",
tabs_script: "price by price",
hampers_title: "Hampers &",
hampers_script: "boxes",
seasonal_eyebrow: "The Seasonal Edit",
seasonal_title: "Chocolate for the",
seasonal_script: "calendar",
sort: 0,
},
];
@@ -296,6 +313,14 @@ const SCHEMAS = {
{ name: "hero_title", type: "text" },
{ name: "hero_script", type: "text" },
{ name: "hero_lead", type: "text" },
{ name: "tabs_eyebrow", type: "text" },
{ name: "tabs_title", type: "text" },
{ name: "tabs_script", type: "text" },
{ name: "hampers_title", type: "text" },
{ name: "hampers_script", type: "text" },
{ name: "seasonal_eyebrow", type: "text" },
{ name: "seasonal_title", type: "text" },
{ name: "seasonal_script", type: "text" },
{ name: "sort", type: "number" },
],
},
@@ -308,6 +333,41 @@ const SITE_SETTINGS = [
"Complimentary delivery in Chandigarh Tricity on orders above ₹1,500 · Intercity shipped at actuals",
sort: 0,
},
{
key: "home_seasonal_eyebrow",
value: "The Seasonal Edit",
sort: 1,
},
{
key: "home_seasonal_title",
value: "Chocolate for the",
sort: 2,
},
{
key: "home_seasonal_script",
value: "calendar",
sort: 3,
},
{
key: "home_universe_eyebrow",
value: "Our World",
sort: 4,
},
{
key: "home_universe_title",
value: "Discover the universe of",
sort: 5,
},
{
key: "home_universe_script",
value: "Mozimo",
sort: 6,
},
{
key: "home_universe_cta",
value: "Explore our world",
sort: 7,
},
];
const CORPORATE_CHILDREN = [
@@ -475,6 +535,54 @@ async function main() {
}
}
}
// migration: fill section copy that arrived after the record was seeded
// (only empty fields — anything edited in the admin is never overwritten)
if (name === "gifting_page") {
const rec = (await authed(`/api/collections/${name}/records?perPage=1`)).body.items?.[0];
if (rec) {
const patch = {};
for (const [k, v] of Object.entries(SEEDS[name][0] ?? {})) {
if (k !== "sort" && !rec[k]) patch[k] = v;
}
if (Object.keys(patch).length) {
const patched = await authed(`/api/collections/${name}/records/${rec.id}`, {
method: "PATCH",
body: JSON.stringify(patch),
});
if (patched.ok)
console.log(`[pb-seed] gifting_page: filled ${Object.keys(patch).length} empty field(s)`);
}
}
}
// migration: make sure editorial rows/settings that shipped later exist
if (name === "collection_rows") {
const all = (await authed(`/api/collections/${name}/records?perPage=100`)).body.items ?? [];
for (const row of COLLECTION_ROWS) {
if (!all.some((r) => r.shopify_handle === row.shopify_handle)) {
const inserted = await authed(`/api/collections/${name}/records`, {
method: "POST",
body: JSON.stringify(row),
});
if (inserted.ok)
console.log(`[pb-seed] collection_rows: added missing row "${row.name_override}"`);
}
}
}
if (name === "site_settings") {
const all = (await authed(`/api/collections/${name}/records?perPage=100`)).body.items ?? [];
for (const setting of SITE_SETTINGS) {
if (!all.some((r) => r.key === setting.key)) {
const inserted = await authed(`/api/collections/${name}/records`, {
method: "POST",
body: JSON.stringify(setting),
});
if (inserted.ok)
console.log(`[pb-seed] site_settings: added "${setting.key}"`);
}
}
}
continue;
}
for (const record of SEEDS[name]) {