medusa-storefront-data 2.3.0 → 2.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.
Files changed (269) hide show
  1. package/HOMEPAGE_CONFIG.md +99 -0
  2. package/dist/segment-data/default-page-input.json +191 -0
  3. package/dist/src/config.d.ts.map +1 -0
  4. package/dist/src/cookies.d.ts.map +1 -0
  5. package/dist/src/edge.d.ts.map +1 -0
  6. package/dist/src/middleware.d.ts.map +1 -0
  7. package/dist/src/server/cart.d.ts.map +1 -0
  8. package/dist/src/server/categories.d.ts.map +1 -0
  9. package/dist/src/server/collections.d.ts.map +1 -0
  10. package/dist/src/server/config-merge.d.ts +3 -0
  11. package/dist/src/server/config-merge.d.ts.map +1 -0
  12. package/dist/src/server/config-merge.js +31 -0
  13. package/dist/src/server/contact.d.ts.map +1 -0
  14. package/dist/src/server/customer-registration.d.ts.map +1 -0
  15. package/dist/src/server/customer.d.ts.map +1 -0
  16. package/dist/src/server/dynamic-config.d.ts +240 -0
  17. package/dist/src/server/dynamic-config.d.ts.map +1 -0
  18. package/dist/src/server/dynamic-config.js +703 -0
  19. package/dist/src/server/fulfillment.d.ts.map +1 -0
  20. package/dist/src/server/guest.d.ts.map +1 -0
  21. package/dist/src/server/home-sections/about-brand.d.ts +9 -0
  22. package/dist/src/server/home-sections/about-brand.d.ts.map +1 -0
  23. package/dist/src/server/home-sections/about-brand.js +9 -0
  24. package/dist/src/server/home-sections/baptism-picks.d.ts +10 -0
  25. package/dist/src/server/home-sections/baptism-picks.d.ts.map +1 -0
  26. package/dist/src/server/home-sections/baptism-picks.js +27 -0
  27. package/dist/src/server/home-sections/baptism.d.ts +13 -0
  28. package/dist/src/server/home-sections/baptism.d.ts.map +1 -0
  29. package/dist/src/server/home-sections/baptism.js +43 -0
  30. package/dist/src/server/home-sections/blog-posts.d.ts +9 -0
  31. package/dist/src/server/home-sections/blog-posts.d.ts.map +1 -0
  32. package/dist/src/server/home-sections/blog-posts.js +9 -0
  33. package/dist/src/server/home-sections/brand-marquee.d.ts +8 -0
  34. package/dist/src/server/home-sections/brand-marquee.d.ts.map +1 -0
  35. package/dist/src/server/home-sections/brand-marquee.js +7 -0
  36. package/dist/src/server/home-sections/brand-pillars.d.ts +9 -0
  37. package/dist/src/server/home-sections/brand-pillars.d.ts.map +1 -0
  38. package/dist/src/server/home-sections/brand-pillars.js +9 -0
  39. package/dist/src/server/home-sections/category-pills.d.ts +9 -0
  40. package/dist/src/server/home-sections/category-pills.d.ts.map +1 -0
  41. package/dist/src/server/home-sections/category-pills.js +19 -0
  42. package/dist/src/server/home-sections/celebrity-trust.d.ts +12 -0
  43. package/dist/src/server/home-sections/celebrity-trust.d.ts.map +1 -0
  44. package/dist/src/server/home-sections/celebrity-trust.js +27 -0
  45. package/dist/src/server/home-sections/features.d.ts +9 -0
  46. package/dist/src/server/home-sections/features.d.ts.map +1 -0
  47. package/dist/src/server/home-sections/features.js +9 -0
  48. package/dist/src/server/home-sections/hero.d.ts +9 -0
  49. package/dist/src/server/home-sections/hero.d.ts.map +1 -0
  50. package/dist/src/server/home-sections/hero.js +9 -0
  51. package/dist/src/server/home-sections/instagram-posts.d.ts +9 -0
  52. package/dist/src/server/home-sections/instagram-posts.d.ts.map +1 -0
  53. package/dist/src/server/home-sections/instagram-posts.js +9 -0
  54. package/dist/src/server/home-sections/loved-by-moms.d.ts +12 -0
  55. package/dist/src/server/home-sections/loved-by-moms.d.ts.map +1 -0
  56. package/dist/src/server/home-sections/loved-by-moms.js +20 -0
  57. package/dist/src/server/home-sections/luxe-favourites.d.ts +11 -0
  58. package/dist/src/server/home-sections/luxe-favourites.d.ts.map +1 -0
  59. package/dist/src/server/home-sections/luxe-favourites.js +19 -0
  60. package/dist/src/server/home-sections/new-arrivals-classic.d.ts +8 -0
  61. package/dist/src/server/home-sections/new-arrivals-classic.d.ts.map +1 -0
  62. package/dist/src/server/home-sections/new-arrivals-classic.js +10 -0
  63. package/dist/src/server/home-sections/new-arrivals.d.ts +12 -0
  64. package/dist/src/server/home-sections/new-arrivals.d.ts.map +1 -0
  65. package/dist/src/server/home-sections/new-arrivals.js +28 -0
  66. package/dist/src/server/home-sections/promo-announcements.d.ts +7 -0
  67. package/dist/src/server/home-sections/promo-announcements.d.ts.map +1 -0
  68. package/dist/src/server/home-sections/promo-announcements.js +7 -0
  69. package/dist/src/server/home-sections/promo-countdown.d.ts +6 -0
  70. package/dist/src/server/home-sections/promo-countdown.d.ts.map +1 -0
  71. package/dist/src/server/home-sections/promo-countdown.js +5 -0
  72. package/dist/src/server/home-sections/shared.d.ts +10 -0
  73. package/dist/src/server/home-sections/shared.d.ts.map +1 -0
  74. package/dist/src/server/home-sections/shared.js +29 -0
  75. package/dist/src/server/home-sections/shop-by-age.d.ts +9 -0
  76. package/dist/src/server/home-sections/shop-by-age.d.ts.map +1 -0
  77. package/dist/src/server/home-sections/shop-by-age.js +17 -0
  78. package/dist/src/server/home-sections/shop-by-category.d.ts +10 -0
  79. package/dist/src/server/home-sections/shop-by-category.d.ts.map +1 -0
  80. package/dist/src/server/home-sections/shop-by-category.js +17 -0
  81. package/dist/src/server/home-sections/testimonials.d.ts +9 -0
  82. package/dist/src/server/home-sections/testimonials.d.ts.map +1 -0
  83. package/dist/src/server/home-sections/testimonials.js +9 -0
  84. package/dist/src/server/home-sections/theme-dresses.d.ts +12 -0
  85. package/dist/src/server/home-sections/theme-dresses.d.ts.map +1 -0
  86. package/dist/src/server/home-sections/theme-dresses.js +27 -0
  87. package/dist/src/server/home-sections/video-stories.d.ts +9 -0
  88. package/dist/src/server/home-sections/video-stories.d.ts.map +1 -0
  89. package/dist/src/server/home-sections/video-stories.js +9 -0
  90. package/dist/src/server/home-sections/why-choose-us.d.ts +9 -0
  91. package/dist/src/server/home-sections/why-choose-us.d.ts.map +1 -0
  92. package/dist/src/server/home-sections/why-choose-us.js +9 -0
  93. package/dist/src/server/home.d.ts +62 -0
  94. package/dist/src/server/home.d.ts.map +1 -0
  95. package/dist/{server → src/server}/home.js +29 -31
  96. package/dist/src/server/homepage-config.types.d.ts +274 -0
  97. package/dist/src/server/homepage-config.types.d.ts.map +1 -0
  98. package/dist/src/server/homepage-config.types.js +33 -0
  99. package/dist/{server → src/server}/homepage-section-defaults.d.ts +35 -2
  100. package/dist/src/server/homepage-section-defaults.d.ts.map +1 -0
  101. package/dist/{server → src/server}/homepage-section-defaults.js +41 -2
  102. package/dist/{server → src/server}/index.d.ts +2 -0
  103. package/dist/src/server/index.d.ts.map +1 -0
  104. package/dist/{server → src/server}/index.js +2 -0
  105. package/dist/src/server/locale-actions.d.ts.map +1 -0
  106. package/dist/src/server/locales.d.ts.map +1 -0
  107. package/dist/src/server/notifications.d.ts.map +1 -0
  108. package/dist/src/server/onboarding.d.ts.map +1 -0
  109. package/dist/src/server/orders.d.ts.map +1 -0
  110. package/dist/src/server/page-input.d.ts +19 -0
  111. package/dist/src/server/page-input.d.ts.map +1 -0
  112. package/dist/src/server/page-input.js +40 -0
  113. package/dist/src/server/payment-details.d.ts.map +1 -0
  114. package/dist/src/server/payment.d.ts.map +1 -0
  115. package/dist/src/server/pincode.d.ts.map +1 -0
  116. package/dist/src/server/products.d.ts.map +1 -0
  117. package/dist/src/server/regions.d.ts.map +1 -0
  118. package/dist/src/server/resolve-home-segment-data.d.ts +25 -0
  119. package/dist/src/server/resolve-home-segment-data.d.ts.map +1 -0
  120. package/dist/src/server/resolve-home-segment-data.js +20 -0
  121. package/dist/src/server/returns.d.ts.map +1 -0
  122. package/dist/src/server/shoppable-looks.d.ts +17 -0
  123. package/dist/src/server/shoppable-looks.d.ts.map +1 -0
  124. package/dist/src/server/shoppable-looks.js +136 -0
  125. package/dist/src/server/swaps.d.ts.map +1 -0
  126. package/dist/src/server/variants.d.ts.map +1 -0
  127. package/dist/src/server/wishlist.d.ts.map +1 -0
  128. package/dist/src/util/get-locale-header.d.ts.map +1 -0
  129. package/dist/src/util/medusa-error.d.ts.map +1 -0
  130. package/dist/src/util/revalidate-cart.d.ts.map +1 -0
  131. package/dist/src/util/sort-products.d.ts.map +1 -0
  132. package/dist/src/util/store-client.d.ts.map +1 -0
  133. package/homepage-config.example.json +209 -0
  134. package/homepage-sections.example.json +55 -0
  135. package/package.json +121 -2
  136. package/segment-data/default-page-input.json +191 -0
  137. package/src/server/config-merge.ts +31 -0
  138. package/src/server/dynamic-config.ts +620 -508
  139. package/src/server/home-sections/about-brand.ts +24 -0
  140. package/src/server/home-sections/baptism-picks.ts +46 -0
  141. package/src/server/home-sections/baptism.ts +64 -0
  142. package/src/server/home-sections/blog-posts.ts +23 -0
  143. package/src/server/home-sections/brand-marquee.ts +17 -0
  144. package/src/server/home-sections/brand-pillars.ts +23 -0
  145. package/src/server/home-sections/category-pills.ts +32 -0
  146. package/src/server/home-sections/celebrity-trust.ts +42 -0
  147. package/src/server/home-sections/features.ts +23 -0
  148. package/src/server/home-sections/hero.ts +24 -0
  149. package/src/server/home-sections/instagram-posts.ts +23 -0
  150. package/src/server/home-sections/loved-by-moms.ts +34 -0
  151. package/src/server/home-sections/luxe-favourites.ts +30 -0
  152. package/src/server/home-sections/new-arrivals-classic.ts +21 -0
  153. package/src/server/home-sections/new-arrivals.ts +47 -0
  154. package/src/server/home-sections/promo-announcements.ts +17 -0
  155. package/src/server/home-sections/promo-countdown.ts +15 -0
  156. package/src/server/home-sections/shared.ts +44 -0
  157. package/src/server/home-sections/shop-by-age.ts +26 -0
  158. package/src/server/home-sections/shop-by-category.ts +28 -0
  159. package/src/server/home-sections/testimonials.ts +23 -0
  160. package/src/server/home-sections/theme-dresses.ts +49 -0
  161. package/src/server/home-sections/video-stories.ts +23 -0
  162. package/src/server/home-sections/why-choose-us.ts +23 -0
  163. package/src/server/home.ts +68 -54
  164. package/src/server/homepage-config.types.ts +335 -0
  165. package/src/server/homepage-section-defaults.ts +41 -2
  166. package/src/server/index.ts +2 -0
  167. package/src/server/page-input.ts +64 -0
  168. package/src/server/resolve-home-segment-data.ts +63 -0
  169. package/src/server/shoppable-looks.ts +178 -0
  170. package/dist/config.d.ts.map +0 -1
  171. package/dist/cookies.d.ts.map +0 -1
  172. package/dist/edge.d.ts.map +0 -1
  173. package/dist/middleware.d.ts.map +0 -1
  174. package/dist/server/cart.d.ts.map +0 -1
  175. package/dist/server/categories.d.ts.map +0 -1
  176. package/dist/server/collections.d.ts.map +0 -1
  177. package/dist/server/contact.d.ts.map +0 -1
  178. package/dist/server/customer-registration.d.ts.map +0 -1
  179. package/dist/server/customer.d.ts.map +0 -1
  180. package/dist/server/dynamic-config.d.ts +0 -202
  181. package/dist/server/dynamic-config.d.ts.map +0 -1
  182. package/dist/server/dynamic-config.js +0 -675
  183. package/dist/server/fulfillment.d.ts.map +0 -1
  184. package/dist/server/guest.d.ts.map +0 -1
  185. package/dist/server/home.d.ts +0 -42
  186. package/dist/server/home.d.ts.map +0 -1
  187. package/dist/server/homepage-section-defaults.d.ts.map +0 -1
  188. package/dist/server/index.d.ts.map +0 -1
  189. package/dist/server/locale-actions.d.ts.map +0 -1
  190. package/dist/server/locales.d.ts.map +0 -1
  191. package/dist/server/notifications.d.ts.map +0 -1
  192. package/dist/server/onboarding.d.ts.map +0 -1
  193. package/dist/server/orders.d.ts.map +0 -1
  194. package/dist/server/payment-details.d.ts.map +0 -1
  195. package/dist/server/payment.d.ts.map +0 -1
  196. package/dist/server/pincode.d.ts.map +0 -1
  197. package/dist/server/products.d.ts.map +0 -1
  198. package/dist/server/regions.d.ts.map +0 -1
  199. package/dist/server/returns.d.ts.map +0 -1
  200. package/dist/server/swaps.d.ts.map +0 -1
  201. package/dist/server/variants.d.ts.map +0 -1
  202. package/dist/server/wishlist.d.ts.map +0 -1
  203. package/dist/util/get-locale-header.d.ts.map +0 -1
  204. package/dist/util/medusa-error.d.ts.map +0 -1
  205. package/dist/util/revalidate-cart.d.ts.map +0 -1
  206. package/dist/util/sort-products.d.ts.map +0 -1
  207. package/dist/util/store-client.d.ts.map +0 -1
  208. /package/dist/{config.d.ts → src/config.d.ts} +0 -0
  209. /package/dist/{config.js → src/config.js} +0 -0
  210. /package/dist/{cookies.d.ts → src/cookies.d.ts} +0 -0
  211. /package/dist/{cookies.js → src/cookies.js} +0 -0
  212. /package/dist/{edge.d.ts → src/edge.d.ts} +0 -0
  213. /package/dist/{edge.js → src/edge.js} +0 -0
  214. /package/dist/{middleware.d.ts → src/middleware.d.ts} +0 -0
  215. /package/dist/{middleware.js → src/middleware.js} +0 -0
  216. /package/dist/{server → src/server}/cart.d.ts +0 -0
  217. /package/dist/{server → src/server}/cart.js +0 -0
  218. /package/dist/{server → src/server}/categories.d.ts +0 -0
  219. /package/dist/{server → src/server}/categories.js +0 -0
  220. /package/dist/{server → src/server}/collections.d.ts +0 -0
  221. /package/dist/{server → src/server}/collections.js +0 -0
  222. /package/dist/{server → src/server}/contact.d.ts +0 -0
  223. /package/dist/{server → src/server}/contact.js +0 -0
  224. /package/dist/{server → src/server}/customer-registration.d.ts +0 -0
  225. /package/dist/{server → src/server}/customer-registration.js +0 -0
  226. /package/dist/{server → src/server}/customer.d.ts +0 -0
  227. /package/dist/{server → src/server}/customer.js +0 -0
  228. /package/dist/{server → src/server}/fulfillment.d.ts +0 -0
  229. /package/dist/{server → src/server}/fulfillment.js +0 -0
  230. /package/dist/{server → src/server}/guest.d.ts +0 -0
  231. /package/dist/{server → src/server}/guest.js +0 -0
  232. /package/dist/{server → src/server}/locale-actions.d.ts +0 -0
  233. /package/dist/{server → src/server}/locale-actions.js +0 -0
  234. /package/dist/{server → src/server}/locales.d.ts +0 -0
  235. /package/dist/{server → src/server}/locales.js +0 -0
  236. /package/dist/{server → src/server}/notifications.d.ts +0 -0
  237. /package/dist/{server → src/server}/notifications.js +0 -0
  238. /package/dist/{server → src/server}/onboarding.d.ts +0 -0
  239. /package/dist/{server → src/server}/onboarding.js +0 -0
  240. /package/dist/{server → src/server}/orders.d.ts +0 -0
  241. /package/dist/{server → src/server}/orders.js +0 -0
  242. /package/dist/{server → src/server}/payment-details.d.ts +0 -0
  243. /package/dist/{server → src/server}/payment-details.js +0 -0
  244. /package/dist/{server → src/server}/payment.d.ts +0 -0
  245. /package/dist/{server → src/server}/payment.js +0 -0
  246. /package/dist/{server → src/server}/pincode.d.ts +0 -0
  247. /package/dist/{server → src/server}/pincode.js +0 -0
  248. /package/dist/{server → src/server}/products.d.ts +0 -0
  249. /package/dist/{server → src/server}/products.js +0 -0
  250. /package/dist/{server → src/server}/regions.d.ts +0 -0
  251. /package/dist/{server → src/server}/regions.js +0 -0
  252. /package/dist/{server → src/server}/returns.d.ts +0 -0
  253. /package/dist/{server → src/server}/returns.js +0 -0
  254. /package/dist/{server → src/server}/swaps.d.ts +0 -0
  255. /package/dist/{server → src/server}/swaps.js +0 -0
  256. /package/dist/{server → src/server}/variants.d.ts +0 -0
  257. /package/dist/{server → src/server}/variants.js +0 -0
  258. /package/dist/{server → src/server}/wishlist.d.ts +0 -0
  259. /package/dist/{server → src/server}/wishlist.js +0 -0
  260. /package/dist/{util → src/util}/get-locale-header.d.ts +0 -0
  261. /package/dist/{util → src/util}/get-locale-header.js +0 -0
  262. /package/dist/{util → src/util}/medusa-error.d.ts +0 -0
  263. /package/dist/{util → src/util}/medusa-error.js +0 -0
  264. /package/dist/{util → src/util}/revalidate-cart.d.ts +0 -0
  265. /package/dist/{util → src/util}/revalidate-cart.js +0 -0
  266. /package/dist/{util → src/util}/sort-products.d.ts +0 -0
  267. /package/dist/{util → src/util}/sort-products.js +0 -0
  268. /package/dist/{util → src/util}/store-client.d.ts +0 -0
  269. /package/dist/{util → src/util}/store-client.js +0 -0
