@cimplify/sdk 0.40.1 → 0.41.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.
Files changed (219) hide show
  1. package/dist/dispatcher.mjs +3 -2
  2. package/dist/styles.css +1 -1
  3. package/package.json +1 -1
  4. package/templates/storefront-bakery/.env.example +5 -0
  5. package/templates/storefront-bakery/AGENTS.md +57 -0
  6. package/templates/storefront-bakery/app/about/page.tsx +21 -44
  7. package/templates/storefront-bakery/app/categories/[slug]/page.tsx +2 -1
  8. package/templates/storefront-bakery/app/collections/[slug]/page.tsx +2 -1
  9. package/templates/storefront-bakery/app/error.tsx +60 -0
  10. package/templates/storefront-bakery/app/faq/page.tsx +13 -89
  11. package/templates/storefront-bakery/app/layout.tsx +37 -2
  12. package/templates/storefront-bakery/app/llms.txt/route.ts +94 -0
  13. package/templates/storefront-bakery/app/not-found.tsx +39 -0
  14. package/templates/storefront-bakery/app/page.tsx +6 -6
  15. package/templates/storefront-bakery/app/privacy/page.tsx +24 -68
  16. package/templates/storefront-bakery/app/robots.ts +18 -0
  17. package/templates/storefront-bakery/app/shop/page.tsx +3 -2
  18. package/templates/storefront-bakery/app/sitemap.ts +62 -0
  19. package/templates/storefront-bakery/app/terms/page.tsx +24 -82
  20. package/templates/storefront-bakery/components/footer.tsx +88 -130
  21. package/templates/storefront-bakery/components/header.tsx +8 -16
  22. package/templates/storefront-bakery/lib/brand.ts +453 -0
  23. package/templates/storefront-fashion/.env.example +16 -0
  24. package/templates/storefront-fashion/AGENTS.md +52 -0
  25. package/templates/storefront-fashion/README.md +77 -0
  26. package/templates/storefront-fashion/app/about/page.tsx +41 -0
  27. package/templates/storefront-fashion/app/cart/page.tsx +9 -0
  28. package/templates/storefront-fashion/app/categories/[slug]/listing-client.tsx +19 -0
  29. package/templates/storefront-fashion/app/categories/[slug]/page.tsx +130 -0
  30. package/templates/storefront-fashion/app/checkout/page.tsx +17 -0
  31. package/templates/storefront-fashion/app/collections/[slug]/listing-client.tsx +20 -0
  32. package/templates/storefront-fashion/app/collections/[slug]/page.tsx +130 -0
  33. package/templates/storefront-fashion/app/error.tsx +61 -0
  34. package/templates/storefront-fashion/app/faq/page.tsx +46 -0
  35. package/templates/storefront-fashion/app/globals.css +46 -0
  36. package/templates/storefront-fashion/app/layout.tsx +76 -0
  37. package/templates/storefront-fashion/app/llms.txt/route.ts +94 -0
  38. package/templates/storefront-fashion/app/not-found.tsx +39 -0
  39. package/templates/storefront-fashion/app/orders/[id]/page.tsx +24 -0
  40. package/templates/storefront-fashion/app/page.tsx +183 -0
  41. package/templates/storefront-fashion/app/privacy/page.tsx +44 -0
  42. package/templates/storefront-fashion/app/products/[slug]/page.tsx +165 -0
  43. package/templates/storefront-fashion/app/products/[slug]/product-detail.tsx +71 -0
  44. package/templates/storefront-fashion/app/robots.ts +18 -0
  45. package/templates/storefront-fashion/app/shop/page.tsx +63 -0
  46. package/templates/storefront-fashion/app/shop/shop-client.tsx +32 -0
  47. package/templates/storefront-fashion/app/sitemap.ts +59 -0
  48. package/templates/storefront-fashion/app/terms/page.tsx +44 -0
  49. package/templates/storefront-fashion/components/brand-marquee.tsx +27 -0
  50. package/templates/storefront-fashion/components/cart-pill.tsx +32 -0
  51. package/templates/storefront-fashion/components/category-grid.tsx +28 -0
  52. package/templates/storefront-fashion/components/category-tiles.tsx +104 -0
  53. package/templates/storefront-fashion/components/collection-strip.tsx +45 -0
  54. package/templates/storefront-fashion/components/feature-hero.tsx +82 -0
  55. package/templates/storefront-fashion/components/footer.tsx +153 -0
  56. package/templates/storefront-fashion/components/header.tsx +43 -0
  57. package/templates/storefront-fashion/components/hero.tsx +28 -0
  58. package/templates/storefront-fashion/components/nav-link.tsx +20 -0
  59. package/templates/storefront-fashion/components/newsletter.tsx +50 -0
  60. package/templates/storefront-fashion/components/promo-banner.tsx +41 -0
  61. package/templates/storefront-fashion/components/providers.tsx +31 -0
  62. package/templates/storefront-fashion/components/section-heading.tsx +37 -0
  63. package/templates/storefront-fashion/components/store-product-card.tsx +83 -0
  64. package/templates/storefront-fashion/components/trade-in-cta.tsx +54 -0
  65. package/templates/storefront-fashion/components/trust-bar.tsx +66 -0
  66. package/templates/storefront-fashion/lib/brand.ts +421 -0
  67. package/templates/storefront-fashion/lib/cart.ts +27 -0
  68. package/templates/storefront-fashion/next.config.ts +40 -0
  69. package/templates/storefront-fashion/package.json +28 -0
  70. package/templates/storefront-fashion/postcss.config.mjs +7 -0
  71. package/templates/storefront-fashion/tsconfig.json +23 -0
  72. package/templates/storefront-grocery/.env.example +16 -0
  73. package/templates/storefront-grocery/AGENTS.md +39 -0
  74. package/templates/storefront-grocery/README.md +73 -0
  75. package/templates/storefront-grocery/app/about/page.tsx +38 -0
  76. package/templates/storefront-grocery/app/cart/page.tsx +9 -0
  77. package/templates/storefront-grocery/app/categories/[slug]/listing-client.tsx +19 -0
  78. package/templates/storefront-grocery/app/categories/[slug]/page.tsx +118 -0
  79. package/templates/storefront-grocery/app/checkout/page.tsx +17 -0
  80. package/templates/storefront-grocery/app/collections/[slug]/listing-client.tsx +20 -0
  81. package/templates/storefront-grocery/app/collections/[slug]/page.tsx +118 -0
  82. package/templates/storefront-grocery/app/error.tsx +60 -0
  83. package/templates/storefront-grocery/app/faq/page.tsx +46 -0
  84. package/templates/storefront-grocery/app/globals.css +45 -0
  85. package/templates/storefront-grocery/app/layout.tsx +75 -0
  86. package/templates/storefront-grocery/app/llms.txt/route.ts +94 -0
  87. package/templates/storefront-grocery/app/not-found.tsx +39 -0
  88. package/templates/storefront-grocery/app/orders/[id]/page.tsx +21 -0
  89. package/templates/storefront-grocery/app/page.tsx +97 -0
  90. package/templates/storefront-grocery/app/privacy/page.tsx +44 -0
  91. package/templates/storefront-grocery/app/robots.ts +18 -0
  92. package/templates/storefront-grocery/app/shop/page.tsx +31 -0
  93. package/templates/storefront-grocery/app/shop/shop-client.tsx +27 -0
  94. package/templates/storefront-grocery/app/sitemap.ts +62 -0
  95. package/templates/storefront-grocery/app/terms/page.tsx +44 -0
  96. package/templates/storefront-grocery/components/cart-pill.tsx +32 -0
  97. package/templates/storefront-grocery/components/category-grid.tsx +28 -0
  98. package/templates/storefront-grocery/components/collection-strip.tsx +45 -0
  99. package/templates/storefront-grocery/components/footer.tsx +148 -0
  100. package/templates/storefront-grocery/components/header.tsx +43 -0
  101. package/templates/storefront-grocery/components/hero.tsx +25 -0
  102. package/templates/storefront-grocery/components/nav-link.tsx +20 -0
  103. package/templates/storefront-grocery/components/providers.tsx +31 -0
  104. package/templates/storefront-grocery/components/store-product-card.tsx +83 -0
  105. package/templates/storefront-grocery/lib/brand.ts +284 -0
  106. package/templates/storefront-grocery/lib/cart.ts +27 -0
  107. package/templates/storefront-grocery/next.config.ts +40 -0
  108. package/templates/storefront-grocery/package.json +28 -0
  109. package/templates/storefront-grocery/postcss.config.mjs +7 -0
  110. package/templates/storefront-grocery/tsconfig.json +23 -0
  111. package/templates/storefront-restaurant/.env.example +16 -0
  112. package/templates/storefront-restaurant/AGENTS.md +39 -0
  113. package/templates/storefront-restaurant/README.md +73 -0
  114. package/templates/storefront-restaurant/app/about/page.tsx +38 -0
  115. package/templates/storefront-restaurant/app/cart/page.tsx +9 -0
  116. package/templates/storefront-restaurant/app/categories/[slug]/listing-client.tsx +19 -0
  117. package/templates/storefront-restaurant/app/categories/[slug]/page.tsx +118 -0
  118. package/templates/storefront-restaurant/app/checkout/page.tsx +17 -0
  119. package/templates/storefront-restaurant/app/collections/[slug]/listing-client.tsx +20 -0
  120. package/templates/storefront-restaurant/app/collections/[slug]/page.tsx +118 -0
  121. package/templates/storefront-restaurant/app/error.tsx +60 -0
  122. package/templates/storefront-restaurant/app/faq/page.tsx +46 -0
  123. package/templates/storefront-restaurant/app/globals.css +44 -0
  124. package/templates/storefront-restaurant/app/layout.tsx +80 -0
  125. package/templates/storefront-restaurant/app/llms.txt/route.ts +94 -0
  126. package/templates/storefront-restaurant/app/not-found.tsx +39 -0
  127. package/templates/storefront-restaurant/app/orders/[id]/page.tsx +21 -0
  128. package/templates/storefront-restaurant/app/page.tsx +97 -0
  129. package/templates/storefront-restaurant/app/privacy/page.tsx +44 -0
  130. package/templates/storefront-restaurant/app/robots.ts +18 -0
  131. package/templates/storefront-restaurant/app/shop/page.tsx +31 -0
  132. package/templates/storefront-restaurant/app/shop/shop-client.tsx +27 -0
  133. package/templates/storefront-restaurant/app/sitemap.ts +62 -0
  134. package/templates/storefront-restaurant/app/terms/page.tsx +44 -0
  135. package/templates/storefront-restaurant/components/cart-pill.tsx +32 -0
  136. package/templates/storefront-restaurant/components/category-grid.tsx +28 -0
  137. package/templates/storefront-restaurant/components/collection-strip.tsx +45 -0
  138. package/templates/storefront-restaurant/components/footer.tsx +148 -0
  139. package/templates/storefront-restaurant/components/header.tsx +43 -0
  140. package/templates/storefront-restaurant/components/hero.tsx +25 -0
  141. package/templates/storefront-restaurant/components/nav-link.tsx +20 -0
  142. package/templates/storefront-restaurant/components/product-modal.tsx +105 -0
  143. package/templates/storefront-restaurant/components/providers.tsx +31 -0
  144. package/templates/storefront-restaurant/components/store-product-card.tsx +83 -0
  145. package/templates/storefront-restaurant/lib/brand.ts +287 -0
  146. package/templates/storefront-restaurant/lib/cart.ts +27 -0
  147. package/templates/storefront-restaurant/next.config.ts +40 -0
  148. package/templates/storefront-restaurant/package.json +28 -0
  149. package/templates/storefront-restaurant/postcss.config.mjs +7 -0
  150. package/templates/storefront-restaurant/tsconfig.json +23 -0
  151. package/templates/storefront-retail/.env.example +5 -0
  152. package/templates/storefront-retail/AGENTS.md +64 -0
  153. package/templates/storefront-retail/app/about/page.tsx +24 -54
  154. package/templates/storefront-retail/app/categories/[slug]/page.tsx +2 -1
  155. package/templates/storefront-retail/app/collections/[slug]/page.tsx +2 -1
  156. package/templates/storefront-retail/app/error.tsx +61 -0
  157. package/templates/storefront-retail/app/faq/page.tsx +11 -92
  158. package/templates/storefront-retail/app/layout.tsx +37 -8
  159. package/templates/storefront-retail/app/llms.txt/route.ts +94 -0
  160. package/templates/storefront-retail/app/not-found.tsx +39 -0
  161. package/templates/storefront-retail/app/page.tsx +16 -73
  162. package/templates/storefront-retail/app/privacy/page.tsx +24 -81
  163. package/templates/storefront-retail/app/products/[slug]/page.tsx +165 -0
  164. package/templates/storefront-retail/app/products/[slug]/product-detail.tsx +71 -0
  165. package/templates/storefront-retail/app/robots.ts +18 -0
  166. package/templates/storefront-retail/app/shop/page.tsx +3 -3
  167. package/templates/storefront-retail/app/sitemap.ts +59 -0
  168. package/templates/storefront-retail/app/terms/page.tsx +24 -97
  169. package/templates/storefront-retail/components/brand-marquee.tsx +6 -15
  170. package/templates/storefront-retail/components/feature-hero.tsx +2 -1
  171. package/templates/storefront-retail/components/footer.tsx +85 -120
  172. package/templates/storefront-retail/components/header.tsx +10 -12
  173. package/templates/storefront-retail/components/newsletter.tsx +7 -9
  174. package/templates/storefront-retail/components/promo-banner.tsx +12 -15
  175. package/templates/storefront-retail/components/store-product-card.tsx +7 -7
  176. package/templates/storefront-retail/components/trade-in-cta.tsx +11 -17
  177. package/templates/storefront-retail/components/trust-bar.tsx +45 -5
  178. package/templates/storefront-retail/lib/brand.ts +567 -0
  179. package/templates/storefront-services/.env.example +16 -0
  180. package/templates/storefront-services/AGENTS.md +41 -0
  181. package/templates/storefront-services/README.md +73 -0
  182. package/templates/storefront-services/app/about/page.tsx +38 -0
  183. package/templates/storefront-services/app/cart/page.tsx +9 -0
  184. package/templates/storefront-services/app/categories/[slug]/listing-client.tsx +19 -0
  185. package/templates/storefront-services/app/categories/[slug]/page.tsx +118 -0
  186. package/templates/storefront-services/app/checkout/page.tsx +17 -0
  187. package/templates/storefront-services/app/collections/[slug]/listing-client.tsx +20 -0
  188. package/templates/storefront-services/app/collections/[slug]/page.tsx +118 -0
  189. package/templates/storefront-services/app/error.tsx +60 -0
  190. package/templates/storefront-services/app/faq/page.tsx +46 -0
  191. package/templates/storefront-services/app/globals.css +45 -0
  192. package/templates/storefront-services/app/layout.tsx +80 -0
  193. package/templates/storefront-services/app/llms.txt/route.ts +94 -0
  194. package/templates/storefront-services/app/not-found.tsx +39 -0
  195. package/templates/storefront-services/app/orders/[id]/page.tsx +21 -0
  196. package/templates/storefront-services/app/page.tsx +97 -0
  197. package/templates/storefront-services/app/privacy/page.tsx +44 -0
  198. package/templates/storefront-services/app/robots.ts +18 -0
  199. package/templates/storefront-services/app/shop/page.tsx +31 -0
  200. package/templates/storefront-services/app/shop/shop-client.tsx +27 -0
  201. package/templates/storefront-services/app/sitemap.ts +62 -0
  202. package/templates/storefront-services/app/terms/page.tsx +44 -0
  203. package/templates/storefront-services/components/cart-pill.tsx +32 -0
  204. package/templates/storefront-services/components/category-grid.tsx +28 -0
  205. package/templates/storefront-services/components/collection-strip.tsx +45 -0
  206. package/templates/storefront-services/components/footer.tsx +148 -0
  207. package/templates/storefront-services/components/header.tsx +43 -0
  208. package/templates/storefront-services/components/hero.tsx +25 -0
  209. package/templates/storefront-services/components/nav-link.tsx +20 -0
  210. package/templates/storefront-services/components/product-modal.tsx +105 -0
  211. package/templates/storefront-services/components/providers.tsx +31 -0
  212. package/templates/storefront-services/components/store-product-card.tsx +83 -0
  213. package/templates/storefront-services/lib/brand.ts +303 -0
  214. package/templates/storefront-services/lib/cart.ts +27 -0
  215. package/templates/storefront-services/next.config.ts +40 -0
  216. package/templates/storefront-services/package.json +28 -0
  217. package/templates/storefront-services/postcss.config.mjs +7 -0
  218. package/templates/storefront-services/tsconfig.json +23 -0
  219. /package/templates/{storefront-retail → storefront-grocery}/components/product-modal.tsx +0 -0
