@mohasinac/appkit 2.4.10 → 2.5.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 (889) hide show
  1. package/dist/_internal/client/features/products/index.d.ts +1 -0
  2. package/dist/_internal/client/features/products/index.js +3 -0
  3. package/dist/_internal/client/i18n/LabelsProvider.d.ts +13 -0
  4. package/dist/_internal/client/i18n/LabelsProvider.js +38 -0
  5. package/dist/_internal/client/index.d.ts +0 -0
  6. package/dist/_internal/client/index.js +4 -0
  7. package/dist/_internal/client/scaffolds/AppShell.d.ts +39 -0
  8. package/dist/_internal/client/scaffolds/AppShell.js +9 -0
  9. package/dist/_internal/client/scaffolds/DashboardScaffold.d.ts +34 -0
  10. package/dist/_internal/client/scaffolds/DashboardScaffold.js +23 -0
  11. package/dist/_internal/client/scaffolds/index.d.ts +4 -0
  12. package/dist/_internal/client/scaffolds/index.js +2 -0
  13. package/dist/_internal/server/features/account/actions.d.ts +7 -0
  14. package/dist/_internal/server/features/account/actions.js +7 -0
  15. package/dist/_internal/server/features/account/data.d.ts +17 -0
  16. package/dist/_internal/server/features/account/data.js +25 -0
  17. package/dist/_internal/server/features/account/index.d.ts +2 -0
  18. package/dist/_internal/server/features/account/index.js +2 -0
  19. package/dist/_internal/server/features/auctions/actions.d.ts +1 -0
  20. package/dist/_internal/server/features/auctions/actions.js +44 -0
  21. package/dist/_internal/server/features/auctions/data.d.ts +4 -0
  22. package/dist/_internal/server/features/auctions/data.js +9 -0
  23. package/dist/_internal/server/features/auctions/index.d.ts +5 -0
  24. package/dist/_internal/server/features/auctions/index.js +5 -0
  25. package/dist/_internal/server/features/auctions/og.d.ts +19 -0
  26. package/dist/_internal/server/features/auctions/og.js +51 -0
  27. package/dist/_internal/server/features/auctions/service.d.ts +13 -0
  28. package/dist/_internal/server/features/auctions/service.js +57 -0
  29. package/dist/_internal/server/features/auth/actions.d.ts +8 -0
  30. package/dist/_internal/server/features/auth/actions.js +8 -0
  31. package/dist/_internal/server/features/auth/index.d.ts +1 -0
  32. package/dist/_internal/server/features/auth/index.js +1 -0
  33. package/dist/_internal/server/features/blog/actions.d.ts +5 -0
  34. package/dist/_internal/server/features/blog/actions.js +51 -0
  35. package/dist/_internal/server/features/blog/data.d.ts +2 -0
  36. package/dist/_internal/server/features/blog/data.js +8 -0
  37. package/dist/_internal/server/features/blog/index.d.ts +5 -0
  38. package/dist/_internal/server/features/blog/index.js +5 -0
  39. package/dist/_internal/server/features/blog/og.d.ts +23 -0
  40. package/dist/_internal/server/features/blog/og.js +64 -0
  41. package/dist/_internal/server/features/blog/service.d.ts +3 -0
  42. package/dist/_internal/server/features/blog/service.js +18 -0
  43. package/dist/_internal/server/features/brands/actions.d.ts +4 -0
  44. package/dist/_internal/server/features/brands/actions.js +32 -0
  45. package/dist/_internal/server/features/brands/data.d.ts +12 -0
  46. package/dist/_internal/server/features/brands/data.js +16 -0
  47. package/dist/_internal/server/features/brands/index.d.ts +5 -0
  48. package/dist/_internal/server/features/brands/index.js +5 -0
  49. package/dist/_internal/server/features/brands/og.d.ts +17 -0
  50. package/dist/_internal/server/features/brands/og.js +37 -0
  51. package/dist/_internal/server/features/brands/service.d.ts +3 -0
  52. package/dist/_internal/server/features/brands/service.js +14 -0
  53. package/dist/_internal/server/features/bundles/data.d.ts +9 -0
  54. package/dist/_internal/server/features/bundles/data.js +9 -0
  55. package/dist/_internal/server/features/bundles/index.d.ts +2 -0
  56. package/dist/_internal/server/features/bundles/index.js +2 -0
  57. package/dist/_internal/server/features/cart/actions.d.ts +12 -0
  58. package/dist/_internal/server/features/cart/actions.js +35 -0
  59. package/dist/_internal/server/features/cart/data.d.ts +1 -0
  60. package/dist/_internal/server/features/cart/data.js +5 -0
  61. package/dist/_internal/server/features/cart/index.d.ts +4 -0
  62. package/dist/_internal/server/features/cart/index.js +4 -0
  63. package/dist/_internal/server/features/cart/service.d.ts +8 -0
  64. package/dist/_internal/server/features/cart/service.js +25 -0
  65. package/dist/_internal/server/features/categories/data.d.ts +13 -0
  66. package/dist/_internal/server/features/categories/data.js +40 -0
  67. package/dist/_internal/server/features/categories/index.d.ts +2 -0
  68. package/dist/_internal/server/features/categories/index.js +2 -0
  69. package/dist/_internal/server/features/checkout/actions.d.ts +35 -0
  70. package/dist/_internal/server/features/checkout/actions.js +327 -0
  71. package/dist/_internal/server/features/checkout/data.d.ts +13 -0
  72. package/dist/_internal/server/features/checkout/data.js +13 -0
  73. package/dist/_internal/server/features/checkout/index.d.ts +3 -0
  74. package/dist/_internal/server/features/checkout/index.js +3 -0
  75. package/dist/_internal/server/features/events/actions.d.ts +4 -0
  76. package/dist/_internal/server/features/events/actions.js +60 -0
  77. package/dist/_internal/server/features/events/data.d.ts +1 -0
  78. package/dist/_internal/server/features/events/data.js +5 -0
  79. package/dist/_internal/server/features/events/index.d.ts +5 -0
  80. package/dist/_internal/server/features/events/index.js +5 -0
  81. package/dist/_internal/server/features/events/og.d.ts +26 -0
  82. package/dist/_internal/server/features/events/og.js +87 -0
  83. package/dist/_internal/server/features/events/service.d.ts +2 -0
  84. package/dist/_internal/server/features/events/service.js +27 -0
  85. package/dist/_internal/server/features/grouped/data.d.ts +25 -0
  86. package/dist/_internal/server/features/grouped/data.js +116 -0
  87. package/dist/_internal/server/features/grouped/index.d.ts +2 -0
  88. package/dist/_internal/server/features/grouped/index.js +2 -0
  89. package/dist/_internal/server/features/history/actions.d.ts +8 -0
  90. package/dist/_internal/server/features/history/actions.js +15 -0
  91. package/dist/_internal/server/features/history/data.d.ts +7 -0
  92. package/dist/_internal/server/features/history/data.js +6 -0
  93. package/dist/_internal/server/features/history/index.d.ts +3 -0
  94. package/dist/_internal/server/features/history/index.js +3 -0
  95. package/dist/_internal/server/features/homepage/data.d.ts +18 -0
  96. package/dist/_internal/server/features/homepage/data.js +39 -0
  97. package/dist/_internal/server/features/homepage/index.d.ts +2 -0
  98. package/dist/_internal/server/features/homepage/index.js +2 -0
  99. package/dist/_internal/server/features/messages/actions.d.ts +6 -0
  100. package/dist/_internal/server/features/messages/actions.js +6 -0
  101. package/dist/_internal/server/features/messages/data.d.ts +10 -0
  102. package/dist/_internal/server/features/messages/data.js +24 -0
  103. package/dist/_internal/server/features/messages/index.d.ts +2 -0
  104. package/dist/_internal/server/features/messages/index.js +2 -0
  105. package/dist/_internal/server/features/orders/actions.d.ts +4 -0
  106. package/dist/_internal/server/features/orders/actions.js +50 -0
  107. package/dist/_internal/server/features/orders/adapters.d.ts +3 -0
  108. package/dist/_internal/server/features/orders/adapters.js +56 -0
  109. package/dist/_internal/server/features/orders/data.d.ts +10 -0
  110. package/dist/_internal/server/features/orders/data.js +18 -0
  111. package/dist/_internal/server/features/orders/index.d.ts +5 -0
  112. package/dist/_internal/server/features/orders/index.js +5 -0
  113. package/dist/_internal/server/features/orders/service.d.ts +4 -0
  114. package/dist/_internal/server/features/orders/service.js +30 -0
  115. package/dist/_internal/server/features/payments/actions.d.ts +30 -0
  116. package/dist/_internal/server/features/payments/actions.js +45 -0
  117. package/dist/_internal/server/features/payments/data.d.ts +11 -0
  118. package/dist/_internal/server/features/payments/data.js +14 -0
  119. package/dist/_internal/server/features/payments/index.d.ts +3 -0
  120. package/dist/_internal/server/features/payments/index.js +3 -0
  121. package/dist/_internal/server/features/pre-orders/actions.d.ts +7 -0
  122. package/dist/_internal/server/features/pre-orders/actions.js +26 -0
  123. package/dist/_internal/server/features/pre-orders/data.d.ts +4 -0
  124. package/dist/_internal/server/features/pre-orders/data.js +9 -0
  125. package/dist/_internal/server/features/pre-orders/index.d.ts +5 -0
  126. package/dist/_internal/server/features/pre-orders/index.js +5 -0
  127. package/dist/_internal/server/features/pre-orders/og.d.ts +19 -0
  128. package/dist/_internal/server/features/pre-orders/og.js +49 -0
  129. package/dist/_internal/server/features/pre-orders/service.d.ts +7 -0
  130. package/dist/_internal/server/features/pre-orders/service.js +30 -0
  131. package/dist/_internal/server/features/products/actions.d.ts +7 -0
  132. package/dist/_internal/server/features/products/actions.js +74 -0
  133. package/dist/_internal/server/features/products/data.d.ts +14 -0
  134. package/dist/_internal/server/features/products/data.js +48 -0
  135. package/dist/_internal/server/features/products/index.d.ts +5 -0
  136. package/dist/_internal/server/features/products/index.js +5 -0
  137. package/dist/_internal/server/features/products/og.d.ts +19 -0
  138. package/dist/_internal/server/features/products/og.js +43 -0
  139. package/dist/_internal/server/features/products/service.d.ts +11 -0
  140. package/dist/_internal/server/features/products/service.js +55 -0
  141. package/dist/_internal/server/features/profile/index.d.ts +1 -0
  142. package/dist/_internal/server/features/profile/index.js +1 -0
  143. package/dist/_internal/server/features/profile/og.d.ts +26 -0
  144. package/dist/_internal/server/features/profile/og.js +91 -0
  145. package/dist/_internal/server/features/promotions/actions.d.ts +9 -0
  146. package/dist/_internal/server/features/promotions/actions.js +38 -0
  147. package/dist/_internal/server/features/promotions/data.d.ts +1 -0
  148. package/dist/_internal/server/features/promotions/data.js +5 -0
  149. package/dist/_internal/server/features/promotions/index.d.ts +4 -0
  150. package/dist/_internal/server/features/promotions/index.js +4 -0
  151. package/dist/_internal/server/features/promotions/service.d.ts +3 -0
  152. package/dist/_internal/server/features/promotions/service.js +47 -0
  153. package/dist/_internal/server/features/reviews/actions.d.ts +4 -0
  154. package/dist/_internal/server/features/reviews/actions.js +66 -0
  155. package/dist/_internal/server/features/reviews/data.d.ts +10 -0
  156. package/dist/_internal/server/features/reviews/data.js +18 -0
  157. package/dist/_internal/server/features/reviews/index.d.ts +3 -0
  158. package/dist/_internal/server/features/reviews/index.js +3 -0
  159. package/dist/_internal/server/features/reviews/service.d.ts +5 -0
  160. package/dist/_internal/server/features/reviews/service.js +27 -0
  161. package/dist/_internal/server/features/scams/data.d.ts +10 -0
  162. package/dist/_internal/server/features/scams/data.js +22 -0
  163. package/dist/_internal/server/features/scams/index.d.ts +1 -0
  164. package/dist/_internal/server/features/scams/index.js +1 -0
  165. package/dist/_internal/server/features/search/actions.d.ts +15 -0
  166. package/dist/_internal/server/features/search/actions.js +18 -0
  167. package/dist/_internal/server/features/search/data.d.ts +15 -0
  168. package/dist/_internal/server/features/search/data.js +18 -0
  169. package/dist/_internal/server/features/search/index.d.ts +3 -0
  170. package/dist/_internal/server/features/search/index.js +2 -0
  171. package/dist/_internal/server/features/stores/data.d.ts +31 -0
  172. package/dist/_internal/server/features/stores/data.js +58 -0
  173. package/dist/_internal/server/features/stores/index.d.ts +3 -0
  174. package/dist/_internal/server/features/stores/index.js +3 -0
  175. package/dist/_internal/server/features/stores/og.d.ts +19 -0
  176. package/dist/_internal/server/features/stores/og.js +52 -0
  177. package/dist/_internal/server/features/sublisting-categories/data.d.ts +1 -0
  178. package/dist/_internal/server/features/sublisting-categories/data.js +5 -0
  179. package/dist/_internal/server/features/sublisting-categories/index.d.ts +2 -0
  180. package/dist/_internal/server/features/sublisting-categories/index.js +2 -0
  181. package/dist/_internal/server/features/sublisting-categories/og.d.ts +20 -0
  182. package/dist/_internal/server/features/sublisting-categories/og.js +56 -0
  183. package/dist/_internal/server/features/wishlist/actions.d.ts +13 -0
  184. package/dist/_internal/server/features/wishlist/actions.js +40 -0
  185. package/dist/_internal/server/features/wishlist/data.d.ts +8 -0
  186. package/dist/_internal/server/features/wishlist/data.js +9 -0
  187. package/dist/_internal/server/features/wishlist/index.d.ts +4 -0
  188. package/dist/_internal/server/features/wishlist/index.js +4 -0
  189. package/dist/_internal/server/index.d.ts +0 -0
  190. package/dist/_internal/server/index.js +4 -0
  191. package/dist/_internal/server/jobs/handlers/_helpers.d.ts +8 -0
  192. package/dist/_internal/server/jobs/handlers/_helpers.js +19 -0
  193. package/dist/_internal/server/jobs/handlers/adminAnalytics.d.ts +28 -0
  194. package/dist/_internal/server/jobs/handlers/adminAnalytics.js +98 -0
  195. package/dist/_internal/server/jobs/handlers/auctionSettlement.d.ts +2 -0
  196. package/dist/_internal/server/jobs/handlers/auctionSettlement.js +70 -0
  197. package/dist/_internal/server/jobs/handlers/autoPayoutEligibility.d.ts +2 -0
  198. package/dist/_internal/server/jobs/handlers/autoPayoutEligibility.js +110 -0
  199. package/dist/_internal/server/jobs/handlers/cartPrune.d.ts +2 -0
  200. package/dist/_internal/server/jobs/handlers/cartPrune.js +13 -0
  201. package/dist/_internal/server/jobs/handlers/cleanupRtdbEvents.d.ts +2 -0
  202. package/dist/_internal/server/jobs/handlers/cleanupRtdbEvents.js +45 -0
  203. package/dist/_internal/server/jobs/handlers/countersReconcile.d.ts +2 -0
  204. package/dist/_internal/server/jobs/handlers/countersReconcile.js +109 -0
  205. package/dist/_internal/server/jobs/handlers/couponExpiry.d.ts +2 -0
  206. package/dist/_internal/server/jobs/handlers/couponExpiry.js +13 -0
  207. package/dist/_internal/server/jobs/handlers/dailyDataCleanup.d.ts +2 -0
  208. package/dist/_internal/server/jobs/handlers/dailyDataCleanup.js +20 -0
  209. package/dist/_internal/server/jobs/handlers/index.d.ts +35 -0
  210. package/dist/_internal/server/jobs/handlers/index.js +35 -0
  211. package/dist/_internal/server/jobs/handlers/listingProcessor.d.ts +30 -0
  212. package/dist/_internal/server/jobs/handlers/listingProcessor.js +128 -0
  213. package/dist/_internal/server/jobs/handlers/mediaTmpCleanup.d.ts +14 -0
  214. package/dist/_internal/server/jobs/handlers/mediaTmpCleanup.js +69 -0
  215. package/dist/_internal/server/jobs/handlers/messages.d.ts +45 -0
  216. package/dist/_internal/server/jobs/handlers/messages.js +45 -0
  217. package/dist/_internal/server/jobs/handlers/notificationPrune.d.ts +2 -0
  218. package/dist/_internal/server/jobs/handlers/notificationPrune.js +13 -0
  219. package/dist/_internal/server/jobs/handlers/offerExpiry.d.ts +2 -0
  220. package/dist/_internal/server/jobs/handlers/offerExpiry.js +50 -0
  221. package/dist/_internal/server/jobs/handlers/onBidPlaced.d.ts +12 -0
  222. package/dist/_internal/server/jobs/handlers/onBidPlaced.js +63 -0
  223. package/dist/_internal/server/jobs/handlers/onCategoryWrite.d.ts +10 -0
  224. package/dist/_internal/server/jobs/handlers/onCategoryWrite.js +136 -0
  225. package/dist/_internal/server/jobs/handlers/onOrderCreate.d.ts +14 -0
  226. package/dist/_internal/server/jobs/handlers/onOrderCreate.js +83 -0
  227. package/dist/_internal/server/jobs/handlers/onOrderStatusChange.d.ts +14 -0
  228. package/dist/_internal/server/jobs/handlers/onOrderStatusChange.js +141 -0
  229. package/dist/_internal/server/jobs/handlers/onProductWrite.d.ts +8 -0
  230. package/dist/_internal/server/jobs/handlers/onProductWrite.js +92 -0
  231. package/dist/_internal/server/jobs/handlers/onReviewWrite.d.ts +2 -0
  232. package/dist/_internal/server/jobs/handlers/onReviewWrite.js +51 -0
  233. package/dist/_internal/server/jobs/handlers/onStoreWrite.d.ts +10 -0
  234. package/dist/_internal/server/jobs/handlers/onStoreWrite.js +9 -0
  235. package/dist/_internal/server/jobs/handlers/payoutBatch.d.ts +11 -0
  236. package/dist/_internal/server/jobs/handlers/payoutBatch.js +104 -0
  237. package/dist/_internal/server/jobs/handlers/pendingOrderTimeout.d.ts +8 -0
  238. package/dist/_internal/server/jobs/handlers/pendingOrderTimeout.js +33 -0
  239. package/dist/_internal/server/jobs/handlers/positionsReconcile.d.ts +7 -0
  240. package/dist/_internal/server/jobs/handlers/positionsReconcile.js +87 -0
  241. package/dist/_internal/server/jobs/handlers/productStatsSync.d.ts +8 -0
  242. package/dist/_internal/server/jobs/handlers/productStatsSync.js +36 -0
  243. package/dist/_internal/server/jobs/handlers/promotions.d.ts +12 -0
  244. package/dist/_internal/server/jobs/handlers/promotions.js +43 -0
  245. package/dist/_internal/server/jobs/handlers/storeAnalytics.d.ts +30 -0
  246. package/dist/_internal/server/jobs/handlers/storeAnalytics.js +109 -0
  247. package/dist/_internal/server/jobs/handlers/weeklyPayoutEligibility.d.ts +8 -0
  248. package/dist/_internal/server/jobs/handlers/weeklyPayoutEligibility.js +87 -0
  249. package/dist/_internal/server/jobs/index.d.ts +4 -0
  250. package/dist/_internal/server/jobs/index.js +3 -0
  251. package/dist/_internal/server/jobs/runtime/adapters/firebase.d.ts +50 -0
  252. package/dist/_internal/server/jobs/runtime/adapters/firebase.js +156 -0
  253. package/dist/_internal/server/jobs/runtime/types.d.ts +52 -0
  254. package/dist/_internal/server/jobs/runtime/types.js +13 -0
  255. package/dist/_internal/shared/config/index.d.ts +1 -0
  256. package/dist/_internal/shared/config/index.js +1 -0
  257. package/dist/_internal/shared/config/schema.d.ts +82 -0
  258. package/dist/_internal/shared/config/schema.js +1 -0
  259. package/dist/_internal/shared/constants/index.d.ts +1 -0
  260. package/dist/_internal/shared/constants/index.js +1 -0
  261. package/dist/_internal/shared/errors/index.d.ts +24 -0
  262. package/dist/_internal/shared/errors/index.js +46 -0
  263. package/dist/_internal/shared/features/auctions/config.d.ts +6 -0
  264. package/dist/_internal/shared/features/auctions/config.js +6 -0
  265. package/dist/_internal/shared/features/auctions/errors.d.ts +16 -0
  266. package/dist/_internal/shared/features/auctions/errors.js +31 -0
  267. package/dist/_internal/shared/features/auctions/schema.d.ts +30 -0
  268. package/dist/_internal/shared/features/auctions/schema.js +12 -0
  269. package/dist/_internal/shared/features/blog/config.d.ts +6 -0
  270. package/dist/_internal/shared/features/blog/config.js +6 -0
  271. package/dist/_internal/shared/features/blog/errors.d.ts +10 -0
  272. package/dist/_internal/shared/features/blog/errors.js +19 -0
  273. package/dist/_internal/shared/features/blog/schema.d.ts +81 -0
  274. package/dist/_internal/shared/features/blog/schema.js +17 -0
  275. package/dist/_internal/shared/features/brands/config.d.ts +4 -0
  276. package/dist/_internal/shared/features/brands/config.js +4 -0
  277. package/dist/_internal/shared/features/brands/errors.d.ts +7 -0
  278. package/dist/_internal/shared/features/brands/errors.js +13 -0
  279. package/dist/_internal/shared/features/brands/schema.d.ts +69 -0
  280. package/dist/_internal/shared/features/brands/schema.js +15 -0
  281. package/dist/_internal/shared/features/bundles/config.d.ts +6 -0
  282. package/dist/_internal/shared/features/bundles/config.js +6 -0
  283. package/dist/_internal/shared/features/cart/config.d.ts +3 -0
  284. package/dist/_internal/shared/features/cart/config.js +3 -0
  285. package/dist/_internal/shared/features/cart/errors.d.ts +10 -0
  286. package/dist/_internal/shared/features/cart/errors.js +19 -0
  287. package/dist/_internal/shared/features/cart/schema.d.ts +132 -0
  288. package/dist/_internal/shared/features/cart/schema.js +33 -0
  289. package/dist/_internal/shared/features/categories/config.d.ts +6 -0
  290. package/dist/_internal/shared/features/categories/config.js +6 -0
  291. package/dist/_internal/shared/features/checkout/config.d.ts +8 -0
  292. package/dist/_internal/shared/features/checkout/config.js +7 -0
  293. package/dist/_internal/shared/features/events/config.d.ts +5 -0
  294. package/dist/_internal/shared/features/events/config.js +5 -0
  295. package/dist/_internal/shared/features/events/errors.d.ts +16 -0
  296. package/dist/_internal/shared/features/events/errors.js +31 -0
  297. package/dist/_internal/shared/features/events/schema.d.ts +91 -0
  298. package/dist/_internal/shared/features/events/schema.js +21 -0
  299. package/dist/_internal/shared/features/grouped/config.d.ts +3 -0
  300. package/dist/_internal/shared/features/grouped/config.js +3 -0
  301. package/dist/_internal/shared/features/history/config.d.ts +2 -0
  302. package/dist/_internal/shared/features/history/config.js +2 -0
  303. package/dist/_internal/shared/features/homepage/config.d.ts +3 -0
  304. package/dist/_internal/shared/features/homepage/config.js +3 -0
  305. package/dist/_internal/shared/features/orders/config.d.ts +8 -0
  306. package/dist/_internal/shared/features/orders/config.js +8 -0
  307. package/dist/_internal/shared/features/orders/errors.d.ts +13 -0
  308. package/dist/_internal/shared/features/orders/errors.js +25 -0
  309. package/dist/_internal/shared/features/orders/schema.d.ts +114 -0
  310. package/dist/_internal/shared/features/orders/schema.js +33 -0
  311. package/dist/_internal/shared/features/payments/config.d.ts +2 -0
  312. package/dist/_internal/shared/features/payments/config.js +2 -0
  313. package/dist/_internal/shared/features/pre-orders/config.d.ts +4 -0
  314. package/dist/_internal/shared/features/pre-orders/config.js +4 -0
  315. package/dist/_internal/shared/features/pre-orders/errors.d.ts +13 -0
  316. package/dist/_internal/shared/features/pre-orders/errors.js +25 -0
  317. package/dist/_internal/shared/features/pre-orders/schema.d.ts +25 -0
  318. package/dist/_internal/shared/features/pre-orders/schema.js +10 -0
  319. package/dist/_internal/shared/features/products/config.d.ts +5 -0
  320. package/dist/_internal/shared/features/products/config.js +5 -0
  321. package/dist/_internal/shared/features/products/errors.d.ts +16 -0
  322. package/dist/_internal/shared/features/products/errors.js +31 -0
  323. package/dist/_internal/shared/features/products/schema.d.ts +364 -0
  324. package/dist/_internal/shared/features/products/schema.js +58 -0
  325. package/dist/_internal/shared/features/products/types.d.ts +46 -0
  326. package/dist/_internal/shared/features/products/types.js +1 -0
  327. package/dist/_internal/shared/features/promotions/config.d.ts +3 -0
  328. package/dist/_internal/shared/features/promotions/config.js +3 -0
  329. package/dist/_internal/shared/features/promotions/errors.d.ts +19 -0
  330. package/dist/_internal/shared/features/promotions/errors.js +37 -0
  331. package/dist/_internal/shared/features/promotions/schema.d.ts +242 -0
  332. package/dist/_internal/shared/features/promotions/schema.js +37 -0
  333. package/dist/_internal/shared/features/reviews/config.d.ts +8 -0
  334. package/dist/_internal/shared/features/reviews/config.js +8 -0
  335. package/dist/_internal/shared/features/reviews/errors.d.ts +13 -0
  336. package/dist/_internal/shared/features/reviews/errors.js +25 -0
  337. package/dist/_internal/shared/features/reviews/schema.d.ts +44 -0
  338. package/dist/_internal/shared/features/reviews/schema.js +18 -0
  339. package/dist/_internal/shared/features/stores/config.d.ts +4 -0
  340. package/dist/_internal/shared/features/stores/config.js +4 -0
  341. package/dist/_internal/shared/features/wishlist/config.d.ts +2 -0
  342. package/dist/_internal/shared/features/wishlist/config.js +2 -0
  343. package/dist/_internal/shared/features/wishlist/errors.d.ts +4 -0
  344. package/dist/_internal/shared/features/wishlist/errors.js +7 -0
  345. package/dist/_internal/shared/index.d.ts +2 -0
  346. package/dist/_internal/shared/index.js +4 -0
  347. package/dist/_internal/shared/serialization/index.d.ts +17 -0
  348. package/dist/_internal/shared/serialization/index.js +42 -0
  349. package/dist/_internal/shared/tokens/index.d.ts +137 -0
  350. package/dist/_internal/shared/tokens/index.js +159 -0
  351. package/dist/client-entry.d.ts +23 -0
  352. package/dist/client-entry.js +27 -0
  353. package/dist/client.d.ts +47 -5
  354. package/dist/client.js +68 -33
  355. package/dist/configs/eslint.d.ts +29 -0
  356. package/dist/configs/eslint.js +38 -0
  357. package/dist/configs/index.d.ts +14 -0
  358. package/dist/configs/index.js +14 -0
  359. package/dist/configs/next.d.ts +38 -0
  360. package/dist/configs/next.js +116 -0
  361. package/dist/configs/postcss.d.ts +22 -0
  362. package/dist/configs/postcss.js +22 -0
  363. package/dist/configs/tailwind.d.ts +59 -0
  364. package/dist/configs/tailwind.js +62 -0
  365. package/dist/constants/api-endpoints.d.ts +24 -0
  366. package/dist/constants/api-endpoints.js +8 -0
  367. package/dist/constants/index.d.ts +1 -0
  368. package/dist/constants/index.js +1 -0
  369. package/dist/constants/limits.d.ts +15 -0
  370. package/dist/constants/limits.js +15 -0
  371. package/dist/contracts/client-auth.d.ts +2 -0
  372. package/dist/errors/messages.d.ts +23 -0
  373. package/dist/errors/messages.js +25 -0
  374. package/dist/features/about/components/PublicProfileView.js +16 -9
  375. package/dist/features/account/components/AddressBook.d.ts +2 -1
  376. package/dist/features/account/components/AddressBook.js +2 -2
  377. package/dist/features/account/components/UserReturnsView.d.ts +10 -0
  378. package/dist/features/account/components/UserReturnsView.js +5 -0
  379. package/dist/features/account/components/index.d.ts +2 -0
  380. package/dist/features/account/components/index.js +1 -0
  381. package/dist/features/account/hooks/useProfile.d.ts +2 -0
  382. package/dist/features/account/schemas/index.d.ts +18 -18
  383. package/dist/features/admin/actions/chat-actions.d.ts +1 -1
  384. package/dist/features/admin/actions/chat-actions.js +10 -10
  385. package/dist/features/admin/components/AdminBlogEditorView.d.ts +2 -1
  386. package/dist/features/admin/components/AdminBlogEditorView.js +16 -14
  387. package/dist/features/admin/components/AdminBlogView.js +6 -3
  388. package/dist/features/admin/components/AdminBrandEditorView.d.ts +3 -1
  389. package/dist/features/admin/components/AdminBrandEditorView.js +16 -14
  390. package/dist/features/admin/components/AdminBrandsView.js +6 -3
  391. package/dist/features/admin/components/AdminCategoriesView.js +6 -3
  392. package/dist/features/admin/components/AdminCategoryEditorView.d.ts +2 -1
  393. package/dist/features/admin/components/AdminCategoryEditorView.js +16 -14
  394. package/dist/features/admin/components/AdminCouponEditorView.d.ts +2 -1
  395. package/dist/features/admin/components/AdminCouponEditorView.js +16 -14
  396. package/dist/features/admin/components/AdminCouponsView.js +6 -3
  397. package/dist/features/admin/components/AdminFaqEditorView.d.ts +2 -1
  398. package/dist/features/admin/components/AdminFaqEditorView.js +16 -14
  399. package/dist/features/admin/components/AdminFaqsView.js +6 -3
  400. package/dist/features/admin/components/AdminFeatureEditorView.d.ts +19 -0
  401. package/dist/features/admin/components/AdminFeatureEditorView.js +150 -0
  402. package/dist/features/admin/components/AdminFeaturesView.d.ts +4 -0
  403. package/dist/features/admin/components/AdminFeaturesView.js +95 -0
  404. package/dist/features/admin/components/AdminHistoryView.d.ts +4 -0
  405. package/dist/features/admin/components/AdminHistoryView.js +57 -0
  406. package/dist/features/admin/components/AdminMediaView.js +64 -2
  407. package/dist/features/admin/components/AdminOrdersView.js +31 -4
  408. package/dist/features/admin/components/AdminProductEditorView.d.ts +2 -1
  409. package/dist/features/admin/components/AdminProductEditorView.js +30 -19
  410. package/dist/features/admin/components/AdminProductsView.js +40 -3
  411. package/dist/features/admin/components/AdminSectionsView.js +138 -2
  412. package/dist/features/admin/components/AdminSiteSettingsView.js +22 -2
  413. package/dist/features/admin/components/AdminStoresView.js +5 -4
  414. package/dist/features/admin/components/AdminUserEditorView.d.ts +4 -1
  415. package/dist/features/admin/components/AdminUserEditorView.js +2 -2
  416. package/dist/features/admin/components/AdminUsersView.js +1 -1
  417. package/dist/features/admin/components/AdminWishlistsView.js +17 -15
  418. package/dist/features/admin/components/DataTable.d.ts +2 -1
  419. package/dist/features/admin/components/DataTable.js +14 -12
  420. package/dist/features/admin/components/DrawerFormFooter.d.ts +9 -21
  421. package/dist/features/admin/components/DrawerFormFooter.js +10 -2
  422. package/dist/features/admin/components/QuickEditMenu.d.ts +20 -0
  423. package/dist/features/admin/components/QuickEditMenu.js +31 -0
  424. package/dist/features/admin/components/analytics/AdminAnalyticsCharts.js +11 -23
  425. package/dist/features/admin/components/index.d.ts +8 -0
  426. package/dist/features/admin/components/index.js +4 -0
  427. package/dist/features/admin/components/sections/adminSectionsBuildParse.d.ts +9 -1
  428. package/dist/features/admin/components/sections/adminSectionsBuildParse.js +169 -9
  429. package/dist/features/admin/components/sections/adminSectionsTypes.d.ts +62 -1
  430. package/dist/features/admin/components/sections/adminSectionsTypes.js +57 -4
  431. package/dist/features/admin/hooks/useChat.d.ts +1 -1
  432. package/dist/features/admin/repository/chat.repository.d.ts +2 -2
  433. package/dist/features/admin/repository/chat.repository.js +7 -7
  434. package/dist/features/admin/schemas/firestore.d.ts +42 -7
  435. package/dist/features/admin/schemas/firestore.js +7 -7
  436. package/dist/features/admin/types/product.types.d.ts +2 -2
  437. package/dist/features/auctions/actions/bid-actions.js +3 -2
  438. package/dist/features/auctions/components/AuctionDetailPageView.d.ts +11 -1
  439. package/dist/features/auctions/components/AuctionDetailPageView.js +80 -68
  440. package/dist/features/auctions/components/AuctionsListView.js +11 -6
  441. package/dist/features/auctions/components/MarketplaceAuctionCard.d.ts +2 -1
  442. package/dist/features/auctions/hooks/useAuctions.js +2 -1
  443. package/dist/features/auctions/repository/auctions.repository.js +4 -4
  444. package/dist/features/auctions/schemas/index.d.ts +24 -24
  445. package/dist/features/auctions/types/index.d.ts +2 -1
  446. package/dist/features/auth/hooks/useAuth.d.ts +8 -0
  447. package/dist/features/auth/hooks/useAuth.js +9 -0
  448. package/dist/features/auth/schemas/index.d.ts +2 -2
  449. package/dist/features/before-after/schemas/index.d.ts +2 -2
  450. package/dist/features/blog/actions/blog-actions.d.ts +63 -63
  451. package/dist/features/blog/components/BlogPostView.d.ts +3 -1
  452. package/dist/features/blog/components/BlogPostView.js +3 -2
  453. package/dist/features/blog/schemas/index.d.ts +41 -41
  454. package/dist/features/bundles/components/AdminBundleEditorView.d.ts +8 -0
  455. package/dist/features/bundles/components/AdminBundleEditorView.js +7 -0
  456. package/dist/features/bundles/components/BundleDetailPageView.d.ts +9 -0
  457. package/dist/features/bundles/components/BundleDetailPageView.js +45 -0
  458. package/dist/features/bundles/components/BundleForm.d.ts +12 -0
  459. package/dist/features/bundles/components/BundleForm.js +126 -0
  460. package/dist/features/bundles/components/BundleItemsPicker.d.ts +9 -0
  461. package/dist/features/bundles/components/BundleItemsPicker.js +77 -0
  462. package/dist/features/bundles/components/BundlesListingView.d.ts +17 -0
  463. package/dist/features/bundles/components/BundlesListingView.js +50 -0
  464. package/dist/features/bundles/components/FeaturedBundlesSection.d.ts +5 -0
  465. package/dist/features/bundles/components/FeaturedBundlesSection.js +55 -0
  466. package/dist/features/bundles/components/SellerBundleCreateView.d.ts +8 -0
  467. package/dist/features/bundles/components/SellerBundleCreateView.js +7 -0
  468. package/dist/features/bundles/components/SellerBundleEditView.d.ts +9 -0
  469. package/dist/features/bundles/components/SellerBundleEditView.js +7 -0
  470. package/dist/features/bundles/components/index.d.ts +16 -0
  471. package/dist/features/bundles/components/index.js +8 -0
  472. package/dist/features/bundles/constants/index.d.ts +32 -0
  473. package/dist/features/bundles/constants/index.js +35 -0
  474. package/dist/features/bundles/index.d.ts +2 -0
  475. package/dist/features/bundles/index.js +2 -0
  476. package/dist/features/bundles/repository/bundles.repository.d.ts +36 -0
  477. package/dist/features/bundles/repository/bundles.repository.js +148 -0
  478. package/dist/features/bundles/repository/index.d.ts +1 -0
  479. package/dist/features/bundles/repository/index.js +1 -0
  480. package/dist/features/bundles/schemas/firestore.d.ts +88 -0
  481. package/dist/features/bundles/schemas/firestore.js +29 -0
  482. package/dist/features/bundles/schemas/index.d.ts +1 -0
  483. package/dist/features/bundles/schemas/index.js +1 -0
  484. package/dist/features/cart/actions/cart-actions.js +2 -1
  485. package/dist/features/cart/repository/cart.repository.js +1 -2
  486. package/dist/features/cart/schemas/firestore.d.ts +9 -6
  487. package/dist/features/cart/schemas/firestore.js +1 -2
  488. package/dist/features/cart/schemas/index.d.ts +7 -7
  489. package/dist/features/cart/utils/guest-cart.d.ts +6 -0
  490. package/dist/features/cart/utils/guest-cart.js +14 -0
  491. package/dist/features/categories/components/BrandDetailPageView.d.ts +3 -1
  492. package/dist/features/categories/components/BrandDetailPageView.js +6 -6
  493. package/dist/features/categories/components/CategoryDetailPageView.js +3 -3
  494. package/dist/features/categories/components/CategoryProductsListing.js +1 -1
  495. package/dist/features/categories/schemas/index.d.ts +24 -24
  496. package/dist/features/collections/schemas/index.d.ts +3 -3
  497. package/dist/features/consultation/schemas/index.d.ts +7 -7
  498. package/dist/features/corporate/schemas/index.d.ts +1 -1
  499. package/dist/features/events/components/AdminEventEditorView.d.ts +2 -1
  500. package/dist/features/events/components/AdminEventEditorView.js +10 -8
  501. package/dist/features/events/components/AdminEventsView.js +6 -3
  502. package/dist/features/events/components/EventDetailView.d.ts +7 -1
  503. package/dist/features/events/components/EventDetailView.js +4 -1
  504. package/dist/features/events/components/EventRafflesSection.d.ts +12 -0
  505. package/dist/features/events/components/EventRafflesSection.js +17 -0
  506. package/dist/features/events/components/index.d.ts +2 -0
  507. package/dist/features/events/components/index.js +1 -0
  508. package/dist/features/events/schemas/index.d.ts +41 -41
  509. package/dist/features/faq/actions/faq-actions.d.ts +16 -16
  510. package/dist/features/faq/schemas/index.d.ts +12 -12
  511. package/dist/features/history/actions/history-actions.d.ts +24 -0
  512. package/dist/features/history/actions/history-actions.js +43 -0
  513. package/dist/features/history/actions/index.d.ts +1 -0
  514. package/dist/features/history/actions/index.js +1 -0
  515. package/dist/features/history/components/HistoryTracker.d.ts +8 -0
  516. package/dist/features/history/components/HistoryTracker.js +18 -0
  517. package/dist/features/history/hooks/useHistory.d.ts +16 -0
  518. package/dist/features/history/hooks/useHistory.js +148 -0
  519. package/dist/features/history/hooks/useHistoryMergeOnLogin.d.ts +1 -0
  520. package/dist/features/history/hooks/useHistoryMergeOnLogin.js +41 -0
  521. package/dist/features/history/index.d.ts +5 -0
  522. package/dist/features/history/index.js +4 -0
  523. package/dist/features/history/repository/user-history.repository.d.ts +59 -0
  524. package/dist/features/history/repository/user-history.repository.js +203 -0
  525. package/dist/features/history/server.d.ts +6 -0
  526. package/dist/features/history/server.js +6 -0
  527. package/dist/features/history/utils/guest-history.d.ts +24 -0
  528. package/dist/features/history/utils/guest-history.js +66 -0
  529. package/dist/features/homepage/actions/homepage-section-actions.d.ts +4 -4
  530. package/dist/features/homepage/components/BrandsSection.d.ts +7 -1
  531. package/dist/features/homepage/components/BrandsSection.js +26 -4
  532. package/dist/features/homepage/components/CollectionCardsSection.d.ts +13 -0
  533. package/dist/features/homepage/components/CollectionCardsSection.js +41 -0
  534. package/dist/features/homepage/components/FAQSection.d.ts +14 -4
  535. package/dist/features/homepage/components/FAQSection.js +63 -13
  536. package/dist/features/homepage/components/FeaturedProductsSection.d.ts +8 -1
  537. package/dist/features/homepage/components/FeaturedProductsSection.js +42 -2
  538. package/dist/features/homepage/components/MarketplaceHomepageView.js +17 -8
  539. package/dist/features/homepage/components/ShopByCategorySection.d.ts +8 -1
  540. package/dist/features/homepage/components/ShopByCategorySection.js +44 -4
  541. package/dist/features/homepage/components/SocialFeedSection.js +22 -2
  542. package/dist/features/homepage/components/SocialPostCard.js +20 -5
  543. package/dist/features/homepage/components/WelcomeSection.js +2 -2
  544. package/dist/features/homepage/components/WhatsAppCommunitySection.d.ts +0 -1
  545. package/dist/features/homepage/components/WhatsAppCommunitySection.js +4 -4
  546. package/dist/features/homepage/lib/live-stats.d.ts +18 -5
  547. package/dist/features/homepage/lib/live-stats.js +60 -29
  548. package/dist/features/homepage/lib/section-renderer.d.ts +2 -1
  549. package/dist/features/homepage/lib/section-renderer.js +50 -11
  550. package/dist/features/homepage/repository/carousels.repository.d.ts +38 -0
  551. package/dist/features/homepage/repository/carousels.repository.js +142 -0
  552. package/dist/features/homepage/schemas/firestore.d.ts +177 -21
  553. package/dist/features/homepage/schemas/firestore.js +24 -0
  554. package/dist/features/layout/AppLayoutShell.d.ts +3 -1
  555. package/dist/features/layout/AppLayoutShell.js +2 -2
  556. package/dist/features/layout/TitleBarLayout.d.ts +3 -1
  557. package/dist/features/layout/TitleBarLayout.js +5 -4
  558. package/dist/features/layout/index.d.ts +1 -1
  559. package/dist/features/media/MediaPickerModal.js +67 -3
  560. package/dist/features/media/types/index.d.ts +2 -2
  561. package/dist/features/media/upload/MediaUploadField.js +21 -5
  562. package/dist/features/messages/actions/index.d.ts +2 -0
  563. package/dist/features/messages/actions/index.js +2 -0
  564. package/dist/features/messages/actions/messages-actions.d.ts +15 -0
  565. package/dist/features/messages/actions/messages-actions.js +33 -0
  566. package/dist/features/messages/actions/ping-rtdb.d.ts +2 -0
  567. package/dist/features/messages/actions/ping-rtdb.js +24 -0
  568. package/dist/features/messages/hooks/useConversation.d.ts +22 -0
  569. package/dist/features/messages/hooks/useConversation.js +125 -0
  570. package/dist/features/messages/hooks/useConversations.d.ts +9 -0
  571. package/dist/features/messages/hooks/useConversations.js +62 -0
  572. package/dist/features/messages/index.d.ts +6 -0
  573. package/dist/features/messages/index.js +4 -0
  574. package/dist/features/messages/realtime.d.ts +32 -0
  575. package/dist/features/messages/realtime.js +39 -0
  576. package/dist/features/messages/repository/conversations.repository.d.ts +35 -0
  577. package/dist/features/messages/repository/conversations.repository.js +180 -0
  578. package/dist/features/messages/server.d.ts +6 -0
  579. package/dist/features/messages/server.js +6 -0
  580. package/dist/features/orders/schemas/firestore.d.ts +21 -0
  581. package/dist/features/orders/schemas/index.d.ts +28 -28
  582. package/dist/features/orders/utils/order-splitter.d.ts +12 -2
  583. package/dist/features/orders/utils/order-splitter.js +13 -2
  584. package/dist/features/payments/schemas/index.d.ts +6 -6
  585. package/dist/features/pre-orders/api/route.js +10 -11
  586. package/dist/features/pre-orders/components/PreOrderDetailPageView.d.ts +11 -1
  587. package/dist/features/pre-orders/components/PreOrderDetailPageView.js +45 -35
  588. package/dist/features/pre-orders/components/PreOrdersIndexListing.js +24 -7
  589. package/dist/features/pre-orders/components/PreOrdersListView.js +10 -5
  590. package/dist/features/pre-orders/schemas/index.d.ts +6 -6
  591. package/dist/features/products/actions/product-actions.d.ts +2 -2
  592. package/dist/features/products/actions/product-actions.js +21 -16
  593. package/dist/features/products/api/[id]/route.js +4 -4
  594. package/dist/features/products/api/route.js +21 -6
  595. package/dist/features/products/components/AuctionsIndexListing.js +1 -1
  596. package/dist/features/products/components/CompareOverlay.d.ts +51 -0
  597. package/dist/features/products/components/CompareOverlay.js +154 -0
  598. package/dist/features/products/components/FeatureBadge.d.ts +28 -0
  599. package/dist/features/products/components/FeatureBadge.js +63 -0
  600. package/dist/features/products/components/GroupSettingsPanel.js +1 -1
  601. package/dist/features/products/components/NonRefundableConsentModal.d.ts +23 -0
  602. package/dist/features/products/components/NonRefundableConsentModal.js +55 -0
  603. package/dist/features/products/components/PrizeDrawsSection.d.ts +12 -0
  604. package/dist/features/products/components/PrizeDrawsSection.js +17 -0
  605. package/dist/features/products/components/ProductDetailPageView.d.ts +16 -1
  606. package/dist/features/products/components/ProductDetailPageView.js +65 -60
  607. package/dist/features/products/components/ProductFeaturesContext.d.ts +9 -0
  608. package/dist/features/products/components/ProductFeaturesContext.js +11 -0
  609. package/dist/features/products/components/ProductFeaturesSelector.d.ts +12 -0
  610. package/dist/features/products/components/ProductFeaturesSelector.js +72 -0
  611. package/dist/features/products/components/ProductForm.js +9 -3
  612. package/dist/features/products/components/ProductGrid.js +9 -3
  613. package/dist/features/products/components/ProductsIndexListing.js +24 -8
  614. package/dist/features/products/components/ProductsIndexPageView.js +12 -7
  615. package/dist/features/products/components/ShowGroupSection.js +2 -1
  616. package/dist/features/products/components/SublistingCarouselSection.js +3 -2
  617. package/dist/features/products/components/index.d.ts +12 -0
  618. package/dist/features/products/components/index.js +6 -0
  619. package/dist/features/products/constants/action-defs.d.ts +209 -0
  620. package/dist/features/products/constants/action-defs.js +270 -0
  621. package/dist/features/products/constants/product-features.constants.d.ts +23 -0
  622. package/dist/features/products/constants/product-features.constants.js +50 -0
  623. package/dist/features/products/hooks/useProducts.d.ts +1 -0
  624. package/dist/features/products/hooks/useProducts.js +15 -6
  625. package/dist/features/products/hooks/useRelatedProducts.d.ts +5 -0
  626. package/dist/features/products/hooks/useRelatedProducts.js +9 -1
  627. package/dist/features/products/index.d.ts +3 -1
  628. package/dist/features/products/index.js +3 -1
  629. package/dist/features/products/repository/loadProductFeatures.d.ts +2 -0
  630. package/dist/features/products/repository/loadProductFeatures.js +23 -0
  631. package/dist/features/products/repository/product-features.repository.d.ts +27 -0
  632. package/dist/features/products/repository/product-features.repository.js +141 -0
  633. package/dist/features/products/repository/product-templates.repository.d.ts +12 -0
  634. package/dist/features/products/repository/product-templates.repository.js +61 -0
  635. package/dist/features/products/repository/products.repository.d.ts +16 -1
  636. package/dist/features/products/repository/products.repository.js +126 -6
  637. package/dist/features/products/schemas/firestore.d.ts +43 -5
  638. package/dist/features/products/schemas/firestore.js +6 -7
  639. package/dist/features/products/schemas/index.d.ts +147 -51
  640. package/dist/features/products/schemas/index.js +32 -3
  641. package/dist/features/products/schemas/product-features.d.ts +84 -0
  642. package/dist/features/products/schemas/product-features.js +33 -0
  643. package/dist/features/products/schemas/product-features.validators.d.ts +107 -0
  644. package/dist/features/products/schemas/product-features.validators.js +64 -0
  645. package/dist/features/products/schemas/product-templates.d.ts +28 -0
  646. package/dist/features/products/schemas/product-templates.js +6 -0
  647. package/dist/features/products/types/index.d.ts +13 -5
  648. package/dist/features/products/utils/listing-type.d.ts +23 -2
  649. package/dist/features/products/utils/listing-type.js +14 -7
  650. package/dist/features/products/utils/sanitize.d.ts +2 -0
  651. package/dist/features/products/utils/sanitize.js +25 -0
  652. package/dist/features/promotions/actions/coupon-actions.d.ts +2 -2
  653. package/dist/features/promotions/components/CouponsIndexListing.d.ts +4 -4
  654. package/dist/features/promotions/components/CouponsIndexListing.js +3 -3
  655. package/dist/features/promotions/hooks/useCouponValidate.d.ts +2 -2
  656. package/dist/features/promotions/repository/coupons.repository.d.ts +2 -2
  657. package/dist/features/promotions/repository/coupons.repository.js +5 -5
  658. package/dist/features/promotions/schemas/index.d.ts +18 -18
  659. package/dist/features/reviews/schemas/index.d.ts +16 -16
  660. package/dist/features/search/actions/search-actions.js +4 -5
  661. package/dist/features/search/api/route.js +13 -10
  662. package/dist/features/search/columns/index.d.ts +1 -1
  663. package/dist/features/search/columns/index.js +4 -4
  664. package/dist/features/search/repository/search.repository.js +4 -6
  665. package/dist/features/search/schemas/index.d.ts +5 -5
  666. package/dist/features/search/types/index.d.ts +4 -3
  667. package/dist/features/seller/actions/offer-actions.js +1 -2
  668. package/dist/features/seller/components/BrandInlineSelect.d.ts +9 -0
  669. package/dist/features/seller/components/BrandInlineSelect.js +26 -0
  670. package/dist/features/seller/components/CategoryInlineSelect.d.ts +9 -0
  671. package/dist/features/seller/components/CategoryInlineSelect.js +26 -0
  672. package/dist/features/seller/components/SellerFeaturesView.d.ts +1 -0
  673. package/dist/features/seller/components/SellerFeaturesView.js +61 -0
  674. package/dist/features/seller/components/SellerProductShell.d.ts +15 -1
  675. package/dist/features/seller/components/SellerProductShell.js +7 -7
  676. package/dist/features/seller/components/SellerProductsView.js +17 -17
  677. package/dist/features/seller/components/SellerStorefrontView.d.ts +7 -0
  678. package/dist/features/seller/components/SellerStorefrontView.js +12 -2
  679. package/dist/features/seller/components/analytics/SellerRevenueChart.js +9 -17
  680. package/dist/features/seller/components/index.d.ts +6 -0
  681. package/dist/features/seller/components/index.js +4 -0
  682. package/dist/features/seller/schemas/index.d.ts +26 -26
  683. package/dist/features/shell/FormShell.d.ts +9 -1
  684. package/dist/features/shell/FormShell.js +5 -3
  685. package/dist/features/stores/actions/store-query-actions.js +2 -2
  686. package/dist/features/stores/api/[storeSlug]/auctions/route.js +11 -15
  687. package/dist/features/stores/api/[storeSlug]/products/route.js +11 -15
  688. package/dist/features/stores/api/route.js +12 -14
  689. package/dist/features/stores/components/StoreAuctionsListing.d.ts +2 -4
  690. package/dist/features/stores/components/StoreAuctionsListing.js +3 -4
  691. package/dist/features/stores/components/StoreAuctionsPageView.js +1 -1
  692. package/dist/features/stores/components/StoreDetailLayoutView.js +3 -3
  693. package/dist/features/stores/components/StorePreOrdersListing.d.ts +1 -3
  694. package/dist/features/stores/components/StorePreOrdersListing.js +2 -3
  695. package/dist/features/stores/components/StorePreOrdersPageView.js +1 -1
  696. package/dist/features/stores/components/StoreProductsListing.d.ts +2 -4
  697. package/dist/features/stores/components/StoreProductsListing.js +2 -3
  698. package/dist/features/stores/components/StoreProductsPageView.d.ts +4 -1
  699. package/dist/features/stores/components/StoreProductsPageView.js +17 -11
  700. package/dist/features/stores/repository/store.repository.d.ts +10 -0
  701. package/dist/features/stores/repository/store.repository.js +39 -0
  702. package/dist/features/stores/schemas/firestore.d.ts +7 -0
  703. package/dist/features/stores/schemas/index.d.ts +8 -8
  704. package/dist/features/stores/types/index.d.ts +4 -3
  705. package/dist/features/wishlist/actions/wishlist-actions.d.ts +8 -6
  706. package/dist/features/wishlist/actions/wishlist-actions.js +9 -7
  707. package/dist/features/wishlist/components/WishlistCapWatcher.d.ts +1 -0
  708. package/dist/features/wishlist/components/WishlistCapWatcher.js +24 -0
  709. package/dist/features/wishlist/components/index.d.ts +1 -0
  710. package/dist/features/wishlist/components/index.js +1 -0
  711. package/dist/features/wishlist/hooks/useWishlistCount.d.ts +17 -0
  712. package/dist/features/wishlist/hooks/useWishlistCount.js +36 -1
  713. package/dist/features/wishlist/index.d.ts +2 -0
  714. package/dist/features/wishlist/index.js +1 -0
  715. package/dist/features/wishlist/repository/user-wishlist.repository.d.ts +52 -7
  716. package/dist/features/wishlist/repository/user-wishlist.repository.js +154 -44
  717. package/dist/features/wishlist/schemas/index.d.ts +2 -2
  718. package/dist/features/wishlist/server.d.ts +1 -1
  719. package/dist/features/wishlist/server.js +1 -1
  720. package/dist/features/wishlist/types/index.d.ts +2 -2
  721. package/dist/index.d.ts +87 -5
  722. package/dist/index.js +101 -12
  723. package/dist/next/api/routeHandler.d.ts +7 -0
  724. package/dist/next/api/routeHandler.js +8 -0
  725. package/dist/next/routing/route-map.d.ts +68 -0
  726. package/dist/next/routing/route-map.js +32 -0
  727. package/dist/providers/db-firebase/filter-aliases.d.ts +20 -0
  728. package/dist/providers/db-firebase/filter-aliases.js +29 -0
  729. package/dist/providers/db-firebase/index.d.ts +2 -2
  730. package/dist/providers/db-firebase/index.js +1 -1
  731. package/dist/providers/db-firebase/sieve.d.ts +9 -0
  732. package/dist/providers/db-firebase/sieve.js +24 -6
  733. package/dist/providers/firebase-client/auth.d.ts +1 -0
  734. package/dist/providers/firebase-client/auth.js +9 -1
  735. package/dist/providers/shipping-shiprocket/index.d.ts +9 -0
  736. package/dist/providers/shipping-shiprocket/index.js +11 -0
  737. package/dist/react/hooks/use-action-dispatch.d.ts +25 -0
  738. package/dist/react/hooks/use-action-dispatch.js +30 -0
  739. package/dist/react/hooks/use-panel-url-sync.d.ts +15 -0
  740. package/dist/react/hooks/use-panel-url-sync.js +46 -0
  741. package/dist/react/hooks/useInfiniteScroll.d.ts +52 -0
  742. package/dist/react/hooks/useInfiniteScroll.js +45 -0
  743. package/dist/repositories/index.d.ts +9 -1
  744. package/dist/repositories/index.js +8 -1
  745. package/dist/seed/_bundle-constants.d.ts +14 -0
  746. package/dist/seed/_bundle-constants.js +14 -0
  747. package/dist/seed/actions/demo-seed-actions.d.ts +1 -1
  748. package/dist/seed/bids-seed-data.js +165 -0
  749. package/dist/seed/blog-posts-seed-data.js +393 -0
  750. package/dist/seed/bundles-seed-data.d.ts +13 -0
  751. package/dist/seed/bundles-seed-data.js +229 -0
  752. package/dist/seed/carousels-seed-data.d.ts +2 -0
  753. package/dist/seed/carousels-seed-data.js +16 -0
  754. package/dist/seed/cart-seed-data.js +161 -16
  755. package/dist/seed/categories-seed-data.js +168 -0
  756. package/dist/seed/coupons-seed-data.js +174 -0
  757. package/dist/seed/events-seed-data.js +161 -0
  758. package/dist/seed/history-seed-data.d.ts +19 -0
  759. package/dist/seed/history-seed-data.js +61 -0
  760. package/dist/seed/homepage-sections-seed-data.js +97 -1
  761. package/dist/seed/index.d.ts +4 -3
  762. package/dist/seed/index.js +9 -3
  763. package/dist/seed/manifest.js +23 -1
  764. package/dist/seed/notifications-seed-data.js +60 -0
  765. package/dist/seed/orders-seed-data.js +2 -2
  766. package/dist/seed/product-features-seed-data.d.ts +10 -0
  767. package/dist/seed/product-features-seed-data.js +162 -0
  768. package/dist/seed/products-auctions-seed-data.d.ts +6 -1
  769. package/dist/seed/products-auctions-seed-data.js +495 -24
  770. package/dist/seed/products-preorders-seed-data.d.ts +6 -1
  771. package/dist/seed/products-preorders-seed-data.js +27 -18
  772. package/dist/seed/products-standard-seed-data.d.ts +5 -0
  773. package/dist/seed/products-standard-seed-data.js +208 -297
  774. package/dist/seed/runner.js +95 -16
  775. package/dist/seed/server.d.ts +2 -0
  776. package/dist/seed/server.js +7 -0
  777. package/dist/seed/site-settings-seed-data.js +11 -1
  778. package/dist/seed/types.d.ts +58 -1
  779. package/dist/seed/types.js +14 -1
  780. package/dist/seed/wishlists-seed-data.d.ts +14 -7
  781. package/dist/seed/wishlists-seed-data.js +52 -109
  782. package/dist/seo/json-ld.d.ts +2 -1
  783. package/dist/server-entry.d.ts +60 -0
  784. package/dist/server-entry.js +93 -0
  785. package/dist/server.d.ts +26 -3
  786. package/dist/server.js +39 -7
  787. package/dist/stores/panel-store.d.ts +9 -0
  788. package/dist/stores/panel-store.js +8 -0
  789. package/dist/tailwind-utilities.css +1 -1
  790. package/dist/tokens/tokens.css +182 -12
  791. package/dist/ui/DataTable.style.css +192 -190
  792. package/dist/ui/components/Accordion.style.css +82 -82
  793. package/dist/ui/components/ActiveFilterChips.style.css +12 -12
  794. package/dist/ui/components/Alert.style.css +187 -187
  795. package/dist/ui/components/Avatar.style.css +71 -71
  796. package/dist/ui/components/AvatarDisplay.style.css +3 -3
  797. package/dist/ui/components/Badge.style.css +114 -114
  798. package/dist/ui/components/BaseListingCard.style.css +86 -86
  799. package/dist/ui/components/Breadcrumb.style.css +10 -10
  800. package/dist/ui/components/BulkActionBar.style.css +196 -196
  801. package/dist/ui/components/BulkActionsBar.d.ts +2 -0
  802. package/dist/ui/components/BulkActionsBar.js +5 -2
  803. package/dist/ui/components/Button.d.ts +3 -1
  804. package/dist/ui/components/Button.js +12 -2
  805. package/dist/ui/components/Button.style.css +160 -160
  806. package/dist/ui/components/Card.style.css +190 -190
  807. package/dist/ui/components/Checkbox.style.css +111 -111
  808. package/dist/ui/components/ConfirmDeleteModal.style.css +89 -89
  809. package/dist/ui/components/DashboardStatsCard.style.css +68 -68
  810. package/dist/ui/components/DescriptionField.style.css +36 -36
  811. package/dist/ui/components/DetailViewShell.js +1 -2
  812. package/dist/ui/components/Divider.style.css +39 -39
  813. package/dist/ui/components/Drawer.style.css +150 -150
  814. package/dist/ui/components/Dropdown.style.css +110 -110
  815. package/dist/ui/components/DynamicSelect.style.css +101 -101
  816. package/dist/ui/components/EmptyState.style.css +2 -2
  817. package/dist/ui/components/FilterDrawer.style.css +61 -61
  818. package/dist/ui/components/FlowDiagram.style.css +3 -3
  819. package/dist/ui/components/Form.style.css +27 -27
  820. package/dist/ui/components/FormActionBar.d.ts +22 -0
  821. package/dist/ui/components/FormActionBar.js +8 -0
  822. package/dist/ui/components/FormActionBar.style.css +77 -0
  823. package/dist/ui/components/FormField.style.css +30 -30
  824. package/dist/ui/components/HorizontalScroller.style.css +10 -10
  825. package/dist/ui/components/IconButton.style.css +103 -103
  826. package/dist/ui/components/ImageGallery.style.css +4 -4
  827. package/dist/ui/components/InlineCreateSelect.d.ts +13 -3
  828. package/dist/ui/components/InlineCreateSelect.js +9 -4
  829. package/dist/ui/components/Input.style.css +28 -28
  830. package/dist/ui/components/Layout.d.ts +2 -0
  831. package/dist/ui/components/Layout.js +2 -0
  832. package/dist/ui/components/Layout.style.css +22 -5
  833. package/dist/ui/components/ListingLayout.style.css +491 -491
  834. package/dist/ui/components/Modal.style.css +106 -106
  835. package/dist/ui/components/Pagination.style.css +76 -76
  836. package/dist/ui/components/PasswordStrengthIndicator.style.css +56 -56
  837. package/dist/ui/components/PriceDisplay.style.css +47 -47
  838. package/dist/ui/components/Progress.style.css +81 -81
  839. package/dist/ui/components/Radio.style.css +153 -153
  840. package/dist/ui/components/RatingDisplay.style.css +50 -50
  841. package/dist/ui/components/RowActionMenu.style.css +91 -91
  842. package/dist/ui/components/SectionTabs.style.css +18 -18
  843. package/dist/ui/components/Select.style.css +177 -177
  844. package/dist/ui/components/SideDrawer.style.css +206 -206
  845. package/dist/ui/components/SideModal.style.css +73 -73
  846. package/dist/ui/components/SiteLogo.d.ts +26 -0
  847. package/dist/ui/components/SiteLogo.js +18 -0
  848. package/dist/ui/components/Skeleton.style.css +55 -55
  849. package/dist/ui/components/SkipToMain.style.css +3 -3
  850. package/dist/ui/components/Slider.style.css +15 -15
  851. package/dist/ui/components/Spinner.style.css +84 -84
  852. package/dist/ui/components/StarRating.style.css +44 -44
  853. package/dist/ui/components/StatsGrid.style.css +96 -96
  854. package/dist/ui/components/StepperNav.style.css +110 -110
  855. package/dist/ui/components/SummaryCard.style.css +80 -82
  856. package/dist/ui/components/TabStrip.style.css +97 -97
  857. package/dist/ui/components/TablePagination.style.css +89 -89
  858. package/dist/ui/components/Tabs.style.css +44 -44
  859. package/dist/ui/components/TagInput.style.css +121 -121
  860. package/dist/ui/components/TextLink.style.css +94 -94
  861. package/dist/ui/components/Textarea.style.css +30 -30
  862. package/dist/ui/components/Toast.style.css +112 -112
  863. package/dist/ui/components/Toggle.style.css +105 -105
  864. package/dist/ui/components/Tooltip.style.css +114 -114
  865. package/dist/ui/components/Typography.style.css +178 -178
  866. package/dist/ui/components/UnsavedChangesModal.style.css +1 -1
  867. package/dist/ui/components/ViewToggle.style.css +8 -8
  868. package/dist/ui/components/index.style.css +1 -0
  869. package/dist/ui/index.d.ts +4 -0
  870. package/dist/ui/index.js +2 -0
  871. package/dist/ui/rich-text/RichText.style.css +40 -40
  872. package/dist/utils/index.d.ts +1 -0
  873. package/dist/utils/index.js +1 -0
  874. package/dist/utils/listing-params.d.ts +86 -0
  875. package/dist/utils/listing-params.js +121 -0
  876. package/dist/validation/schemas.d.ts +22 -22
  877. package/package.json +62 -10
  878. package/scripts/audit-violations.mjs +77 -0
  879. package/scripts/init-config.mjs +76 -0
  880. package/scripts/labels-extract.mjs +64 -0
  881. package/scripts/seed-cli-loader.mjs +37 -0
  882. package/scripts/seed-cli.mjs +660 -0
  883. package/scripts/sieve-audit.mjs +475 -0
  884. package/scripts/smoke-bundle.mjs +60 -0
  885. package/scripts/smoke-ssr.mjs +81 -0
  886. package/scripts/smoke-theme.mjs +105 -0
  887. package/scripts/verify-css-build.mjs +49 -0
  888. package/scripts/verify-entries.mjs +55 -0
  889. package/tsconfig.base.json +16 -0