@@ -0,0 +1,49 @@
1
+ import "server-only"
2
+
3
+ import { HttpTypes } from "@medusajs/types"
4
+ import { fetchRatings } from "medusa-reviews-logic/server"
5
+ import { getHomeSectionsCopyFromPageInput } from "../dynamic-config"
6
+ import { listCategories } from "../categories"
7
+ import { getProductsByTag } from "../products"
8
+ import {
9
+ categoryIdsMatching,
10
+ productsForCategoryIds,
11
+ requireRegion,
12
+ type SectionLoaderOptions,
13
+ } from "./shared"
14
+
15
+ export type ThemeDressesSectionData = {
16
+ region: NonNullable<Awaited<ReturnType<typeof requireRegion>>>
17
+ themeProducts: HttpTypes.StoreProduct[]
18
+ ratings: unknown[]
19
+ copy: ReturnType<typeof getHomeSectionsCopyFromPageInput>["themeDresses"]
20
+ }
21
+
22
+ export async function loadThemeDressesSectionData(
23
+ countryCode: string,
24
+ options?: SectionLoaderOptions
25
+ ): Promise<ThemeDressesSectionData | null> {
26
+ const region = await requireRegion(countryCode)
27
+ if (!region) return null
28
+ const pageInput = options?.pageInput ?? null
29
+ const [themeByTag, categoriesResult, ratings] = await Promise.all([
30
+ getProductsByTag({ tagValue: "theme", limit: 8, countryCode }).catch(() => []),
31
+ listCategories({ limit: 100 }).catch(() => []),
32
+ fetchRatings(),
33
+ ])
34
+ const categories = (categoriesResult ?? []) as HttpTypes.StoreProductCategory[]
35
+ const themeProducts =
36
+ themeByTag.length > 0
37
+ ? themeByTag
38
+ : await productsForCategoryIds(
39
+ countryCode,
40
+ categoryIdsMatching(categories, /theme/),
41
+ 8
42
+ )
43
+ return {
44
+ region,
45
+ themeProducts,
46
+ ratings: ratings ?? [],
47
+ copy: getHomeSectionsCopyFromPageInput(pageInput).themeDresses,
48
+ }
49
+ }
@@ -0,0 +1,23 @@
1
+ import "server-only"
2
+
3
+ import {
4
+ getHomeSectionsCopyFromPageInput,
5
+ getVideoStoriesFromPageInput,
6
+ } from "../dynamic-config"
7
+ import type { SectionLoaderOptions } from "./shared"
8
+
9
+ export type VideoStoriesSectionData = {
10
+ videoStories: ReturnType<typeof getVideoStoriesFromPageInput>
11
+ copy: ReturnType<typeof getHomeSectionsCopyFromPageInput>["videoStories"]
12
+ }
13
+
14
+ export async function loadVideoStoriesSectionData(
15
+ _countryCode: string,
16
+ options?: SectionLoaderOptions
17
+ ): Promise<VideoStoriesSectionData> {
18
+ const pageInput = options?.pageInput ?? null
19
+ return {
20
+ videoStories: getVideoStoriesFromPageInput(pageInput),
21
+ copy: getHomeSectionsCopyFromPageInput(pageInput).videoStories,
22
+ }
23
+ }
@@ -0,0 +1,23 @@
1
+ import "server-only"
2
+
3
+ import {
4
+ getFeaturesFromPageInput,
5
+ getHomeSectionsCopyFromPageInput,
6
+ } from "../dynamic-config"
7
+ import type { SectionLoaderOptions } from "./shared"
8
+
9
+ export type WhyChooseUsSectionData = {
10
+ whyChooseUsFeatures: ReturnType<typeof getFeaturesFromPageInput>
11
+ copy: ReturnType<typeof getHomeSectionsCopyFromPageInput>["whyChooseUs"]
12
+ }
13
+
14
+ export async function loadWhyChooseUsSectionData(
15
+ _countryCode: string,
16
+ options?: SectionLoaderOptions
17
+ ): Promise<WhyChooseUsSectionData> {
18
+ const pageInput = options?.pageInput ?? null
19
+ return {
20
+ whyChooseUsFeatures: getFeaturesFromPageInput(pageInput),
21
+ copy: getHomeSectionsCopyFromPageInput(pageInput).whyChooseUs,
22
+ }
23
+ }
@@ -1,27 +1,26 @@
1
- "use server";
1
+ import "server-only";
2
2
 