@@ -0,0 +1,303 @@
1
+ /**
2
+ * Brand & content configuration — single source of truth for every visible
3
+ * string. Edit this file to rebrand. See ../AGENTS.md.
4
+ */
5
+
6
+ export interface BrandSocial {
7
+ label: string;
8
+ href: string;
9
+ icon?: "instagram" | "x" | "tiktok" | "facebook" | "youtube" | "linkedin" | "whatsapp";
10
+ }
11
+
12
+ export interface BrandFaqEntry { q: string; a: string }
13
+ export interface BrandFaqSection { title: string; items: BrandFaqEntry[] }
14
+ export interface BrandPolicySection {
15
+ heading: string;
16
+ body: string | { intro: string; bullets: string[] };
17
+ }
18
+ export interface BrandSitemapSection { title: string; links: { label: string; href: string }[] }
19
+
20
+ export interface Brand {
21
+ name: string; shortName: string; microTag: string; description: string;
22
+ schemaType:
23
+ | "Store" | "Bakery" | "Restaurant" | "BeautySalon"
24
+ | "GroceryStore" | "LocalBusiness" | "Organization";
25
+ currency: string; locale: string;
26
+ contact: {
27
+ address: string; streetAddress: string; city: string; countryCode: string;
28
+ phone: string; phoneTel: string; email: string; privacyEmail: string;
29
+ supportEmail?: string; businessEmail?: string; hours: string;
30
+ };
31
+ socials: BrandSocial[];
32
+ header: { nav: { label: string; href: string }[] };
33
+ hero: {
34
+ badge: string; title: string; subtitle: string;
35
+ primaryCtaLabel: string;
36
+ secondaryCtaLabel?: string; secondaryCtaHref?: string;
37
+ };
38
+ trustItems?: { label: string; value: string; description: string; iconKey: string }[];
39
+ brandStrip?: { headline: string; brands: string[] };
40
+ promo?: { badge: string; title: string; body: string; ctaLabel: string; ctaHref: string };
41
+ tradeIn?: {
42
+ eyebrow: string; title: string; body: string;
43
+ primaryCtaLabel: string; primaryCtaHref: string;
44
+ secondaryCtaLabel: string; secondaryCtaHref: string;
45
+ steps: { step: string; title: string; body: string }[];
46
+ };
47
+ newsletter: {
48
+ eyebrow: string; title: string; body: string; placeholder: string;
49
+ submitLabel: string; successLabel: string;
50
+ };
51
+ about: {
52
+ eyebrow: string; title: string; paragraphs: string[];
53
+ sections: { heading: string; body: string }[];
54
+ };
55
+ faq: {
56
+ eyebrow: string; title: string; sections: BrandFaqSection[];
57
+ contactPrompt: string; contactEmail: string;
58
+ };
59
+ terms: { eyebrow: string; title: string; lastUpdated: string; sections: BrandPolicySection[] };
60
+ privacy: { eyebrow: string; title: string; lastUpdated: string; sections: BrandPolicySection[] };
61
+ footer: {
62
+ blurb: string; sitemap: BrandSitemapSection[];
63
+ poweredBy?: { label: string; href: string };
64
+ };
65
+ llms: { summary: string };
66
+ mock: { seed: string; businessId: string };
67
+ }
68
+
69
+ export const brand: Brand = {
70
+ name: "Serene Spa",
71
+ shortName: "Serene",
72
+ microTag: "STUDIO · ACCRA",
73
+ description:
74
+ "Massage, facials, hands & feet — by appointment in Cantonments. Calm, considered, by people who trust touch.",
75
+ schemaType: "BeautySalon",
76
+
77
+ currency: "GHS",
78
+ locale: "en_GH",
79
+
80
+ contact: {
81
+ address: "5 Ebony Close, Cantonments, Accra",
82
+ streetAddress: "5 Ebony Close, Cantonments",
83
+ city: "Accra",
84
+ countryCode: "GH",
85
+ phone: "+233 244 777 222",
86
+ phoneTel: "+233244777222",
87
+ email: "hello@serenespa.test",
88
+ privacyEmail: "privacy@serenespa.test",
89
+ hours: "Tue–Sun · 10am–8pm · closed Mondays",
90
+ },
91
+
92
+ socials: [
93
+ { label: "Instagram", href: "https://instagram.com/serenespa", icon: "instagram" },
94
+ { label: "Facebook", href: "https://facebook.com/serenespa", icon: "facebook" },
95
+ { label: "WhatsApp", href: "https://wa.me/233244777222", icon: "whatsapp" },
96
+ ],
97
+
98
+ header: {
99
+ nav: [
100
+ { label: "Treatments", href: "/shop" },
101
+ { label: "Memberships", href: "/categories/memberships" },
102
+ { label: "About", href: "/about" },
103
+ { label: "FAQ", href: "/faq" },
104
+ ],
105
+ },
106
+
107
+ hero: {
108
+ badge: "Now booking · April",
109
+ title: "Slow down.\nLet us take care.",
110
+ subtitle:
111
+ "A small studio in Cantonments. Massage, facials, hands and feet — by qualified, kind hands. Couples rooms, infrared sauna, and herbal tea on arrival.",
112
+ primaryCtaLabel: "Book a treatment",
113
+ secondaryCtaLabel: "See the menu",
114
+ secondaryCtaHref: "/shop",
115
+ },
116
+
117
+ trustItems: [
118
+ {
119
+ label: "Studio",
120
+ value: "Six private rooms",
121
+ description: "Two couples rooms, four singles. All en-suite.",
122
+ iconKey: "verified",
123
+ },
124
+ {
125
+ label: "Therapists",
126
+ value: "8 certified practitioners",
127
+ description: "Average 12 years' practice, all ITEC-trained.",
128
+ iconKey: "support",
129
+ },
130
+ {
131
+ label: "Members",
132
+ value: "20% off · always",
133
+ description: "Monthly membership with two treatments included.",
134
+ iconKey: "warranty",
135
+ },
136
+ {
137
+ label: "Booking",
138
+ value: "Same-week availability",
139
+ description: "Free cancellation up to 24 hours.",
140
+ iconKey: "delivery",
141
+ },
142
+ ],
143
+
144
+ promo: {
145
+ badge: "April only",
146
+ title: "The Reset Package — 90 minutes for two.",
147
+ body: "Couples massage, infrared sauna, fresh juice, and a debrief. GH₵850 for two when booked together. Through April.",
148
+ ctaLabel: "Reserve the Reset",
149
+ ctaHref: "/shop",
150
+ },
151
+
152
+ newsletter: {
153
+ eyebrow: "Quiet list",
154
+ title: "A short note, once a month.",
155
+ body: "Seasonal treatments, new therapists, and the discount codes worth knowing about. We don't email more than monthly. Unsubscribe in one click.",
156
+ placeholder: "you@email.com",
157
+ submitLabel: "Stay in touch",
158
+ successLabel: "On the list ✓",
159
+ },
160
+
161
+ about: {
162
+ eyebrow: "About Serene",
163
+ title: "A studio, not a chain.",
164
+ paragraphs: [
165
+ "Serene opened in 2020 above a flower shop on Ebony Close. Eight therapists, six rooms, and a quiet rule: no upselling, no time pressure, no two-treatment minimums. You book what you need; we bring the same care to a 30-minute scalp massage as to a 3-hour reset.",
166
+ "Every therapist is ITEC-trained or holds an equivalent international certification. Several are massage specialists with 15+ years of practice — including post-natal, deep-tissue, and oncology-cleared work.",
167
+ "We use locally-sourced shea, baobab, and coconut bases — pressed in Tamale, blended with essential oils we choose ourselves. No hidden synthetic fragrances, ever.",
168
+ ],
169
+ sections: [
170
+ {
171
+ heading: "Memberships",
172
+ body: "Monthly members get 20% off everything, two treatments included, and priority booking. Pause any month, no questions.",
173
+ },
174
+ {
175
+ heading: "Gift cards",
176
+ body: "Available in any amount. Delivered instantly by email — printable, redeemable in person or online, with no expiry.",
177
+ },
178
+ {
179
+ heading: "Visit",
180
+ body: "5 Ebony Close, Cantonments · Tue–Sun, 10am–8pm. Mondays the studio rests.",
181
+ },
182
+ ],
183
+ },
184
+
185
+ faq: {
186
+ eyebrow: "Q&A",
187
+ title: "What to expect.",
188
+ sections: [
189
+ {
190
+ title: "Booking & arrival",
191
+ items: [
192
+ { q: "How do I book?", a: "Online via the Treatments menu, or send a WhatsApp to +233 244 777 222. Most slots are bookable same-week." },
193
+ { q: "What's your cancellation policy?", a: "Free cancellation up to 24 hours before your appointment. Within 24 hours we charge 50% of the treatment cost." },
194
+ { q: "When should I arrive?", a: "10 minutes early on your first visit (a brief intake form), 5 minutes for return visits." },
195
+ { q: "Can I bring a guest?", a: "Couples rooms accommodate two. For solo bookings, guests are welcome to wait in our garden lounge." },
196
+ ],
197
+ },
198
+ {
199
+ title: "Treatments",
200
+ items: [
201
+ { q: "What if I have a medical condition?", a: "Tell us at booking. Some treatments — deep-tissue, hot stone, certain pressure points — aren't suitable during pregnancy, post-surgery, or with specific conditions. Our therapists will adjust or recommend alternatives." },
202
+ { q: "Are your products allergen-free?", a: "Our base oils are shea, baobab, and coconut — locally pressed. Essential oils we use are listed on the product page; flag any allergies at booking." },
203
+ { q: "Is tipping expected?", a: "Not expected, always appreciated. Cash or via the kiosk after your treatment." },
204
+ ],
205
+ },
206
+ {
207
+ title: "Memberships",
208
+ items: [
209
+ { q: "How does membership work?", a: "GH₵400/month. Includes two 60-minute treatments per month, 20% off everything else, priority booking, and bring-a-guest credits." },
210
+ { q: "Can I pause it?", a: "Any month, anytime. Email or message us before the next billing date." },
211
+ { q: "Do treatments roll over?", a: "Up to one treatment, for up to 60 days." },
212
+ ],
213
+ },
214
+ ],
215
+ contactPrompt: "Other questions? Message us:",
216
+ contactEmail: "hello@serenespa.test",
217
+ },
218
+
219
+ terms: {
220
+ eyebrow: "Terms of service",
221
+ title: "Terms of Service",
222
+ lastUpdated: "1 May 2026",
223
+ sections: [
224
+ { heading: "1. Who we are", body: "Serene Spa (\"we\", \"us\") is a wellness studio at 5 Ebony Close, Cantonments, Accra. By booking a treatment you (\"you\", \"client\") agree to these terms." },
225
+ { heading: "2. Bookings", body: "Slot is held when payment is received (full or 50% deposit). Confirmation by email and SMS." },
226
+ { heading: "3. Cancellations", body: "Free cancellation up to 24 hours before your appointment. Within 24 hours, 50% of the treatment cost is charged." },
227
+ { heading: "4. Late arrival", body: "Treatments end at the scheduled time. Late arrival shortens the treatment, not the cost." },
228
+ { heading: "5. Health & contraindications", body: "You're responsible for declaring relevant medical conditions, allergies, and medications. We may decline or adjust treatment in the interest of your safety." },
229
+ { heading: "6. Memberships", body: "Monthly subscriptions auto-renew. Pause or cancel any month before the next billing date." },
230
+ { heading: "7. Liability", body: "Maximum liability for any session is the price of that session. We're not liable for items left in the studio." },
231
+ { heading: "8. Governing law", body: "These terms are governed by the laws of Ghana." },
232
+ ],
233
+ },
234
+
235
+ privacy: {
236
+ eyebrow: "Privacy",
237
+ title: "Privacy Policy",
238
+ lastUpdated: "1 May 2026",
239
+ sections: [
240
+ { heading: "What we collect", body: "Booking details (name, phone, email, treatment, time slot), the intake form for health-relevant context, and payment data via our processors. We do not store payment cards." },
241
+ { heading: "How we use it", body: { intro: "We use your data to:", bullets: [
242
+ "Confirm and run your appointments.",
243
+ "Adapt treatments to your stated conditions and preferences.",
244
+ "Send appointment reminders by SMS.",
245
+ "Send our monthly note (only if you opted in).",
246
+ ] } },
247
+ { heading: "Health data", body: "Intake-form information is treated as sensitive. Only the therapist scheduled to see you accesses it; we never share with third parties." },
248
+ { heading: "Who we share it with", body: "Payment processors (Paystack, Stripe), our SMS provider for reminders. No one else." },
249
+ { heading: "Your rights", body: "Under the Ghana Data Protection Act, 2012 (Act 843), you can access, correct, or delete your data. Email privacy@serenespa.test." },
250
+ { heading: "Retention", body: "Booking records: 7 years (tax). Intake forms: 3 years from your last visit." },
251
+ ],
252
+ },
253
+
254
+ footer: {
255
+ blurb:
256
+ "A small spa in Cantonments. Massage, facials, hands & feet — by qualified, kind therapists.",
257
+ sitemap: [
258
+ {
259
+ title: "Visit",
260
+ links: [
261
+ { label: "Treatments", href: "/shop" },
262
+ { label: "Memberships", href: "/categories/memberships" },
263
+ { label: "Gift cards", href: "/about" },
264
+ { label: "Couples", href: "/about" },
265
+ ],
266
+ },
267
+ {
268
+ title: "Studio",
269
+ links: [
270
+ { label: "About", href: "/about" },
271
+ { label: "Therapists", href: "/about" },
272
+ { label: "Press", href: "mailto:press@serenespa.test" },
273
+ ],
274
+ },
275
+ {
276
+ title: "Help",
277
+ links: [
278
+ { label: "Contact", href: "mailto:hello@serenespa.test" },
279
+ { label: "FAQ", href: "/faq" },
280
+ { label: "Cancellation policy", href: "/faq" },
281
+ ],
282
+ },
283
+ {
284
+ title: "Legal",
285
+ links: [
286
+ { label: "Terms of Service", href: "/terms" },
287
+ { label: "Privacy Policy", href: "/privacy" },
288
+ ],
289
+ },
290
+ ],
291
+ poweredBy: { label: "Cimplify", href: "https://app.cimplify.io" },
292
+ },
293
+
294
+ llms: {
295
+ summary:
296
+ "Serene Spa — small wellness studio in Cantonments, Accra. Massage, facials, hands and feet by appointment. Couples rooms, infrared sauna, monthly membership. Booking via website or WhatsApp.",
297
+ },
298
+
299
+ mock: {
300
+ seed: "services",
301
+ businessId: "bus_serene_spa",
302
+ },
303
+ };
@@ -0,0 +1,27 @@
1
+ "use client";
2
+
3
+ import { useEffect, useState } from "react";
4
+ import { useCimplifyClient } from "@cimplify/sdk/react";
5
+
6
+ /**
7
+ * Tiny hook for the live cart-count pill in the header. Re-fetches on
8
+ * mount and exposes a refresh callback. The SDK's `useCart` hook is
9
+ * fine-grained but heavier — this is enough for a header badge.
10
+ */
11
+ export function useCartCount(): { count: number; refresh: () => void } {
12
+ const { client } = useCimplifyClient();
13
+ const [count, setCount] = useState(0);
14
+
15
+ const refresh = () => {
16
+ void client.cart.getCount().then((r) => {
17
+ if (r.ok) setCount(r.value);
18
+ });
19
+ };
20
+
21
+ useEffect(() => {
22
+ refresh();
23
+ // eslint-disable-next-line react-hooks/exhaustive-deps
24
+ }, [client]);
25
+
26
+ return { count, refresh };
27
+ }
@@ -0,0 +1,40 @@
1
+ import type { NextConfig } from "next";
2
+
3
+ const MOCK_URL = process.env.NEXT_PUBLIC_CIMPLIFY_API_URL?.trim() || "http://127.0.0.1:8787";
4
+
5
+ /**
6
+ * Same-origin proxy to the Cimplify mock so the browser never makes a
7
+ * cross-origin request in dev (no CORS preflights, no flaky `Origin`
8
+ * mismatches). The SDK's base URL stays empty/relative — requests go to
9
+ * `/api/v1/...` on the Next origin, then this rewrite forwards them to
10
+ * the mock at `127.0.0.1:8787`.
11
+ *
12
+ * In production, point `NEXT_PUBLIC_CIMPLIFY_API_URL` at your Cimplify
13
+ * host and the rewrite continues to work the same way (or remove it and
14
+ * pass the absolute URL through `<CimplifyProvider/>`).
15
+ */
16
+ const nextConfig: NextConfig = {
17
+ // Enable Next 16's `cacheComponents` mode so we can use `'use cache'` +
18
+ // `cacheTag` / `cacheLife` for SSR caching. Cached chrome streams first,
19
+ // dynamic Suspense boundaries fill in when ready.
20
+ cacheComponents: true,
21
+ async rewrites() {
22
+ return [
23
+ { source: "/api/v1/:path*", destination: `${MOCK_URL}/api/v1/:path*` },
24
+ { source: "/img/:path*", destination: `${MOCK_URL}/img/:path*` },
25
+ { source: "/elements/:path*", destination: `${MOCK_URL}/elements/:path*` },
26
+ { source: "/_mock/:path*", destination: `${MOCK_URL}/_mock/:path*` },
27
+ ];
28
+ },
29
+ images: {
30
+ remotePatterns: [
31
+ { protocol: "http", hostname: "127.0.0.1", port: "8787", pathname: "/img/**" },
32
+ { protocol: "http", hostname: "localhost", port: "8787", pathname: "/img/**" },
33
+ { protocol: "http", hostname: "localhost", port: "3000", pathname: "/img/**" },
34
+ { protocol: "https", hostname: "loremflickr.com", pathname: "/**" },
35
+ { protocol: "https", hostname: "images.unsplash.com", pathname: "/**" },
36
+ ],
37
+ },
38
+ };
39
+
40
+ export default nextConfig;
@@ -0,0 +1,28 @@
1
+ {
2
+ "name": "__STOREFRONT_NAME__",
3
+ "private": true,
4
+ "version": "0.0.0",
5
+ "scripts": {
6
+ "dev": "concurrently -k -n mock,next -c blue,magenta \"bunx @cimplify/sdk --seed services --quiet\" \"next dev\"",
7
+ "dev:storefront": "next dev",
8
+ "dev:mock": "bunx @cimplify/sdk --seed services",
9
+ "build": "next build",
10
+ "start": "next start",
11
+ "lint": "next lint"
12
+ },
13
+ "dependencies": {
14
+ "@cimplify/sdk": "^0.40.1",
15
+ "next": "^16.2.4",
16
+ "react": "^19.0.0",
17
+ "react-dom": "^19.0.0"
18
+ },
19
+ "devDependencies": {
20
+ "@tailwindcss/postcss": "^4.2.4",
21
+ "@types/node": "^22.10.0",
22
+ "@types/react": "^19.0.0",
23
+ "@types/react-dom": "^19.0.0",
24
+ "concurrently": "^9.0.0",
25
+ "tailwindcss": "^4.2.4",
26
+ "typescript": "^5.9.3"
27
+ }
28
+ }
@@ -0,0 +1,7 @@
1
+ const config = {
2
+ plugins: {
3
+ "@tailwindcss/postcss": {},
4
+ },
5
+ };
6
+
7
+ export default config;
@@ -0,0 +1,23 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "lib": ["dom", "dom.iterable", "esnext"],
5
+ "allowJs": false,
6
+ "skipLibCheck": true,
7
+ "strict": true,
8
+ "noEmit": true,
9
+ "esModuleInterop": true,
10
+ "module": "esnext",
11
+ "moduleResolution": "bundler",
12
+ "resolveJsonModule": true,
13
+ "isolatedModules": true,
14
+ "jsx": "preserve",
15
+ "incremental": true,
16
+ "plugins": [{ "name": "next" }],
17
+ "paths": {
18
+ "@/*": ["./*"]
19
+ }
20
+ },
21
+ "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts", ".next/dev/types/**/*.ts"],
22
+ "exclude": ["node_modules"]
23
+ }