@cogenta/starters 0.2.2 → 0.4.0
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/blueprints/assets/photos/association/coat-bank.jpg +0 -0
- package/dist/blueprints/assets/photos/association/food-bank.jpg +0 -0
- package/dist/blueprints/assets/photos/association/garden-corner.jpg +0 -0
- package/dist/blueprints/assets/photos/association/garden-planting.jpg +0 -0
- package/dist/blueprints/assets/photos/association/hall.jpg +0 -0
- package/dist/blueprints/assets/photos/association/hero.jpg +0 -0
- package/dist/blueprints/assets/photos/association/homework-club.jpg +0 -0
- package/dist/blueprints/assets/photos/association/orientation.jpg +0 -0
- package/dist/blueprints/assets/photos/association/partner-fr-college.png +0 -0
- package/dist/blueprints/assets/photos/association/partner-fr-delcourt.png +0 -0
- package/dist/blueprints/assets/photos/association/partner-fr-fondation.png +0 -0
- package/dist/blueprints/assets/photos/association/partner-fr-habitat.png +0 -0
- package/dist/blueprints/assets/photos/association/partner-fr-mairie.png +0 -0
- package/dist/blueprints/assets/photos/association/partner-fr-pharmacie.png +0 -0
- package/dist/blueprints/assets/photos/association/supper.jpg +0 -0
- package/dist/blueprints/assets/photos/blog/desk-setup.jpg +0 -0
- package/dist/blueprints/assets/photos/blog/library.jpg +0 -0
- package/dist/blueprints/assets/photos/blog/notebook-and-coffee.jpg +0 -0
- package/dist/blueprints/assets/photos/blog/notebooks.jpg +0 -0
- package/dist/blueprints/assets/photos/blog/platform.jpg +0 -0
- package/dist/blueprints/assets/photos/blog/pour-over.jpg +0 -0
- package/dist/blueprints/assets/photos/blog/typing.jpg +0 -0
- package/dist/blueprints/assets/photos/documentation/delivery-flow-en.png +0 -0
- package/dist/blueprints/assets/photos/documentation/delivery-flow-fr.png +0 -0
- package/dist/blueprints/assets/photos/magazine/allotments.jpg +0 -0
- package/dist/blueprints/assets/photos/magazine/archive-stacks.jpg +0 -0
- package/dist/blueprints/assets/photos/magazine/baguettes.jpg +0 -0
- package/dist/blueprints/assets/photos/magazine/dining-room.jpg +0 -0
- package/dist/blueprints/assets/photos/magazine/empty-tram-stop.jpg +0 -0
- package/dist/blueprints/assets/photos/magazine/gallery.jpg +0 -0
- package/dist/blueprints/assets/photos/magazine/office-block-dusk.jpg +0 -0
- package/dist/blueprints/assets/photos/magazine/reading-room.jpg +0 -0
- package/dist/blueprints/assets/photos/magazine/reception-hall.jpg +0 -0
- package/dist/blueprints/assets/photos/magazine/theatre.jpg +0 -0
- package/dist/blueprints/assets/photos/magazine/town-hall.jpg +0 -0
- package/dist/blueprints/assets/photos/magazine/tram-stop.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/coast-boats.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/coast-cover.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/coast-ridge.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/coast-water.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/forest-beech.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/forest-birch.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/forest-branches.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/forest-cover.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/glacier-cave.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/glacier-cover.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/glacier-melt.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/glacier-tongue.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/lagoon-cover.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/lagoon-egret.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/lagoon-shore.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/lagoon-storm.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/port-cover.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/port-dusk.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/port-marina.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/port-quay.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/towers-cover.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/towers-green.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/towers-single.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/towers-valley.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/vines-cover.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/vines-grapes.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/vines-shed.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/vines-tree.jpg +0 -0
- package/dist/blueprints/assets/photos/restaurant/beetroot-carpaccio.jpg +0 -0
- package/dist/blueprints/assets/photos/restaurant/chocolate-tart.jpg +0 -0
- package/dist/blueprints/assets/photos/restaurant/cod-vin-jaune.jpg +0 -0
- package/dist/blueprints/assets/photos/restaurant/duck-confit.jpg +0 -0
- package/dist/blueprints/assets/photos/restaurant/grilled-octopus.jpg +0 -0
- package/dist/blueprints/assets/photos/restaurant/hero.jpg +0 -0
- package/dist/blueprints/assets/photos/restaurant/market-stall.jpg +0 -0
- package/dist/blueprints/assets/photos/restaurant/mushroom-risotto.jpg +0 -0
- package/dist/blueprints/assets/photos/restaurant/pike-quenelle.jpg +0 -0
- package/dist/blueprints/assets/photos/restaurant/poached-pear.jpg +0 -0
- package/dist/blueprints/assets/photos/restaurant/praline-cake.jpg +0 -0
- package/dist/blueprints/assets/photos/restaurant/pumpkin-soup.jpg +0 -0
- package/dist/blueprints/assets/photos/restaurant/street-burdeau.jpg +0 -0
- package/dist/blueprints/assets/photos/saas/api-webhooks-en.png +0 -0
- package/dist/blueprints/assets/photos/saas/api-webhooks-fr.png +0 -0
- package/dist/blueprints/assets/photos/saas/approvals-queue-en.png +0 -0
- package/dist/blueprints/assets/photos/saas/approvals-queue-fr.png +0 -0
- package/dist/blueprints/assets/photos/saas/audit-log-en.png +0 -0
- package/dist/blueprints/assets/photos/saas/audit-log-fr.png +0 -0
- package/dist/blueprints/assets/photos/saas/erp-sync-en.png +0 -0
- package/dist/blueprints/assets/photos/saas/erp-sync-fr.png +0 -0
- package/dist/blueprints/assets/photos/saas/logo-castellan-alimentaire.png +0 -0
- package/dist/blueprints/assets/photos/saas/logo-cliniques-du-vivier.png +0 -0
- package/dist/blueprints/assets/photos/saas/logo-marenne-logistique.png +0 -0
- package/dist/blueprints/assets/photos/saas/logo-nordgate-habitat.png +0 -0
- package/dist/blueprints/assets/photos/saas/logo-tessaly-energies.png +0 -0
- package/dist/blueprints/assets/photos/saas/office-london.jpg +0 -0
- package/dist/blueprints/assets/photos/saas/office-montreal.jpg +0 -0
- package/dist/blueprints/assets/photos/saas/office-paris.jpg +0 -0
- package/dist/blueprints/assets/photos/saas/office-toronto.jpg +0 -0
- package/dist/blueprints/assets/photos/saas/policy-editor-en.png +0 -0
- package/dist/blueprints/assets/photos/saas/policy-editor-fr.png +0 -0
- package/dist/blueprints/assets/photos/saas/security-racks.jpg +0 -0
- package/dist/blueprints/assets/photos/saas/spend-reporting-en.png +0 -0
- package/dist/blueprints/assets/photos/saas/spend-reporting-fr.png +0 -0
- package/dist/blueprints/assets/photos/saas/sso-scim-en.png +0 -0
- package/dist/blueprints/assets/photos/saas/sso-scim-fr.png +0 -0
- package/dist/blueprints/assets/photos/store/aleppo-soap.jpg +0 -0
- package/dist/blueprints/assets/photos/store/copper-pan.jpg +0 -0
- package/dist/blueprints/assets/photos/store/crochet-throw.jpg +0 -0
- package/dist/blueprints/assets/photos/store/enamel-mug.jpg +0 -0
- package/dist/blueprints/assets/photos/store/hero.jpg +0 -0
- package/dist/blueprints/assets/photos/store/knit-sweater.jpg +0 -0
- package/dist/blueprints/assets/photos/store/leather-boots.jpg +0 -0
- package/dist/blueprints/assets/photos/store/leather-duffel.jpg +0 -0
- package/dist/blueprints/assets/photos/store/leather-wallet.jpg +0 -0
- package/dist/blueprints/assets/photos/store/moka-pot.jpg +0 -0
- package/dist/blueprints/assets/photos/store/skillet.jpg +0 -0
- package/dist/blueprints/assets/photos/store/stoneware-bottles.jpg +0 -0
- package/dist/blueprints/assets/photos/store/story.jpg +0 -0
- package/dist/blueprints/assets/photos/store/turned-bowl.jpg +0 -0
- package/dist/blueprints/association-copy-en.d.ts +3 -0
- package/dist/blueprints/association-copy-en.d.ts.map +1 -0
- package/dist/blueprints/association-copy-en.js +834 -0
- package/dist/blueprints/association-copy-en.js.map +1 -0
- package/dist/blueprints/association-copy-fr.d.ts +3 -0
- package/dist/blueprints/association-copy-fr.d.ts.map +1 -0
- package/dist/blueprints/association-copy-fr.js +841 -0
- package/dist/blueprints/association-copy-fr.js.map +1 -0
- package/dist/blueprints/association-copy.d.ts +301 -0
- package/dist/blueprints/association-copy.d.ts.map +1 -0
- package/dist/blueprints/association-copy.js +17 -0
- package/dist/blueprints/association-copy.js.map +1 -0
- package/dist/blueprints/association-credits.d.ts +16 -0
- package/dist/blueprints/association-credits.d.ts.map +1 -0
- package/dist/blueprints/association-credits.js +80 -0
- package/dist/blueprints/association-credits.js.map +1 -0
- package/dist/blueprints/association-typography.d.ts +23 -0
- package/dist/blueprints/association-typography.d.ts.map +1 -0
- package/dist/blueprints/association-typography.js +55 -0
- package/dist/blueprints/association-typography.js.map +1 -0
- package/dist/blueprints/association.d.ts +86 -287
- package/dist/blueprints/association.d.ts.map +1 -1
- package/dist/blueprints/association.js +510 -1082
- package/dist/blueprints/association.js.map +1 -1
- package/dist/blueprints/blog-copy-en.d.ts +4 -0
- package/dist/blueprints/blog-copy-en.d.ts.map +1 -0
- package/dist/blueprints/blog-copy-en.js +701 -0
- package/dist/blueprints/blog-copy-en.js.map +1 -0
- package/dist/blueprints/blog-copy-fr.d.ts +12 -0
- package/dist/blueprints/blog-copy-fr.d.ts.map +1 -0
- package/dist/blueprints/blog-copy-fr.js +722 -0
- package/dist/blueprints/blog-copy-fr.js.map +1 -0
- package/dist/blueprints/blog-copy.d.ts +157 -0
- package/dist/blueprints/blog-copy.d.ts.map +1 -0
- package/dist/blueprints/blog-copy.js +2 -0
- package/dist/blueprints/blog-copy.js.map +1 -0
- package/dist/blueprints/blog-credits.d.ts +28 -0
- package/dist/blueprints/blog-credits.d.ts.map +1 -0
- package/dist/blueprints/blog-credits.js +73 -0
- package/dist/blueprints/blog-credits.js.map +1 -0
- package/dist/blueprints/blog-rich.d.ts +19 -0
- package/dist/blueprints/blog-rich.d.ts.map +1 -0
- package/dist/blueprints/blog-rich.js +51 -0
- package/dist/blueprints/blog-rich.js.map +1 -0
- package/dist/blueprints/blog.d.ts +51 -176
- package/dist/blueprints/blog.d.ts.map +1 -1
- package/dist/blueprints/blog.js +358 -947
- package/dist/blueprints/blog.js.map +1 -1
- package/dist/blueprints/content-pack.d.ts.map +1 -1
- package/dist/blueprints/content-pack.js +11 -16
- package/dist/blueprints/content-pack.js.map +1 -1
- package/dist/blueprints/content-packs.d.ts +2 -4
- package/dist/blueprints/content-packs.d.ts.map +1 -1
- package/dist/blueprints/content-packs.js +27 -15
- package/dist/blueprints/content-packs.js.map +1 -1
- package/dist/blueprints/documentation-copy-en.d.ts +3 -0
- package/dist/blueprints/documentation-copy-en.d.ts.map +1 -0
- package/dist/blueprints/documentation-copy-en.js +883 -0
- package/dist/blueprints/documentation-copy-en.js.map +1 -0
- package/dist/blueprints/documentation-copy-fr.d.ts +3 -0
- package/dist/blueprints/documentation-copy-fr.d.ts.map +1 -0
- package/dist/blueprints/documentation-copy-fr.js +939 -0
- package/dist/blueprints/documentation-copy-fr.js.map +1 -0
- package/dist/blueprints/documentation-copy.d.ts +52 -0
- package/dist/blueprints/documentation-copy.d.ts.map +1 -0
- package/dist/blueprints/documentation-copy.js +2 -0
- package/dist/blueprints/documentation-copy.js.map +1 -0
- package/dist/blueprints/documentation-writer.d.ts +67 -0
- package/dist/blueprints/documentation-writer.d.ts.map +1 -0
- package/dist/blueprints/documentation-writer.js +190 -0
- package/dist/blueprints/documentation-writer.js.map +1 -0
- package/dist/blueprints/documentation.d.ts +26 -29
- package/dist/blueprints/documentation.d.ts.map +1 -1
- package/dist/blueprints/documentation.js +106 -1064
- package/dist/blueprints/documentation.js.map +1 -1
- package/dist/blueprints/magazine-copy-en.d.ts +13 -0
- package/dist/blueprints/magazine-copy-en.d.ts.map +1 -0
- package/dist/blueprints/magazine-copy-en.js +553 -0
- package/dist/blueprints/magazine-copy-en.js.map +1 -0
- package/dist/blueprints/magazine-copy-fr.d.ts +14 -0
- package/dist/blueprints/magazine-copy-fr.d.ts.map +1 -0
- package/dist/blueprints/magazine-copy-fr.js +568 -0
- package/dist/blueprints/magazine-copy-fr.js.map +1 -0
- package/dist/blueprints/magazine-copy.d.ts +166 -0
- package/dist/blueprints/magazine-copy.d.ts.map +1 -0
- package/dist/blueprints/magazine-copy.js +58 -0
- package/dist/blueprints/magazine-copy.js.map +1 -0
- package/dist/blueprints/magazine-credits.d.ts +19 -0
- package/dist/blueprints/magazine-credits.d.ts.map +1 -0
- package/dist/blueprints/magazine-credits.js +109 -0
- package/dist/blueprints/magazine-credits.js.map +1 -0
- package/dist/blueprints/magazine.d.ts +30 -78
- package/dist/blueprints/magazine.d.ts.map +1 -1
- package/dist/blueprints/magazine.js +269 -690
- package/dist/blueprints/magazine.js.map +1 -1
- package/dist/blueprints/portfolio-copy-en.d.ts +4 -0
- package/dist/blueprints/portfolio-copy-en.d.ts.map +1 -0
- package/dist/blueprints/portfolio-copy-en.js +745 -0
- package/dist/blueprints/portfolio-copy-en.js.map +1 -0
- package/dist/blueprints/portfolio-copy-fr.d.ts +9 -0
- package/dist/blueprints/portfolio-copy-fr.d.ts.map +1 -0
- package/dist/blueprints/portfolio-copy-fr.js +737 -0
- package/dist/blueprints/portfolio-copy-fr.js.map +1 -0
- package/dist/blueprints/portfolio-copy.d.ts +204 -0
- package/dist/blueprints/portfolio-copy.d.ts.map +1 -0
- package/dist/blueprints/portfolio-copy.js +15 -0
- package/dist/blueprints/portfolio-copy.js.map +1 -0
- package/dist/blueprints/portfolio-credits.d.ts +18 -0
- package/dist/blueprints/portfolio-credits.d.ts.map +1 -0
- package/dist/blueprints/portfolio-credits.js +239 -0
- package/dist/blueprints/portfolio-credits.js.map +1 -0
- package/dist/blueprints/portfolio-typography.d.ts +19 -0
- package/dist/blueprints/portfolio-typography.d.ts.map +1 -0
- package/dist/blueprints/portfolio-typography.js +41 -0
- package/dist/blueprints/portfolio-typography.js.map +1 -0
- package/dist/blueprints/portfolio.d.ts +68 -157
- package/dist/blueprints/portfolio.d.ts.map +1 -1
- package/dist/blueprints/portfolio.js +475 -727
- package/dist/blueprints/portfolio.js.map +1 -1
- package/dist/blueprints/restaurant-copy-en.d.ts +3 -0
- package/dist/blueprints/restaurant-copy-en.d.ts.map +1 -0
- package/dist/blueprints/restaurant-copy-en.js +641 -0
- package/dist/blueprints/restaurant-copy-en.js.map +1 -0
- package/dist/blueprints/restaurant-copy-fr.d.ts +3 -0
- package/dist/blueprints/restaurant-copy-fr.d.ts.map +1 -0
- package/dist/blueprints/restaurant-copy-fr.js +665 -0
- package/dist/blueprints/restaurant-copy-fr.js.map +1 -0
- package/dist/blueprints/restaurant-copy.d.ts +234 -0
- package/dist/blueprints/restaurant-copy.d.ts.map +1 -0
- package/dist/blueprints/restaurant-copy.js +15 -0
- package/dist/blueprints/restaurant-copy.js.map +1 -0
- package/dist/blueprints/restaurant-credits.d.ts +18 -0
- package/dist/blueprints/restaurant-credits.d.ts.map +1 -0
- package/dist/blueprints/restaurant-credits.js +121 -0
- package/dist/blueprints/restaurant-credits.js.map +1 -0
- package/dist/blueprints/restaurant.d.ts +55 -128
- package/dist/blueprints/restaurant.d.ts.map +1 -1
- package/dist/blueprints/restaurant.js +425 -770
- package/dist/blueprints/restaurant.js.map +1 -1
- package/dist/blueprints/saas-copy-en.d.ts +3 -0
- package/dist/blueprints/saas-copy-en.d.ts.map +1 -0
- package/dist/blueprints/saas-copy-en.js +901 -0
- package/dist/blueprints/saas-copy-en.js.map +1 -0
- package/dist/blueprints/saas-copy-fr.d.ts +3 -0
- package/dist/blueprints/saas-copy-fr.d.ts.map +1 -0
- package/dist/blueprints/saas-copy-fr.js +912 -0
- package/dist/blueprints/saas-copy-fr.js.map +1 -0
- package/dist/blueprints/saas-copy.d.ts +266 -0
- package/dist/blueprints/saas-copy.d.ts.map +1 -0
- package/dist/blueprints/saas-copy.js +18 -0
- package/dist/blueprints/saas-copy.js.map +1 -0
- package/dist/blueprints/saas-credits.d.ts +22 -0
- package/dist/blueprints/saas-credits.d.ts.map +1 -0
- package/dist/blueprints/saas-credits.js +44 -0
- package/dist/blueprints/saas-credits.js.map +1 -0
- package/dist/blueprints/saas.d.ts +59 -203
- package/dist/blueprints/saas.d.ts.map +1 -1
- package/dist/blueprints/saas.js +505 -1108
- package/dist/blueprints/saas.js.map +1 -1
- package/dist/blueprints/store-copy-en.d.ts +4 -0
- package/dist/blueprints/store-copy-en.d.ts.map +1 -0
- package/dist/blueprints/store-copy-en.js +521 -0
- package/dist/blueprints/store-copy-en.js.map +1 -0
- package/dist/blueprints/store-copy-fr.d.ts +4 -0
- package/dist/blueprints/store-copy-fr.d.ts.map +1 -0
- package/dist/blueprints/store-copy-fr.js +521 -0
- package/dist/blueprints/store-copy-fr.js.map +1 -0
- package/dist/blueprints/store-copy.d.ts +219 -0
- package/dist/blueprints/store-copy.d.ts.map +1 -0
- package/dist/blueprints/store-copy.js +16 -0
- package/dist/blueprints/store-copy.js.map +1 -0
- package/dist/blueprints/store-credits.d.ts +3 -0
- package/dist/blueprints/store-credits.d.ts.map +1 -0
- package/dist/blueprints/store-credits.js +117 -0
- package/dist/blueprints/store-credits.js.map +1 -0
- package/dist/blueprints/store.d.ts +43 -231
- package/dist/blueprints/store.d.ts.map +1 -1
- package/dist/blueprints/store.js +466 -789
- package/dist/blueprints/store.js.map +1 -1
- package/dist/blueprints/vitrine-copy-en.d.ts.map +1 -1
- package/dist/blueprints/vitrine-copy-en.js +1 -0
- package/dist/blueprints/vitrine-copy-en.js.map +1 -1
- package/dist/blueprints/vitrine-copy-fr.d.ts.map +1 -1
- package/dist/blueprints/vitrine-copy-fr.js +1 -0
- package/dist/blueprints/vitrine-copy-fr.js.map +1 -1
- package/dist/blueprints/vitrine-copy.d.ts +1 -0
- package/dist/blueprints/vitrine-copy.d.ts.map +1 -1
- package/dist/blueprints/vitrine.d.ts +1 -0
- package/dist/blueprints/vitrine.d.ts.map +1 -1
- package/dist/blueprints/vitrine.js +24 -3
- package/dist/blueprints/vitrine.js.map +1 -1
- package/package.json +10 -10
- package/dist/blueprints/assets/photos/association/fundraising-dinner.jpg +0 -0
- package/dist/blueprints/assets/photos/association/volunteer-orientation.jpg +0 -0
- package/dist/blueprints/assets/photos/association/volunteer-portrait.jpg +0 -0
- package/dist/blueprints/assets/photos/association/winter-coat-collection.jpg +0 -0
- package/dist/blueprints/assets/photos/documentation/delivery-flow.png +0 -0
- package/dist/blueprints/assets/photos/magazine/archive-room.jpg +0 -0
- package/dist/blueprints/assets/photos/magazine/banquet-hall.jpg +0 -0
- package/dist/blueprints/assets/photos/magazine/city-hall.jpg +0 -0
- package/dist/blueprints/assets/photos/magazine/downtown-towers.jpg +0 -0
- package/dist/blueprints/assets/photos/magazine/gallery-opening.jpg +0 -0
- package/dist/blueprints/assets/photos/magazine/garden-volunteers.jpg +0 -0
- package/dist/blueprints/assets/photos/magazine/station-platform.jpg +0 -0
- package/dist/blueprints/assets/photos/magazine/theater-stage.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/fenmore-branch.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/fenmore-cover.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/fenmore-stationery.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/gannet-cover.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/gannet-sardines.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/gannet-shelf.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/hollis-crane-cover.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/hollis-crane-grid.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/hollis-crane-salt-year.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/hollis-crane-spines.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/rookery-hall-brochure.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/rookery-hall-cover.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/rookery-hall-poster-carnival.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/rookery-hall-poster-sibelius.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/rookery-hall-series.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/saltmarsh-quay-cover.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/saltmarsh-quay-gate.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/saltmarsh-quay-pictograms.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/saltmarsh-quay-totem.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/tidewater-cover.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/tidewater-data.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/tidewater-report-cover.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/warp-and-weft-cover.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/warp-and-weft-room.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/westmoor-rail-components.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/westmoor-rail-cover.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/westmoor-rail-departures.jpg +0 -0
- package/dist/blueprints/assets/photos/restaurant/beetroot-goats-curd.jpg +0 -0
- package/dist/blueprints/assets/photos/restaurant/ceps-risotto.jpg +0 -0
- package/dist/blueprints/assets/photos/restaurant/duck-leg-red-cabbage.jpg +0 -0
- package/dist/blueprints/assets/photos/restaurant/hake-green-peppercorns.jpg +0 -0
- package/dist/blueprints/assets/photos/restaurant/vegetable-broth.jpg +0 -0
- package/dist/blueprints/assets/photos/saas/adrian-tan.jpg +0 -0
- package/dist/blueprints/assets/photos/saas/api-webhooks.png +0 -0
- package/dist/blueprints/assets/photos/saas/approvals-queue.png +0 -0
- package/dist/blueprints/assets/photos/saas/audit-log.png +0 -0
- package/dist/blueprints/assets/photos/saas/erp-sync.png +0 -0
- package/dist/blueprints/assets/photos/saas/policy-editor.png +0 -0
- package/dist/blueprints/assets/photos/saas/spend-reporting.png +0 -0
- package/dist/blueprints/assets/photos/saas/sso-scim.png +0 -0
- package/dist/blueprints/assets/photos/store/brushed-cotton-overshirt.jpg +0 -0
- package/dist/blueprints/assets/photos/store/cable-knit-beanie.jpg +0 -0
- package/dist/blueprints/assets/photos/store/canvas-shoulder-bag.jpg +0 -0
- package/dist/blueprints/assets/photos/store/canvas-tote.jpg +0 -0
- package/dist/blueprints/assets/photos/store/cast-iron-skillet.jpg +0 -0
- package/dist/blueprints/assets/photos/store/field-jacket.jpg +0 -0
- package/dist/blueprints/assets/photos/store/heavyweight-t-shirt.jpg +0 -0
- package/dist/blueprints/assets/photos/store/leather-card-holder.jpg +0 -0
- package/dist/blueprints/assets/photos/store/linen-table-runner.jpg +0 -0
- package/dist/blueprints/assets/photos/store/porcelain-pour-over-set.jpg +0 -0
- package/dist/blueprints/assets/photos/store/striped-wool-blanket.jpg +0 -0
package/dist/blueprints/store.js
CHANGED
|
@@ -3,13 +3,22 @@ import { createContentStore, defineCollection, f, validateCollectionSet, } from
|
|
|
3
3
|
import { coverArt, heroArt, productArt } from '../demo-art/compositions.js';
|
|
4
4
|
import { definePageCollection, SEO_FIELDS, toBlockZoneEntry, } from './content-pack.js';
|
|
5
5
|
import { STARTING_SKINS } from './starting-skins.js';
|
|
6
|
+
import { STORE_COPY_EN } from './store-copy-en.js';
|
|
7
|
+
import { STORE_COPY_FR } from './store-copy-fr.js';
|
|
8
|
+
import { STORE_PHOTO_CREDITS } from './store-credits.js';
|
|
6
9
|
/**
|
|
7
|
-
* The `store` blueprint (L27, `@cogenta/theme-ecommerce`): a small
|
|
8
|
-
* durable everyday goods with a
|
|
9
|
-
* products from the workshops it buys from,
|
|
10
|
-
* real shop needs before it takes an order (how to order, delivery and
|
|
10
|
+
* The `store` blueprint (L27, `@cogenta/theme-ecommerce`): a small shop in
|
|
11
|
+
* Lyon of durable everyday goods with a repair bench behind the counter,
|
|
12
|
+
* twelve products from the workshops it buys from, three departments, and the
|
|
13
|
+
* pages a real shop needs before it takes an order (how to order, delivery and
|
|
11
14
|
* returns, repairs, contact, terms).
|
|
12
15
|
*
|
|
16
|
+
* Written in French and in English, not translated at render time: the
|
|
17
|
+
* installer picks the copy for the site's default locale, and with it the
|
|
18
|
+
* addresses (`/boutique/…` in French, `/shop/…` in English), the names the
|
|
19
|
+
* administration shows and every word of demo content. Every photograph is a
|
|
20
|
+
* real one under an open licence, credited on its own page.
|
|
21
|
+
*
|
|
13
22
|
* **Contract A only, and no checkout.** A blueprint writes
|
|
14
23
|
* `cogenta.schema.mjs` and seeds content; it cannot provision
|
|
15
24
|
* `@cogenta/commerce`'s tables (contract E, ADR-0024), and contract B has no
|
|
@@ -27,7 +36,10 @@ import { STARTING_SKINS } from './starting-skins.js';
|
|
|
27
36
|
* list filters on and what the product page prints.
|
|
28
37
|
*/
|
|
29
38
|
export const DEFAULT_SHOP_NAME = 'Atelier Goods';
|
|
30
|
-
|
|
39
|
+
/** The copy for a site's default locale: French for any `fr*` locale, English otherwise. */
|
|
40
|
+
export function storeCopyFor(locale) {
|
|
41
|
+
return locale.toLowerCase().startsWith('fr') ? STORE_COPY_FR : STORE_COPY_EN;
|
|
42
|
+
}
|
|
31
43
|
const CURRENCIES = ['EUR', 'GBP', 'CHF', 'DKK', 'SEK', 'USD'];
|
|
32
44
|
const PERMISSIONS = {
|
|
33
45
|
read: ['public'],
|
|
@@ -36,65 +48,65 @@ const PERMISSIONS = {
|
|
|
36
48
|
delete: ['admin'],
|
|
37
49
|
publish: ['admin'],
|
|
38
50
|
};
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
max:
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
max: 300,
|
|
63
|
-
multiline: true,
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
})
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
export const
|
|
96
|
-
export const
|
|
97
|
-
|
|
51
|
+
/** The content model, named and routed in the copy's language. */
|
|
52
|
+
export function storeSchema(copy) {
|
|
53
|
+
const product = defineCollection({
|
|
54
|
+
name: 'product',
|
|
55
|
+
versioning: { drafts: true, history: true },
|
|
56
|
+
labels: copy.schema.labels.product,
|
|
57
|
+
routing: { pattern: copy.schema.routes.product },
|
|
58
|
+
fields: {
|
|
59
|
+
name: f.text({ required: true, max: 120 }),
|
|
60
|
+
slug: f.slug({ from: 'name', unique: true }),
|
|
61
|
+
description: f.text({ max: 300, multiline: true }),
|
|
62
|
+
price: f.number({ required: true, min: 0 }),
|
|
63
|
+
currency: f.select({ options: [...CURRENCIES], default: 'EUR' }),
|
|
64
|
+
category: f.select({
|
|
65
|
+
options: copy.categories.map((entry) => entry.name),
|
|
66
|
+
required: true,
|
|
67
|
+
}),
|
|
68
|
+
inStock: f.boolean({ default: true }),
|
|
69
|
+
material: f.text({ max: 200 }),
|
|
70
|
+
dimensions: f.text({ max: 200 }),
|
|
71
|
+
weight: f.text({ max: 60 }),
|
|
72
|
+
capacity: f.text({ max: 60 }),
|
|
73
|
+
origin: f.text({ max: 160 }),
|
|
74
|
+
care: f.text({ max: 300, multiline: true }),
|
|
75
|
+
delivery: f.text({ max: 300, multiline: true }),
|
|
76
|
+
orderLink: f.text({ max: 400 }),
|
|
77
|
+
photo: f.media({ accept: ['image'] }),
|
|
78
|
+
blocks: f.blocks(),
|
|
79
|
+
...SEO_FIELDS,
|
|
80
|
+
},
|
|
81
|
+
indexes: [['slug'], ['category']],
|
|
82
|
+
permissions: PERMISSIONS,
|
|
83
|
+
});
|
|
84
|
+
const category = defineCollection({
|
|
85
|
+
name: 'category',
|
|
86
|
+
versioning: { drafts: true, history: true },
|
|
87
|
+
labels: copy.schema.labels.category,
|
|
88
|
+
routing: { pattern: copy.schema.routes.category },
|
|
89
|
+
fields: {
|
|
90
|
+
name: f.text({ required: true, max: 80 }),
|
|
91
|
+
slug: f.slug({ from: 'name', unique: true }),
|
|
92
|
+
summary: f.text({ max: 240, multiline: true }),
|
|
93
|
+
photo: f.media({ accept: ['image'] }),
|
|
94
|
+
blocks: f.blocks(),
|
|
95
|
+
...SEO_FIELDS,
|
|
96
|
+
},
|
|
97
|
+
indexes: [['slug']],
|
|
98
|
+
permissions: PERMISSIONS,
|
|
99
|
+
});
|
|
100
|
+
const page = definePageCollection('/:slug');
|
|
101
|
+
const collections = [product, category, page];
|
|
102
|
+
validateCollectionSet(collections);
|
|
103
|
+
return { product, category, page, collections };
|
|
104
|
+
}
|
|
105
|
+
const ENGLISH_SCHEMA = storeSchema(STORE_COPY_EN);
|
|
106
|
+
export const product = ENGLISH_SCHEMA.product;
|
|
107
|
+
export const category = ENGLISH_SCHEMA.category;
|
|
108
|
+
export const page = ENGLISH_SCHEMA.page;
|
|
109
|
+
export const STORE_COLLECTIONS = ENGLISH_SCHEMA.collections;
|
|
98
110
|
const BLOCK_VERSION = '1.0.0';
|
|
99
111
|
// ---------------------------------------------------------------------------
|
|
100
112
|
// Copy helpers
|
|
@@ -112,6 +124,16 @@ function nameOf(siteName) {
|
|
|
112
124
|
const trimmed = siteName?.trim();
|
|
113
125
|
return trimmed === undefined || trimmed === '' ? DEFAULT_SHOP_NAME : trimmed;
|
|
114
126
|
}
|
|
127
|
+
function factsOf(siteName) {
|
|
128
|
+
const name = nameOf(siteName);
|
|
129
|
+
return {
|
|
130
|
+
name,
|
|
131
|
+
hello: shopEmail(name),
|
|
132
|
+
orders: shopEmail(name, 'orders'),
|
|
133
|
+
repairs: shopEmail(name, 'repairs'),
|
|
134
|
+
letters: shopEmail(name, 'letters'),
|
|
135
|
+
};
|
|
136
|
+
}
|
|
115
137
|
/**
|
|
116
138
|
* A paragraph where `[words](href)` becomes a link. Nothing else is
|
|
117
139
|
* interpreted: the copy stays plain text a person can read in this file.
|
|
@@ -156,270 +178,17 @@ function questions(key, items) {
|
|
|
156
178
|
answer: answer(`${key}-${index}-a`, text),
|
|
157
179
|
}));
|
|
158
180
|
}
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
category: 'Living',
|
|
171
|
-
price: 68,
|
|
172
|
-
inStock: false,
|
|
173
|
-
description: 'A long runner in washed white linen with knotted fringes, woven narrow enough to leave room for plates on either side.',
|
|
174
|
-
material: 'Linen, stone washed.',
|
|
175
|
-
dimensions: '45 × 200 cm, fringes included.',
|
|
176
|
-
origin: 'Guimarães, Portugal',
|
|
177
|
-
care: 'Wash at 40 °C and line dry. Linen looks best a little creased.',
|
|
178
|
-
delivery: 'The next weaving is due in April. Write to us and we will keep one aside for you.',
|
|
179
|
-
story: [
|
|
180
|
-
'Woven in Guimarães from flax grown in Normandy and spun in the north of Portugal. The ends are left to fray for a few centimetres and then knotted by hand, so there is no hem to pucker in the wash.',
|
|
181
|
-
'Stone washing softens the cloth before it reaches you. It turns whiter and more supple each time it is washed, and red wine comes out with cold water if you get to it the same evening.',
|
|
182
|
-
],
|
|
183
|
-
},
|
|
184
|
-
{
|
|
185
|
-
name: 'Enamel mug',
|
|
186
|
-
slug: 'enamel-mug',
|
|
187
|
-
category: 'Kitchen',
|
|
188
|
-
price: 24,
|
|
189
|
-
inStock: true,
|
|
190
|
-
description: 'A 350 ml mug in forest green enamel over steel, with a rolled stainless rim. Light enough for a rucksack and good enough for the table.',
|
|
191
|
-
material: 'Enamelled steel, stainless steel rim.',
|
|
192
|
-
capacity: '350 ml',
|
|
193
|
-
dimensions: '8.5 cm across, 8 cm high.',
|
|
194
|
-
origin: 'Olkusz, Poland',
|
|
195
|
-
care: 'Dishwasher safe. A chip in the enamel does not spread, so keep using it.',
|
|
196
|
-
delivery: SHIPS,
|
|
197
|
-
story: [
|
|
198
|
-
'Pressed and enamelled in Olkusz, a town that has made enamelware since the beginning of the last century. Each mug is dipped twice and fired at 800 °C, which gives the green its depth and a surface that coffee will not stain.',
|
|
199
|
-
'It can go on a camping stove and in the oven. We drink from these at the shop counter every morning, and some of ours have been in daily use for six years.',
|
|
200
|
-
],
|
|
201
|
-
},
|
|
202
|
-
{
|
|
203
|
-
name: 'Cable-knit beanie',
|
|
204
|
-
slug: 'cable-knit-beanie',
|
|
205
|
-
category: 'Wear',
|
|
206
|
-
price: 42,
|
|
207
|
-
inStock: true,
|
|
208
|
-
description: 'A deep, loose beanie in charcoal lambswool with a wide turn-up. Knitted on hand-flat machines and finished by hand.',
|
|
209
|
-
material: 'Lambswool, charcoal melange.',
|
|
210
|
-
dimensions: 'One size, 28 cm high unfolded.',
|
|
211
|
-
origin: 'Covilhã, Portugal',
|
|
212
|
-
care: 'Hand wash cold with wool soap and dry flat on a towel.',
|
|
213
|
-
delivery: SHIPS,
|
|
214
|
-
story: [
|
|
215
|
-
'Knitted in Covilhã, a town that once ran on its wool mills and still has a handful of knitters working hand-flat machines. The cable is set loose, so the hat rests on the head instead of gripping it.',
|
|
216
|
-
'Lambswool pills a little in the first weeks of wear. A wool comb takes it off, and the hat stays soft for years afterwards.',
|
|
217
|
-
],
|
|
218
|
-
},
|
|
219
|
-
{
|
|
220
|
-
name: 'Canvas tote',
|
|
221
|
-
slug: 'canvas-tote',
|
|
222
|
-
category: 'Carry',
|
|
223
|
-
price: 48,
|
|
224
|
-
inStock: true,
|
|
225
|
-
description: 'An undyed cotton canvas tote with handles long enough to wear over a coat. It stands up on its own and carries a week of shopping.',
|
|
226
|
-
material: 'Cotton canvas, 14 oz, undyed.',
|
|
227
|
-
dimensions: '38 × 42 × 12 cm. Handles 62 cm.',
|
|
228
|
-
origin: 'Lisbon, Portugal',
|
|
229
|
-
care: 'Machine wash cold, reshape while damp and dry flat. It softens and shrinks slightly.',
|
|
230
|
-
delivery: SHIPS,
|
|
231
|
-
story: [
|
|
232
|
-
'The first thing we ever made, and still the thing we sell most of. The body is one piece of canvas folded at the base, so there is no seam along the bottom to split, and the handles run down both sides to carry the weight.',
|
|
233
|
-
'It arrives undyed and a little stiff. After a few months it creases where you hold it and takes the shape of what you carry.',
|
|
234
|
-
],
|
|
235
|
-
},
|
|
236
|
-
{
|
|
237
|
-
name: 'Brushed cotton overshirt',
|
|
238
|
-
slug: 'brushed-cotton-overshirt',
|
|
239
|
-
category: 'Wear',
|
|
240
|
-
price: 98,
|
|
241
|
-
inStock: false,
|
|
242
|
-
description: 'A grey overshirt in brushed cotton flannel with a button-down collar and one chest pocket. Heavy enough to wear as a light jacket in spring.',
|
|
243
|
-
material: 'Cotton flannel, 220 g/m², brushed on both sides. Mother-of-pearl buttons.',
|
|
244
|
-
dimensions: 'Sizes S to XL. Size M: 76 cm back length, 57 cm across the chest.',
|
|
245
|
-
origin: 'Guimarães, Portugal',
|
|
246
|
-
care: 'Wash at 30 °C and line dry. Iron on low heat.',
|
|
247
|
-
delivery: 'The next batch is being cut and should reach the shop in March.',
|
|
248
|
-
story: [
|
|
249
|
-
'The flannel is brushed on both faces at a finishing mill outside Guimarães, which gives it a soft, slightly dusty surface and traps enough air to feel warm on a cold morning. We make it in one grey, a mix of undyed and black cotton.',
|
|
250
|
-
'This batch sold out in six weeks. Write to us and we will tell you when the next one arrives. Nothing is charged until it does.',
|
|
251
|
-
],
|
|
252
|
-
},
|
|
253
|
-
{
|
|
254
|
-
name: 'Cast-iron skillet',
|
|
255
|
-
slug: 'cast-iron-skillet',
|
|
256
|
-
category: 'Kitchen',
|
|
257
|
-
price: 89,
|
|
258
|
-
inStock: true,
|
|
259
|
-
description: 'A 26 cm skillet cast in one piece, with a pouring lip on each side. Seasoned with linseed oil and ready to cook with.',
|
|
260
|
-
material: 'Cast iron, seasoned with three coats of linseed oil.',
|
|
261
|
-
dimensions: '26 cm across, 5 cm deep, 45 cm with the handle.',
|
|
262
|
-
weight: '2.6 kg',
|
|
263
|
-
origin: 'Aveiro, Portugal',
|
|
264
|
-
care: 'Rinse with hot water and a brush, dry on the hob, wipe with a drop of oil. Keep it out of the dishwasher.',
|
|
265
|
-
delivery: 'Ships from Lisbon within two working days by tracked courier. Free returns within 30 days.',
|
|
266
|
-
story: [
|
|
267
|
-
'Cast in sand moulds at a foundry near Aveiro that otherwise makes parts for water pumps. The cooking surface is machined smoother than most cast iron, so the seasoning builds quickly and eggs release after a few weeks of use.',
|
|
268
|
-
'It works on gas, electric and induction hobs, in the oven and over a fire. A skillet that has rusted or lost its seasoning can be saved: we strip and reseason them at the shop for the price of the oil.',
|
|
269
|
-
],
|
|
270
|
-
},
|
|
271
|
-
{
|
|
272
|
-
name: 'Leather card holder',
|
|
273
|
-
slug: 'leather-card-holder',
|
|
274
|
-
category: 'Carry',
|
|
275
|
-
price: 55,
|
|
276
|
-
inStock: true,
|
|
277
|
-
description: 'A slim holder for four to six cards in vegetable-tanned leather, stitched with waxed thread. It darkens and shines where your hand holds it.',
|
|
278
|
-
material: 'Vegetable-tanned cowhide, 1.4 mm. Waxed linen thread.',
|
|
279
|
-
dimensions: '10.5 × 7.5 cm. Two outer pockets and a centre slot.',
|
|
280
|
-
origin: 'Lisbon, Portugal',
|
|
281
|
-
care: 'Keep it dry. A little neutral leather balm once a year.',
|
|
282
|
-
delivery: SHIPS,
|
|
283
|
-
story: [
|
|
284
|
-
'Cut from the offcuts of our bag handles, so none of the hide is wasted. Each holder is saddle stitched by hand at the workshop with two needles and one waxed thread, a stitch that holds even if a single loop is cut.',
|
|
285
|
-
'The leather is tanned with tree bark over several weeks, which leaves it firm and pale at first. Within a few months it takes on the colour of your pocket.',
|
|
286
|
-
],
|
|
287
|
-
},
|
|
288
|
-
{
|
|
289
|
-
name: 'Heavyweight T-shirt',
|
|
290
|
-
slug: 'heavyweight-t-shirt',
|
|
291
|
-
category: 'Wear',
|
|
292
|
-
price: 38,
|
|
293
|
-
inStock: true,
|
|
294
|
-
description: 'A white T-shirt in dense organic cotton jersey with a narrow ribbed collar that keeps its shape. Straight cut, slightly longer at the back.',
|
|
295
|
-
material: 'Organic cotton jersey, 240 g/m².',
|
|
296
|
-
dimensions: 'Sizes XS to XXL. Size M: 71 cm back length, 54 cm across the chest.',
|
|
297
|
-
origin: 'Barcelos, Portugal',
|
|
298
|
-
care: 'Wash at 40 °C and dry flat or on a line. Allow 3% shrinkage on the first wash.',
|
|
299
|
-
delivery: SHIPS,
|
|
300
|
-
story: [
|
|
301
|
-
'Knitted and sewn by a family firm in Barcelos that has made T-shirts for other labels for three generations. The jersey is heavier than most, which keeps a white T-shirt from turning sheer and lets the collar lie flat after hundreds of washes.',
|
|
302
|
-
'We make it in white only, because white is the one we wear. The body is cut straight, so take a size up for a looser fit.',
|
|
303
|
-
],
|
|
304
|
-
},
|
|
305
|
-
{
|
|
306
|
-
name: 'Striped wool blanket',
|
|
307
|
-
slug: 'striped-wool-blanket',
|
|
308
|
-
category: 'Living',
|
|
309
|
-
price: 190,
|
|
310
|
-
inStock: true,
|
|
311
|
-
description: 'A heavy blanket in undyed wool with indigo stripes and hand-knotted fringes. Large enough for the foot of a double bed or the back of a sofa.',
|
|
312
|
-
material: 'Serra da Estrela wool, undyed, with indigo-dyed stripes.',
|
|
313
|
-
dimensions: '130 × 190 cm, plus 8 cm of fringe at each end.',
|
|
314
|
-
weight: '1.6 kg',
|
|
315
|
-
origin: 'Manteigas, Portugal',
|
|
316
|
-
care: 'Air it outside rather than washing it. Hand wash cold with wool soap if needed and dry flat.',
|
|
317
|
-
delivery: SHIPS,
|
|
318
|
-
story: [
|
|
319
|
-
'Woven on a shuttle loom in Manteigas, a mountain town where wool has been washed in the river Zêzere for five hundred years. The mill buys fleece from shepherds in the Serra da Estrela and spins it without bleaching, so the cream of the blanket is the colour of the sheep.',
|
|
320
|
-
'The stripes are dyed with indigo in small lots, and the fringes are knotted by hand as each blanket comes off the loom. Wool this dense keeps out a draught and seldom needs washing: a dry day on a line is enough.',
|
|
321
|
-
],
|
|
322
|
-
},
|
|
323
|
-
{
|
|
324
|
-
name: 'Porcelain pour-over set',
|
|
325
|
-
slug: 'porcelain-pour-over-set',
|
|
326
|
-
category: 'Kitchen',
|
|
327
|
-
price: 72,
|
|
328
|
-
inStock: true,
|
|
329
|
-
description: 'A porcelain dripper and a 600 ml glass carafe with a cork collar, for two large cups at a time. The dripper takes size 2 paper filters.',
|
|
330
|
-
material: 'Porcelain, borosilicate glass, natural cork.',
|
|
331
|
-
capacity: '600 ml, two large cups.',
|
|
332
|
-
dimensions: 'Carafe 19 cm high. Dripper 11.5 cm across.',
|
|
333
|
-
origin: 'Porcelain from Ílhavo, Portugal. Glass from Bohemia, Czech Republic.',
|
|
334
|
-
care: 'Dishwasher safe once the cork collar is lifted off. Wipe the cork dry.',
|
|
335
|
-
delivery: 'Ships from Lisbon within two working days, packed in recycled paper. Free returns within 30 days.',
|
|
336
|
-
story: [
|
|
337
|
-
'The dripper is made at a porcelain works in Ílhavo that has supplied restaurants in Porto since the 1950s. Its ribs are cut deep enough that the paper never seals against the wall, so the water runs through evenly and a pour takes about three minutes.',
|
|
338
|
-
'The carafe is mouth-blown borosilicate glass and can sit on a gas flame at low heat to keep coffee warm. The cork collar lets you hold it by the neck without a cloth.',
|
|
339
|
-
],
|
|
340
|
-
},
|
|
341
|
-
{
|
|
342
|
-
name: 'Canvas shoulder bag',
|
|
343
|
-
slug: 'canvas-shoulder-bag',
|
|
344
|
-
category: 'Carry',
|
|
345
|
-
price: 165,
|
|
346
|
-
inStock: true,
|
|
347
|
-
description: 'A roomy bag in tan cotton canvas with bridle leather handles and a detachable strap. Wide enough for a laptop and a change of clothes.',
|
|
348
|
-
material: 'Cotton canvas, 18 oz. Vegetable-tanned bridle leather. Steel hooks.',
|
|
349
|
-
dimensions: '40 × 34 × 14 cm. The strap adjusts from 90 to 130 cm.',
|
|
350
|
-
weight: '1.1 kg',
|
|
351
|
-
origin: 'Lisbon, Portugal',
|
|
352
|
-
care: 'Brush off dust and spot clean with cold water. Condition the leather once a year.',
|
|
353
|
-
delivery: SHIPS,
|
|
354
|
-
story: [
|
|
355
|
-
'We cut and sew this bag in our own workshop behind the shop, twelve at a time. The canvas is a heavy cotton duck that holds its shape when the bag is empty and relaxes as it fills, and each handle is one length of bridle leather riveted through both layers.',
|
|
356
|
-
'Every seam that carries weight is stitched twice. The strap clips off with two steel hooks, so the bag goes by hand on a train and over the shoulder on a bicycle. We keep spare straps and hooks at the workshop for as long as we make the bag.',
|
|
357
|
-
],
|
|
358
|
-
},
|
|
359
|
-
{
|
|
360
|
-
name: 'Field jacket',
|
|
361
|
-
slug: 'field-jacket',
|
|
362
|
-
category: 'Wear',
|
|
363
|
-
price: 245,
|
|
364
|
-
inStock: true,
|
|
365
|
-
description: 'A four-pocket jacket in olive cotton drill, cut long enough to cover a sweater and loose enough to wear over one. Corozo buttons and a stand collar.',
|
|
366
|
-
material: 'Cotton drill, 280 g/m², garment washed. Corozo nut buttons.',
|
|
367
|
-
dimensions: 'Sizes XS to XL. Size M: 74 cm back length, 58 cm across the chest.',
|
|
368
|
-
origin: 'Guimarães, Portugal',
|
|
369
|
-
care: 'Wash at 30 °C inside out, line dry, iron warm.',
|
|
370
|
-
delivery: SHIPS,
|
|
371
|
-
story: [
|
|
372
|
-
'The pattern comes from a work jacket that one of our tailors in Guimarães wore for twenty years. We kept its proportions, raised the chest pockets two centimetres so they clear a bag strap, and chose corozo buttons, which survive a hot wash and can be sewn back on at the shop.',
|
|
373
|
-
'The drill is woven for us in runs of four hundred metres and washed once before cutting, so the jacket will not shrink after it reaches you. It softens and fades along the seams over a few years of wear. When a pocket tears or a cuff frays, send it back and we will mend it.',
|
|
374
|
-
],
|
|
375
|
-
},
|
|
376
|
-
];
|
|
377
|
-
export const STORE_DEMO_CATEGORIES = [
|
|
378
|
-
{
|
|
379
|
-
name: 'Wear',
|
|
380
|
-
slug: 'wear',
|
|
381
|
-
summary: 'Jackets, shirts and knitwear cut in Guimarães, Barcelos and Covilhã, and mended at the shop when they tear.',
|
|
382
|
-
photoOf: 'cable-knit-beanie',
|
|
383
|
-
relatedTitle: 'More to wear',
|
|
384
|
-
makers: [
|
|
385
|
-
'Our clothes come from three workshops in the north of Portugal, each of which has sewn or knitted for larger labels for decades. We choose cloth with them, agree a pattern, and order in runs small enough to sell within a season.',
|
|
386
|
-
'Every garment is sold with the promise we make for everything in the shop: if a seam opens, a pocket tears or a button goes, bring it or send it back and we will repair it for as long as we sell the piece.',
|
|
387
|
-
],
|
|
388
|
-
},
|
|
389
|
-
{
|
|
390
|
-
name: 'Carry',
|
|
391
|
-
slug: 'carry',
|
|
392
|
-
summary: 'Bags and small leather goods, most of them cut and sewn at our own workshop behind the shop in Lisbon.',
|
|
393
|
-
photoOf: 'leather-card-holder',
|
|
394
|
-
relatedTitle: 'More to carry',
|
|
395
|
-
makers: [
|
|
396
|
-
'Canvas comes from a mill in Guimarães and leather from a vegetable tannery in Alcanena. Both are cut on the long table at the back of the shop, and anyone buying a bag can watch the next one being sewn.',
|
|
397
|
-
'We keep spare straps, hooks and rivets for everything we have made, so a bag can be put right long after the batch it came from has sold out.',
|
|
398
|
-
],
|
|
399
|
-
},
|
|
400
|
-
{
|
|
401
|
-
name: 'Kitchen',
|
|
402
|
-
slug: 'kitchen',
|
|
403
|
-
summary: 'Cookware and tableware from a foundry, a porcelain works and an enamel maker, for use every day.',
|
|
404
|
-
photoOf: 'cast-iron-skillet',
|
|
405
|
-
relatedTitle: 'More for the kitchen',
|
|
406
|
-
makers: [
|
|
407
|
-
'Nothing in the kitchen range is coated, and nothing needs to be handled gently. Cast iron, porcelain, glass and enamelled steel all last for decades when they are used every day, which is the only way we test them.',
|
|
408
|
-
'We cook with every piece at the shop before we sell it, and we reseason skillets for customers for the price of the oil.',
|
|
409
|
-
],
|
|
410
|
-
},
|
|
411
|
-
{
|
|
412
|
-
name: 'Living',
|
|
413
|
-
slug: 'living',
|
|
414
|
-
summary: 'Blankets and table linen woven on old looms in Manteigas and Guimarães, from wool and flax left undyed.',
|
|
415
|
-
photoOf: 'linen-table-runner',
|
|
416
|
-
relatedTitle: 'More for the house',
|
|
417
|
-
makers: [
|
|
418
|
-
'Our blankets and linens come from two weaving mills that still run shuttle looms, slower than modern machines and able to weave a denser cloth with a finished edge.',
|
|
419
|
-
'The mills weave for us twice a year, in spring and in autumn, so a piece that sells out comes back with the next season.',
|
|
420
|
-
],
|
|
421
|
-
},
|
|
422
|
-
];
|
|
181
|
+
function categoryOf(copy, id) {
|
|
182
|
+
const found = copy.categories.find((entry) => entry.id === id);
|
|
183
|
+
if (found === undefined) {
|
|
184
|
+
throw new CogentaError({
|
|
185
|
+
code: 'BLUEPRINT_REGISTRY_CORRUPT',
|
|
186
|
+
message: `The store copy names no "${id}" category.`,
|
|
187
|
+
hint: 'Every product of the store copy must name one of its categories.',
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
return found;
|
|
191
|
+
}
|
|
423
192
|
function productsGrid(key, options) {
|
|
424
193
|
return {
|
|
425
194
|
_key: key,
|
|
@@ -433,39 +202,27 @@ function productsGrid(key, options) {
|
|
|
433
202
|
layout: 'grid',
|
|
434
203
|
};
|
|
435
204
|
}
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
title: '30 days to return anything unworn',
|
|
449
|
-
link: { href: '/delivery-and-returns' },
|
|
450
|
-
},
|
|
451
|
-
{
|
|
452
|
-
_key: 'commitment-repairs',
|
|
453
|
-
title: 'Repairs for as long as we sell the piece',
|
|
454
|
-
link: { href: '/repairs' },
|
|
455
|
-
},
|
|
456
|
-
],
|
|
457
|
-
};
|
|
458
|
-
function withKey(block, key) {
|
|
459
|
-
return { ...block, _key: key };
|
|
205
|
+
function commitments(copy, facts, key) {
|
|
206
|
+
const words = copy.pages(facts).home;
|
|
207
|
+
return {
|
|
208
|
+
_key: key,
|
|
209
|
+
_type: 'featureGrid',
|
|
210
|
+
_version: BLOCK_VERSION,
|
|
211
|
+
items: words.commitments.map((item, index) => ({
|
|
212
|
+
_key: `${key}-${index}`,
|
|
213
|
+
title: item.title,
|
|
214
|
+
link: { href: `/${copy.pageSlugs[item.page]}` },
|
|
215
|
+
})),
|
|
216
|
+
};
|
|
460
217
|
}
|
|
461
218
|
/** The body of one product's page: how it is made, then more from its category. */
|
|
462
|
-
export function storeProductBlocks(demo) {
|
|
463
|
-
const group =
|
|
219
|
+
export function storeProductBlocks(copy, demo) {
|
|
220
|
+
const group = categoryOf(copy, demo.category);
|
|
464
221
|
return [
|
|
465
222
|
prose(`product-${demo.slug}-story`, [...demo.story]),
|
|
466
223
|
productsGrid(`product-${demo.slug}-more`, {
|
|
467
|
-
title: group
|
|
468
|
-
category:
|
|
224
|
+
title: group.relatedTitle,
|
|
225
|
+
category: group.name,
|
|
469
226
|
limit: 5,
|
|
470
227
|
}),
|
|
471
228
|
];
|
|
@@ -478,18 +235,25 @@ export function storeCategoryBlocks(demo) {
|
|
|
478
235
|
];
|
|
479
236
|
}
|
|
480
237
|
export function buildStoreHomeBlocks(options = {}) {
|
|
238
|
+
const copy = storeCopyFor(options.locale ?? 'en');
|
|
481
239
|
const media = options.media ?? {};
|
|
482
|
-
const
|
|
483
|
-
const
|
|
240
|
+
const facts = factsOf(options.siteName);
|
|
241
|
+
const words = copy.pages(facts).home;
|
|
484
242
|
return [
|
|
485
243
|
{
|
|
486
244
|
_key: 'home-banner',
|
|
487
245
|
_type: 'hero',
|
|
488
246
|
_version: BLOCK_VERSION,
|
|
489
|
-
title:
|
|
490
|
-
subtitle:
|
|
247
|
+
title: words.heroTitle,
|
|
248
|
+
subtitle: words.heroSubtitle,
|
|
491
249
|
...(media.hero === undefined ? {} : { media: media.hero }),
|
|
492
|
-
actions: [
|
|
250
|
+
actions: [
|
|
251
|
+
{
|
|
252
|
+
label: words.heroAction,
|
|
253
|
+
target: { href: `/${copy.pageSlugs.shop}` },
|
|
254
|
+
emphasis: 'primary',
|
|
255
|
+
},
|
|
256
|
+
],
|
|
493
257
|
},
|
|
494
258
|
{
|
|
495
259
|
_key: 'home-categories',
|
|
@@ -500,8 +264,8 @@ export function buildStoreHomeBlocks(options = {}) {
|
|
|
500
264
|
limit: 4,
|
|
501
265
|
layout: 'grid',
|
|
502
266
|
},
|
|
503
|
-
productsGrid('home-new', { title:
|
|
504
|
-
|
|
267
|
+
productsGrid('home-new', { title: words.newTitle, limit: 4 }),
|
|
268
|
+
commitments(copy, facts, 'home-commitments'),
|
|
505
269
|
...(media.story === undefined
|
|
506
270
|
? []
|
|
507
271
|
: [
|
|
@@ -510,54 +274,36 @@ export function buildStoreHomeBlocks(options = {}) {
|
|
|
510
274
|
_type: 'mediaFigure',
|
|
511
275
|
_version: BLOCK_VERSION,
|
|
512
276
|
media: media.story,
|
|
513
|
-
ratio: '
|
|
277
|
+
ratio: '4:3',
|
|
514
278
|
align: 'start',
|
|
515
|
-
caption:
|
|
516
|
-
credit: 'Enamel mug, made in Olkusz',
|
|
279
|
+
caption: words.storyCaption,
|
|
517
280
|
},
|
|
518
281
|
]),
|
|
519
282
|
{
|
|
520
283
|
_key: 'home-letter',
|
|
521
284
|
_type: 'testimonial',
|
|
522
285
|
_version: BLOCK_VERSION,
|
|
523
|
-
quote: answer('home-letter-quote',
|
|
524
|
-
attribution: { name:
|
|
286
|
+
quote: answer('home-letter-quote', words.letter.quote),
|
|
287
|
+
attribution: { name: words.letter.name, role: words.letter.role },
|
|
525
288
|
},
|
|
526
289
|
{
|
|
527
290
|
_key: 'home-faq',
|
|
528
291
|
_type: 'faq',
|
|
529
292
|
_version: BLOCK_VERSION,
|
|
530
|
-
title:
|
|
531
|
-
items: questions('home-faq',
|
|
532
|
-
[
|
|
533
|
-
'How do I place an order?',
|
|
534
|
-
'Use the order button on a product page to write to us, or come to the shop. We reply within one working day with the total, delivery included, and a secure payment link. Nothing is charged until you confirm.',
|
|
535
|
-
],
|
|
536
|
-
[
|
|
537
|
-
'How long does delivery take?',
|
|
538
|
-
'Two to three working days in mainland Portugal and three to five across the rest of the European Union. Orders confirmed before noon leave Lisbon the same day.',
|
|
539
|
-
],
|
|
540
|
-
[
|
|
541
|
-
'Can I collect my order from the shop?',
|
|
542
|
-
'Yes. Ask for collection when you write, and your order will be waiting at Rua da Boavista 84 from the next day, Tuesday to Saturday.',
|
|
543
|
-
],
|
|
544
|
-
[
|
|
545
|
-
'What if something does not fit?',
|
|
546
|
-
'Send it back unworn within 30 days for a refund or another size. Returns are free within Portugal, and from elsewhere in the EU we refund the cost of the cheapest tracked service.',
|
|
547
|
-
],
|
|
548
|
-
]),
|
|
293
|
+
title: words.faqTitle,
|
|
294
|
+
items: questions('home-faq', words.faq),
|
|
549
295
|
},
|
|
550
296
|
{
|
|
551
297
|
_key: 'home-letters',
|
|
552
298
|
_type: 'cta',
|
|
553
299
|
_version: BLOCK_VERSION,
|
|
554
|
-
title:
|
|
555
|
-
text:
|
|
300
|
+
title: words.lettersTitle,
|
|
301
|
+
text: words.lettersText,
|
|
556
302
|
actions: [
|
|
557
303
|
{
|
|
558
|
-
label:
|
|
304
|
+
label: words.lettersAction,
|
|
559
305
|
target: {
|
|
560
|
-
href: `mailto:${letters}?subject=${encodeURIComponent(
|
|
306
|
+
href: `mailto:${facts.letters}?subject=${encodeURIComponent(words.lettersSubject)}`,
|
|
561
307
|
},
|
|
562
308
|
emphasis: 'secondary',
|
|
563
309
|
},
|
|
@@ -566,224 +312,145 @@ export function buildStoreHomeBlocks(options = {}) {
|
|
|
566
312
|
];
|
|
567
313
|
}
|
|
568
314
|
/**
|
|
569
|
-
* `home`, `shop` (every product), `about`,
|
|
570
|
-
*
|
|
571
|
-
* menus and the copy link to.
|
|
315
|
+
* `home`, `shop` (every product), `about`, how to order, delivery and
|
|
316
|
+
* returns, repairs, contact, terms and the photo credits: every page the
|
|
317
|
+
* menus and the copy link to, in the copy's language.
|
|
572
318
|
*/
|
|
573
319
|
export function buildStoreDemoPages(options = {}) {
|
|
320
|
+
const copy = storeCopyFor(options.locale ?? 'en');
|
|
574
321
|
const media = options.media ?? {};
|
|
575
|
-
const
|
|
576
|
-
const
|
|
577
|
-
const
|
|
578
|
-
const
|
|
579
|
-
|
|
322
|
+
const facts = factsOf(options.siteName);
|
|
323
|
+
const words = copy.pages(facts);
|
|
324
|
+
const slug = copy.pageSlugs;
|
|
325
|
+
const entry = (key, blocks) => ({
|
|
326
|
+
title: words.titles[key],
|
|
327
|
+
slug: slug[key],
|
|
328
|
+
blocks,
|
|
329
|
+
});
|
|
580
330
|
return [
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
: [
|
|
601
|
-
{
|
|
602
|
-
_key: 'about-figure',
|
|
603
|
-
_type: 'mediaFigure',
|
|
604
|
-
_version: BLOCK_VERSION,
|
|
605
|
-
media: media.hero,
|
|
606
|
-
ratio: '21:9',
|
|
607
|
-
align: 'wide',
|
|
608
|
-
caption: 'A canvas tote, a lambswool beanie and a card holder, all made within a day of Lisbon.',
|
|
609
|
-
},
|
|
610
|
-
]),
|
|
611
|
-
{
|
|
612
|
-
_key: 'about-figures',
|
|
613
|
-
_type: 'stats',
|
|
614
|
-
_version: BLOCK_VERSION,
|
|
615
|
-
title: 'The shop in numbers',
|
|
616
|
-
items: [
|
|
617
|
-
{
|
|
618
|
-
_key: 'about-figure-workshops',
|
|
619
|
-
value: '11',
|
|
620
|
-
label: 'workshops we buy from, nine of them in Portugal',
|
|
621
|
-
},
|
|
622
|
-
{
|
|
623
|
-
_key: 'about-figure-repairs',
|
|
624
|
-
value: '1,380',
|
|
625
|
-
label: 'repairs done at the bench last year',
|
|
626
|
-
},
|
|
627
|
-
{
|
|
628
|
-
_key: 'about-figure-opened',
|
|
629
|
-
value: '2014',
|
|
630
|
-
label: 'the year we opened on Rua da Boavista',
|
|
631
|
-
},
|
|
632
|
-
],
|
|
633
|
-
},
|
|
634
|
-
{
|
|
635
|
-
_key: 'about-visit',
|
|
636
|
-
_type: 'cta',
|
|
637
|
-
_version: BLOCK_VERSION,
|
|
638
|
-
title: 'Visit the shop and the repair bench',
|
|
639
|
-
text: 'Rua da Boavista 84, Lisbon. Open Tuesday to Saturday, 11:00 to 19:00.',
|
|
640
|
-
actions: [
|
|
641
|
-
{
|
|
642
|
-
label: 'Opening hours and directions',
|
|
643
|
-
target: { href: '/contact' },
|
|
644
|
-
emphasis: 'secondary',
|
|
645
|
-
},
|
|
646
|
-
],
|
|
647
|
-
},
|
|
648
|
-
],
|
|
649
|
-
},
|
|
650
|
-
{
|
|
651
|
-
title: 'How to order',
|
|
652
|
-
slug: 'how-to-order',
|
|
653
|
-
blocks: [
|
|
654
|
-
prose('order-intro', [
|
|
655
|
-
'We sell through the shop and by email, so that every order is read by the person who will pack it. It takes a little longer than a checkout and it means we can answer a question about size or delivery before you pay.',
|
|
656
|
-
'## Ordering by email',
|
|
657
|
-
`Use the order button on any product page, or write to [${orders}](mailto:${orders}) with the pieces, the sizes and the delivery address. We reply within one working day, Tuesday to Saturday, with the total including delivery and a secure payment link by card or MB WAY. Your order leaves Lisbon as soon as the payment arrives.`,
|
|
658
|
-
'## Ordering at the shop',
|
|
659
|
-
'Everything on the site is in the shop at Rua da Boavista 84, and most sizes can be tried on. We can also keep an item aside for a week if you tell us when you plan to come.',
|
|
660
|
-
]),
|
|
661
|
-
{
|
|
662
|
-
_key: 'order-notes',
|
|
663
|
-
_type: 'accordion',
|
|
664
|
-
_version: BLOCK_VERSION,
|
|
665
|
-
title: 'Payment and delivery',
|
|
666
|
-
items: questions('order-notes', [
|
|
667
|
-
[
|
|
668
|
-
'Which payment methods do you accept?',
|
|
669
|
-
'Visa, Mastercard and MB WAY through a payment link, bank transfer to our account in Lisbon, and cash or card at the shop. Prices include Portuguese VAT.',
|
|
670
|
-
],
|
|
671
|
-
[
|
|
672
|
-
'What does delivery cost?',
|
|
673
|
-
'Delivery is €5 in mainland Portugal and €12 to the rest of the EU, free on orders over €150. Blankets and skillets travel by tracked courier at the same price.',
|
|
674
|
-
],
|
|
675
|
-
[
|
|
676
|
-
'Do you send orders outside the European Union?',
|
|
677
|
-
'We send to the United Kingdom, Switzerland and Norway at cost. Import duties and taxes are paid by the recipient on arrival, and we tell you the estimate before you pay.',
|
|
678
|
-
],
|
|
679
|
-
[
|
|
680
|
-
'Can you wrap a gift?',
|
|
681
|
-
'Yes, in brown paper and cotton string, with a card written by hand if you send us the words. It costs nothing.',
|
|
682
|
-
],
|
|
683
|
-
]),
|
|
684
|
-
},
|
|
685
|
-
],
|
|
686
|
-
},
|
|
687
|
-
{
|
|
688
|
-
title: 'Delivery and returns',
|
|
689
|
-
slug: 'delivery-and-returns',
|
|
690
|
-
blocks: [
|
|
691
|
-
prose('delivery-intro', [
|
|
692
|
-
'Orders leave the shop in Lisbon every working day at 14:00, packed in recycled paper and card with no plastic. You receive a tracking number by email when the parcel is collected.',
|
|
693
|
-
]),
|
|
694
|
-
{
|
|
695
|
-
_key: 'delivery-faq',
|
|
696
|
-
_type: 'faq',
|
|
697
|
-
_version: BLOCK_VERSION,
|
|
698
|
-
title: 'Delivery and returns',
|
|
699
|
-
items: questions('delivery-faq', [
|
|
700
|
-
[
|
|
701
|
-
'How long does delivery take?',
|
|
702
|
-
'Two to three working days in mainland Portugal, three to five working days to the rest of the European Union, and five to eight to the United Kingdom, Switzerland and Norway.',
|
|
703
|
-
],
|
|
704
|
-
[
|
|
705
|
-
'How do I return something?',
|
|
706
|
-
`Write to [${orders}](mailto:${orders}) within 30 days of delivery with your order number. We send a prepaid label for returns within Portugal, and an address for returns from elsewhere.`,
|
|
707
|
-
],
|
|
708
|
-
[
|
|
709
|
-
'When will I be refunded?',
|
|
710
|
-
'Within five working days of the parcel reaching us, to the card or account you paid from. Delivery costs are refunded when the whole order is returned.',
|
|
711
|
-
],
|
|
712
|
-
[
|
|
713
|
-
'Can I exchange a size?',
|
|
714
|
-
'Yes. Tell us the size you need when you write, and we send it as soon as the first piece is on its way back to us.',
|
|
715
|
-
],
|
|
716
|
-
[
|
|
717
|
-
'What cannot be returned?',
|
|
718
|
-
'Pieces that have been worn, washed or altered, and anything we have repaired or made to order for you.',
|
|
719
|
-
],
|
|
720
|
-
]),
|
|
721
|
-
},
|
|
722
|
-
],
|
|
723
|
-
},
|
|
724
|
-
{
|
|
725
|
-
title: 'Repairs',
|
|
726
|
-
slug: 'repairs',
|
|
727
|
-
blocks: [
|
|
728
|
-
prose('repairs-intro', [
|
|
729
|
-
'We repair everything we sell for as long as we sell it, and most things long after. The bench is at the back of the shop, and two of us work at it every afternoon.',
|
|
730
|
-
'## What we mend',
|
|
731
|
-
'Seams, pockets, cuffs and buttons on clothing. Straps, hooks, rivets and stitching on bags and leather. Rust and lost seasoning on cast iron. Moth holes in knitwear, if they are small enough to darn.',
|
|
732
|
-
'## What it costs',
|
|
733
|
-
'Repairs to anything bought from us in the last two years are free. After that we charge for the materials and nothing for the time, which comes to between €5 and €25 for most repairs. We tell you the price before we start.',
|
|
734
|
-
'## How to send something in',
|
|
735
|
-
`Bring it to the shop, or write to [${repairs}](mailto:${repairs}) with a photograph of the damage. We reply with the price, the time it will take (usually two to three weeks) and the address to post it to.`,
|
|
736
|
-
]),
|
|
737
|
-
{
|
|
738
|
-
_key: 'repairs-figures',
|
|
739
|
-
_type: 'statCounter',
|
|
740
|
-
_version: BLOCK_VERSION,
|
|
741
|
-
title: 'Last year at the bench',
|
|
742
|
-
stats: [
|
|
743
|
-
{ _key: 'repairs-figure-total', value: '1,380', label: 'repairs completed' },
|
|
744
|
-
{ _key: 'repairs-figure-free', value: '62%', label: 'done free of charge' },
|
|
745
|
-
{
|
|
746
|
-
_key: 'repairs-figure-days',
|
|
747
|
-
value: '16',
|
|
748
|
-
label: 'days on average from arrival to return',
|
|
749
|
-
},
|
|
750
|
-
],
|
|
751
|
-
},
|
|
752
|
-
],
|
|
753
|
-
},
|
|
754
|
-
{
|
|
755
|
-
title: 'Contact',
|
|
756
|
-
slug: 'contact',
|
|
757
|
-
blocks: [
|
|
758
|
-
prose('contact-details', [
|
|
759
|
-
'## The shop',
|
|
760
|
-
'Rua da Boavista 84, 1200-066 Lisboa, Portugal. Five minutes on foot from Cais do Sodré station and the 28 tram.',
|
|
761
|
-
'Tuesday to Saturday, 11:00 to 19:00. Closed on Sundays, Mondays and public holidays.',
|
|
762
|
-
'## Writing to us',
|
|
763
|
-
`For orders, [${orders}](mailto:${orders}). For repairs, [${repairs}](mailto:${repairs}). For our letters from the workshop, four a year, [${letters}](mailto:${letters}). For anything else, including workshops that would like to work with us, [${hello}](mailto:${hello}).`,
|
|
764
|
-
'Telephone +351 213 460 218, Tuesday to Saturday during opening hours.',
|
|
765
|
-
]),
|
|
766
|
-
],
|
|
767
|
-
},
|
|
768
|
-
{
|
|
769
|
-
title: 'Terms and privacy',
|
|
770
|
-
slug: 'terms',
|
|
771
|
-
blocks: [
|
|
772
|
-
prose('terms', [
|
|
773
|
-
`These terms apply to every order placed with ${siteName}, Lda., Rua da Boavista 84, 1200-066 Lisboa, registered in Portugal under NIPC 516 204 873.`,
|
|
774
|
-
'## Orders and prices',
|
|
775
|
-
'An order is confirmed when we have received payment and replied to say so. Prices are in euros and include VAT at the Portuguese rate. Delivery costs are stated before payment.',
|
|
776
|
-
'## Your right to cancel',
|
|
777
|
-
'You may cancel an order within 14 days of receiving it without giving a reason, as the law of the European Union provides, and our own returns period of 30 days extends that right. Refunds are made within 14 days of the goods reaching us.',
|
|
778
|
-
'## Guarantee',
|
|
779
|
-
'Every piece carries the legal guarantee of conformity of three years. Our repair service is offered in addition to it and does not replace it.',
|
|
780
|
-
'## Privacy',
|
|
781
|
-
`We keep your name, address and email for as long as it takes to deliver, return or repair an order, and for the ten years Portuguese tax law requires us to keep invoices. We never sell or share them except with the carrier delivering your parcel. Write to [${hello}](mailto:${hello}) to see or delete what we hold. This site sets no advertising or tracking cookies.`,
|
|
331
|
+
entry('home', buildStoreHomeBlocks(options)),
|
|
332
|
+
entry('shop', [
|
|
333
|
+
productsGrid('shop-all', { limit: 48 }),
|
|
334
|
+
commitments(copy, facts, 'shop-commitments'),
|
|
335
|
+
]),
|
|
336
|
+
entry('about', [
|
|
337
|
+
prose('about-intro', words.about.intro),
|
|
338
|
+
...(media.hero === undefined
|
|
339
|
+
? []
|
|
340
|
+
: [
|
|
341
|
+
{
|
|
342
|
+
_key: 'about-figure',
|
|
343
|
+
_type: 'mediaFigure',
|
|
344
|
+
_version: BLOCK_VERSION,
|
|
345
|
+
media: media.hero,
|
|
346
|
+
ratio: '21:9',
|
|
347
|
+
align: 'wide',
|
|
348
|
+
caption: words.about.figureCaption,
|
|
349
|
+
},
|
|
782
350
|
]),
|
|
783
|
-
|
|
784
|
-
|
|
351
|
+
{
|
|
352
|
+
_key: 'about-figures',
|
|
353
|
+
_type: 'stats',
|
|
354
|
+
_version: BLOCK_VERSION,
|
|
355
|
+
title: words.about.figuresTitle,
|
|
356
|
+
items: words.about.figures.map((item, index) => ({
|
|
357
|
+
_key: `about-figure-${index}`,
|
|
358
|
+
...item,
|
|
359
|
+
})),
|
|
360
|
+
},
|
|
361
|
+
{
|
|
362
|
+
_key: 'about-visit',
|
|
363
|
+
_type: 'cta',
|
|
364
|
+
_version: BLOCK_VERSION,
|
|
365
|
+
title: words.about.visitTitle,
|
|
366
|
+
text: words.about.visitText,
|
|
367
|
+
actions: [
|
|
368
|
+
{
|
|
369
|
+
label: words.about.visitAction,
|
|
370
|
+
target: { href: `/${slug.contact}` },
|
|
371
|
+
emphasis: 'secondary',
|
|
372
|
+
},
|
|
373
|
+
],
|
|
374
|
+
},
|
|
375
|
+
]),
|
|
376
|
+
entry('order', [
|
|
377
|
+
prose('order-intro', words.order.intro),
|
|
378
|
+
{
|
|
379
|
+
_key: 'order-notes',
|
|
380
|
+
_type: 'accordion',
|
|
381
|
+
_version: BLOCK_VERSION,
|
|
382
|
+
title: words.order.notesTitle,
|
|
383
|
+
items: questions('order-notes', words.order.notes),
|
|
384
|
+
},
|
|
385
|
+
]),
|
|
386
|
+
entry('delivery', [
|
|
387
|
+
prose('delivery-intro', words.delivery.intro),
|
|
388
|
+
{
|
|
389
|
+
_key: 'delivery-faq',
|
|
390
|
+
_type: 'faq',
|
|
391
|
+
_version: BLOCK_VERSION,
|
|
392
|
+
title: words.delivery.faqTitle,
|
|
393
|
+
items: questions('delivery-faq', words.delivery.faq),
|
|
394
|
+
},
|
|
395
|
+
]),
|
|
396
|
+
entry('repairs', [
|
|
397
|
+
prose('repairs-intro', words.repairs.intro),
|
|
398
|
+
{
|
|
399
|
+
_key: 'repairs-figures',
|
|
400
|
+
_type: 'statCounter',
|
|
401
|
+
_version: BLOCK_VERSION,
|
|
402
|
+
title: words.repairs.figuresTitle,
|
|
403
|
+
stats: words.repairs.figures.map((item, index) => ({
|
|
404
|
+
_key: `repairs-figure-${index}`,
|
|
405
|
+
...item,
|
|
406
|
+
})),
|
|
407
|
+
},
|
|
408
|
+
]),
|
|
409
|
+
entry('contact', [prose('contact-details', words.contact)]),
|
|
410
|
+
entry('terms', [prose('terms', words.terms)]),
|
|
411
|
+
entry('credits', [creditsProse(words.credits, STORE_PHOTO_CREDITS)]),
|
|
785
412
|
];
|
|
786
413
|
}
|
|
414
|
+
/** The credits page's body: a sentence, then one line per photograph with its licence and source. */
|
|
415
|
+
function creditsProse(credits, list) {
|
|
416
|
+
const lines = (credit, index) => {
|
|
417
|
+
const key = `credits-item-${index}`;
|
|
418
|
+
const link = (part, text, href) => ({
|
|
419
|
+
span: { _key: `${key}-s${part}`, _type: 'span', text, marks: [`${key}-l${part}`] },
|
|
420
|
+
mark: { _key: `${key}-l${part}`, _type: 'link', href },
|
|
421
|
+
});
|
|
422
|
+
const plain = (part, text) => ({
|
|
423
|
+
span: { _key: `${key}-s${part}`, _type: 'span', text, marks: [] },
|
|
424
|
+
mark: undefined,
|
|
425
|
+
});
|
|
426
|
+
const parts = [
|
|
427
|
+
plain('0', `${credit.title} · ${credit.author} · `),
|
|
428
|
+
credit.licenceUrl === undefined
|
|
429
|
+
? plain('1', credit.licence)
|
|
430
|
+
: link('1', credit.licence, credit.licenceUrl),
|
|
431
|
+
plain('2', ' · '),
|
|
432
|
+
link('3', credits.sourceWord, credit.source),
|
|
433
|
+
];
|
|
434
|
+
return {
|
|
435
|
+
_key: key,
|
|
436
|
+
_type: 'block',
|
|
437
|
+
style: 'normal',
|
|
438
|
+
listItem: 'bullet',
|
|
439
|
+
level: 1,
|
|
440
|
+
children: parts.map((part) => part.span),
|
|
441
|
+
markDefs: parts.flatMap((part) => (part.mark === undefined ? [] : [part.mark])),
|
|
442
|
+
};
|
|
443
|
+
};
|
|
444
|
+
return {
|
|
445
|
+
_key: 'credits-body',
|
|
446
|
+
_type: 'prose',
|
|
447
|
+
_version: BLOCK_VERSION,
|
|
448
|
+
body: [
|
|
449
|
+
...credits.intro.map((line, index) => textBlock(`credits-intro-${index}`, 'normal', line)),
|
|
450
|
+
...list.map(lines),
|
|
451
|
+
],
|
|
452
|
+
};
|
|
453
|
+
}
|
|
787
454
|
// ---------------------------------------------------------------------------
|
|
788
455
|
// Media, menus, settings
|
|
789
456
|
// ---------------------------------------------------------------------------
|
|
@@ -804,20 +471,6 @@ function storePalette() {
|
|
|
804
471
|
}
|
|
805
472
|
return skin.color;
|
|
806
473
|
}
|
|
807
|
-
const PRODUCT_ALT = {
|
|
808
|
-
'linen-table-runner': 'White linen runner with fringed ends laid along a dark oak table',
|
|
809
|
-
'enamel-mug': 'Forest green enamel mug with a steel rim on a wooden table',
|
|
810
|
-
'cable-knit-beanie': 'Charcoal cable-knit lambswool beanie against a white wall',
|
|
811
|
-
'canvas-tote': 'Undyed cotton canvas tote with long handles standing on its base',
|
|
812
|
-
'brushed-cotton-overshirt': 'Grey brushed cotton overshirt with a button-down collar and chest pocket',
|
|
813
|
-
'cast-iron-skillet': 'Black cast-iron skillet with a pouring lip, seen from above at an angle',
|
|
814
|
-
'leather-card-holder': 'Tan vegetable-tanned leather card holder with hand stitching and two cards inside',
|
|
815
|
-
'heavyweight-t-shirt': 'White heavyweight cotton T-shirt laid flat on a pale grey ground',
|
|
816
|
-
'striped-wool-blanket': 'Folded cream wool blanket with navy stripes and a knotted fringe',
|
|
817
|
-
'porcelain-pour-over-set': 'Porcelain coffee dripper resting on a glass carafe with a cork collar',
|
|
818
|
-
'canvas-shoulder-bag': 'Tan canvas shoulder bag with brown leather handles and a detachable strap',
|
|
819
|
-
'field-jacket': 'Olive cotton drill field jacket with four pockets and a stand collar',
|
|
820
|
-
};
|
|
821
474
|
/**
|
|
822
475
|
* Every visual this blueprint seeds is a bundled photograph: the banner, one
|
|
823
476
|
* per product, one per category (the photograph of a product from that
|
|
@@ -825,122 +478,129 @@ const PRODUCT_ALT = {
|
|
|
825
478
|
* `spec` is `seedDemoMedia`'s fallback if a file is ever missing, never the
|
|
826
479
|
* intended picture.
|
|
827
480
|
*/
|
|
828
|
-
export
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
]
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
}
|
|
481
|
+
export function storeMediaSpecs(copy) {
|
|
482
|
+
const palette = storePalette();
|
|
483
|
+
const altOf = (key) => copy.products.find((demo) => demo.key === key)?.alt ?? key;
|
|
484
|
+
return [
|
|
485
|
+
{
|
|
486
|
+
name: 'hero',
|
|
487
|
+
spec: heroArt(palette, 'blocks', 11),
|
|
488
|
+
alt: copy.media.hero,
|
|
489
|
+
photo: 'store/hero.jpg',
|
|
490
|
+
},
|
|
491
|
+
...copy.categories.map((demo, index) => ({
|
|
492
|
+
name: `category-${demo.id}`,
|
|
493
|
+
spec: coverArt(palette, 50 + index),
|
|
494
|
+
alt: altOf(demo.photoOf),
|
|
495
|
+
photo: `store/${demo.photoOf}.jpg`,
|
|
496
|
+
})),
|
|
497
|
+
{
|
|
498
|
+
name: 'story',
|
|
499
|
+
spec: coverArt(palette, 60),
|
|
500
|
+
alt: copy.media.story,
|
|
501
|
+
photo: 'store/story.jpg',
|
|
502
|
+
},
|
|
503
|
+
...copy.products.map((demo, index) => ({
|
|
504
|
+
name: `product-${demo.key}`,
|
|
505
|
+
spec: productArt(palette, index + 1),
|
|
506
|
+
alt: demo.alt,
|
|
507
|
+
photo: `store/${demo.key}.jpg`,
|
|
508
|
+
})),
|
|
509
|
+
];
|
|
510
|
+
}
|
|
511
|
+
export function storeMenus(copy) {
|
|
512
|
+
const url = (key) => `/${copy.pageSlugs[key]}`;
|
|
513
|
+
return {
|
|
514
|
+
header: [
|
|
515
|
+
{ label: copy.menus.shop, url: url('shop') },
|
|
516
|
+
...copy.categories.map((demo) => ({
|
|
517
|
+
label: demo.name,
|
|
518
|
+
url: `${copy.schema.routes.category.replace('/:slug', '')}/${demo.slug}`,
|
|
519
|
+
})),
|
|
520
|
+
{ label: copy.menus.about, url: url('about') },
|
|
521
|
+
],
|
|
522
|
+
footer: copy.menus.footer.map((item) => ({ label: item.label, url: url(item.page) })),
|
|
523
|
+
headerAction: { label: copy.menus.action, url: url('order') },
|
|
524
|
+
};
|
|
525
|
+
}
|
|
870
526
|
const HOME = { kind: 'home' };
|
|
871
527
|
const SEARCH_RESULTS = { kind: 'search' };
|
|
872
528
|
const pagePath = (path) => ({ kind: 'path', path });
|
|
873
|
-
const CUSTOMER_CARE_PAGES = [
|
|
874
|
-
{ label: 'How to order', href: '/how-to-order' },
|
|
875
|
-
{ label: 'Delivery and returns', href: '/delivery-and-returns' },
|
|
876
|
-
{ label: 'Repairs', href: '/repairs' },
|
|
877
|
-
{ label: 'Contact', href: '/contact' },
|
|
878
|
-
{ label: 'Terms and privacy', href: '/terms' },
|
|
879
|
-
];
|
|
880
529
|
function shownOn(mode, ...targets) {
|
|
881
530
|
return { pages: { mode, targets } };
|
|
882
531
|
}
|
|
883
|
-
export
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
}
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
{
|
|
899
|
-
area: 'sidebar',
|
|
900
|
-
type: 'cta',
|
|
901
|
-
title: 'Before you order',
|
|
902
|
-
settings: {
|
|
903
|
-
heading: 'A question about a size or a delivery',
|
|
904
|
-
body: 'Write to us or call the shop. We reply within one working day, Tuesday to Saturday, and nothing is charged until you confirm.',
|
|
905
|
-
label: 'Contact the shop',
|
|
906
|
-
href: '/contact',
|
|
532
|
+
export function storeWidgets(copy) {
|
|
533
|
+
const w = copy.widgets;
|
|
534
|
+
const slug = copy.pageSlugs;
|
|
535
|
+
const care = ['order', 'delivery', 'repairs', 'contact', 'terms'].map((key) => ({
|
|
536
|
+
label: w.careLabels[key],
|
|
537
|
+
href: `/${slug[key]}`,
|
|
538
|
+
}));
|
|
539
|
+
const contactHref = `/${slug.contact}`;
|
|
540
|
+
return [
|
|
541
|
+
{
|
|
542
|
+
area: 'sidebar',
|
|
543
|
+
type: 'recentEntries',
|
|
544
|
+
title: w.newTitle,
|
|
545
|
+
settings: { collection: 'product', count: 4, showDate: false, showImage: true },
|
|
546
|
+
visibility: shownOn('only', SEARCH_RESULTS),
|
|
907
547
|
},
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
settings: {
|
|
915
|
-
phone: '+351 213 460 218',
|
|
916
|
-
hours: [{ label: 'Answered', value: 'Tuesday to Saturday, during opening hours' }],
|
|
548
|
+
{
|
|
549
|
+
area: 'sidebar',
|
|
550
|
+
type: 'links',
|
|
551
|
+
title: w.careTitle,
|
|
552
|
+
settings: { items: care.map((item) => ({ ...item })) },
|
|
553
|
+
visibility: shownOn('only', ...care.map((item) => pagePath(item.href)), SEARCH_RESULTS),
|
|
917
554
|
},
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
555
|
+
{
|
|
556
|
+
area: 'sidebar',
|
|
557
|
+
type: 'cta',
|
|
558
|
+
title: w.beforeTitle,
|
|
559
|
+
settings: {
|
|
560
|
+
heading: w.beforeHeading,
|
|
561
|
+
body: w.beforeBody,
|
|
562
|
+
label: w.beforeLabel,
|
|
563
|
+
href: contactHref,
|
|
564
|
+
},
|
|
565
|
+
visibility: shownOn('only', ...care.filter((item) => item.href !== contactHref).map((item) => pagePath(item.href))),
|
|
929
566
|
},
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
567
|
+
{
|
|
568
|
+
area: 'footer-1',
|
|
569
|
+
type: 'contact',
|
|
570
|
+
title: w.phoneTitle,
|
|
571
|
+
settings: {
|
|
572
|
+
phone: w.phone,
|
|
573
|
+
hours: [{ label: w.phoneHoursLabel, value: w.phoneHoursValue }],
|
|
574
|
+
},
|
|
575
|
+
visibility: shownOn('except', pagePath(contactHref)),
|
|
576
|
+
},
|
|
577
|
+
{
|
|
578
|
+
area: 'footer-2',
|
|
579
|
+
type: 'cta',
|
|
580
|
+
title: w.lettersTitle,
|
|
581
|
+
settings: {
|
|
582
|
+
heading: w.lettersHeading,
|
|
583
|
+
body: w.lettersBody,
|
|
584
|
+
label: w.lettersLabel,
|
|
585
|
+
href: contactHref,
|
|
586
|
+
},
|
|
587
|
+
visibility: shownOn('except', HOME, pagePath(contactHref)),
|
|
588
|
+
},
|
|
589
|
+
];
|
|
590
|
+
}
|
|
591
|
+
export function storeSiteSettings(copy) {
|
|
592
|
+
return {
|
|
593
|
+
'general.tagline': copy.settings.tagline,
|
|
594
|
+
'general.socialLinks': [
|
|
595
|
+
{ label: 'Instagram', url: 'https://instagram.com/example' },
|
|
596
|
+
{ label: 'Pinterest', url: 'https://pinterest.com/example' },
|
|
597
|
+
],
|
|
598
|
+
'general.footerNote': copy.settings.footerNote,
|
|
599
|
+
// A catalogue is not a discussion: no comment form under a product. An
|
|
600
|
+
// editor can open comments again per collection or per entry.
|
|
601
|
+
'discussion.enabled': false,
|
|
602
|
+
};
|
|
603
|
+
}
|
|
944
604
|
export const STORE_RECOMMENDED_AGENTS = [
|
|
945
605
|
{
|
|
946
606
|
name: 'performanceAgent',
|
|
@@ -954,78 +614,95 @@ export const STORE_RECOMMENDED_AGENTS = [
|
|
|
954
614
|
},
|
|
955
615
|
];
|
|
956
616
|
/** The email address a product's order button writes to, with the product in the subject line. */
|
|
957
|
-
export function orderLinkFor(siteName, productName) {
|
|
958
|
-
|
|
617
|
+
export function orderLinkFor(siteName, productName, locale = 'en') {
|
|
618
|
+
const subject = storeCopyFor(locale).orderSubject.replace('{product}', productName);
|
|
619
|
+
return `mailto:${shopEmail(nameOf(siteName), 'orders')}?subject=${encodeURIComponent(subject)}`;
|
|
959
620
|
}
|
|
621
|
+
// Kept for the blueprints that still list a single, English set of constants.
|
|
622
|
+
export const STORE_DEMO_PRODUCTS = STORE_COPY_EN.products;
|
|
623
|
+
export const STORE_DEMO_CATEGORIES = STORE_COPY_EN.categories;
|
|
624
|
+
export const STORE_MEDIA_SPECS = storeMediaSpecs(STORE_COPY_EN);
|
|
625
|
+
export const STORE_MENUS = storeMenus(STORE_COPY_EN);
|
|
626
|
+
export const STORE_WIDGETS = storeWidgets(STORE_COPY_EN);
|
|
627
|
+
export const STORE_SITE_SETTINGS = storeSiteSettings(STORE_COPY_EN);
|
|
960
628
|
/**
|
|
961
629
|
* Inserts the blueprint's content through the real `ContentStore`, never
|
|
962
630
|
* mocked (house rule): categories first (the home page lists them in that
|
|
963
631
|
* order), then the products oldest first, then the pages. Everything is
|
|
964
632
|
* published, so every list and every link has something real behind it.
|
|
965
633
|
*/
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
const
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
634
|
+
function seedStoreDemoContent(copy) {
|
|
635
|
+
return async (ctx) => {
|
|
636
|
+
const { db, defaultLocale, adminId, media } = ctx;
|
|
637
|
+
const siteName = nameOf(ctx.siteName);
|
|
638
|
+
const model = storeSchema(copy);
|
|
639
|
+
const categoryStore = createContentStore({ db, collection: model.category, defaultLocale });
|
|
640
|
+
const productStore = createContentStore({ db, collection: model.product, defaultLocale });
|
|
641
|
+
const pageStore = createContentStore({ db, collection: model.page, defaultLocale });
|
|
642
|
+
for (const demo of copy.categories) {
|
|
643
|
+
const photo = media[`category-${demo.id}`];
|
|
644
|
+
await categoryStore.create({
|
|
645
|
+
status: 'published',
|
|
646
|
+
createdBy: adminId,
|
|
647
|
+
values: {
|
|
648
|
+
name: demo.name,
|
|
649
|
+
slug: demo.slug,
|
|
650
|
+
summary: demo.summary,
|
|
651
|
+
...(photo === undefined ? {} : { photo }),
|
|
652
|
+
},
|
|
653
|
+
blocks: { blocks: storeCategoryBlocks(demo).map(toBlockZoneEntry) },
|
|
654
|
+
});
|
|
655
|
+
}
|
|
656
|
+
for (const demo of copy.products) {
|
|
657
|
+
const photo = media[`product-${demo.key}`];
|
|
658
|
+
await productStore.create({
|
|
659
|
+
status: 'published',
|
|
660
|
+
createdBy: adminId,
|
|
661
|
+
values: {
|
|
662
|
+
name: demo.name,
|
|
663
|
+
slug: demo.slug,
|
|
664
|
+
description: demo.description,
|
|
665
|
+
price: demo.price,
|
|
666
|
+
currency: 'EUR',
|
|
667
|
+
category: categoryOf(copy, demo.category).name,
|
|
668
|
+
inStock: demo.inStock,
|
|
669
|
+
material: demo.material,
|
|
670
|
+
dimensions: demo.dimensions,
|
|
671
|
+
...(demo.weight === undefined ? {} : { weight: demo.weight }),
|
|
672
|
+
...(demo.capacity === undefined ? {} : { capacity: demo.capacity }),
|
|
673
|
+
origin: demo.origin,
|
|
674
|
+
care: demo.care,
|
|
675
|
+
delivery: demo.delivery,
|
|
676
|
+
orderLink: orderLinkFor(siteName, demo.name, copy.locale),
|
|
677
|
+
...(photo === undefined ? {} : { photo }),
|
|
678
|
+
},
|
|
679
|
+
blocks: { blocks: storeProductBlocks(copy, demo).map(toBlockZoneEntry) },
|
|
680
|
+
});
|
|
681
|
+
}
|
|
682
|
+
for (const demo of buildStoreDemoPages({ siteName, media, locale: copy.locale })) {
|
|
683
|
+
await pageStore.create({
|
|
684
|
+
status: 'published',
|
|
685
|
+
createdBy: adminId,
|
|
686
|
+
values: { title: demo.title, slug: demo.slug },
|
|
687
|
+
blocks: { blocks: demo.blocks.map(toBlockZoneEntry) },
|
|
688
|
+
});
|
|
689
|
+
}
|
|
690
|
+
};
|
|
1020
691
|
}
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
692
|
+
/** The whole blueprint, in one language. */
|
|
693
|
+
export function createStoreContentPack(locale) {
|
|
694
|
+
const copy = storeCopyFor(locale);
|
|
695
|
+
return {
|
|
696
|
+
collections: storeSchema(copy).collections,
|
|
697
|
+
recommendedAgents: STORE_RECOMMENDED_AGENTS,
|
|
698
|
+
seedDemoContent: seedStoreDemoContent(copy),
|
|
699
|
+
defaultTheme: '@cogenta/theme-ecommerce',
|
|
700
|
+
menus: storeMenus(copy),
|
|
701
|
+
widgets: storeWidgets(copy),
|
|
702
|
+
siteSettings: storeSiteSettings(copy),
|
|
703
|
+
mediaSpecs: storeMediaSpecs(copy),
|
|
704
|
+
};
|
|
705
|
+
}
|
|
706
|
+
/** The English pack, which `BLUEPRINT_CONTENT_PACKS` lists; `contentPackFor` picks by locale. */
|
|
707
|
+
export const storeContentPack = createStoreContentPack('en');
|
|
1031
708
|
//# sourceMappingURL=store.js.map
|