3
3
  import { HttpTypes } from "@medusajs/types";
4
4
  import { listCollections } from "./collections";
5
5
  import { listCategories } from "./categories";
6
6
  import { listProductsWithSort, getProductsByTag, listProducts } from "./products";
7
7
  import { getRegion } from "./regions";
8
- import {
9
- getTestimonialsFromConfig,
10
- getVideoStoriesFromConfig,
11
- getAnnouncementMessagesFromConfig,
12
- getAboutBrandFromConfig,
13
- getBrandPillarsFromConfig,
14
- getBlogPostsFromConfig,
15
- getPromoCountdownFromConfig,
16
- getHomeSectionsCopyFromConfig,
17
- getTrustFeaturesFromConfig,
18
- type AboutBrandConfig,
19
- type BrandPillarConfig,
20
- type BlogPostConfig,
21
- type HomeSectionsCopy,
22
- type TrustFeaturesConfig,
8
+ import type { HomepageConfig } from "./homepage-config.types";
9
+ import type {
10
+ InstagramPostsData,
11
+ AboutBrandConfig,
12
+ BrandPillarConfig,
13
+ BlogPostConfig,
14
+ HomeSectionsCopy,
15
+ TrustFeaturesConfig,
16
+ HomepageBanner,
23
17
  } from "./dynamic-config";
24
18
  import { fetchRatings } from "medusa-reviews-logic/server";
19
+ import {
20
+ getBaptismPicksLooks,
21
+ type ShoppableLook,
22
+ } from "./shoppable-looks";
23
+ import { resolveHomeSegmentConfigData } from "./resolve-home-segment-data";
25
24
 
26
25
  async function productsForCategoryIds(
27
26
  countryCode: string,
@@ -68,24 +67,45 @@ export type HomePageData = {
68
67
  message: string | null;
69
68
  endAt: string | null;
70
69
  active: boolean;
70
+ ctaLabel: string | null;
71
+ ctaHref: string | null;
71
72
  };
72
73
  luxeFavourites: HttpTypes.StoreProduct[];
73
74
  celebrityProduct: HttpTypes.StoreProduct | null;
74
75
  baptismGirl: HttpTypes.StoreProduct[];
75
76
  baptismBoy: HttpTypes.StoreProduct[];
76
- baptismPicks: HttpTypes.StoreProduct[];
77
+ baptismPicks: ShoppableLook[];
77
78
  themeProducts: HttpTypes.StoreProduct[];
78
79
  aboutBrand: AboutBrandConfig;
79
80
  brandPillars: { sectionTitle: string; pillars: BrandPillarConfig[] };
80
81
  blogPosts: BlogPostConfig[];
82
+ instagramPosts: InstagramPostsData;
81
83
  sectionsCopy: HomeSectionsCopy;
82
84
  trustFeatures: TrustFeaturesConfig;
85
+ homeBanners: HomepageBanner[] | null;
86
+ appBanners: HomepageBanner[] | null;
87
+ whyChooseUsFeatures: {
88
+ title: string;
89
+ features: Array<{ name: string; icon: string }>;
90
+ };
91
+ };
92
+
93
+ export type LoadHomePageDataOptions = {
94
+ /** Merged `homepage-config` from main project (fetched via dynamic-config API there). */
95
+ pageInput?: HomepageConfig | null;
83
96
  };
84
97
 
85
98
  /**
86
- * Parallel home page data loader for full storefront homepage sections.
99
+ * Parallel home page data loader. Catalog APIs run here; segment copy comes from
100
+ * `pageInput` (or package JSON defaults) — no dynamic-config fetch in this package.
87
101
  */
88
- export async function loadHomePageData(countryCode: string): Promise<HomePageData | null> {
102
+ export async function loadHomePageData(
103
+ countryCode: string,
104
+ options?: LoadHomePageDataOptions
105
+ ): Promise<HomePageData | null> {
106
+ const pageInput = options?.pageInput ?? null;
107
+ const segmentConfig = resolveHomeSegmentConfigData(pageInput);
108
+
89
109
  const region = await getRegion(countryCode);
90
110
  if (!region) return null;
91
111
 
@@ -94,23 +114,18 @@ export async function loadHomePageData(countryCode: string): Promise<HomePageDat
94
114
  categoriesResult,
95
115
  newArrivalsResult,
96
116
  bestsellersResult,
97
- testimonialsData,
98
117
  allRatings,
99
- videoStoriesData,
100
- announcementMessages,
101
- promoCountdown,
102
- aboutBrand,
103
- brandPillars,
104
- blogPosts,
105
118
  themeByTag,
106
119
  baptismByTag,
107
- sectionsCopy,
108
- trustFeatures,
109
120
  ] = await Promise.all([
110
121
  listCollections({ fields: "id, handle, title, metadata" }).catch(() => ({
111
122
  collections: [],
112
123
  })),
113
- listCategories({ limit: 100 }).catch(() => []),
124
+ listCategories({
125
+ limit: 100,
126
+ fields:
127
+ "id,handle,name,metadata,parent_category_id,*parent_category,*parent_category.parent_category",
128
+ }).catch(() => []),
114
129
  listProductsWithSort({
115
130
  page: 1,
116
131
  queryParams: { limit: 12 },
@@ -122,24 +137,9 @@ export async function loadHomePageData(countryCode: string): Promise<HomePageDat
122
137
  limit: 10,
123
138
  countryCode,
124
139
  }).catch(() => []),
125
- getTestimonialsFromConfig().catch(() => ({
126
- title: "",
127
- testimonials: [],
128
- })),
129
140
  fetchRatings(),
130
- getVideoStoriesFromConfig().catch(() => ({
131
- title: "",
132
- videoUrls: [],
133
- })),
134
- getAnnouncementMessagesFromConfig(),
135
- getPromoCountdownFromConfig(),
136
- getAboutBrandFromConfig(),
137
- getBrandPillarsFromConfig(),
138
- getBlogPostsFromConfig(),
139
141
  getProductsByTag({ tagValue: "theme", limit: 8, countryCode }).catch(() => []),
140
142
  getProductsByTag({ tagValue: "baptism", limit: 12, countryCode }).catch(() => []),
141
- getHomeSectionsCopyFromConfig(),
142
- getTrustFeaturesFromConfig(),
143
143
  ]);
144
144
 
145
145
  const categories = (categoriesResult ?? []) as HttpTypes.StoreProductCategory[];
@@ -185,27 +185,41 @@ export async function loadHomePageData(countryCode: string): Promise<HomePageDat
185
185
  8
186
186
  );
187
187
 
188
+ const baptismPicksFallback = (baptismByTag.length ? baptismByTag : baptismFallback).slice(
189
+ 0,
190
+ 8
191
+ );
192
+ const baptismPicks = await getBaptismPicksLooks(
193
+ countryCode,
194
+ baptismPicksFallback,
195
+ pageInput
196
+ );
197
+
188
198
  return {
189
199
  region,
190
200
  collections: collections as Array<Record<string, unknown>>,
191
201
  categories,
192
202
  newArrivals,
193
203
  bestsellers,
194
- testimonials: testimonialsData,
204
+ testimonials: segmentConfig.testimonials,
195
205
  ratings: allRatings ?? [],
196
- videoStories: videoStoriesData,
197
- announcementMessages,
198
- promoCountdown,
206
+ videoStories: segmentConfig.videoStories,
207
+ announcementMessages: segmentConfig.announcementMessages,
208
+ promoCountdown: segmentConfig.promoCountdown,
199
209
  luxeFavourites: bestsellers.slice(0, 4),
200
210
  celebrityProduct: bestsellers[0] ?? newArrivals[0] ?? null,
201
211
  baptismGirl: resolvedBaptismGirl,
202
212
  baptismBoy: resolvedBaptismBoy,
203
- baptismPicks: (baptismByTag.length ? baptismByTag : baptismFallback).slice(0, 5),
213
+ baptismPicks,
204
214
  themeProducts,
205
- aboutBrand,
206
- brandPillars,
207
- blogPosts,
208
- sectionsCopy,
209
- trustFeatures,
215
+ aboutBrand: segmentConfig.aboutBrand,
216
+ brandPillars: segmentConfig.brandPillars,
217
+ blogPosts: segmentConfig.blogPosts,
218
+ instagramPosts: segmentConfig.instagramPosts,
219
+ sectionsCopy: segmentConfig.sectionsCopy,
220
+ trustFeatures: segmentConfig.trustFeatures,
221
+ homeBanners: segmentConfig.homeBanners,
222
+ appBanners: segmentConfig.appBanners,
223
+ whyChooseUsFeatures: segmentConfig.whyChooseUsFeatures,
210
224
  };
211
225
  }