@@ -12,12 +12,14 @@ import { ProductDetailView } from "./ProductDetailView";
12
12
  import { ProductGalleryClient } from "./ProductGalleryClient";
13
13
  import { ProductTabsShell } from "./ProductTabsShell";
14
14
  import { ProductFeatureBadges } from "./ProductFeatureBadges";
15
+ import { FeatureBadgeList } from "./FeatureBadge";
15
16
  import { RelatedProductsCarousel } from "./RelatedProductsCarousel";
16
17
  import { BuyBar } from "./BuyBar";
17
18
  import { ShareButton } from "./ShareButton";
18
19
  import { CustomSectionTabContent } from "./CustomSectionTabContent";
19
20
  import { SublistingCarouselSection } from "./SublistingCarouselSection";
20
21
  import { ShowGroupSection } from "./ShowGroupSection";
22
+ import { HistoryTracker } from "../../history/components/HistoryTracker";
21
23
  // ---------------------------------------------------------------------------
22
24
  // Helpers
23
25
  // ---------------------------------------------------------------------------
@@ -85,10 +87,13 @@ function StarRating({ value }) {
85
87
  // ---------------------------------------------------------------------------
86
88
  // Component
87
89
  // ---------------------------------------------------------------------------
88
- export async function ProductDetailPageView({ slug, renderOfferAction, }) {
89
- const product = await productRepository
90
- .findByIdOrSlug(slug)
91
- .catch(() => undefined);
90
+ export async function ProductDetailPageView({ slug, initialProduct, renderOfferAction, productFeatures, }) {
91
+ // Use pre-fetched data when available to avoid a redundant repository call.
92
+ // The page layer wraps getProductForDetail in React.cache(), so both
93
+ // generateMetadata() and this component share the same in-flight promise.
94
+ const product = initialProduct !== undefined
95
+ ? (initialProduct ?? undefined)
96
+ : await productRepository.findByIdOrSlug(slug).catch(() => undefined);
92
97
  if (!product) {
93
98
  return (_jsx(Main, { children: _jsx(Section, { className: "py-20", children: _jsx(Container, { size: "md", children: _jsxs(Stack, { align: "center", gap: "md", className: "text-center", children: [_jsx(Heading, { level: 1, className: "text-2xl font-semibold text-zinc-900 dark:text-zinc-50", children: "Product Not Found" }), _jsx(Text, { className: "text-zinc-500", children: "The product you are looking for may have been removed or the link is incorrect." }), _jsx(Link, { href: String(ROUTES.PUBLIC.PRODUCTS), className: "text-sm font-medium text-primary-600 hover:underline", children: "Browse Products" })] }) }) }) }));
94
99
  }
@@ -145,17 +150,11 @@ export async function ProductDetailPageView({ slug, renderOfferAction, }) {
145
150
  const freeShipping = shippingPaidBy === "seller";
146
151
  const featured = p.featured === true;
147
152
  const storeName = typeof p.storeName === "string" ? p.storeName : null;
148
- const sellerName = typeof p.sellerName === "string" ? p.sellerName : null;
149
- const safeSeller = (storeName || sellerName)
150
- ? safeDisplayName((storeName || sellerName) ?? "", "")
151
- : null;
153
+ const safeSeller = storeName ? safeDisplayName(storeName, "") : null;
152
154
  const storeSlug = (typeof p.storeSlug === "string" ? p.storeSlug : null) || (typeof p.storeId === "string" ? p.storeId : null);
153
- const sellerId = typeof p.sellerId === "string" ? p.sellerId : null;
154
155
  const storeHref = storeSlug
155
156
  ? String(ROUTES.PUBLIC.STORE_DETAIL(storeSlug))
156
- : sellerId
157
- ? String(ROUTES.PUBLIC.SELLER_DETAIL(sellerId))
158
- : null;
157
+ : null;
159
158
  const descriptionHtml = toDescriptionHtml(p.description);
160
159
  const sublistingCategoryId = typeof p.sublistingCategoryId === "string" ? p.sublistingCategoryId : null;
161
160
  const groupId = typeof p.groupId === "string" ? p.groupId : null;
@@ -177,52 +176,58 @@ export async function ProductDetailPageView({ slug, renderOfferAction, }) {
177
176
  .map(toProductItem);
178
177
  const formattedPrice = price !== null ? formatCurrency(price, currency) : null;
179
178
  const formattedOriginal = originalPrice !== null ? formatCurrency(originalPrice, currency) : null;
180
- return (_jsx(Main, { children: _jsxs(Container, { size: "xl", className: "px-4 py-6", children: [_jsx(ProductDetailView, { renderBreadcrumb: () => (_jsxs("div", { className: "mb-4 flex items-center justify-between flex-wrap gap-2", children: [_jsxs("nav", { "aria-label": "Breadcrumb", className: "flex items-center gap-1.5 text-xs text-zinc-500 dark:text-zinc-400 flex-wrap", children: [_jsx(Link, { href: String(ROUTES.HOME), className: "hover:text-primary-600 transition-colors", children: "Home" }), _jsx(Span, { "aria-hidden": true, children: "/" }), _jsx(Link, { href: String(ROUTES.PUBLIC.PRODUCTS), className: "hover:text-primary-600 transition-colors", children: "Products" }), category && (_jsxs(_Fragment, { children: [_jsx(Span, { "aria-hidden": true, children: "/" }), _jsx(Link, { href: String(ROUTES.PUBLIC.CATEGORY_DETAIL(category)), className: "hover:text-primary-600 transition-colors", children: categoryName || category })] })), subcategory && (_jsxs(_Fragment, { children: [_jsx(Span, { "aria-hidden": true, children: "/" }), _jsx(Span, { className: "capitalize", children: subcategory })] }))] }), _jsx(ShareButton, { title: title || undefined })] })), renderGallery: () => (_jsx(ProductGalleryClient, { images: images, productName: title || undefined })), renderInfo: () => (_jsxs(Stack, { gap: "sm", children: [_jsxs(Div, { children: [condition && (_jsx(Span, { className: "mb-1.5 inline-block rounded-full bg-zinc-100 dark:bg-zinc-800 px-2.5 py-0.5 text-xs font-medium capitalize text-zinc-600 dark:text-zinc-300", children: condition === "new"
181
- ? "Brand New"
182
- : condition === "like_new"
183
- ? "Like New"
184
- : condition === "refurbished"
185
- ? "Refurbished"
186
- : condition === "used"
187
- ? "Used"
188
- : condition })), _jsx(Heading, { level: 1, className: "text-xl font-bold leading-snug text-zinc-900 dark:text-zinc-50 sm:text-2xl", children: title || "Untitled Product" })] }), avgRating !== null && (_jsxs(Row, { align: "center", gap: "sm", children: [_jsx(StarRating, { value: avgRating }), _jsxs(Span, { className: "text-sm text-zinc-600 dark:text-zinc-400", children: [avgRating.toFixed(1), reviewCount ? ` (${reviewCount} reviews)` : ""] }), _jsxs(Span, { className: `ml-auto rounded-full px-2.5 py-0.5 text-xs font-medium ${inStock
189
- ? "bg-emerald-50 text-emerald-700 dark:bg-emerald-900/30 dark:text-emerald-400"
190
- : "bg-red-50 text-red-700 dark:bg-red-900/30 dark:text-red-400"}`, children: [inStock ? "✓ In Stock" : "✗ Out of Stock", inStock && effectiveStock !== null && effectiveStock <= 10
191
- ? ` — only ${effectiveStock} left`
192
- : ""] })] })), formattedPrice && (_jsxs(Row, { align: "baseline", gap: "sm", children: [_jsx(Span, { className: "text-2xl font-bold text-zinc-900 dark:text-zinc-50", children: formattedPrice }), formattedOriginal && discount && (_jsxs(_Fragment, { children: [_jsx(Span, { className: "text-sm text-zinc-400 line-through dark:text-zinc-500", children: formattedOriginal }), _jsxs(Span, { className: "rounded-full bg-red-500 px-2 py-0.5 text-xs font-bold text-white", children: ["-", discount, "%"] })] }))] })), avgRating === null && (_jsxs(Span, { className: `inline-flex w-fit items-center gap-1.5 rounded-full px-3 py-1 text-xs font-medium ${inStock
193
- ? "bg-emerald-50 text-emerald-700 dark:bg-emerald-900/30 dark:text-emerald-400"
194
- : "bg-red-50 text-red-700 dark:bg-red-900/30 dark:text-red-400"}`, children: [inStock ? " In Stock" : " Out of Stock", inStock && effectiveStock !== null && effectiveStock <= 10
195
- ? ` only ${effectiveStock} left`
196
- : ""] })), (categoryName || category || brand) && (_jsxs(Row, { align: "center", gap: "xs", className: "text-xs text-zinc-400 dark:text-zinc-500 flex-wrap", children: [category && (_jsx(Link, { href: String(ROUTES.PUBLIC.CATEGORY_DETAIL(category)), className: "hover:text-primary-600 dark:hover:text-primary-400 transition-colors", children: categoryName || category })), category && brand && _jsx(Span, { children: "\u203A" }), brand && (brandSlug ? (_jsx(Link, { href: String(ROUTES.PUBLIC.BRAND_DETAIL(brandSlug)), className: "font-medium text-zinc-600 dark:text-zinc-300 hover:text-primary-600 dark:hover:text-primary-400 transition-colors", children: brand })) : (_jsx(Span, { className: "font-medium text-zinc-600 dark:text-zinc-300", children: brand })))] })), _jsx(ProductFeatureBadges, { featured: featured, freeShipping: freeShipping, condition: condition ?? undefined, returnable: returnPolicy != null && returnPolicy.length > 0, labels: {
197
- featured: "Featured",
198
- fasterDelivery: "Faster Delivery",
199
- ratedSeller: "Rated Seller",
200
- condition: "Condition",
201
- conditionNew: "New",
202
- conditionUsed: "Used",
203
- conditionBroken: "For Parts",
204
- conditionRefurbished: "Refurbished",
205
- returnable: "Returnable",
206
- freeShipping: "Free Shipping",
207
- codAvailable: "Cash on Delivery",
208
- wishlistCount: (n) => `${n} wishlisted`,
209
- categoryProductCount: (n, cat) => `${n} in ${cat}`,
210
- } }), features.length > 0 && (_jsxs(Div, { className: "rounded-xl border border-zinc-100 dark:border-zinc-800 bg-zinc-50 dark:bg-zinc-900/60 px-4 py-3", children: [_jsx(Text, { className: "mb-2 text-xs font-semibold uppercase tracking-wide text-zinc-500 dark:text-zinc-400", children: "About this product" }), _jsx("ul", { className: "space-y-1.5", children: features.map((f, i) => (_jsxs("li", { className: "flex items-start gap-2 text-sm text-zinc-700 dark:text-zinc-300", children: [_jsx(Span, { className: "mt-0.5 flex-shrink-0 text-primary-500", children: "\u2022" }), f] }, i))) })] })), descriptionHtml && (_jsx(RichText, { html: descriptionHtml, proseClass: "prose prose-sm max-w-none dark:prose-invert prose-p:my-0", className: "text-sm leading-relaxed text-zinc-600 dark:text-zinc-400 line-clamp-4" })), safeSeller && (_jsx(Div, { className: "rounded-xl border border-zinc-100 dark:border-zinc-800 bg-zinc-50 dark:bg-zinc-900/60 p-3", children: _jsxs(Row, { justify: "between", align: "center", children: [_jsxs(Div, { children: [_jsx(Text, { className: "text-[10px] uppercase tracking-wide text-zinc-400 dark:text-zinc-500 mb-0.5", children: "Sold by" }), _jsx(Text, { className: "text-sm font-semibold text-zinc-800 dark:text-zinc-200", children: safeSeller })] }), storeHref && (_jsx(Link, { href: storeHref, className: "shrink-0 rounded-lg bg-primary/10 dark:bg-primary/20 px-3 py-1.5 text-xs font-semibold text-primary-700 dark:text-primary-300 hover:bg-primary/20 dark:hover:bg-primary/30 transition-colors", children: "Visit Store \u2192" }))] }) }))] })), renderActions: () => (_jsxs(Div, { className: "rounded-xl border border-zinc-100 dark:border-zinc-800 bg-zinc-50 dark:bg-zinc-900/60 p-5 space-y-4", children: [formattedPrice && (_jsxs(Div, { children: [_jsx(Text, { className: "text-2xl font-bold text-zinc-900 dark:text-zinc-50", children: formattedPrice }), inStock && effectiveStock !== null && effectiveStock <= 10 && (_jsxs(Text, { className: "mt-0.5 text-xs text-amber-600 dark:text-amber-400", children: ["Only ", effectiveStock, " left \u2014 order soon!"] }))] })), _jsxs(Stack, { gap: "sm", children: [_jsx(Button, { variant: "primary", size: "md", className: "w-full", disabled: !inStock, children: inStock ? "Buy Now" : "Out of Stock" }), _jsx(Button, { variant: "secondary", size: "md", className: "w-full", disabled: !inStock, children: inStock ? "Add to Cart" : "Out of Stock" }), _jsx(Button, { variant: "ghost", size: "md", className: "w-full", children: "\u2661 Add to Wishlist" }), allowOffers && productType === "simple" && price !== null && renderOfferAction?.({
211
- productId: product.id,
212
- price,
213
- currency,
214
- minOfferPercent,
215
- })] }), (shippingInfo || returnPolicy || freeShipping) && (_jsxs(Div, { className: "border-t border-zinc-200 dark:border-zinc-700 pt-4 space-y-2.5", children: [freeShipping && (_jsxs(Row, { align: "start", gap: "sm", children: [_jsx(Span, { className: "mt-0.5 flex-shrink-0 text-emerald-500", children: "\uD83D\uDE9A" }), _jsxs(Div, { children: [_jsx(Text, { className: "text-xs font-medium text-zinc-700 dark:text-zinc-300", children: "Free Delivery" }), shippingInfo && (_jsx(Text, { className: "text-xs text-zinc-500", children: shippingInfo }))] })] })), !freeShipping && shippingInfo && (_jsxs(Row, { align: "start", gap: "sm", children: [_jsx(Span, { className: "mt-0.5 flex-shrink-0 text-zinc-400", children: "\uD83D\uDCE6" }), _jsx(Text, { className: "text-xs text-zinc-600 dark:text-zinc-400", children: shippingInfo })] })), returnPolicy && (_jsxs(Row, { align: "start", gap: "sm", children: [_jsx(Span, { className: "mt-0.5 flex-shrink-0 text-zinc-400", children: "\u21BA" }), _jsx(Text, { className: "text-xs text-zinc-600 dark:text-zinc-400", children: returnPolicy })] }))] })), tags.length > 0 && (_jsxs(Div, { className: "border-t border-zinc-200 dark:border-zinc-700 pt-4", children: [_jsx(Text, { className: "mb-2 text-xs font-medium text-zinc-500 dark:text-zinc-400", children: "Tags" }), _jsx(Row, { wrap: true, gap: "xs", children: tags.map((tag) => (_jsx(Span, { className: "rounded-full bg-zinc-100 dark:bg-zinc-800 px-2.5 py-1 text-xs text-zinc-600 dark:text-zinc-300", children: tag }, tag))) })] })), _jsx(Div, { className: "border-t border-zinc-200 dark:border-zinc-700 pt-4", children: _jsx(Row, { wrap: true, gap: "sm", className: "justify-center text-center", children: [
216
- { icon: "🔒", label: "Secure\nPayment" },
217
- { icon: "✓", label: "Verified\nSeller" },
218
- { icon: "⭐", label: "Quality\nGuarantee" },
219
- ].map(({ icon, label }) => (_jsxs(Div, { className: "flex flex-col items-center gap-1 text-xs text-zinc-500 dark:text-zinc-400 min-w-[60px]", children: [_jsx(Span, { className: "text-base", children: icon }), _jsx(Span, { className: "whitespace-pre-line leading-tight", children: label })] }, label))) }) })] })), renderSublistingSection: sublistingCategoryId
220
- ? () => (_jsx(SublistingCarouselSection, { sublistingCategoryId: sublistingCategoryId, currentListingId: String(product.id) }))
221
- : undefined, renderGroupSection: groupId
222
- ? () => (_jsx(ShowGroupSection, { groupId: groupId, currentSlug: String(p.slug ?? product.id), isParent: isGroupParent, groupTitle: groupTitle }))
223
- : undefined, renderTabs: () => (_jsx(ProductTabsShell, { descriptionContent: descriptionHtml ? (_jsx(RichText, { html: descriptionHtml, proseClass: "prose prose-sm sm:prose max-w-none dark:prose-invert", className: "text-zinc-700 dark:text-zinc-300" })) : undefined, specsContent: specs.length > 0 ? (_jsx("dl", { className: "divide-y divide-zinc-100 dark:divide-zinc-800 rounded-xl border border-zinc-100 dark:border-zinc-800 overflow-hidden text-sm", children: specs.map((s, i) => (_jsxs("div", { className: "flex gap-4 px-4 py-3 bg-white dark:bg-zinc-900 even:bg-zinc-50 dark:even:bg-zinc-800/50", children: [_jsx("dt", { className: "w-36 flex-shrink-0 font-medium text-zinc-700 dark:text-zinc-300", children: s.name }), _jsxs("dd", { className: "flex-1 text-zinc-600 dark:text-zinc-400", children: [s.value, s.unit ? ` ${s.unit}` : ""] })] }, i))) })) : undefined, ingredientsContent: ingredients.length > 0 ? (_jsx("ul", { className: "space-y-2", children: ingredients.map((item, i) => (_jsxs("li", { className: "flex items-start gap-2 text-sm text-zinc-700 dark:text-zinc-300", children: [_jsx(Span, { className: "mt-1 flex-shrink-0 h-1.5 w-1.5 rounded-full bg-primary-400" }), item] }, i))) })) : undefined, howToUseContent: howToUse.length > 0 ? (_jsx("ol", { className: "space-y-3", children: howToUse.map((step, i) => (_jsxs("li", { className: "flex items-start gap-3 text-sm text-zinc-700 dark:text-zinc-300", children: [_jsx(Span, { className: "flex-shrink-0 flex h-6 w-6 items-center justify-center rounded-full bg-primary-100 dark:bg-primary-900/30 text-xs font-bold text-primary-700 dark:text-primary-300", children: i + 1 }), step] }, i))) })) : undefined, reviewsContent: _jsx(ReviewsList, { reviews: reviews, emptyLabel: "No reviews yet \u2014 be the first to review this product." }), customTabs: customSections.map((s) => ({
224
- id: s.id,
225
- label: s.title,
226
- content: _jsx(CustomSectionTabContent, { section: s }),
227
- })) })), renderRelated: () => relatedItems.length > 0 ? (_jsx(RelatedProductsCarousel, { items: relatedItems })) : null }), _jsxs(BuyBar, { children: [formattedPrice && (_jsx(Span, { className: "mr-auto text-sm font-bold text-zinc-900 dark:text-zinc-50", children: formattedPrice })), _jsx(Button, { variant: "secondary", size: "sm", className: "shrink-0", disabled: !inStock, children: "Add to Cart" }), _jsx(Button, { variant: "primary", size: "sm", className: "flex-1", disabled: !inStock, children: inStock ? "Buy Now" : "Out of Stock" })] })] }) }));
179
+ return (_jsxs(Main, { children: [_jsx(HistoryTracker, { productId: product.id, productType: "product", snapshot: {
180
+ title: product.title,
181
+ thumb: product.mainImage ?? product.images?.[0],
182
+ price: product.price,
183
+ storeId: product.storeId,
184
+ storeName: product.storeName,
185
+ } }), _jsxs(Container, { size: "xl", className: "px-4 py-6", children: [_jsx(ProductDetailView, { renderBreadcrumb: () => (_jsxs("div", { className: "mb-4 flex items-center justify-between flex-wrap gap-2", children: [_jsxs("nav", { "aria-label": "Breadcrumb", className: "flex items-center gap-1.5 text-xs text-zinc-500 dark:text-zinc-400 flex-wrap", children: [_jsx(Link, { href: String(ROUTES.HOME), className: "hover:text-primary-600 transition-colors", children: "Home" }), _jsx(Span, { "aria-hidden": true, children: "/" }), _jsx(Link, { href: String(ROUTES.PUBLIC.PRODUCTS), className: "hover:text-primary-600 transition-colors", children: "Products" }), category && (_jsxs(_Fragment, { children: [_jsx(Span, { "aria-hidden": true, children: "/" }), _jsx(Link, { href: String(ROUTES.PUBLIC.CATEGORY_DETAIL(category)), className: "hover:text-primary-600 transition-colors", children: categoryName || category })] })), subcategory && (_jsxs(_Fragment, { children: [_jsx(Span, { "aria-hidden": true, children: "/" }), _jsx(Span, { className: "capitalize", children: subcategory })] }))] }), _jsx(ShareButton, { title: title || undefined })] })), renderGallery: () => (_jsx(ProductGalleryClient, { images: images, productName: title || undefined })), renderInfo: () => (_jsxs(Stack, { gap: "md", children: [_jsxs(Div, { children: [condition && (_jsx(Span, { className: "mb-2 inline-block rounded-full bg-zinc-100 dark:bg-zinc-800 px-2.5 py-0.5 text-xs font-medium capitalize text-zinc-600 dark:text-zinc-300", children: condition === "new"
186
+ ? "Brand New"
187
+ : condition === "like_new"
188
+ ? "Like New"
189
+ : condition === "refurbished"
190
+ ? "Refurbished"
191
+ : condition === "used"
192
+ ? "Used"
193
+ : condition })), _jsx(Heading, { level: 1, className: "text-xl font-bold leading-snug text-zinc-900 dark:text-zinc-50 sm:text-2xl", children: title || "Untitled Product" })] }), avgRating !== null ? (_jsxs(Row, { align: "center", gap: "sm", children: [_jsx(StarRating, { value: avgRating }), _jsxs(Span, { className: "text-sm text-zinc-600 dark:text-zinc-400", children: [avgRating.toFixed(1), reviewCount ? ` (${reviewCount} reviews)` : ""] }), _jsxs(Span, { className: `ml-auto rounded-full px-2.5 py-0.5 text-xs font-medium ${inStock
194
+ ? "bg-emerald-50 text-emerald-700 dark:bg-emerald-900/30 dark:text-emerald-400"
195
+ : "bg-red-50 text-red-700 dark:bg-red-900/30 dark:text-red-400"}`, children: [inStock ? "✓ In Stock" : " Out of Stock", inStock && effectiveStock !== null && effectiveStock <= 10
196
+ ? ` — only ${effectiveStock} left`
197
+ : ""] })] })) : (_jsxs(Span, { className: `inline-flex w-fit items-center gap-1.5 rounded-full px-3 py-1 text-xs font-medium ${inStock
198
+ ? "bg-emerald-50 text-emerald-700 dark:bg-emerald-900/30 dark:text-emerald-400"
199
+ : "bg-red-50 text-red-700 dark:bg-red-900/30 dark:text-red-400"}`, children: [inStock ? "✓ In Stock" : "✗ Out of Stock", inStock && effectiveStock !== null && effectiveStock <= 10
200
+ ? ` — only ${effectiveStock} left`
201
+ : ""] })), (categoryName || category || subcategory || brand) && (_jsxs(Row, { gap: "sm", wrap: true, children: [category && (_jsx(Link, { href: String(ROUTES.PUBLIC.CATEGORY_DETAIL(category)), className: "inline-flex items-center rounded-full border border-zinc-200 dark:border-zinc-700 bg-zinc-50 dark:bg-zinc-800/50 px-2.5 py-1 text-xs font-medium text-zinc-600 dark:text-zinc-300 transition-colors hover:border-primary-300 hover:bg-primary-50 hover:text-primary-700 dark:hover:border-primary-700/60 dark:hover:bg-primary-900/20 dark:hover:text-primary-400", children: categoryName || category })), subcategory && (_jsx(Span, { className: "inline-flex items-center rounded-full border border-zinc-100 dark:border-zinc-800 bg-zinc-50 dark:bg-zinc-800/50 px-2.5 py-1 text-xs font-medium text-zinc-500 dark:text-zinc-400 capitalize", children: subcategory })), brand && brandSlug && (_jsx(Link, { href: String(ROUTES.PUBLIC.BRAND_DETAIL(brandSlug)), className: "inline-flex items-center rounded-full border border-zinc-200 dark:border-zinc-700 bg-zinc-50 dark:bg-zinc-800/50 px-2.5 py-1 text-xs font-medium text-zinc-600 dark:text-zinc-300 transition-colors hover:border-primary-300 hover:bg-primary-50 hover:text-primary-700 dark:hover:border-primary-700/60 dark:hover:bg-primary-900/20 dark:hover:text-primary-400", children: brand })), brand && !brandSlug && (_jsx(Span, { className: "inline-flex items-center rounded-full border border-zinc-100 dark:border-zinc-800 bg-zinc-50 dark:bg-zinc-800/50 px-2.5 py-1 text-xs font-medium text-zinc-500 dark:text-zinc-400", children: brand }))] })), _jsx(ProductFeatureBadges, { featured: featured, freeShipping: freeShipping, condition: condition ?? undefined, returnable: returnPolicy != null && returnPolicy.length > 0, labels: {
202
+ featured: "Featured",
203
+ fasterDelivery: "Faster Delivery",
204
+ ratedSeller: "Rated Seller",
205
+ condition: "Condition",
206
+ conditionNew: "New",
207
+ conditionUsed: "Used",
208
+ conditionBroken: "For Parts",
209
+ conditionRefurbished: "Refurbished",
210
+ returnable: "Returnable",
211
+ freeShipping: "Free Shipping",
212
+ codAvailable: "Cash on Delivery",
213
+ wishlistCount: (n) => `${n} wishlisted`,
214
+ categoryProductCount: (n, cat) => `${n} in ${cat}`,
215
+ } }), productFeatures && features.length > 0 && (_jsx(FeatureBadgeList, { productFeatureIds: features, features: productFeatures })), !productFeatures && features.length > 0 && (_jsxs(Div, { className: "rounded-xl border border-zinc-100 dark:border-zinc-800 bg-zinc-50 dark:bg-zinc-900/60 px-4 py-3", children: [_jsx(Text, { className: "mb-2 text-xs font-semibold uppercase tracking-wide text-zinc-500 dark:text-zinc-400", children: "About this product" }), _jsx("ul", { className: "space-y-1.5", children: features.map((f, i) => (_jsxs("li", { className: "flex items-start gap-2 text-sm text-zinc-700 dark:text-zinc-300", children: [_jsx(Span, { className: "mt-0.5 flex-shrink-0 text-primary-500", children: "\u2022" }), f] }, i))) })] })), descriptionHtml && (_jsx(RichText, { html: descriptionHtml, proseClass: "prose prose-sm max-w-none dark:prose-invert prose-p:my-0", className: "text-sm leading-relaxed text-zinc-600 dark:text-zinc-400 line-clamp-4" })), safeSeller && (_jsx(Div, { className: "rounded-xl border border-zinc-100 dark:border-zinc-800 bg-zinc-50 dark:bg-zinc-900/60 p-3", children: _jsxs(Row, { justify: "between", align: "center", children: [_jsxs(Div, { children: [_jsx(Text, { className: "text-[10px] uppercase tracking-wide text-zinc-400 dark:text-zinc-500 mb-0.5", children: "Sold by" }), _jsx(Text, { className: "text-sm font-semibold text-zinc-800 dark:text-zinc-200", children: safeSeller })] }), storeHref && (_jsx(Link, { href: storeHref, className: "shrink-0 rounded-lg bg-primary/10 dark:bg-primary/20 px-3 py-1.5 text-xs font-semibold text-primary-700 dark:text-primary-300 hover:bg-primary/20 dark:hover:bg-primary/30 transition-colors", children: "Visit Store \u2192" }))] }) }))] })), renderActions: () => (_jsxs(Div, { className: "rounded-xl border border-zinc-100 dark:border-zinc-800 bg-zinc-50 dark:bg-zinc-900/60 p-5 space-y-4", children: [formattedPrice && (_jsxs(Div, { children: [_jsxs(Row, { align: "baseline", gap: "sm", wrap: true, children: [_jsx(Text, { className: "text-2xl font-bold text-zinc-900 dark:text-zinc-50", children: formattedPrice }), formattedOriginal && discount && (_jsxs(_Fragment, { children: [_jsx(Span, { className: "text-sm text-zinc-400 line-through dark:text-zinc-500", children: formattedOriginal }), _jsxs(Span, { className: "rounded-full bg-red-500 px-2 py-0.5 text-xs font-bold text-white", children: ["-", discount, "%"] })] }))] }), inStock && effectiveStock !== null && effectiveStock <= 10 && (_jsxs(Text, { className: "mt-1 text-xs text-amber-600 dark:text-amber-400", children: ["Only ", effectiveStock, " left \u2014 order soon!"] }))] })), _jsxs(Stack, { gap: "sm", children: [_jsx(Button, { variant: "primary", size: "md", className: "w-full", disabled: !inStock, children: inStock ? "Buy Now" : "Out of Stock" }), _jsx(Button, { variant: "secondary", size: "md", className: "w-full", disabled: !inStock, children: inStock ? "Add to Cart" : "Out of Stock" }), _jsx(Button, { variant: "ghost", size: "md", className: "w-full", children: "\u2661 Add to Wishlist" }), allowOffers && productType === "simple" && price !== null && renderOfferAction?.({
216
+ productId: product.id,
217
+ price,
218
+ currency,
219
+ minOfferPercent,
220
+ })] }), (shippingInfo || returnPolicy || freeShipping) && (_jsxs(Div, { className: "border-t border-zinc-200 dark:border-zinc-700 pt-4 space-y-2.5", children: [freeShipping && (_jsxs(Row, { align: "start", gap: "sm", children: [_jsx(Span, { className: "mt-0.5 flex-shrink-0 text-emerald-500", children: "\uD83D\uDE9A" }), _jsxs(Div, { children: [_jsx(Text, { className: "text-xs font-medium text-zinc-700 dark:text-zinc-300", children: "Free Delivery" }), shippingInfo && (_jsx(Text, { className: "text-xs text-zinc-500", children: shippingInfo }))] })] })), !freeShipping && shippingInfo && (_jsxs(Row, { align: "start", gap: "sm", children: [_jsx(Span, { className: "mt-0.5 flex-shrink-0 text-zinc-400", children: "\uD83D\uDCE6" }), _jsx(Text, { className: "text-xs text-zinc-600 dark:text-zinc-400", children: shippingInfo })] })), returnPolicy && (_jsxs(Row, { align: "start", gap: "sm", children: [_jsx(Span, { className: "mt-0.5 flex-shrink-0 text-zinc-400", children: "\u21BA" }), _jsx(Text, { className: "text-xs text-zinc-600 dark:text-zinc-400", children: returnPolicy })] }))] })), tags.length > 0 && (_jsxs(Div, { className: "border-t border-zinc-200 dark:border-zinc-700 pt-4", children: [_jsx(Text, { className: "mb-2 text-xs font-medium text-zinc-500 dark:text-zinc-400", children: "Tags" }), _jsx(Row, { wrap: true, gap: "xs", children: tags.map((tag) => (_jsx(Span, { className: "rounded-full bg-zinc-100 dark:bg-zinc-800 px-2.5 py-1 text-xs text-zinc-600 dark:text-zinc-300", children: tag }, tag))) })] })), _jsx(Div, { className: "border-t border-zinc-200 dark:border-zinc-700 pt-4", children: _jsx(Row, { wrap: true, gap: "sm", className: "justify-center text-center", children: [
221
+ { icon: "🔒", label: "Secure\nPayment" },
222
+ { icon: "", label: "Verified\nSeller" },
223
+ { icon: "⭐", label: "Quality\nGuarantee" },
224
+ ].map(({ icon, label }) => (_jsxs(Div, { className: "flex flex-col items-center gap-1 text-xs text-zinc-500 dark:text-zinc-400 min-w-[60px]", children: [_jsx(Span, { className: "text-base", children: icon }), _jsx(Span, { className: "whitespace-pre-line leading-tight", children: label })] }, label))) }) })] })), renderSublistingSection: sublistingCategoryId
225
+ ? () => (_jsx(SublistingCarouselSection, { sublistingCategoryId: sublistingCategoryId, currentListingId: String(product.id) }))
226
+ : undefined, renderGroupSection: groupId
227
+ ? () => (_jsx(ShowGroupSection, { groupId: groupId, currentSlug: String(p.slug ?? product.id), isParent: isGroupParent, groupTitle: groupTitle }))
228
+ : undefined, renderTabs: () => (_jsx(ProductTabsShell, { descriptionContent: descriptionHtml ? (_jsx(RichText, { html: descriptionHtml, proseClass: "prose prose-sm sm:prose max-w-none dark:prose-invert", className: "text-zinc-700 dark:text-zinc-300" })) : undefined, specsContent: specs.length > 0 ? (_jsx("dl", { className: "divide-y divide-zinc-100 dark:divide-zinc-800 rounded-xl border border-zinc-100 dark:border-zinc-800 overflow-hidden text-sm", children: specs.map((s, i) => (_jsxs("div", { className: "flex gap-4 px-4 py-3 bg-white dark:bg-zinc-900 even:bg-zinc-50 dark:even:bg-zinc-800/50", children: [_jsx("dt", { className: "w-36 flex-shrink-0 font-medium text-zinc-700 dark:text-zinc-300", children: s.name }), _jsxs("dd", { className: "flex-1 text-zinc-600 dark:text-zinc-400", children: [s.value, s.unit ? ` ${s.unit}` : ""] })] }, i))) })) : undefined, ingredientsContent: ingredients.length > 0 ? (_jsx("ul", { className: "space-y-2", children: ingredients.map((item, i) => (_jsxs("li", { className: "flex items-start gap-2 text-sm text-zinc-700 dark:text-zinc-300", children: [_jsx(Span, { className: "mt-1 flex-shrink-0 h-1.5 w-1.5 rounded-full bg-primary-400" }), item] }, i))) })) : undefined, howToUseContent: howToUse.length > 0 ? (_jsx("ol", { className: "space-y-3", children: howToUse.map((step, i) => (_jsxs("li", { className: "flex items-start gap-3 text-sm text-zinc-700 dark:text-zinc-300", children: [_jsx(Span, { className: "flex-shrink-0 flex h-6 w-6 items-center justify-center rounded-full bg-primary-100 dark:bg-primary-900/30 text-xs font-bold text-primary-700 dark:text-primary-300", children: i + 1 }), step] }, i))) })) : undefined, reviewsContent: _jsx(ReviewsList, { reviews: reviews, emptyLabel: "No reviews yet \u2014 be the first to review this product." }), customTabs: customSections.map((s) => ({
229
+ id: s.id,
230
+ label: s.title,
231
+ content: _jsx(CustomSectionTabContent, { section: s }),
232
+ })) })), renderRelated: () => relatedItems.length > 0 ? (_jsx(RelatedProductsCarousel, { items: relatedItems })) : null }), _jsxs(BuyBar, { children: [formattedPrice && (_jsx(Span, { className: "mr-auto text-sm font-bold text-zinc-900 dark:text-zinc-50", children: formattedPrice })), _jsx(Button, { variant: "secondary", size: "sm", className: "shrink-0", disabled: !inStock, children: "Add to Cart" }), _jsx(Button, { variant: "primary", size: "sm", className: "flex-1", disabled: !inStock, children: inStock ? "Buy Now" : "Out of Stock" })] })] })] }));
228
233
  }
@@ -0,0 +1,9 @@
1
+ import React from "react";
2
+ import type { ProductFeatureDocument } from "../schemas/product-features";
3
+ export interface ProductFeaturesProviderProps {
4
+ features: ProductFeatureDocument[];
5
+ children: React.ReactNode;
6
+ }
7
+ export declare function ProductFeaturesProvider({ features, children, }: ProductFeaturesProviderProps): import("react/jsx-runtime").JSX.Element;
8
+ /** Returns the registered features list, or null when no provider is mounted. */
9
+ export declare function useProductFeatures(): ProductFeatureDocument[] | null;
@@ -0,0 +1,11 @@
1
+ "use client";
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import React from "react";
4
+ const Ctx = React.createContext(null);
5
+ export function ProductFeaturesProvider({ features, children, }) {
6
+ return _jsx(Ctx.Provider, { value: features, children: children });
7
+ }
8
+ /** Returns the registered features list, or null when no provider is mounted. */
9
+ export function useProductFeatures() {
10
+ return React.useContext(Ctx);
11
+ }
@@ -0,0 +1,12 @@
1
+ import { type ProductFeatureProductType } from "../schemas/product-features";
2
+ export interface ProductFeaturesSelectorProps {
3
+ /** Selected feature IDs. */
4
+ value: string[];
5
+ onChange: (next: string[]) => void;
6
+ /** Determines which platform features are eligible. */
7
+ productType: ProductFeatureProductType;
8
+ /** Store ID — when present, store-scope features are also loaded. */
9
+ storeId?: string;
10
+ disabled?: boolean;
11
+ }
12
+ export declare function ProductFeaturesSelector({ value, onChange, productType, storeId, disabled, }: ProductFeaturesSelectorProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,72 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import React from "react";
4
+ import { useQuery } from "@tanstack/react-query";
5
+ import { Div, Grid, Heading, Stack, Text } from "../../../ui";
6
+ import { apiClient } from "../../../http";
7
+ import { ADMIN_ENDPOINTS } from "../../../constants/api-endpoints";
8
+ import { PRODUCT_FEATURE_QUERY_STALE_MS } from "../constants/product-features.constants";
9
+ import { MAX_FEATURES_PER_PRODUCT, } from "../schemas/product-features";
10
+ const SECTION_LABEL_CLASS = "text-[var(--appkit-font-size-2xs,11px)] font-semibold uppercase tracking-wide text-zinc-500 dark:text-zinc-400 mb-2";
11
+ const ROW_BASE_CLASS = "flex items-start gap-2 rounded-lg border px-3 py-2 text-xs cursor-pointer transition-colors";
12
+ const ROW_CHECKED_CLASS = "border-primary bg-primary/5 dark:bg-primary/10";
13
+ const ROW_DISABLED_CLASS = "border-zinc-200 dark:border-slate-700 opacity-50 cursor-not-allowed";
14
+ const ROW_DEFAULT_CLASS = "border-zinc-200 dark:border-slate-700 hover:bg-zinc-50 dark:hover:bg-slate-800";
15
+ const OVER_LIMIT_BANNER_CLASS = "rounded-lg border border-red-200 dark:border-red-900/60 bg-red-50 dark:bg-red-950/40 px-3 py-2 text-xs text-red-700 dark:text-red-200";
16
+ const EMPTY_STATE_CLASS = "rounded-lg border border-zinc-200 dark:border-slate-700 bg-white dark:bg-slate-900 px-3 py-4 text-xs text-zinc-500 dark:text-zinc-400 text-center";
17
+ function applyProductType(list, productType) {
18
+ if (productType === "all")
19
+ return list;
20
+ return list.filter((f) => f.productTypes.includes("all") || f.productTypes.includes(productType));
21
+ }
22
+ function rowClass(checked, cantSelect) {
23
+ if (checked)
24
+ return `${ROW_BASE_CLASS} ${ROW_CHECKED_CLASS}`;
25
+ if (cantSelect)
26
+ return `${ROW_BASE_CLASS} ${ROW_DISABLED_CLASS}`;
27
+ return `${ROW_BASE_CLASS} ${ROW_DEFAULT_CLASS}`;
28
+ }
29
+ function unwrapItems(res) {
30
+ const body = res?.data ??
31
+ res;
32
+ return body?.items ?? [];
33
+ }
34
+ export function ProductFeaturesSelector({ value, onChange, productType, storeId, disabled, }) {
35
+ const platformQuery = useQuery({
36
+ queryKey: ["product-features", "platform", "active"],
37
+ queryFn: async () => unwrapItems(await apiClient.get(`${ADMIN_ENDPOINTS.PRODUCT_FEATURES}?scope=platform&isActive=true`)),
38
+ staleTime: PRODUCT_FEATURE_QUERY_STALE_MS,
39
+ });
40
+ const storeQuery = useQuery({
41
+ queryKey: ["product-features", "store", "active", storeId],
42
+ queryFn: async () => unwrapItems(await apiClient.get(`${ADMIN_ENDPOINTS.PRODUCT_FEATURES}?scope=store&storeId=${encodeURIComponent(storeId)}&isActive=true`)),
43
+ enabled: !!storeId,
44
+ staleTime: PRODUCT_FEATURE_QUERY_STALE_MS,
45
+ });
46
+ const platformFeatures = applyProductType(platformQuery.data ?? [], productType);
47
+ const storeFeatures = applyProductType(storeQuery.data ?? [], productType);
48
+ const selectedSet = React.useMemo(() => new Set(value), [value]);
49
+ const atLimit = value.length >= MAX_FEATURES_PER_PRODUCT;
50
+ const overLimit = value.length > MAX_FEATURES_PER_PRODUCT;
51
+ const toggle = (id) => {
52
+ if (disabled)
53
+ return;
54
+ if (selectedSet.has(id)) {
55
+ onChange(value.filter((v) => v !== id));
56
+ return;
57
+ }
58
+ if (atLimit)
59
+ return;
60
+ onChange([...value, id]);
61
+ };
62
+ const renderRow = (f) => {
63
+ const checked = selectedSet.has(f.id);
64
+ const cantSelect = !checked && atLimit;
65
+ return (_jsxs("label", { className: rowClass(checked, cantSelect), children: [_jsx("input", { type: "checkbox", className: "mt-0.5", checked: checked, disabled: disabled || cantSelect, onChange: () => toggle(f.id), "aria-label": f.label }), _jsxs(Div, { className: "flex-1", children: [_jsx(Text, { as: "span", className: "block font-medium text-zinc-900 dark:text-zinc-100", children: f.label }), f.description && (_jsx(Text, { as: "span", className: "block text-zinc-500 dark:text-zinc-400 mt-0.5", children: f.description }))] })] }, f.id));
66
+ };
67
+ const hasAny = platformQuery.isLoading ||
68
+ storeQuery.isLoading ||
69
+ platformFeatures.length > 0 ||
70
+ storeFeatures.length > 0;
71
+ return (_jsxs(Stack, { gap: "sm", children: [_jsxs(Div, { children: [_jsx(Heading, { level: 3, className: "mb-1 text-sm font-semibold text-zinc-700 dark:text-zinc-300", children: "Feature badges" }), _jsxs(Text, { className: "text-xs text-zinc-500 dark:text-zinc-400", children: ["Selected: ", value.length, " of ", MAX_FEATURES_PER_PRODUCT, ". Badges appear on product cards and detail pages."] })] }), overLimit && (_jsxs(Div, { className: OVER_LIMIT_BANNER_CLASS, children: ["Too many features selected \u2014 remove", " ", value.length - MAX_FEATURES_PER_PRODUCT, " before saving."] })), platformFeatures.length > 0 && (_jsxs(Div, { children: [_jsx(Div, { className: SECTION_LABEL_CLASS, children: "Platform features" }), _jsx(Grid, { cols: "halves", gap: "xs", children: platformFeatures.map(renderRow) })] })), storeFeatures.length > 0 && (_jsxs(Div, { children: [_jsx(Div, { className: SECTION_LABEL_CLASS, children: "Store custom features" }), _jsx(Grid, { cols: "halves", gap: "xs", children: storeFeatures.map(renderRow) })] })), !hasAny && (_jsx(Div, { className: EMPTY_STATE_CLASS, children: "No applicable feature badges available." }))] }));
72
+ }
@@ -5,10 +5,12 @@ import { useTranslations } from "next-intl";
5
5
  import { Alert, Checkbox, Div, FormField, FormGroup, Heading, RichTextEditor, Stack, Text, } from "../../../ui";
6
6
  import { CustomSectionsEditor } from "./CustomSectionsEditor";
7
7
  import { SublistingCategorySelect } from "./SublistingCategorySelect";
8
+ import { ProductFeaturesSelector } from "./ProductFeaturesSelector";
8
9
  import { ImageUpload, MediaUploadField, MediaUploadList, } from "../../media";
9
10
  import { useMediaUpload } from "../../media";
10
11
  import { resolveDate } from "../../../utils/date.formatter";
11
12
  import { normalizeRichTextHtml } from "../../../utils/string.formatter";
13
+ import { isAuctionListing, isPreOrderListing, } from "../utils/listing-type";
12
14
  export const PRODUCT_STATUS_OPTIONS = [
13
15
  { value: "draft", label: "Draft" },
14
16
  { value: "published", label: "Published" },
@@ -105,7 +107,7 @@ export function ProductForm({ product, onChange, isReadonly = false, renderDescr
105
107
  ] })] }), _jsx(Checkbox, { label: t("formInsurance"), checked: !!product.insurance, onChange: (e) => update({
106
108
  insurance: e.target.checked,
107
109
  insuranceCost: e.target.checked ? product.insuranceCost || 0 : undefined,
108
- }), disabled: isReadonly }), product.insurance && (_jsxs(_Fragment, { children: [_jsx(Alert, { variant: "info", title: t("formInsuranceHelp"), children: t("formInsuranceHelp") }), _jsx(FormField, { name: "insuranceCost", label: t("formInsuranceCost"), type: "number", value: String(product.insuranceCost ?? ""), onChange: (value) => update({ insuranceCost: Number(value) }), disabled: isReadonly, placeholder: `${currencyPrefix}0` })] })), _jsx(Heading, { level: 4, className: "mt-4", children: t("sectionAuctionSettings") }), _jsx(Checkbox, { label: t("formIsAuction"), checked: !!product.isAuction, onChange: (e) => update({ isAuction: e.target.checked }), disabled: isReadonly }), product.isAuction && (_jsxs(_Fragment, { children: [_jsxs(FormGroup, { columns: 2, children: [_jsx(FormField, { name: "startingBid", label: t("formStartingBid"), type: "number", value: String(product.startingBid ?? ""), onChange: (value) => update({ startingBid: Number(value) }), disabled: isReadonly, placeholder: "0" }), _jsx(FormField, { name: "auctionEndDate", label: t("formAuctionEndDate"), type: "datetime-local", value: (() => {
110
+ }), disabled: isReadonly }), product.insurance && (_jsxs(_Fragment, { children: [_jsx(Alert, { variant: "info", title: t("formInsuranceHelp"), children: t("formInsuranceHelp") }), _jsx(FormField, { name: "insuranceCost", label: t("formInsuranceCost"), type: "number", value: String(product.insuranceCost ?? ""), onChange: (value) => update({ insuranceCost: Number(value) }), disabled: isReadonly, placeholder: `${currencyPrefix}0` })] })), _jsx(Heading, { level: 4, className: "mt-4", children: t("sectionAuctionSettings") }), _jsx(Checkbox, { label: t("formIsAuction"), checked: isAuctionListing(product), onChange: (e) => update({ listingType: e.target.checked ? "auction" : "standard" }), disabled: isReadonly }), isAuctionListing(product) && (_jsxs(_Fragment, { children: [_jsxs(FormGroup, { columns: 2, children: [_jsx(FormField, { name: "startingBid", label: t("formStartingBid"), type: "number", value: String(product.startingBid ?? ""), onChange: (value) => update({ startingBid: Number(value) }), disabled: isReadonly, placeholder: "0" }), _jsx(FormField, { name: "auctionEndDate", label: t("formAuctionEndDate"), type: "datetime-local", value: (() => {
109
111
  const d = resolveDate(product.auctionEndDate);
110
112
  if (!d)
111
113
  return "";
@@ -115,7 +117,7 @@ export function ProductForm({ product, onChange, isReadonly = false, renderDescr
115
117
  }), disabled: isReadonly, options: [
116
118
  { value: "winner", label: t("formAuctionShippingPaidByWinner") },
117
119
  { value: "seller", label: t("formAuctionShippingPaidBySeller") },
118
- ] }), _jsx(Text, { variant: "secondary", weight: "semibold", className: "mt-2", children: t("sectionAuctionAdvanced") }), _jsx(Checkbox, { label: t("formAutoExtendable"), checked: !!product.autoExtendable, onChange: (e) => update({ autoExtendable: e.target.checked }), disabled: isReadonly }), product.autoExtendable && (_jsxs(_Fragment, { children: [_jsx(Alert, { variant: "info", title: t("formAutoExtendableHelp"), children: t("formAutoExtendableHelp") }), _jsx(FormField, { name: "auctionExtensionMinutes", label: t("formAuctionExtensionMinutes"), type: "number", value: String(product.auctionExtensionMinutes ?? 5), onChange: (value) => update({ auctionExtensionMinutes: Number(value) || 5 }), disabled: isReadonly, placeholder: "5", helpText: t("formAuctionExtensionMinutesHelp") })] }))] })), _jsx(Heading, { level: 4, className: "mt-4", children: t("sectionPreOrderSettings") }), _jsx(Checkbox, { label: t("formIsPreOrder"), checked: !!product.isPreOrder, onChange: (e) => update({ isPreOrder: e.target.checked }), disabled: isReadonly }), product.isPreOrder && (_jsxs(_Fragment, { children: [_jsxs(FormGroup, { columns: 2, children: [_jsx(FormField, { name: "preOrderDeliveryDate", label: t("formPreOrderDeliveryDate"), type: "datetime-local", value: (() => {
120
+ ] }), _jsx(Text, { variant: "secondary", weight: "semibold", className: "mt-2", children: t("sectionAuctionAdvanced") }), _jsx(Checkbox, { label: t("formAutoExtendable"), checked: !!product.autoExtendable, onChange: (e) => update({ autoExtendable: e.target.checked }), disabled: isReadonly }), product.autoExtendable && (_jsxs(_Fragment, { children: [_jsx(Alert, { variant: "info", title: t("formAutoExtendableHelp"), children: t("formAutoExtendableHelp") }), _jsx(FormField, { name: "auctionExtensionMinutes", label: t("formAuctionExtensionMinutes"), type: "number", value: String(product.auctionExtensionMinutes ?? 5), onChange: (value) => update({ auctionExtensionMinutes: Number(value) || 5 }), disabled: isReadonly, placeholder: "5", helpText: t("formAuctionExtensionMinutesHelp") })] }))] })), _jsx(Heading, { level: 4, className: "mt-4", children: t("sectionPreOrderSettings") }), _jsx(Checkbox, { label: t("formIsPreOrder"), checked: isPreOrderListing(product), onChange: (e) => update({ listingType: e.target.checked ? "pre-order" : "standard" }), disabled: isReadonly }), isPreOrderListing(product) && (_jsxs(_Fragment, { children: [_jsxs(FormGroup, { columns: 2, children: [_jsx(FormField, { name: "preOrderDeliveryDate", label: t("formPreOrderDeliveryDate"), type: "datetime-local", value: (() => {
119
121
  const d = resolveDate(product.preOrderDeliveryDate);
120
122
  if (!d)
121
123
  return "";
@@ -137,5 +139,9 @@ export function ProductForm({ product, onChange, isReadonly = false, renderDescr
137
139
  value: product.pickupAddressId || "",
138
140
  onChange: (value) => update({ pickupAddressId: value }),
139
141
  disabled: isReadonly,
140
- }) })) : (_jsx(FormField, { name: "pickupAddressId", label: t("formPickupAddress"), type: "text", value: product.pickupAddressId || "", onChange: (value) => update({ pickupAddressId: value }), disabled: isReadonly })), _jsx(SublistingCategorySelect, { value: product.sublistingCategoryId ?? "", onChange: (id) => update({ sublistingCategoryId: id || undefined }), disabled: isReadonly }), !product.isAuction && renderGroupSettings?.(product), _jsxs(Div, { children: [_jsx(Heading, { level: 3, className: "mb-1 text-sm font-semibold text-zinc-700 dark:text-zinc-300", children: "Custom Sections" }), _jsx(Text, { className: "mb-3 text-xs text-zinc-500 dark:text-zinc-400", children: "Add up to 3 custom tabs to your product page \u2014 e.g. \"Box Contents\", \"Compatibility\", \"Grading Details\"." }), _jsx(CustomSectionsEditor, { sections: product.customSections ?? [], onChange: (sections) => update({ customSections: sections }) })] }), _jsx(FormField, { name: "shippingInfo", label: t("formShipping"), type: "textarea", value: product.shippingInfo || "", onChange: (value) => update({ shippingInfo: value }), disabled: isReadonly, placeholder: "Shipping information..." }), _jsx(FormField, { name: "returnPolicy", label: t("formReturnPolicy"), type: "textarea", value: product.returnPolicy || "", onChange: (value) => update({ returnPolicy: value }), disabled: isReadonly, placeholder: "Return policy details..." }), product.storeName && (_jsx(FormField, { name: "storeName", label: t("formSeller"), type: "text", value: product.storeName, onChange: () => { }, disabled: true }))] }));
142
+ }) })) : (_jsx(FormField, { name: "pickupAddressId", label: t("formPickupAddress"), type: "text", value: product.pickupAddressId || "", onChange: (value) => update({ pickupAddressId: value }), disabled: isReadonly })), _jsx(SublistingCategorySelect, { value: product.sublistingCategoryId ?? "", onChange: (id) => update({ sublistingCategoryId: id || undefined }), disabled: isReadonly }), !isAuctionListing(product) && renderGroupSettings?.(product), _jsx(ProductFeaturesSelector, { value: product.features ?? [], onChange: (features) => update({ features }), productType: (isAuctionListing(product)
143
+ ? "auction"
144
+ : isPreOrderListing(product)
145
+ ? "preorder"
146
+ : "product"), storeId: product.storeId, disabled: isReadonly }), _jsxs(Div, { children: [_jsx(Heading, { level: 3, className: "mb-1 text-sm font-semibold text-zinc-700 dark:text-zinc-300", children: "Custom Sections" }), _jsx(Text, { className: "mb-3 text-xs text-zinc-500 dark:text-zinc-400", children: "Add up to 3 custom tabs to your product page \u2014 e.g. \"Box Contents\", \"Compatibility\", \"Grading Details\"." }), _jsx(CustomSectionsEditor, { sections: product.customSections ?? [], onChange: (sections) => update({ customSections: sections }) })] }), _jsx(FormField, { name: "shippingInfo", label: t("formShipping"), type: "textarea", value: product.shippingInfo || "", onChange: (value) => update({ shippingInfo: value }), disabled: isReadonly, placeholder: "Shipping information..." }), _jsx(FormField, { name: "returnPolicy", label: t("formReturnPolicy"), type: "textarea", value: product.returnPolicy || "", onChange: (value) => update({ returnPolicy: value }), disabled: isReadonly, placeholder: "Return policy details..." }), product.storeName && (_jsx(FormField, { name: "storeName", label: t("formSeller"), type: "text", value: product.storeName, onChange: () => { }, disabled: true }))] }));
141
147
  }
@@ -8,19 +8,25 @@ import { formatCurrency } from "../../../utils/number.formatter";
8
8
  import { getDefaultCurrency } from "../../../core/baseline-resolver";
9
9
  import { safeDisplayName } from "../../../security";
10
10
  import { useLongPress } from "../../../react/hooks/useLongPress";
11
+ import { FeatureBadgeList } from "./FeatureBadge";
12
+ import { useProductFeatures } from "./ProductFeaturesContext";
13
+ import { PRODUCT_FEATURE_CARD_MAX_VISIBLE } from "../constants/product-features.constants";
14
+ import { isAuctionListing, isPreOrderListing } from "../utils/listing-type";
11
15
  export function ProductCard({ product, href, onClick, onAddToWishlist, isWishlisted, onAddToCart, onBuyNow, className = "", selectionMode = false, isSelected = false, onSelect, }) {
12
16
  const discount = product.originalPrice && product.originalPrice > product.price
13
17
  ? Math.round(((product.originalPrice - product.price) / product.originalPrice) *
14
18
  100)
15
19
  : null;
16
- const isAuction = product.isAuction || product.listingType === "auction";
17
- const isPreOrder = product.isPreOrder || product.listingType === "pre-order";
20
+ // SB1-G canonical accessors that handle the legacy boolean fallback.
21
+ const isAuction = isAuctionListing(product);
22
+ const isPreOrder = isPreOrderListing(product);
18
23
  const typeBadge = isAuction
19
24
  ? { label: "Auction", cls: "bg-amber-500 text-white" }
20
25
  : isPreOrder
21
26
  ? { label: "Pre-Order", cls: "bg-violet-600 text-white" }
22
27
  : null;
23
28
  const longPress = useLongPress(() => onSelect?.(product.id));
29
+ const featuresList = useProductFeatures();
24
30
  const handleCardClick = selectionMode
25
31
  ? (e) => { e.preventDefault(); e.stopPropagation(); onSelect?.(product.id); }
26
32
  : onClick && !href ? () => onClick(product) : undefined;
@@ -60,7 +66,7 @@ export function ProductCard({ product, href, onClick, onAddToWishlist, isWishlis
60
66
  ].join(" "), children: _jsx("svg", { className: "h-4 w-4", fill: isWishlisted ? "currentColor" : "none", stroke: "currentColor", strokeWidth: 2, viewBox: "0 0 24 24", "aria-hidden": "true", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M21 8.25c0-2.485-2.099-4.5-4.688-4.5-1.935 0-3.597 1.126-4.312 2.733-.715-1.607-2.377-2.733-4.313-2.733C5.1 3.75 3 5.765 3 8.25c0 7.22 9 12 9 12s9-4.78 9-12z" }) }) }))] }), _jsxs(Div, { className: "flex flex-1 flex-col p-3 pt-2.5", children: [_jsx(Text, { className: `${THEME_CONSTANTS.utilities.textClamp2} text-sm font-semibold text-zinc-900 dark:text-white leading-snug`, children: product.title }), (product.categoryName || product.brand) && (_jsxs(Row, { className: "mt-1 gap-1 flex-wrap", children: [product.categoryName && (_jsx(Span, { className: "rounded-full bg-zinc-100 dark:bg-zinc-800 px-1.5 py-0.5 text-[10px] text-zinc-500 dark:text-zinc-400 truncate max-w-[90px]", children: product.categoryName })), product.brand && (_jsx(Span, { className: "rounded-full bg-zinc-100 dark:bg-zinc-800 px-1.5 py-0.5 text-[10px] text-zinc-500 dark:text-zinc-400 truncate max-w-[80px]", children: product.brand }))] })), (() => {
61
67
  const seller = safeDisplayName(product.storeName, "");
62
68
  return seller ? (_jsxs(Text, { className: "mt-0.5 text-[11px] text-zinc-400 dark:text-zinc-500 truncate", children: ["by ", seller] })) : null;
63
- })(), product.rating !== undefined && (_jsxs(Row, { className: "mt-1 gap-1 items-center", children: [_jsx(Span, { className: "text-[11px] text-amber-400", children: "\u2605" }), _jsxs(Span, { className: "text-[11px] text-zinc-500 dark:text-zinc-400", children: [product.rating.toFixed(1), product.reviewCount ? ` (${product.reviewCount})` : ""] })] })), _jsxs(Div, { className: "mt-auto pt-2", children: [_jsxs(Row, { className: "items-baseline gap-2", children: [_jsx(Span, { className: "text-base font-bold text-primary dark:text-primary-400", children: formatCurrency(product.price, getDefaultCurrency()) }), product.originalPrice && product.originalPrice > product.price && (_jsx(Span, { className: "text-xs text-zinc-400 line-through dark:text-zinc-500", children: formatCurrency(product.originalPrice, getDefaultCurrency()) }))] }), (onAddToCart || onBuyNow) && (_jsxs(Div, { className: "mt-2 grid gap-1.5", style: { gridTemplateColumns: onBuyNow && onAddToCart ? "1fr 1fr" : "1fr" }, children: [onBuyNow && (_jsxs(Button, { type: "button", onClick: (e) => {
69
+ })(), product.rating !== undefined && (_jsxs(Row, { className: "mt-1 gap-1 items-center", children: [_jsx(Span, { className: "text-[11px] text-amber-400", children: "\u2605" }), _jsxs(Span, { className: "text-[11px] text-zinc-500 dark:text-zinc-400", children: [product.rating.toFixed(1), product.reviewCount ? ` (${product.reviewCount})` : ""] })] })), _jsxs(Div, { className: "mt-auto pt-2", children: [_jsxs(Row, { className: "items-baseline gap-2", children: [_jsx(Span, { className: "text-base font-bold text-primary dark:text-primary-400", children: formatCurrency(product.price, getDefaultCurrency()) }), product.originalPrice && product.originalPrice > product.price && (_jsx(Span, { className: "text-xs text-zinc-400 line-through dark:text-zinc-500", children: formatCurrency(product.originalPrice, getDefaultCurrency()) }))] }), featuresList && product.features && product.features.length > 0 && (_jsx(FeatureBadgeList, { productFeatureIds: product.features, features: featuresList, maxVisible: PRODUCT_FEATURE_CARD_MAX_VISIBLE, className: "mt-2" })), (onAddToCart || onBuyNow) && (_jsxs(Div, { className: "mt-2 grid gap-1.5", style: { gridTemplateColumns: onBuyNow && onAddToCart ? "1fr 1fr" : "1fr" }, children: [onBuyNow && (_jsxs(Button, { type: "button", onClick: (e) => {
64
70
  e.stopPropagation();
65
71
  e.preventDefault();
66
72
  onBuyNow(product);
@@ -1,11 +1,13 @@
1
1
  "use client";
2
2
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
3
  import { useState, useCallback, useMemo } from "react";
4
- import { X, ShoppingCart, Heart, SlidersHorizontal } from "lucide-react";
4
+ import { X, ShoppingCart, Heart, SlidersHorizontal, Columns } from "lucide-react";
5
5
  import { useRouter } from "next/navigation";
6
6
  import { useUrlTable } from "../../../react/hooks/useUrlTable";
7
7
  import { useProducts } from "../hooks/useProducts";
8
8
  import { Pagination, useToast, BulkActionsBar, ListingToolbar } from "../../../ui";
9
+ import { ACTION_ID, ACTION_META, COMPARE_MAX_ITEMS } from "../constants/action-defs";
10
+ import { CompareOverlay } from "./CompareOverlay";
9
11
  import { ROUTES } from "../../../next";
10
12
  import { ProductGrid, ProductFilters, PRODUCT_PUBLIC_SORT_OPTIONS } from ".";
11
13
  import { useGuestCart } from "../../cart/hooks/useGuestCart";
@@ -20,6 +22,7 @@ export function ProductsIndexListing({ initialData }) {
20
22
  const { showToast } = useToast();
21
23
  const [searchInput, setSearchInput] = useState(table.get("q") || "");
22
24
  const [filterOpen, setFilterOpen] = useState(false);
25
+ const [compareIds, setCompareIds] = useState([]);
23
26
  const showSold = table.get("showSold") === "true";
24
27
  const [view, setView] = useState(table.get("view") || "card");
25
28
  // Pending filter state — buffered until "Apply Filters" clicked
@@ -93,8 +96,7 @@ export function ProductsIndexListing({ initialData }) {
93
96
  sort: table.get("sort") || "-createdAt",
94
97
  page: table.getNumber("page", 1),
95
98
  perPage: table.getNumber("pageSize", 24),
96
- isAuction: false,
97
- isPreOrder: false,
99
+ listingType: "standard",
98
100
  status: showSold ? undefined : "published",
99
101
  };
100
102
  const { products, totalPages, page, isLoading } = useProducts(params, { initialData });
@@ -144,8 +146,8 @@ export function ProductsIndexListing({ initialData }) {
144
146
  }, [localCart, router]);
145
147
  return (_jsxs("div", { className: "min-h-screen", children: [_jsx(ListingToolbar, { filterCount: activeFilterCount, onFiltersClick: openFilters, searchValue: searchInput, searchPlaceholder: "Search products...", onSearchChange: setSearchInput, onSearchCommit: commitSearch, onSearchKeyDown: handleSearchKeyDown, sortValue: table.get("sort") || "-createdAt", sortOptions: PRODUCT_PUBLIC_SORT_OPTIONS, onSortChange: (v) => { table.set("sort", v); table.setPage(1); }, view: view === "card" ? "grid" : "list", onViewChange: (v) => handleViewToggle(v === "grid" ? "card" : "list"), onResetAll: resetAll, hasActiveState: hasActiveState, bulkMode: selection.isSelecting, bulkSelectedCount: selection.selectedCount, bulkTotalCount: products.length, onBulkSelectAll: selection.toggleAll, onBulkClear: selection.clearSelection, extra: _jsxs("label", { className: "flex items-center gap-1.5 cursor-pointer select-none shrink-0", children: [_jsx("span", { className: "hidden sm:inline text-xs text-zinc-600 dark:text-zinc-300 whitespace-nowrap", children: "Show sold" }), _jsx("button", { type: "button", role: "switch", "aria-checked": showSold, onClick: () => table.set("showSold", showSold ? "" : "true"), className: `relative inline-flex h-5 w-9 flex-shrink-0 items-center rounded-full transition-colors duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-1 ${showSold ? "bg-primary" : "bg-zinc-300 dark:bg-slate-600"}`, children: _jsx("span", { className: `inline-block h-3.5 w-3.5 transform rounded-full bg-white shadow-sm transition-transform duration-200 ${showSold ? "translate-x-[19px]" : "translate-x-[3px]"}` }) })] }) }), totalPages > 1 && (_jsx("div", { className: "sticky top-[calc(var(--header-height,0px)+44px)] z-10 flex justify-center bg-white/95 dark:bg-slate-900/95 backdrop-blur-sm border-b border-zinc-200 dark:border-slate-700 px-3 py-1.5", children: _jsx(Pagination, { currentPage: page, totalPages: totalPages, onPageChange: (p) => table.setPage(p) }) })), _jsx("div", { className: "py-6", children: isLoading ? (_jsx("div", { className: "grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 gap-4", children: Array.from({ length: 10 }).map((_, i) => (_jsxs("div", { className: "rounded-xl border border-zinc-100 dark:border-slate-700 overflow-hidden animate-pulse", children: [_jsx("div", { className: "aspect-square bg-zinc-200 dark:bg-slate-700" }), _jsxs("div", { className: "p-3 space-y-2", children: [_jsx("div", { className: "h-3 bg-zinc-200 dark:bg-slate-700 rounded w-3/4" }), _jsx("div", { className: "h-3 bg-zinc-200 dark:bg-slate-700 rounded w-1/2" }), _jsx("div", { className: "h-4 bg-zinc-200 dark:bg-slate-700 rounded w-1/3" })] })] }, i))) })) : (_jsx(ProductGrid, { products: products, getProductHref: (p) => String(ROUTES.PUBLIC.PRODUCT_DETAIL(p.slug || p.id)), view: view, onWishlistToggle: handleWishlistToggle, wishlistedIds: wishlistedIds, onAddToCart: handleAddToCart, onBuyNow: handleBuyNow, selectionMode: selection.isSelecting, selectedIds: selection.selectedIdSet, onToggleSelect: selection.toggle })) }), _jsx(BulkActionsBar, { selectedCount: selection.selectedCount, onClearSelection: selection.clearSelection, actions: [
146
148
  {
147
- key: "cart",
148
- label: "Add to Cart",
149
+ key: ACTION_ID.ADD_TO_CART,
150
+ label: ACTION_META[ACTION_ID.ADD_TO_CART].label,
149
151
  icon: _jsx(ShoppingCart, { className: "h-3.5 w-3.5" }),
150
152
  variant: "primary",
151
153
  onClick: () => {
@@ -159,8 +161,8 @@ export function ProductsIndexListing({ initialData }) {
159
161
  },
160
162
  },
161
163
  {
162
- key: "wishlist",
163
- label: "Wishlist",
164
+ key: ACTION_ID.ADD_TO_WISHLIST,
165
+ label: ACTION_META[ACTION_ID.ADD_TO_WISHLIST].label,
164
166
  icon: _jsx(Heart, { className: "h-3.5 w-3.5" }),
165
167
  variant: "secondary",
166
168
  onClick: () => {
@@ -173,5 +175,19 @@ export function ProductsIndexListing({ initialData }) {
173
175
  selection.clearSelection();
174
176
  },
175
177
  },
176
- ] }), filterOpen && (_jsxs(_Fragment, { children: [_jsx("div", { className: "fixed inset-0 z-40 bg-black/40", "aria-hidden": "true", onClick: () => setFilterOpen(false) }), _jsxs("div", { className: "fixed inset-y-0 left-0 z-50 flex w-80 flex-col bg-white dark:bg-slate-900 shadow-2xl", children: [_jsxs("div", { className: "flex items-center justify-between border-b border-zinc-200 dark:border-slate-700 px-4 py-3.5", children: [_jsxs("span", { className: "flex items-center gap-2 text-base font-semibold text-zinc-900 dark:text-zinc-100", children: [_jsx(SlidersHorizontal, { className: "h-4 w-4" }), "Filters"] }), _jsxs("div", { className: "flex items-center gap-2", children: [activeFilterCount > 0 && (_jsx("button", { type: "button", onClick: clearFilters, className: "text-xs text-zinc-500 hover:text-rose-500 dark:text-zinc-400 transition-colors", children: "Clear all" })), _jsx("button", { type: "button", onClick: () => setFilterOpen(false), "aria-label": "Close filters", className: "rounded-lg p-1.5 text-zinc-500 hover:bg-zinc-100 dark:hover:bg-slate-800 transition-colors", children: _jsx(X, { className: "h-5 w-5" }) })] })] }), _jsx("div", { className: "flex-1 overflow-y-auto px-4 py-4", children: _jsx(ProductFilters, { table: pendingTable, currencyPrefix: "\u20B9", categoryOptions: categoryOptions }) }), _jsx("div", { className: "border-t border-zinc-200 dark:border-slate-700 px-4 py-3.5", children: _jsxs("button", { type: "button", onClick: applyFilters, className: "w-full rounded-lg bg-primary py-2.5 text-sm font-semibold text-white hover:bg-primary-600 transition-colors active:scale-[0.98]", children: ["Apply Filters", activeFilterCount > 0 ? ` (${activeFilterCount})` : ""] }) })] })] }))] }));
178
+ {
179
+ key: ACTION_ID.COMPARE,
180
+ label: ACTION_META[ACTION_ID.COMPARE].label,
181
+ icon: _jsx(Columns, { className: "h-3.5 w-3.5" }),
182
+ variant: "secondary",
183
+ disabled: selection.selectedCount < 2 || selection.selectedCount > COMPARE_MAX_ITEMS,
184
+ onClick: () => {
185
+ const ids = Array.from(selection.selectedIdSet).slice(0, COMPARE_MAX_ITEMS);
186
+ setCompareIds(ids);
187
+ },
188
+ },
189
+ ] }), _jsx(CompareOverlay, { isOpen: compareIds.length > 0, productIds: compareIds, productType: "product", onClose: () => {
190
+ setCompareIds([]);
191
+ selection.clearSelection();
192
+ }, onRemove: (id) => setCompareIds((ids) => ids.filter((i) => i !== id)) }), filterOpen && (_jsxs(_Fragment, { children: [_jsx("div", { className: "fixed inset-0 z-40 bg-black/40", "aria-hidden": "true", onClick: () => setFilterOpen(false) }), _jsxs("div", { className: "fixed inset-y-0 left-0 z-50 flex w-80 flex-col bg-white dark:bg-slate-900 shadow-2xl", children: [_jsxs("div", { className: "flex items-center justify-between border-b border-zinc-200 dark:border-slate-700 px-4 py-3.5", children: [_jsxs("span", { className: "flex items-center gap-2 text-base font-semibold text-zinc-900 dark:text-zinc-100", children: [_jsx(SlidersHorizontal, { className: "h-4 w-4" }), "Filters"] }), _jsxs("div", { className: "flex items-center gap-2", children: [activeFilterCount > 0 && (_jsx("button", { type: "button", onClick: clearFilters, className: "text-xs text-zinc-500 hover:text-rose-500 dark:text-zinc-400 transition-colors", children: "Clear all" })), _jsx("button", { type: "button", onClick: () => setFilterOpen(false), "aria-label": "Close filters", className: "rounded-lg p-1.5 text-zinc-500 hover:bg-zinc-100 dark:hover:bg-slate-800 transition-colors", children: _jsx(X, { className: "h-5 w-5" }) })] })] }), _jsx("div", { className: "flex-1 overflow-y-auto px-4 py-4", children: _jsx(ProductFilters, { table: pendingTable, currencyPrefix: "\u20B9", categoryOptions: categoryOptions }) }), _jsx("div", { className: "border-t border-zinc-200 dark:border-slate-700 px-4 py-3.5", children: _jsxs("button", { type: "button", onClick: applyFilters, className: "w-full rounded-lg bg-primary py-2.5 text-sm font-semibold text-white hover:bg-primary-600 transition-colors active:scale-[0.98]", children: ["Apply Filters", activeFilterCount > 0 ? ` (${activeFilterCount})` : ""] }) })] })] }))] }));
177
193
  }
@@ -3,13 +3,17 @@ import { productRepository } from "../../../repositories";
3
3
  import { ROUTES } from "../../../constants";
4
4
  import { Container, Heading, Main, Section } from "../../../ui";
5
5
  import { AdSlot } from "../../homepage/components/AdSlot";
6
+ import { parseListingSearchParams } from "../../../utils/listing-params";
6
7
  import { ProductsIndexListing } from "./ProductsIndexListing";
8
+ const DEFAULT_PAGE = 1;
9
+ const DEFAULT_PAGE_SIZE = 24;
10
+ const DEFAULT_SORT = "-createdAt";
7
11
  function sp(params, key) {
8
12
  const v = params[key];
9
13
  return Array.isArray(v) ? v[0] ?? "" : v ?? "";
10
14
  }
11
15
  function buildProductFilters(params) {
12
- const parts = ["status==published", "isAuction==false"];
16
+ const parts = ["status==published", "listingType==standard"];
13
17
  const condition = sp(params, "condition");
14
18
  if (condition) {
15
19
  const values = condition.split("|").filter(Boolean);
@@ -24,18 +28,19 @@ function buildProductFilters(params) {
24
28
  parts.push(`price>=${minPrice}`);
25
29
  if (maxPrice)
26
30
  parts.push(`price<=${maxPrice}`);
27
- const sellerId = sp(params, "seller");
28
- if (sellerId)
29
- parts.push(`sellerId==${sellerId}`);
31
+ const storeId = sp(params, "seller");
32
+ if (storeId)
33
+ parts.push(`storeId==${storeId}`);
30
34
  const freeShipping = sp(params, "freeShipping");
31
35
  if (freeShipping === "true")
32
36
  parts.push("freeShipping==true");
33
37
  return parts.join(",");
34
38
  }
35
39
  export async function ProductsIndexPageView({ searchParams = {} }) {
36
- const sort = sp(searchParams, "sort") || "-createdAt";
37
- const page = Number(sp(searchParams, "page")) || 1;
38
- const pageSize = Number(sp(searchParams, "pageSize")) || 24;
40
+ const std = parseListingSearchParams(searchParams);
41
+ const sort = std.sorts ?? DEFAULT_SORT;
42
+ const page = std.page ?? DEFAULT_PAGE;
43
+ const pageSize = std.pageSize ?? DEFAULT_PAGE_SIZE;
39
44
  const filters = buildProductFilters(searchParams);
40
45
  const result = await productRepository
41
46
  .list({
@@ -5,9 +5,10 @@ import Link from "next/link";
5
5
  import { ROUTES } from "../../../next";
6
6
  import { Row, Text, Modal, SideDrawer, Button } from "../../../ui";
7
7
  import { formatCurrency } from "../../../utils/number.formatter";
8
+ import { isPreOrderListing } from "../utils/listing-type";
8
9
  function memberHref(m) {
9
10
  const slug = m.slug ?? m.id;
10
- if (m.isPreOrder)
11
+ if (isPreOrderListing(m))
11
12
  return String(ROUTES.PUBLIC.PRE_ORDER_DETAIL(slug));
12
13
  return String(ROUTES.PUBLIC.PRODUCT_DETAIL(slug));
13
14
  }