@@ -0,0 +1,335 @@
1
+ /**
2
+ * Medusa `GET /store/dynamic-config` → `homepage-config` shape.
3
+ * Used by the storefront and as the reference for backend admin JSON.
4
+ *
5
+ * Section keys: camelCase (preferred) or kebab-case (`new-arrivals` → `newArrivals`).
6
+ * Only fields you set override package defaults in `homepage-section-defaults.ts`.
7
+ */
8
+
9
+ /** Shared copy fields merged into every section block. */
10
+ export type HomepageSectionCopyFields = {
11
+ title?: string
12
+ name?: string
13
+ subtitle?: string
14
+ text?: string
15
+ description?: string
16
+ eyebrow?: string
17
+ /** Layout variant, e.g. new arrivals: `grid` | `classic` */
18
+ variant?: string
19
+ layout?: string
20
+ }
21
+
22
+ export type HomepagePromoAnnouncementsSection = HomepageSectionCopyFields & {
23
+ messages?: string[]
24
+ items?: Array<string | { message?: string; text?: string }>
25
+ "announcement-messages"?: string[]
26
+ }
27
+
28
+ export type HomepagePromoCountdownSection = HomepageSectionCopyFields & {
29
+ code?: string
30
+ "coupon-code"?: string
31
+ text?: string
32
+ message?: string
33
+ "promo-text"?: string
34
+ "end-at"?: string
35
+ endAt?: string
36
+ active?: boolean
37
+ "promo-active"?: boolean
38
+ "cta-label"?: string
39
+ "cta-href"?: string
40
+ }
41
+
42
+ export type HomepageNewArrivalsSection = HomepageSectionCopyFields & {
43
+ /** `grid` (ProductCardView) or `classic` (ProductPreview + pink background) */
44
+ variant?: "grid" | "classic" | "legacy" | "preview"
45
+ }
46
+
47
+ export type HomepageTestimonialItem = {
48
+ text?: string
49
+ name?: string
50
+ rating?: number
51
+ avatar?: string
52
+ id?: string
53
+ testimonial?: HomepageTestimonialItem
54
+ review?: HomepageTestimonialItem
55
+ }
56
+
57
+ export type HomepageTestimonialsSection = HomepageSectionCopyFields & {
58
+ items?: HomepageTestimonialItem[]
59
+ testimonials?: HomepageTestimonialItem[]
60
+ reviews?: HomepageTestimonialItem[]
61
+ }
62
+
63
+ export type HomepageRatingItem = HomepageTestimonialItem
64
+
65
+ export type HomepageShoppableLook = {
66
+ image?: string
67
+ "look-image"?: string
68
+ "product-ids"?: string[]
69
+ productIds?: string[]
70
+ "product-handles"?: string[]
71
+ productHandles?: string[]
72
+ look?: HomepageShoppableLook
73
+ }
74
+
75
+ export type HomepageBaptismPicksSection = HomepageSectionCopyFields & {
76
+ looks?: HomepageShoppableLook[]
77
+ "shop-looks"?: HomepageShoppableLook[]
78
+ }
79
+
80
+ export type HomepageAboutBrandStat = {
81
+ label?: string
82
+ name?: string
83
+ value?: string
84
+ }
85
+
86
+ export type HomepageAboutBrandSection = HomepageSectionCopyFields & {
87
+ readMoreHref?: string
88
+ "read-more-link"?: string
89
+ stats?: HomepageAboutBrandStat[]
90
+ "about-stats"?: HomepageAboutBrandStat[]
91
+ }
92
+
93
+ export type HomepageBrandPillar = {
94
+ title?: string
95
+ name?: string
96
+ description?: string
97
+ text?: string
98
+ image?: string
99
+ icon?: string
100
+ pillar?: HomepageBrandPillar
101
+ }
102
+
103
+ export type HomepageBrandPillarsSection = HomepageSectionCopyFields & {
104
+ pillars?: HomepageBrandPillar[]
105
+ "brand-pillars"?: HomepageBrandPillar[]
106
+ }
107
+
108
+ export type HomepageFeatureItem = {
109
+ name?: string
110
+ icon?: string
111
+ "feature-name"?: string
112
+ "feature-icon"?: string
113
+ feature?: HomepageFeatureItem
114
+ }
115
+
116
+ export type HomepageFeaturesSection = HomepageSectionCopyFields & {
117
+ features?: HomepageFeatureItem[]
118
+ items?: HomepageFeatureItem[]
119
+ }
120
+
121
+ export type HomepageBlogPost = {
122
+ title?: string
123
+ href?: string
124
+ link?: string
125
+ url?: string
126
+ excerpt?: string
127
+ description?: string
128
+ category?: string
129
+ tag?: string
130
+ date?: string
131
+ image?: string
132
+ thumbnail?: string
133
+ blog?: HomepageBlogPost
134
+ }
135
+
136
+ export type HomepageBlogPostsSection = HomepageSectionCopyFields & {
137
+ posts?: HomepageBlogPost[]
138
+ "blog-posts"?: HomepageBlogPost[]
139
+ }
140
+
141
+ export type HomepageInstagramPost = {
142
+ id?: string
143
+ image?: string
144
+ "post-image"?: string
145
+ url?: string
146
+ link?: string
147
+ post?: HomepageInstagramPost
148
+ instagram?: HomepageInstagramPost
149
+ }
150
+
151
+ export type HomepageInstagramPostsSection = HomepageSectionCopyFields & {
152
+ handle?: string
153
+ username?: string
154
+ "instagram-handle"?: string
155
+ "profile-url"?: string
156
+ profileUrl?: string
157
+ "profile-image"?: string
158
+ profileImage?: string
159
+ posts?: HomepageInstagramPost[]
160
+ items?: HomepageInstagramPost[]
161
+ }
162
+
163
+ export type HomepageVideoStoryEntry =
164
+ | string
165
+ | {
166
+ "video-url"?: string
167
+ video_url?: string
168
+ url?: string
169
+ src?: string
170
+ video?: string
171
+ "video-story"?: Record<string, unknown>
172
+ }
173
+
174
+ export type HomepageVideoStoriesSection = HomepageSectionCopyFields & {
175
+ "video-urls"?: HomepageVideoStoryEntry[]
176
+ videoUrls?: HomepageVideoStoryEntry[]
177
+ videos?: HomepageVideoStoryEntry[]
178
+ "video-stories"?: HomepageVideoStoryEntry[]
179
+ }
180
+
181
+ /** Per-section blocks under `homepage-config.sections`. */
182
+ export type HomepageSectionsConfig = {
183
+ promoAnnouncements?: HomepagePromoAnnouncementsSection
184
+ hero?: HomepageSectionCopyFields
185
+ categoryPills?: HomepageSectionCopyFields
186
+ newArrivals?: HomepageNewArrivalsSection
187
+ newArrivalsClassic?: HomepageNewArrivalsSection
188
+ promoCountdown?: HomepagePromoCountdownSection
189
+ celebrityTrust?: HomepageSectionCopyFields
190
+ luxeFavourites?: HomepageSectionCopyFields
191
+ shopByCategory?: HomepageSectionCopyFields
192
+ baptism?: HomepageSectionCopyFields
193
+ baptismPicks?: HomepageBaptismPicksSection
194
+ themeDresses?: HomepageSectionCopyFields
195
+ brandMarquee?: HomepageSectionCopyFields
196
+ aboutBrand?: HomepageAboutBrandSection
197
+ testimonials?: HomepageTestimonialsSection
198
+ brandPillars?: HomepageBrandPillarsSection
199
+ instagramPosts?: HomepageInstagramPostsSection
200
+ features?: HomepageFeaturesSection
201
+ shopByAge?: HomepageSectionCopyFields
202
+ whyChooseUs?: HomepageFeaturesSection
203
+ lovedByMoms?: HomepageSectionCopyFields
204
+ videoStories?: HomepageVideoStoriesSection
205
+ blogPosts?: HomepageBlogPostsSection
206
+ /** Allow kebab-case keys from legacy CMS */
207
+ [sectionKey: string]: HomepageSectionCopyFields | undefined
208
+ }
209
+
210
+ export type HomepageBanner = {
211
+ "homepage-banner-image"?: string
212
+ "homepage-banner-title"?: string
213
+ "homepage-banner-subtitle"?: string
214
+ "homepage-banner-description"?: string
215
+ "homepage-banner-button-name"?: string
216
+ "homepage-banner-button-link"?: string
217
+ }
218
+
219
+ export type HomepageBannerEntry = {
220
+ "homepage-banner"?: HomepageBanner
221
+ }
222
+
223
+ export type HomepageAppBanner = {
224
+ "app-banner-image"?: string
225
+ "app-banner-title"?: string
226
+ "app-banner-subtitle"?: string
227
+ "app-banner-description"?: string
228
+ "app-banner-button-name"?: string
229
+ "app-banner-button-link"?: string
230
+ "app-banner-link"?: string
231
+ }
232
+
233
+ export type HomepageAppBannerEntry = {
234
+ "app-banner"?: HomepageAppBanner
235
+ }
236
+
237
+ export type HomepageContactConfig = {
238
+ "contact-phone"?: string
239
+ "contact-email"?: string
240
+ "contact-address"?: string
241
+ }
242
+
243
+ export type HomepageSocialLink = {
244
+ "social-platform-name"?: string
245
+ "social-platform-icon"?: string
246
+ "social-platform-url"?: string
247
+ "social-link"?: HomepageSocialLink
248
+ }
249
+
250
+ export type HomepagePromoBarConfig = {
251
+ "promo-text"?: string
252
+ "promo-code"?: string
253
+ "promo-value"?: string
254
+ "promo-active"?: boolean
255
+ }
256
+
257
+ export type HomepageFaqEntry = {
258
+ "faq-category"?: string
259
+ "faq-question"?: string
260
+ "faq-answer"?: string
261
+ faq?: HomepageFaqEntry
262
+ }
263
+
264
+ /**
265
+ * Root `homepage-config` object stored in Medusa dynamic config.
266
+ */
267
+ export type HomepageConfig = {
268
+ logo?: string
269
+ "website-description"?: string
270
+ website_description?: string
271
+
272
+ /** Hero carousel — used by `hero` section (not `sections.hero`). */
273
+ "homepage-banner-array"?: HomepageBannerEntry[]
274
+
275
+ "app-banner-array"?: HomepageAppBannerEntry[]
276
+
277
+ /** Option 1 — central section copy + structured data (preferred). */
278
+ sections?: HomepageSectionsConfig
279
+
280
+ /**
281
+ * Product reviews for testimonials carousel.
282
+ * Fallback when `sections.testimonials.items` is empty.
283
+ */
284
+ ratings?: HomepageRatingItem[]
285
+
286
+ /** Legacy top-level keys (still read; prefer `sections.*`). */
287
+ "promo-bar"?: HomepagePromoBarConfig
288
+ "contact-us"?: HomepageContactConfig
289
+ "social-links"?: HomepageSocialLink[]
290
+ "faq-array"?: HomepageFaqEntry[]
291
+ "why-choose-us-title"?: string
292
+ "why-choose-us-features"?: HomepageFeatureItem[]
293
+ "about-brand"?: HomepageAboutBrandSection
294
+ "who-we-are"?: HomepageAboutBrandSection
295
+ "video-stories"?: HomepageVideoStoryEntry[]
296
+ "video-stories-array"?: HomepageVideoStoryEntry[]
297
+ video_stories?: HomepageVideoStoryEntry[]
298
+ "announcement-messages"?: string[]
299
+ "announcement-bar"?: string[]
300
+ }
301
+
302
+ /** Full dynamic config API response. */
303
+ export type DynamicConfigResponse = {
304
+ "homepage-config"?: HomepageConfig
305
+ [key: string]: unknown
306
+ }
307
+
308
+ /** All section ids with package defaults. */
309
+ export const HOMEPAGE_SECTION_IDS = [
310
+ "promoAnnouncements",
311
+ "hero",
312
+ "categoryPills",
313
+ "newArrivals",
314
+ "newArrivalsClassic",
315
+ "promoCountdown",
316
+ "celebrityTrust",
317
+ "luxeFavourites",
318
+ "shopByCategory",
319
+ "baptism",
320
+ "baptismPicks",
321
+ "themeDresses",
322
+ "brandMarquee",
323
+ "aboutBrand",
324
+ "testimonials",
325
+ "brandPillars",
326
+ "instagramPosts",
327
+ "features",
328
+ "shopByAge",
329
+ "whyChooseUs",
330
+ "lovedByMoms",
331
+ "videoStories",
332
+ "blogPosts",
333
+ ] as const
334
+
335
+ export type HomepageSectionId = (typeof HOMEPAGE_SECTION_IDS)[number]
@@ -16,11 +16,20 @@ export const DEFAULT_HOMEPAGE_SECTIONS = {
16
16
  newArrivals: {
17
17
  title: "New Arrivals",
18
18
  subtitle: "Fresh styles just landed",
19
+ variant: "grid",
20
+ },
21
+ newArrivalsClassic: {
22
+ title: "New Arrivals",
23
+ subtitle: "Fresh styles just landed",
24
+ variant: "classic",
19
25
  },
20
26
  promoCountdown: {
21
- text: "Limited-time offer — shop your favourites before they're gone!",
22
- code: "SAVE20",
27
+ code: "SAVE50",
28
+ text: "Up to 50% off — shop your favourites before they're gone!",
29
+ "end-at": "2026-12-31T23:59:59.000Z",
23
30
  active: false,
31
+ "cta-label": "Shop Offers",
32
+ "cta-href": "/store",
24
33
  },
25
34
  celebrityTrust: {
26
35
  title: "Trusted by Celebrities",
@@ -38,6 +47,7 @@ export const DEFAULT_HOMEPAGE_SECTIONS = {
38
47
  },
39
48
  baptismPicks: {
40
49
  title: "Baptism Picks",
50
+ looks: [],
41
51
  },
42
52
  themeDresses: {
43
53
  title: "Theme",
@@ -62,6 +72,35 @@ export const DEFAULT_HOMEPAGE_SECTIONS = {
62
72
  testimonials: {
63
73
  title: "What Clients Talk About Us",
64
74
  description: "The Trust We've Earned",
75
+ items: [
76
+ {
77
+ text: "Amazing place if you are looking for a dress for ur little girl's special day. You can even get many aesthetic pics just from the shop because the interior of the shop is amazing too.. the dresses are customizable according to themes that you prefer. My little girl looked like a princess in her pink and white dress which I found within minutes entering the shop.",
78
+ name: "Greeshma thottippal shanmughan",
79
+ },
80
+ {
81
+ text: "I frequently buy dresses for my baby from this store and I am extremely satisfied with the purchase. The quality of the dresses was excellent, and it was perfect for special occasions like birthdays and celebrations.",
82
+ name: "Priyanka Rajesh",
83
+ },
84
+ {
85
+ text: "I recently bought an Onam outfit from this boutique and I'm so glad I did! The quality is excellent, and the design is beautiful. My daughter looked absolutely stunning in it.",
86
+ name: "Riya Rilju",
87
+ },
88
+ {
89
+ text: "I'm beyond happy with the beautiful baptism dress they made for my baby! The craftsmanship, attention to detail, and love put into every stitch truly show.",
90
+ name: "Chinju anthony",
91
+ },
92
+ {
93
+ text: "This is my third baby dress purchase from this store, and I'm still as impressed as ever! The dresses are absolutely adorable, and the sizing is perfect for my little one.",
94
+ name: "Susmitha",
95
+ },
96
+ ],
97
+ },
98
+ instagramPosts: {
99
+ title: "Follow Us on Instagram",
100
+ handle: "yourbrand",
101
+ "profile-url": "https://www.instagram.com/yourbrand/",
102
+ "profile-image": "/Logo.png",
103
+ posts: [],
65
104
  },
66
105
  brandPillars: {
67
106
  title: "This approach resulted in the beautiful structure",