@mohasinac/appkit 4.52.5 → 4.53.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 (630) hide show
  1. package/dist/.build-stamp.json +4 -4
  2. package/dist/_internal/client/features/sticker-trace/canvas-codec.d.ts +2 -0
  3. package/dist/_internal/client/features/sticker-trace/canvas-codec.js +148 -0
  4. package/dist/_internal/server/features/auctions/actions.js +1 -1
  5. package/dist/_internal/server/features/categories/data.js +23 -7
  6. package/dist/_internal/server/features/checkout/actions.js +10 -3
  7. package/dist/_internal/server/features/checkout/data.d.ts +15 -0
  8. package/dist/_internal/server/features/checkout/data.js +20 -3
  9. package/dist/_internal/server/features/lottery/actions.js +9 -1
  10. package/dist/_internal/server/features/lottery/og.d.ts +40 -0
  11. package/dist/_internal/server/features/lottery/og.js +79 -0
  12. package/dist/_internal/server/features/messages/actions.js +4 -0
  13. package/dist/_internal/server/features/offers/adapters.js +17 -3
  14. package/dist/_internal/server/features/orders/actions.js +7 -2
  15. package/dist/_internal/server/features/raffle/actions.d.ts +19 -0
  16. package/dist/_internal/server/features/raffle/actions.js +25 -0
  17. package/dist/_internal/server/features/reviews/actions.js +1 -1
  18. package/dist/_internal/server/features/reviews/data.d.ts +1 -1
  19. package/dist/_internal/server/features/search/index-build/artifact-store.d.ts +89 -0
  20. package/dist/_internal/server/features/search/index-build/artifact-store.js +208 -0
  21. package/dist/_internal/server/features/search/index-build/build.d.ts +57 -0
  22. package/dist/_internal/server/features/search/index-build/build.js +285 -0
  23. package/dist/_internal/server/features/search/index-build/sources.d.ts +53 -0
  24. package/dist/_internal/server/features/search/index-build/sources.js +385 -0
  25. package/dist/_internal/server/features/search/search-sources.d.ts +0 -15
  26. package/dist/_internal/server/features/search/search-sources.js +142 -7
  27. package/dist/_internal/server/features/seo/robots.js +21 -1
  28. package/dist/_internal/server/features/seo/sitemap.js +1 -1
  29. package/dist/_internal/server/features/shared/listing-data-factory.js +16 -4
  30. package/dist/_internal/server/features/site-settings/adapters.d.ts +1 -1
  31. package/dist/_internal/server/features/site-settings/adapters.js +26 -0
  32. package/dist/_internal/server/features/sticker-trace/actions.d.ts +109 -0
  33. package/dist/_internal/server/features/sticker-trace/actions.js +172 -0
  34. package/dist/_internal/server/features/sticker-trace/adapters.d.ts +80 -0
  35. package/dist/_internal/server/features/sticker-trace/adapters.js +174 -0
  36. package/dist/_internal/server/features/sticker-trace/build-cut-file.d.ts +26 -0
  37. package/dist/_internal/server/features/sticker-trace/build-cut-file.js +127 -0
  38. package/dist/_internal/server/features/sticker-trace/coordinator.d.ts +27 -0
  39. package/dist/_internal/server/features/sticker-trace/coordinator.js +169 -0
  40. package/dist/_internal/server/features/sticker-trace/fanout.d.ts +43 -0
  41. package/dist/_internal/server/features/sticker-trace/fanout.js +180 -0
  42. package/dist/_internal/server/features/sticker-trace/finalizer.d.ts +25 -0
  43. package/dist/_internal/server/features/sticker-trace/finalizer.js +123 -0
  44. package/dist/_internal/server/features/sticker-trace/mosaic-inputs.d.ts +30 -0
  45. package/dist/_internal/server/features/sticker-trace/mosaic-inputs.js +112 -0
  46. package/dist/_internal/server/features/sticker-trace/progress.d.ts +81 -0
  47. package/dist/_internal/server/features/sticker-trace/progress.js +198 -0
  48. package/dist/_internal/server/features/sticker-trace/promote.d.ts +23 -0
  49. package/dist/_internal/server/features/sticker-trace/promote.js +193 -0
  50. package/dist/_internal/server/features/sticker-trace/shard.d.ts +50 -0
  51. package/dist/_internal/server/features/sticker-trace/shard.js +174 -0
  52. package/dist/_internal/server/features/sticker-trace/sheet-actions.d.ts +141 -0
  53. package/dist/_internal/server/features/sticker-trace/sheet-actions.js +279 -0
  54. package/dist/_internal/server/features/sticker-trace/storage.d.ts +135 -0
  55. package/dist/_internal/server/features/sticker-trace/storage.js +282 -0
  56. package/dist/_internal/server/functions/scheduled.d.ts +2 -1
  57. package/dist/_internal/server/functions/scheduled.js +25 -1
  58. package/dist/_internal/server/jobs/core/_event-ref.d.ts +51 -0
  59. package/dist/_internal/server/jobs/core/_event-ref.js +63 -0
  60. package/dist/_internal/server/jobs/core/assignSpinPrize.d.ts +18 -0
  61. package/dist/_internal/server/jobs/core/assignSpinPrize.js +77 -16
  62. package/dist/_internal/server/jobs/core/auctionSettlement.js +13 -4
  63. package/dist/_internal/server/jobs/core/autoPayoutEligibility.js +44 -15
  64. package/dist/_internal/server/jobs/core/bundleStockSync.js +3 -4
  65. package/dist/_internal/server/jobs/core/cleanupRtdbEvents.js +44 -0
  66. package/dist/_internal/server/jobs/core/event-draw-reasons.d.ts +78 -0
  67. package/dist/_internal/server/jobs/core/event-draw-reasons.js +133 -0
  68. package/dist/_internal/server/jobs/core/listingProcessor.js +28 -8
  69. package/dist/_internal/server/jobs/core/onOrderCreate.js +12 -1
  70. package/dist/_internal/server/jobs/core/onScamReportCreate.js +13 -2
  71. package/dist/_internal/server/jobs/core/onScamReportRejected.js +8 -2
  72. package/dist/_internal/server/jobs/core/onScamReportVerified.js +8 -2
  73. package/dist/_internal/server/jobs/core/onStoreWrite.js +11 -4
  74. package/dist/_internal/server/jobs/core/prizeDrawAssignWinner.js +5 -4
  75. package/dist/_internal/server/jobs/core/prizeDrawExpiryReveal.js +1 -4
  76. package/dist/_internal/server/jobs/core/prizeDrawSoldOutReveal.js +1 -2
  77. package/dist/_internal/server/jobs/core/promotions.js +7 -4
  78. package/dist/_internal/server/jobs/core/searchIndexBuild.d.ts +7 -0
  79. package/dist/_internal/server/jobs/core/searchIndexBuild.js +211 -0
  80. package/dist/_internal/server/jobs/core/triggerEventRaffle.d.ts +35 -0
  81. package/dist/_internal/server/jobs/core/triggerEventRaffle.js +213 -31
  82. package/dist/_internal/server/jobs/core/weeklyPayoutEligibility.js +20 -14
  83. package/dist/_internal/server/jobs/handlers/assignSpinPrize.d.ts +8 -0
  84. package/dist/_internal/server/jobs/handlers/assignSpinPrize.js +15 -15
  85. package/dist/_internal/server/jobs/handlers/index.d.ts +1 -0
  86. package/dist/_internal/server/jobs/handlers/index.js +1 -0
  87. package/dist/_internal/server/jobs/handlers/onCategoryWrite.js +18 -0
  88. package/dist/_internal/server/jobs/handlers/onProductWrite.js +18 -0
  89. package/dist/_internal/server/jobs/handlers/onReviewWrite.js +18 -0
  90. package/dist/_internal/server/jobs/handlers/onScamReportUpdate.js +18 -0
  91. package/dist/_internal/server/jobs/handlers/onStoreWrite.js +18 -0
  92. package/dist/_internal/server/jobs/handlers/searchIndexBuild.d.ts +2 -0
  93. package/dist/_internal/server/jobs/handlers/searchIndexBuild.js +2 -0
  94. package/dist/_internal/server/jobs/handlers/triggerEventRaffle.d.ts +8 -0
  95. package/dist/_internal/server/jobs/handlers/triggerEventRaffle.js +15 -6
  96. package/dist/_internal/shared/actions/action-registry.js +29 -0
  97. package/dist/_internal/shared/cache/revalidate-targets.d.ts +0 -1
  98. package/dist/_internal/shared/cache/revalidate-targets.js +10 -8
  99. package/dist/_internal/shared/features/events/config.d.ts +14 -0
  100. package/dist/_internal/shared/features/events/config.js +14 -0
  101. package/dist/_internal/shared/features/notifications/action-url.js +8 -0
  102. package/dist/_internal/shared/features/site-settings/types.d.ts +11 -0
  103. package/dist/_internal/shared/features/sticker-trace/codec.d.ts +81 -0
  104. package/dist/_internal/shared/features/sticker-trace/codec.js +30 -0
  105. package/dist/_internal/shared/features/sticker-trace/config.d.ts +81 -0
  106. package/dist/_internal/shared/features/sticker-trace/config.js +177 -0
  107. package/dist/_internal/shared/features/sticker-trace/cut-contour.d.ts +20 -0
  108. package/dist/_internal/shared/features/sticker-trace/cut-contour.js +60 -0
  109. package/dist/_internal/shared/features/sticker-trace/export/build-export-set.d.ts +65 -0
  110. package/dist/_internal/shared/features/sticker-trace/export/build-export-set.js +176 -0
  111. package/dist/_internal/shared/features/sticker-trace/export/cut-svg.d.ts +56 -0
  112. package/dist/_internal/shared/features/sticker-trace/export/cut-svg.js +120 -0
  113. package/dist/_internal/shared/features/sticker-trace/export/machine-profiles.d.ts +92 -0
  114. package/dist/_internal/shared/features/sticker-trace/export/machine-profiles.js +153 -0
  115. package/dist/_internal/shared/features/sticker-trace/export/nesting.d.ts +51 -0
  116. package/dist/_internal/shared/features/sticker-trace/export/nesting.js +110 -0
  117. package/dist/_internal/shared/features/sticker-trace/export/page-sizes.d.ts +68 -0
  118. package/dist/_internal/shared/features/sticker-trace/export/page-sizes.js +223 -0
  119. package/dist/_internal/shared/features/sticker-trace/export/part-tiling.d.ts +51 -0
  120. package/dist/_internal/shared/features/sticker-trace/export/part-tiling.js +178 -0
  121. package/dist/_internal/shared/features/sticker-trace/export/simplify-budget.d.ts +26 -0
  122. package/dist/_internal/shared/features/sticker-trace/export/simplify-budget.js +134 -0
  123. package/dist/_internal/shared/features/sticker-trace/export/vectorise-art.d.ts +40 -0
  124. package/dist/_internal/shared/features/sticker-trace/export/vectorise-art.js +195 -0
  125. package/dist/_internal/shared/features/sticker-trace/index.d.ts +2 -0
  126. package/dist/_internal/shared/features/sticker-trace/index.js +59 -0
  127. package/dist/_internal/shared/features/sticker-trace/math/catmull-rom.d.ts +11 -0
  128. package/dist/_internal/shared/features/sticker-trace/math/catmull-rom.js +66 -0
  129. package/dist/_internal/shared/features/sticker-trace/math/edt.d.ts +27 -0
  130. package/dist/_internal/shared/features/sticker-trace/math/edt.js +165 -0
  131. package/dist/_internal/shared/features/sticker-trace/math/label.d.ts +15 -0
  132. package/dist/_internal/shared/features/sticker-trace/math/label.js +156 -0
  133. package/dist/_internal/shared/features/sticker-trace/math/marching-squares.d.ts +16 -0
  134. package/dist/_internal/shared/features/sticker-trace/math/marching-squares.js +242 -0
  135. package/dist/_internal/shared/features/sticker-trace/math/morphology.d.ts +46 -0
  136. package/dist/_internal/shared/features/sticker-trace/math/morphology.js +168 -0
  137. package/dist/_internal/shared/features/sticker-trace/math/rasterize-path.d.ts +88 -0
  138. package/dist/_internal/shared/features/sticker-trace/math/rasterize-path.js +286 -0
  139. package/dist/_internal/shared/features/sticker-trace/math/rdp.d.ts +10 -0
  140. package/dist/_internal/shared/features/sticker-trace/math/rdp.js +74 -0
  141. package/dist/_internal/shared/features/sticker-trace/resume.d.ts +50 -0
  142. package/dist/_internal/shared/features/sticker-trace/resume.js +160 -0
  143. package/dist/_internal/shared/features/sticker-trace/trace/cluster.d.ts +20 -0
  144. package/dist/_internal/shared/features/sticker-trace/trace/cluster.js +132 -0
  145. package/dist/_internal/shared/features/sticker-trace/trace/cross-profile.d.ts +28 -0
  146. package/dist/_internal/shared/features/sticker-trace/trace/cross-profile.js +120 -0
  147. package/dist/_internal/shared/features/sticker-trace/trace/flood.d.ts +21 -0
  148. package/dist/_internal/shared/features/sticker-trace/trace/flood.js +104 -0
  149. package/dist/_internal/shared/features/sticker-trace/trace/geometry.d.ts +3 -0
  150. package/dist/_internal/shared/features/sticker-trace/trace/geometry.js +140 -0
  151. package/dist/_internal/shared/features/sticker-trace/trace/line-filter.d.ts +15 -0
  152. package/dist/_internal/shared/features/sticker-trace/trace/line-filter.js +138 -0
  153. package/dist/_internal/shared/features/sticker-trace/trace/merge.d.ts +27 -0
  154. package/dist/_internal/shared/features/sticker-trace/trace/merge.js +187 -0
  155. package/dist/_internal/shared/features/sticker-trace/trace/paper.d.ts +32 -0
  156. package/dist/_internal/shared/features/sticker-trace/trace/paper.js +147 -0
  157. package/dist/_internal/shared/features/sticker-trace/trace/prefilter.d.ts +30 -0
  158. package/dist/_internal/shared/features/sticker-trace/trace/prefilter.js +125 -0
  159. package/dist/_internal/shared/features/sticker-trace/trace/quantise.d.ts +10 -0
  160. package/dist/_internal/shared/features/sticker-trace/trace/quantise.js +153 -0
  161. package/dist/_internal/shared/features/sticker-trace/trace/ridge.d.ts +88 -0
  162. package/dist/_internal/shared/features/sticker-trace/trace/ridge.js +344 -0
  163. package/dist/_internal/shared/features/sticker-trace/trace/segment.d.ts +10 -0
  164. package/dist/_internal/shared/features/sticker-trace/trace/segment.js +251 -0
  165. package/dist/_internal/shared/features/sticker-trace/types.d.ts +197 -0
  166. package/dist/_internal/shared/features/sticker-trace/types.js +49 -0
  167. package/dist/_internal/shared/listing-types/_registry.d.ts +11 -0
  168. package/dist/_internal/shared/listing-types/art/config.d.ts +1 -0
  169. package/dist/_internal/shared/listing-types/art/config.js +1 -0
  170. package/dist/_internal/shared/listing-types/auction/config.d.ts +1 -0
  171. package/dist/_internal/shared/listing-types/auction/config.js +1 -0
  172. package/dist/_internal/shared/listing-types/classified/config.d.ts +1 -0
  173. package/dist/_internal/shared/listing-types/classified/config.js +1 -0
  174. package/dist/_internal/shared/listing-types/digital-code/config.d.ts +1 -0
  175. package/dist/_internal/shared/listing-types/digital-code/config.js +1 -0
  176. package/dist/_internal/shared/listing-types/feature-flags.d.ts +7 -0
  177. package/dist/_internal/shared/listing-types/feature-flags.js +9 -0
  178. package/dist/_internal/shared/listing-types/live/config.d.ts +1 -0
  179. package/dist/_internal/shared/listing-types/live/config.js +1 -0
  180. package/dist/_internal/shared/listing-types/pre-order/config.d.ts +1 -0
  181. package/dist/_internal/shared/listing-types/pre-order/config.js +1 -0
  182. package/dist/_internal/shared/listing-types/prize-draw/config.d.ts +1 -0
  183. package/dist/_internal/shared/listing-types/prize-draw/config.js +1 -0
  184. package/dist/_internal/shared/listing-types/standard/config.d.ts +1 -0
  185. package/dist/_internal/shared/listing-types/standard/config.js +1 -0
  186. package/dist/_internal/shared/listing-types/stickers/config.d.ts +1 -0
  187. package/dist/_internal/shared/listing-types/stickers/config.js +1 -0
  188. package/dist/_internal/shared/media/limits.d.ts +12 -2
  189. package/dist/_internal/shared/media/limits.js +12 -2
  190. package/dist/_internal/shared/search/artifact-url.d.ts +35 -0
  191. package/dist/_internal/shared/search/artifact-url.js +119 -0
  192. package/dist/_internal/shared/search/index-record.d.ts +68 -0
  193. package/dist/_internal/shared/search/index-record.js +96 -0
  194. package/dist/_internal/shared/search/match.d.ts +65 -0
  195. package/dist/_internal/shared/search/match.js +263 -0
  196. package/dist/client.d.ts +8 -7
  197. package/dist/client.js +12 -5
  198. package/dist/configs/eslint.js +22 -2
  199. package/dist/constants/api-endpoints.d.ts +68 -0
  200. package/dist/constants/api-endpoints.js +32 -0
  201. package/dist/constants/field-names.d.ts +7 -1
  202. package/dist/constants/field-names.js +36 -1
  203. package/dist/contracts/repository.d.ts +8 -7
  204. package/dist/contracts/search.d.ts +2 -2
  205. package/dist/contracts/table.d.ts +3 -3
  206. package/dist/contracts/table.js +3 -3
  207. package/dist/core/contact-submissions.repository.js +2 -2
  208. package/dist/core/integration-keys.js +7 -1
  209. package/dist/core/newsletter.repository.js +2 -2
  210. package/dist/core/site-config.js +1 -1
  211. package/dist/errors/error-codes.d.ts +30 -0
  212. package/dist/errors/error-codes.js +30 -0
  213. package/dist/errors/error-display-map.js +40 -1
  214. package/dist/features/account/api/[userId]/addresses/route.js +1 -1
  215. package/dist/features/account/components/UserBidsView.js +1 -1
  216. package/dist/features/account/components/index.d.ts +0 -8
  217. package/dist/features/account/components/index.js +0 -4
  218. package/dist/features/addresses/repository/addresses.repository.d.ts +17 -6
  219. package/dist/features/addresses/repository/addresses.repository.js +65 -9
  220. package/dist/features/addresses/schemas/firestore.d.ts +17 -6
  221. package/dist/features/admin/actions/notification-actions.js +15 -6
  222. package/dist/features/admin/api/bids/route.js +1 -1
  223. package/dist/features/admin/api/coupons/route.js +1 -1
  224. package/dist/features/admin/api/products/route.js +1 -1
  225. package/dist/features/admin/api/reviews/route.js +1 -1
  226. package/dist/features/admin/components/AdminAdEditorView.js +19 -5
  227. package/dist/features/admin/components/AdminAuditLogView.js +1 -1
  228. package/dist/features/admin/components/AdminBlogEditorView.js +0 -1
  229. package/dist/features/admin/components/AdminBlogView.js +1 -1
  230. package/dist/features/admin/components/AdminBrandsView.js +17 -1
  231. package/dist/features/admin/components/AdminCategoryEditorView.js +0 -1
  232. package/dist/features/admin/components/AdminContactView.js +1 -1
  233. package/dist/features/admin/components/AdminEmployeeEditorView.js +1 -3
  234. package/dist/features/admin/components/AdminNewsletterView.js +1 -1
  235. package/dist/features/admin/components/AdminOrdersView.js +9 -2
  236. package/dist/features/admin/components/AdminPayoutsView.js +1 -1
  237. package/dist/features/admin/components/AdminPrizeDrawsView.js +11 -0
  238. package/dist/features/admin/components/AdminProductEditorView.d.ts +10 -1
  239. package/dist/features/admin/components/AdminProductEditorView.js +24 -37
  240. package/dist/features/admin/components/AdminProductsView.js +10 -3
  241. package/dist/features/admin/components/AdminScammersView.js +1 -1
  242. package/dist/features/admin/components/AdminSectionsView.js +21 -5
  243. package/dist/features/admin/components/AdminSessionsView.js +1 -1
  244. package/dist/features/admin/components/AdminSublistingCategoriesView.js +22 -1
  245. package/dist/features/admin/components/AdminTeamView.js +1 -1
  246. package/dist/features/admin/components/AdminTesterChecklistItemEditorView.js +0 -1
  247. package/dist/features/admin/components/AdminUsersView.js +1 -1
  248. package/dist/features/admin/components/DataListingView.d.ts +2 -1
  249. package/dist/features/admin/components/DataListingView.js +9 -4
  250. package/dist/features/admin/components/analytics/AdminPageViewsReportView.js +0 -2
  251. package/dist/features/admin/hooks/useAdminListing.d.ts +1 -1
  252. package/dist/features/admin/repository/site-settings.repository.js +8 -3
  253. package/dist/features/admin/schemas/firestore.d.ts +62 -1
  254. package/dist/features/admin/schemas/firestore.js +32 -0
  255. package/dist/features/admin/types/index.d.ts +1 -1
  256. package/dist/features/auctions/actions/bid-actions.d.ts +2 -2
  257. package/dist/features/auctions/actions/bid-actions.js +16 -4
  258. package/dist/features/auctions/api/route.js +1 -1
  259. package/dist/features/auctions/components/AuctionBottomActions.js +4 -0
  260. package/dist/features/auctions/repository/bid.repository.d.ts +46 -4
  261. package/dist/features/auctions/repository/bid.repository.js +114 -13
  262. package/dist/features/auctions/schemas/firestore.d.ts +24 -4
  263. package/dist/features/auctions/schemas/firestore.js +1 -0
  264. package/dist/features/auth/actions/profile-actions.js +30 -4
  265. package/dist/features/auth/components/index.d.ts +0 -1
  266. package/dist/features/auth/components/index.js +0 -1
  267. package/dist/features/auth/repository/session.repository.d.ts +17 -3
  268. package/dist/features/auth/repository/session.repository.js +46 -5
  269. package/dist/features/auth/repository/token.repository.d.ts +27 -4
  270. package/dist/features/auth/repository/token.repository.js +65 -11
  271. package/dist/features/auth/repository/user.repository.d.ts +33 -7
  272. package/dist/features/auth/repository/user.repository.js +100 -15
  273. package/dist/features/auth/schemas/firestore.d.ts +63 -12
  274. package/dist/features/auth/schemas/firestore.js +11 -0
  275. package/dist/features/before-after/api/route.js +1 -1
  276. package/dist/features/blog/components/BlogListView.js +16 -3
  277. package/dist/features/blog/components/BlogPostView.js +1 -1
  278. package/dist/features/blog/schemas/index.d.ts +2 -2
  279. package/dist/features/cart/api/route.js +1 -1
  280. package/dist/features/catalogue/repository/catalogue.repository.d.ts +7 -7
  281. package/dist/features/catalogue/repository/catalogue.repository.js +28 -10
  282. package/dist/features/catalogue/schemas/firestore.d.ts +11 -0
  283. package/dist/features/categories/api/route.js +10 -10
  284. package/dist/features/categories/components/CategoryDetailPageView.js +35 -5
  285. package/dist/features/categories/components/CategorySelectorCreate.js +0 -1
  286. package/dist/features/categories/components/index.d.ts +0 -2
  287. package/dist/features/categories/components/index.js +0 -1
  288. package/dist/features/categories/repository/categories.repository.d.ts +1 -0
  289. package/dist/features/categories/repository/categories.repository.js +31 -1
  290. package/dist/features/categories/schemas/index.d.ts +2 -2
  291. package/dist/features/categories/utils/taxonomy-visual.d.ts +21 -0
  292. package/dist/features/categories/utils/taxonomy-visual.js +58 -0
  293. package/dist/features/checkout/actions/checkout-value-otp-actions.js +8 -1
  294. package/dist/features/collections/api/[slug]/route.js +3 -3
  295. package/dist/features/collections/api/route.js +1 -1
  296. package/dist/features/consultation/api/route.js +1 -1
  297. package/dist/features/consultation/repository/consultations.repository.js +1 -1
  298. package/dist/features/consultation/types/index.d.ts +1 -1
  299. package/dist/features/contact/components/ContactForm.js +1 -3
  300. package/dist/features/corporate/api/route.js +1 -1
  301. package/dist/features/corporate/repository/corporate.repository.js +1 -1
  302. package/dist/features/corporate/types/index.d.ts +1 -1
  303. package/dist/features/cron/jobs/auction-expiry.job.js +1 -1
  304. package/dist/features/cron/jobs/preorder-reminder.job.js +1 -1
  305. package/dist/features/events/actions/event-actions.d.ts +14 -0
  306. package/dist/features/events/actions/event-actions.js +82 -3
  307. package/dist/features/events/api/[id]/route.js +2 -2
  308. package/dist/features/events/components/AdminEventEditorView.js +22 -3
  309. package/dist/features/events/components/AdminEventsView.js +32 -8
  310. package/dist/features/events/components/EventRafflesSection.d.ts +34 -1
  311. package/dist/features/events/components/EventRafflesSection.js +52 -3
  312. package/dist/features/events/components/SpinWheelView.d.ts +2 -2
  313. package/dist/features/events/components/SpinWheelView.js +41 -4
  314. package/dist/features/events/repository/event-entry.repository.d.ts +14 -2
  315. package/dist/features/events/repository/event-entry.repository.js +41 -7
  316. package/dist/features/events/schemas/firestore.d.ts +17 -4
  317. package/dist/features/events/types/index.d.ts +37 -0
  318. package/dist/features/faq/repository/faqs.repository.js +1 -1
  319. package/dist/features/faq/schemas/index.d.ts +5 -2
  320. package/dist/features/faq/schemas/index.js +6 -0
  321. package/dist/features/faq/types/index.d.ts +0 -1
  322. package/dist/features/grouped/components/GroupedListingEditorView.js +17 -2
  323. package/dist/features/homepage/api/carousel/[id]/route.js +1 -1
  324. package/dist/features/homepage/api/carousel/route.js +4 -4
  325. package/dist/features/homepage/api/route.js +2 -2
  326. package/dist/features/homepage/api/sections/route.js +1 -1
  327. package/dist/features/homepage/components/AnnouncementBar.d.ts +1 -9
  328. package/dist/features/homepage/components/AnnouncementBar.js +13 -19
  329. package/dist/features/homepage/components/MarketplaceHomepageView.js +6 -1
  330. package/dist/features/homepage/components/index.d.ts +0 -2
  331. package/dist/features/homepage/components/index.js +0 -1
  332. package/dist/features/homepage/repository/homepage.repository.js +1 -1
  333. package/dist/features/homepage/schemas/firestore.d.ts +6 -0
  334. package/dist/features/homepage/schemas/index.d.ts +10 -10
  335. package/dist/features/layout/AppLayoutShell.d.ts +11 -0
  336. package/dist/features/layout/AppLayoutShell.js +64 -12
  337. package/dist/features/layout/BottomActionsContext.d.ts +16 -0
  338. package/dist/features/layout/BottomActionsContext.js +5 -0
  339. package/dist/features/layout/BottomChrome.js +48 -9
  340. package/dist/features/layout/BottomNavbar.d.ts +14 -0
  341. package/dist/features/layout/BottomNavbar.js +43 -3
  342. package/dist/features/layout/MainNavbar.d.ts +11 -0
  343. package/dist/features/layout/NavbarLayout.d.ts +3 -0
  344. package/dist/features/layout/NavbarLayout.js +88 -11
  345. package/dist/features/layout/SideActionDock.d.ts +1 -0
  346. package/dist/features/layout/SideActionDock.js +219 -0
  347. package/dist/features/layout/TitleBarLayout.js +1 -1
  348. package/dist/features/layout/cta-anchor.d.ts +31 -0
  349. package/dist/features/layout/cta-anchor.js +31 -0
  350. package/dist/features/layout/hooks/useBottomActions.d.ts +7 -0
  351. package/dist/features/layout/hooks/useBottomActions.js +6 -1
  352. package/dist/features/layout/index.d.ts +9 -1
  353. package/dist/features/layout/index.js +9 -1
  354. package/dist/features/layout/useCtaReveal.d.ts +24 -0
  355. package/dist/features/layout/useCtaReveal.js +82 -0
  356. package/dist/features/layout/useHoldToOpen.d.ts +41 -0
  357. package/dist/features/layout/useHoldToOpen.js +84 -0
  358. package/dist/features/lottery/repository/lottery-entry.repository.d.ts +18 -3
  359. package/dist/features/lottery/repository/lottery-entry.repository.js +48 -6
  360. package/dist/features/lottery/schemas/firestore.d.ts +33 -5
  361. package/dist/features/loyalty/api/balance/route.js +1 -1
  362. package/dist/features/loyalty/api/history/route.js +1 -1
  363. package/dist/features/media/MediaImage.js +0 -1
  364. package/dist/features/media/MediaPickerModal.js +7 -1
  365. package/dist/features/media/modals/ImageEditor.js +5 -1
  366. package/dist/features/media/modals/VideoThumbnailSelector.js +17 -1
  367. package/dist/features/media/repository/media-assets.repository.d.ts +19 -0
  368. package/dist/features/media/upload/CameraCapture.js +16 -1
  369. package/dist/features/media/upload/ImageUpload.js +42 -4
  370. package/dist/features/media/upload/MediaUploadField.js +69 -13
  371. package/dist/features/media/upload/downscale-image.d.ts +56 -0
  372. package/dist/features/media/upload/downscale-image.js +150 -0
  373. package/dist/features/messages/components/ConversationThreadView.js +45 -2
  374. package/dist/features/messages/components/MessageSellerButton.d.ts +15 -1
  375. package/dist/features/messages/components/MessageSellerButton.js +10 -2
  376. package/dist/features/messages/schemas/firestore.d.ts +15 -0
  377. package/dist/features/orders/hooks/useOrders.js +4 -2
  378. package/dist/features/orders/repository/orders.repository.d.ts +15 -4
  379. package/dist/features/orders/repository/orders.repository.js +52 -20
  380. package/dist/features/orders/schemas/firestore.d.ts +15 -4
  381. package/dist/features/orders/schemas/index.d.ts +8 -8
  382. package/dist/features/orders/types/index.d.ts +2 -2
  383. package/dist/features/payments/repository/payments.repository.js +2 -2
  384. package/dist/features/payments/repository/payout.repository.d.ts +23 -6
  385. package/dist/features/payments/repository/payout.repository.js +63 -23
  386. package/dist/features/payments/repository/saved-payment-methods.repository.d.ts +17 -6
  387. package/dist/features/payments/repository/saved-payment-methods.repository.js +59 -11
  388. package/dist/features/payments/schemas/firestore.d.ts +14 -3
  389. package/dist/features/payments/schemas/saved-methods-firestore.d.ts +12 -1
  390. package/dist/features/pre-orders/api/[slug]/route.js +1 -1
  391. package/dist/features/pre-orders/api/admin/route.js +1 -1
  392. package/dist/features/pre-orders/api/route.js +1 -1
  393. package/dist/features/pre-orders/repository/pre-orders.repository.d.ts +3 -3
  394. package/dist/features/pre-orders/repository/pre-orders.repository.js +6 -6
  395. package/dist/features/products/api/[id]/route.js +1 -1
  396. package/dist/features/products/components/ListingBottomActions.js +4 -0
  397. package/dist/features/products/components/ProductDetailPageView.js +2 -1
  398. package/dist/features/products/components/ProductGalleryClient.js +2 -2
  399. package/dist/features/products/components/ProductGrid.js +12 -1
  400. package/dist/features/products/components/index.d.ts +0 -2
  401. package/dist/features/products/components/index.js +0 -1
  402. package/dist/features/products/config/listing-type-listing-config.d.ts +0 -3
  403. package/dist/features/products/config/listing-type-listing-config.js +27 -2
  404. package/dist/features/products/constants/listing-tabs.d.ts +9 -0
  405. package/dist/features/products/constants/listing-tabs.js +3 -2
  406. package/dist/features/products/hooks/useProducts.js +2 -2
  407. package/dist/features/products/repository/products.repository.js +13 -1
  408. package/dist/features/products/schemas/index.d.ts +2 -2
  409. package/dist/features/products/types/index.d.ts +1 -1
  410. package/dist/features/promotions/api/route.js +1 -1
  411. package/dist/features/reviews/actions/review-actions.d.ts +6 -6
  412. package/dist/features/reviews/actions/review-actions.js +22 -8
  413. package/dist/features/reviews/components/ReviewDetailPageView.js +13 -1
  414. package/dist/features/reviews/components/ReviewsIndexPageView.js +21 -4
  415. package/dist/features/reviews/repository/reviews.repository.d.ts +19 -7
  416. package/dist/features/reviews/repository/reviews.repository.js +63 -12
  417. package/dist/features/reviews/schemas/firestore.d.ts +13 -2
  418. package/dist/features/reviews/schemas/index.d.ts +2 -2
  419. package/dist/features/scams/actions/scam-actions.js +16 -4
  420. package/dist/features/search/components/SearchResultsPageView.js +2 -1
  421. package/dist/features/search/hooks/useSearchIndex.d.ts +34 -0
  422. package/dist/features/search/hooks/useSearchIndex.js +172 -0
  423. package/dist/features/search/repository/search.repository.js +2 -2
  424. package/dist/features/seller/actions/offer-actions.d.ts +5 -5
  425. package/dist/features/seller/actions/offer-actions.js +38 -8
  426. package/dist/features/seller/actions/seller-actions.js +34 -7
  427. package/dist/features/seller/api/coupons/route.js +1 -1
  428. package/dist/features/seller/api/products/route.js +1 -1
  429. package/dist/features/seller/api/store/route.js +1 -1
  430. package/dist/features/seller/components/SellerBidsView.js +1 -1
  431. package/dist/features/seller/components/SellerCouponsView.js +1 -1
  432. package/dist/features/seller/components/SellerListingTypeView.js +9 -1
  433. package/dist/features/seller/components/SellerOrdersView.js +1 -1
  434. package/dist/features/seller/components/SellerPayoutSettingsView.js +0 -1
  435. package/dist/features/seller/components/SellerPayoutsView.js +1 -1
  436. package/dist/features/seller/components/SellerProductShell.js +0 -1
  437. package/dist/features/seller/components/SellerProductsView.js +1 -1
  438. package/dist/features/seller/components/SellerShippingView.js +0 -1
  439. package/dist/features/seller/components/SellerStorefrontView.js +0 -1
  440. package/dist/features/seller/components/index.d.ts +0 -4
  441. package/dist/features/seller/components/index.js +0 -2
  442. package/dist/features/seller/repository/offer.repository.d.ts +15 -3
  443. package/dist/features/seller/repository/offer.repository.js +43 -7
  444. package/dist/features/seller/schemas/firestore.d.ts +14 -3
  445. package/dist/features/seller/schemas/index.d.ts +4 -4
  446. package/dist/features/seller/schemas/order-forms.d.ts +39 -0
  447. package/dist/features/seller/schemas/order-forms.js +37 -0
  448. package/dist/features/shell/FormShell.js +6 -2
  449. package/dist/features/shell/QuickFormDrawer.js +15 -1
  450. package/dist/features/shipments/components/AdminShipmentEditorView.js +0 -1
  451. package/dist/features/shipments/components/AdminShipmentsView.js +1 -1
  452. package/dist/features/sticker-trace/components/StickerCommitPanel.d.ts +30 -0
  453. package/dist/features/sticker-trace/components/StickerCommitPanel.js +93 -0
  454. package/dist/features/sticker-trace/components/StickerPrintPanel.d.ts +33 -0
  455. package/dist/features/sticker-trace/components/StickerPrintPanel.js +104 -0
  456. package/dist/features/sticker-trace/components/StickerRetryPanel.d.ts +20 -0
  457. package/dist/features/sticker-trace/components/StickerRetryPanel.js +128 -0
  458. package/dist/features/sticker-trace/components/StickerRunHistoryPanel.d.ts +45 -0
  459. package/dist/features/sticker-trace/components/StickerRunHistoryPanel.js +84 -0
  460. package/dist/features/sticker-trace/components/StickerTraceStudio.d.ts +27 -0
  461. package/dist/features/sticker-trace/components/StickerTraceStudio.js +171 -0
  462. package/dist/features/sticker-trace/constants/help-content.d.ts +23 -0
  463. package/dist/features/sticker-trace/constants/help-content.js +172 -0
  464. package/dist/features/sticker-trace/hooks/useLiveTrace.d.ts +27 -0
  465. package/dist/features/sticker-trace/hooks/useLiveTrace.js +160 -0
  466. package/dist/features/sticker-trace/hooks/useStickerTraceProgress.d.ts +22 -0
  467. package/dist/features/sticker-trace/hooks/useStickerTraceProgress.js +106 -0
  468. package/dist/features/sticker-trace/repository/sticker-sheets.repository.d.ts +113 -0
  469. package/dist/features/sticker-trace/repository/sticker-sheets.repository.js +146 -0
  470. package/dist/features/sticker-trace/repository/sticker-trace-runs.repository.d.ts +132 -0
  471. package/dist/features/sticker-trace/repository/sticker-trace-runs.repository.js +174 -0
  472. package/dist/features/sticker-trace/schemas/firestore.d.ts +248 -0
  473. package/dist/features/sticker-trace/schemas/firestore.js +79 -0
  474. package/dist/features/sticker-trace/server.d.ts +8 -0
  475. package/dist/features/sticker-trace/server.js +51 -0
  476. package/dist/features/stores/actions/store-query-actions.d.ts +2 -2
  477. package/dist/features/stores/actions/store-query-actions.js +7 -2
  478. package/dist/features/stores/api/[storeSlug]/auctions/route.js +3 -3
  479. package/dist/features/stores/api/[storeSlug]/products/route.js +3 -3
  480. package/dist/features/stores/api/[storeSlug]/reviews/route.js +1 -1
  481. package/dist/features/stores/api/[storeSlug]/route.js +1 -1
  482. package/dist/features/stores/components/StoreNavTabs.js +17 -2
  483. package/dist/features/stores/manifest.js +8 -4
  484. package/dist/features/support/repository/support.repository.d.ts +14 -3
  485. package/dist/features/support/repository/support.repository.js +93 -13
  486. package/dist/features/support/schemas/firestore.d.ts +16 -5
  487. package/dist/features/tester/seed-data/authored/admin__events-raffles-spin.js +61 -19
  488. package/dist/features/tester/seed-data/authored/buying__browsing-search.js +19 -3
  489. package/dist/features/tester/seed-data/authored/content-discovery__authenticity-checker.d.ts +2 -0
  490. package/dist/features/tester/seed-data/authored/content-discovery__authenticity-checker.js +243 -0
  491. package/dist/features/tester/seed-data/authored/content-discovery__events.js +36 -10
  492. package/dist/features/tester/seed-data/authored/content-discovery__overflowing-pill-rows.d.ts +2 -0
  493. package/dist/features/tester/seed-data/authored/content-discovery__overflowing-pill-rows.js +209 -0
  494. package/dist/features/tester/seed-data/authored/design-ux__header-brand-mark-centring.d.ts +2 -0
  495. package/dist/features/tester/seed-data/authored/design-ux__header-brand-mark-centring.js +90 -0
  496. package/dist/features/tester/seed-data/authored/index.js +8 -0
  497. package/dist/features/tester/seed-data/authored/selling__media-limits.js +19 -17
  498. package/dist/features/tester/seed-data/authored/selling__product-upload-details.js +10 -5
  499. package/dist/features/tester/seed-data/authored/tools__sticker-tracer.d.ts +2 -0
  500. package/dist/features/tester/seed-data/authored/tools__sticker-tracer.js +283 -0
  501. package/dist/features/tester/seed-data/tester-checklist-seed-data.js +192 -22
  502. package/dist/index.d.ts +10 -23
  503. package/dist/index.js +27 -19
  504. package/dist/next/api/routeHandler.js +9 -0
  505. package/dist/next/routing/require-record.d.ts +13 -0
  506. package/dist/next/routing/require-record.js +62 -0
  507. package/dist/next/routing/route-map.d.ts +4 -4
  508. package/dist/next/routing/route-map.js +25 -3
  509. package/dist/providers/db-firebase/base.d.ts +4 -2
  510. package/dist/providers/db-firebase/base.js +21 -5
  511. package/dist/providers/db-firebase/base.repository.d.ts +11 -9
  512. package/dist/providers/db-firebase/base.repository.js +19 -0
  513. package/dist/providers/db-firebase/rtdb-paths.d.ts +12 -0
  514. package/dist/providers/db-firebase/rtdb-paths.js +12 -0
  515. package/dist/react/ErrorBoundary.js +6 -1
  516. package/dist/react/hooks/realtime-event-constants.d.ts +1 -0
  517. package/dist/react/hooks/realtime-event-constants.js +8 -0
  518. package/dist/react/hooks/useEntityDelete.js +5 -1
  519. package/dist/react/hooks/useMessage.js +5 -1
  520. package/dist/repositories/index.d.ts +2 -2
  521. package/dist/repositories/index.js +6 -1
  522. package/dist/schemas/registry.d.ts +13 -20
  523. package/dist/schemas/registry.js +31 -14
  524. package/dist/schemas/webhooks/google-oauth.d.ts +2 -2
  525. package/dist/security/encrypted.d.ts +117 -0
  526. package/dist/security/encrypted.js +100 -0
  527. package/dist/security/index.d.ts +5 -2
  528. package/dist/security/index.js +16 -2
  529. package/dist/security/pii-accessors.d.ts +71 -0
  530. package/dist/security/pii-accessors.js +150 -0
  531. package/dist/security/pii-encrypt.d.ts +0 -8
  532. package/dist/security/pii-encrypt.js +22 -15
  533. package/dist/security/pii-mask.d.ts +18 -0
  534. package/dist/security/pii-mask.js +27 -0
  535. package/dist/seed/_helpers/search-txt-wrappers.d.ts +6 -6
  536. package/dist/seed/_helpers/search-txt-wrappers.js +22 -0
  537. package/dist/seed/addresses-seed-data.d.ts +2 -2
  538. package/dist/seed/authenticity-knowledge-seed-data.d.ts +34 -0
  539. package/dist/seed/authenticity-knowledge-seed-data.js +1277 -0
  540. package/dist/seed/bids-seed-data.d.ts +2 -2
  541. package/dist/seed/bids-seed-data.js +23 -2
  542. package/dist/seed/events-seed-data.d.ts +2 -2
  543. package/dist/seed/events-seed-data.js +5 -0
  544. package/dist/seed/faq-seed-data.js +175 -5
  545. package/dist/seed/homepage-sections-seed-data.js +39 -23
  546. package/dist/seed/index.d.ts +1 -0
  547. package/dist/seed/index.js +1 -0
  548. package/dist/seed/lottery-entries-seed-data.d.ts +2 -2
  549. package/dist/seed/offers-seed-data.d.ts +2 -2
  550. package/dist/seed/offers-seed-data.js +1 -1
  551. package/dist/seed/orders-seed-data.d.ts +2 -2
  552. package/dist/seed/payouts-seed-data.d.ts +2 -2
  553. package/dist/seed/payouts-seed-data.js +1 -1
  554. package/dist/seed/reviews-seed-data.d.ts +1 -2
  555. package/dist/seed/seed-purpose.js +7 -0
  556. package/dist/seed/sessions-seed-data.d.ts +2 -2
  557. package/dist/seed/sessions-seed-data.js +5 -0
  558. package/dist/seed/site-settings-seed-data.js +1 -1
  559. package/dist/seed/support-tickets-seed-data.d.ts +2 -2
  560. package/dist/seed/support-tickets-seed-data.js +1 -1
  561. package/dist/seed/users-seed-data.d.ts +2 -2
  562. package/dist/seed/users-seed-data.js +1 -1
  563. package/dist/seo/json-ld.js +5 -1
  564. package/dist/server.d.ts +18 -3
  565. package/dist/server.js +59 -3
  566. package/dist/styles.css +237 -1
  567. package/dist/tailwind-utilities.css +1 -1
  568. package/dist/ui/components/Button.js +7 -1
  569. package/dist/ui/components/FilterChipGroup.d.ts +11 -0
  570. package/dist/ui/components/FilterChipGroup.js +1 -1
  571. package/dist/ui/components/ImageGallery.js +6 -1
  572. package/dist/ui/components/ListingLayout.js +14 -8
  573. package/dist/ui/components/OverflowRow.d.ts +92 -0
  574. package/dist/ui/components/OverflowRow.js +203 -0
  575. package/dist/ui/components/OverflowRow.style.css +235 -0
  576. package/dist/ui/components/RecordDetailModal.js +14 -1
  577. package/dist/ui/components/RowActionMenu.js +5 -1
  578. package/dist/ui/components/SideDrawer.js +5 -1
  579. package/dist/ui/components/SideModal.js +9 -1
  580. package/dist/ui/components/TabBarShell.d.ts +12 -1
  581. package/dist/ui/components/TabBarShell.js +3 -2
  582. package/dist/ui/components/Tabs.js +36 -24
  583. package/dist/ui/components/Toast.d.ts +3 -24
  584. package/dist/ui/components/Toast.js +2 -19
  585. package/dist/ui/components/TopBannerPortal.d.ts +15 -0
  586. package/dist/ui/components/TopBannerPortal.js +19 -0
  587. package/dist/ui/components/UnsavedChangesModal.js +5 -1
  588. package/dist/ui/components/index.style.css +1 -0
  589. package/dist/ui/components/row-collapse.d.ts +15 -0
  590. package/dist/ui/components/row-collapse.js +127 -0
  591. package/dist/ui/components/toast-context.d.ts +63 -0
  592. package/dist/ui/components/toast-context.js +48 -0
  593. package/dist/ui/components/top-banner-slot.d.ts +37 -0
  594. package/dist/ui/components/top-banner-slot.js +45 -0
  595. package/dist/ui/icons/icon-registry.d.ts +6 -0
  596. package/dist/ui/icons/icon-registry.js +17 -1
  597. package/dist/ui/index.d.ts +2 -0
  598. package/dist/ui/index.js +1 -0
  599. package/dist/utils/array.helper.d.ts +2 -2
  600. package/dist/utils/array.helper.js +5 -5
  601. package/dist/utils/id-generators.d.ts +6 -0
  602. package/dist/utils/id-generators.js +10 -0
  603. package/dist/utils/media-url.js +0 -2
  604. package/dist/utils/search-txt-builders.d.ts +28 -4
  605. package/dist/utils/search-txt-builders.js +41 -1
  606. package/dist/validation/schemas.d.ts +8 -8
  607. package/package.json +6 -2
  608. package/scripts/seed-cli.mjs +3 -0
  609. package/dist/features/account/components/UserAddressesView.d.ts +0 -13
  610. package/dist/features/account/components/UserAddressesView.js +0 -5
  611. package/dist/features/account/components/UserNotificationsView.d.ts +0 -15
  612. package/dist/features/account/components/UserNotificationsView.js +0 -12
  613. package/dist/features/account/components/UserSettingsView.d.ts +0 -16
  614. package/dist/features/account/components/UserSettingsView.js +0 -13
  615. package/dist/features/account/components/UserSupportView.d.ts +0 -3
  616. package/dist/features/account/components/UserSupportView.js +0 -166
  617. package/dist/features/admin/components/DemoSeedView.d.ts +0 -11
  618. package/dist/features/admin/components/DemoSeedView.js +0 -5
  619. package/dist/features/auth/components/AuthStatusPanel.d.ts +0 -10
  620. package/dist/features/auth/components/AuthStatusPanel.js +0 -22
  621. package/dist/features/categories/components/CategoryProductsView.d.ts +0 -45
  622. package/dist/features/categories/components/CategoryProductsView.js +0 -21
  623. package/dist/features/homepage/components/HowItWorksInfoView.d.ts +0 -36
  624. package/dist/features/homepage/components/HowItWorksInfoView.js +0 -10
  625. package/dist/features/layout/BottomActions.d.ts +0 -1
  626. package/dist/features/layout/BottomActions.js +0 -311
  627. package/dist/features/products/components/ProductsView.d.ts +0 -6
  628. package/dist/features/products/components/ProductsView.js +0 -5
  629. package/dist/features/seller/components/SellerStoreView.d.ts +0 -8
  630. package/dist/features/seller/components/SellerStoreView.js +0 -8
@@ -11,6 +11,13 @@ export declare const ALL_EVENT_TYPES: EventType[];
11
11
  */
12
12
  export declare const EVENT_TYPE_LABELS: Record<EventType, string>;
13
13
  export type RaffleType = "top_n_scorers" | "top_n_participants" | "open_raffle" | "spin_wheel";
14
+ /**
15
+ * A spin prize as STORED on the event document. `weight` IS the odds and
16
+ * `couponId` is an internal document id — neither may reach a browser.
17
+ *
18
+ * Authored by the admin editor, read by `assignSpinPrize`. For anything that
19
+ * renders, use `DisplaySpinPrize` below.
20
+ */
14
21
  export interface SpinPrize {
15
22
  id: string;
16
23
  label: string;
@@ -18,6 +25,27 @@ export interface SpinPrize {
18
25
  weight: number;
19
26
  isActive: boolean;
20
27
  }
28
+ /**
29
+ * A spin prize as a VIEW may see it: what it is, not what it is worth.
30
+ *
31
+ * 🛑 This exists because `SpinWheelView.prizes` was typed `SpinPrize[]`, which
32
+ * made `weight` and `couponId` REQUIRED of every caller — so handing the public
33
+ * wheel the full stored prize, odds included, was the only way to satisfy the
34
+ * compiler. The participate page duly cast the stored array straight into a
35
+ * `"use client"` prop and published the odds of every wheel (Root Cause #70).
36
+ *
37
+ * A rendering surface that demands the secret will be given the secret. The
38
+ * structural subset is the fix: `SpinPrize` is assignable to this, so the admin
39
+ * editor keeps passing stored prizes, while a client payload narrowed by
40
+ * `toClientSpinPrize` now satisfies it too — and re-adding `weight` to a
41
+ * client-bound type becomes a deliberate act rather than the path of least
42
+ * resistance.
43
+ */
44
+ export interface DisplaySpinPrize {
45
+ id: string;
46
+ label: string;
47
+ isActive?: boolean;
48
+ }
21
49
  export type EventStatus = "draft" | "active" | "paused" | "ended" | "cancelled";
22
50
  export declare const ALL_EVENT_STATUSES: EventStatus[];
23
51
  /** Dashboard display labels — see `EVENT_TYPE_LABELS`. */
@@ -172,6 +200,15 @@ export interface SpinResultEntry {
172
200
  spinPrizeId?: string;
173
201
  spinPrizeTitle?: string;
174
202
  spinWonAt?: string;
203
+ /**
204
+ * The coupon code the spin awarded, for the caller's OWN results only.
205
+ *
206
+ * 🛑 `getEventSpinResults` — the PUBLIC masked feed of everyone's recent
207
+ * spins — must never populate this. A coupon code is a bearer token: anyone
208
+ * who can read it can redeem it. Only `getUserSpinResultsForEvent`, which
209
+ * takes a `userId` the server supplies from a verified session, sets it.
210
+ */
211
+ spinPrizeCouponCode?: string;
175
212
  }
176
213
  export interface EventListResponse {
177
214
  items: EventItem[];
@@ -20,7 +20,7 @@ export class FAQsRepository {
20
20
  const result = await this.repo.findAll({
21
21
  filters: `isActive==true,category==${category}`,
22
22
  sort: "order",
23
- perPage: 100,
23
+ pageSize: 100,
24
24
  });
25
25
  return result.data;
26
26
  }
@@ -140,18 +140,21 @@ export declare const faqListParamsSchema: z.ZodObject<{
140
140
  homepage: z.ZodOptional<z.ZodBoolean>;
141
141
  q: z.ZodOptional<z.ZodString>;
142
142
  page: z.ZodOptional<z.ZodNumber>;
143
+ pageSize: z.ZodOptional<z.ZodNumber>;
143
144
  perPage: z.ZodOptional<z.ZodNumber>;
144
145
  }, "strip", z.ZodTypeAny, {
145
146
  page?: number | undefined;
146
147
  q?: string | undefined;
147
- perPage?: number | undefined;
148
+ pageSize?: number | undefined;
148
149
  category?: "orders_payment" | "shipping_delivery" | "returns_refunds" | "product_information" | "account_security" | "technical_support" | "general" | undefined;
150
+ perPage?: number | undefined;
149
151
  homepage?: boolean | undefined;
150
152
  }, {
151
153
  page?: number | undefined;
152
154
  q?: string | undefined;
153
- perPage?: number | undefined;
155
+ pageSize?: number | undefined;
154
156
  category?: "orders_payment" | "shipping_delivery" | "returns_refunds" | "product_information" | "account_security" | "technical_support" | "general" | undefined;
157
+ perPage?: number | undefined;
155
158
  homepage?: boolean | undefined;
156
159
  }>;
157
160
  export * from "./firestore";
@@ -57,6 +57,12 @@ export const faqListParamsSchema = z.object({
57
57
  homepage: z.coerce.boolean().optional(),
58
58
  q: z.string().optional(),
59
59
  page: z.coerce.number().optional(),
60
+ pageSize: z.coerce.number().optional(),
61
+ /*
62
+ * Accepted, never emitted — a link built before the `perPage` → `pageSize`
63
+ * rename. Same deliberate back-compat as `blogListParamsSchema`: this is a
64
+ * PUBLIC query parameter, so dropping it would 400 somebody's bookmark.
65
+ */
60
66
  perPage: z.coerce.number().optional(),
61
67
  });
62
68
  export * from "./firestore.js";
@@ -54,7 +54,6 @@ export interface FAQListParams {
54
54
  tags?: string[];
55
55
  showOnHomepage?: boolean;
56
56
  page?: number;
57
- perPage?: number;
58
57
  pageSize?: number;
59
58
  sorts?: string;
60
59
  }
@@ -38,7 +38,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
38
38
  import React from "react";
39
39
  import { useQuery } from "@tanstack/react-query";
40
40
  import { useRouter } from "next/navigation.js";
41
- import { Stack, Text, useToast } from "../../../ui/index.js";
41
+ import { EmptyState, Stack, Text, useToast } from "../../../ui/index.js";
42
42
  import { FieldSelect, FormShellContext, FormErrorSummary, applyZodIssues, useFormShellState, } from "../../../ui/forms/index.js";
43
43
  import { SectionForm, useSectionFormNav } from "../../shell/index.js";
44
44
  import { buildSectionsFromSchema } from "../../shell/build-sections.js";
@@ -134,7 +134,6 @@ export function GroupedListingEditorView({ scope, groupId, fixedStoreId, onSaved
134
134
  });
135
135
  React.useEffect(() => {
136
136
  validate(values);
137
- // eslint-disable-next-line react-hooks/exhaustive-deps
138
137
  }, [values, validate]);
139
138
  const handleSubmit = async () => {
140
139
  const parsed = groupedListingFormSchema.safeParse(values);
@@ -183,6 +182,22 @@ export function GroupedListingEditorView({ scope, groupId, fixedStoreId, onSaved
183
182
  if (isEdit && existing.isLoading) {
184
183
  return _jsx(Text, { color: "muted", children: "Loading\u2026" });
185
184
  }
185
+ /*
186
+ * 🛑 LOADING and MISSING are different states, and collapsing them is the
187
+ * defect `audit-admin-detail-notfound` exists for.
188
+ *
189
+ * Without this branch, an invented `groupId` fell through to the form below
190
+ * with every field at its empty default — a complete, saveable editor for a
191
+ * record that does not exist. `/admin/grouped-listings/zzzznope/edit` looked
192
+ * ready to Save, and the admin PATCH it would call is the one that used to
193
+ * silently drop every key but `productIds` (see this file's page header).
194
+ *
195
+ * Only reached once the query has SETTLED, so a slow fetch still shows
196
+ * "Loading…" rather than flashing "not found" at a record that is on its way.
197
+ */
198
+ if (isEdit && !existing.isLoading && !existing.data) {
199
+ return (_jsx(EmptyState, { title: "Grouped listing not found", description: "This group may have been deleted, or the link may be wrong." }));
200
+ }
186
201
  return (_jsxs(Stack, { gap: "md", children: [needsStorePicker ? (_jsx(FieldSelect, { name: "storeId", label: "Store", required: true, value: storeId, onChange: setStoreId, options: [
187
202
  { value: "", label: "Select a store…" },
188
203
  ...(stores.data ?? []).map((s) => ({
@@ -88,7 +88,7 @@ export const carouselItemPATCH = createRouteHandler({
88
88
  if (patch.active === true && !slide.active) {
89
89
  const active = await repo.findAll({
90
90
  filters: "active==true",
91
- perPage: MAX_ACTIVE_SLIDES + 1,
91
+ pageSize: MAX_ACTIVE_SLIDES + 1,
92
92
  });
93
93
  if (active.data.length >= MAX_ACTIVE_SLIDES) {
94
94
  return NextResponse.json({
@@ -59,7 +59,7 @@ export async function GET(request) {
59
59
  const result = await repo.findAll({
60
60
  sort: "order",
61
61
  order: "asc",
62
- perPage: 100,
62
+ pageSize: 100,
63
63
  });
64
64
  slides = result.data;
65
65
  }
@@ -68,7 +68,7 @@ export async function GET(request) {
68
68
  filters: "active==true",
69
69
  sort: "order",
70
70
  order: "asc",
71
- perPage: MAX_ACTIVE_SLIDES,
71
+ pageSize: MAX_ACTIVE_SLIDES,
72
72
  });
73
73
  slides = result.data.slice(0, MAX_ACTIVE_SLIDES);
74
74
  }
@@ -129,7 +129,7 @@ export const carouselPOST = createRouteHandler({
129
129
  // Guard: max 5 active slides
130
130
  const active = await repo.findAll({
131
131
  filters: "active==true",
132
- perPage: MAX_ACTIVE_SLIDES + 1,
132
+ pageSize: MAX_ACTIVE_SLIDES + 1,
133
133
  });
134
134
  const incoming = body;
135
135
  if (incoming.active !== false && active.data.length >= MAX_ACTIVE_SLIDES) {
@@ -141,7 +141,7 @@ export const carouselPOST = createRouteHandler({
141
141
  const existing = await repo.findAll({
142
142
  sort: "order",
143
143
  order: "desc",
144
- perPage: 1,
144
+ pageSize: 1,
145
145
  });
146
146
  const maxOrder = existing.data[0]?.order ?? -1;
147
147
  const now = new Date().toISOString();
@@ -61,7 +61,7 @@ export async function GET(request) {
61
61
  filters: filterParts.join(",") || undefined,
62
62
  sort: "order",
63
63
  order: "asc",
64
- perPage: 50,
64
+ pageSize: 50,
65
65
  });
66
66
  const sections = result.data.sort((a, b) => (a.order ?? 0) - (b.order ?? 0));
67
67
  const res = NextResponse.json({ success: true, data: sections });
@@ -124,7 +124,7 @@ export const POST = createRouteHandler({
124
124
  const existing = await repo.findAll({
125
125
  sort: "order",
126
126
  order: "desc",
127
- perPage: 1,
127
+ pageSize: 1,
128
128
  });
129
129
  const maxOrder = existing.data[0]?.order ?? -1;
130
130
  const now = new Date().toISOString();
@@ -33,7 +33,7 @@ export async function GET(request) {
33
33
  filters,
34
34
  sort,
35
35
  page,
36
- perPage: pageSize,
36
+ pageSize: pageSize,
37
37
  });
38
38
  const totalPages = Math.max(1, Math.ceil(result.total / pageSize));
39
39
  return NextResponse.json({
@@ -11,13 +11,5 @@ export interface AnnouncementBarProps {
11
11
  className?: string;
12
12
  /** Called when the user dismisses — consumer wires this to a server action to persist. */
13
13
  onDismiss?: (hash: string) => void;
14
- /**
15
- * Renders as a translucent, backdrop-blurred strip pinned to the top edge
16
- * of the nearest positioned ancestor, instead of the default full-bleed
17
- * in-flow bar. Used on the homepage to overlay the banner over the first
18
- * section (e.g. the Welcome hero) rather than pushing it down with extra
19
- * vertical space.
20
- */
21
- overlay?: boolean;
22
14
  }
23
- export declare function AnnouncementBar({ message, link, className, onDismiss, overlay }: AnnouncementBarProps): React.JSX.Element | null;
15
+ export declare function AnnouncementBar({ message, link, className, onDismiss }: AnnouncementBarProps): React.JSX.Element | null;
@@ -38,7 +38,7 @@ function saveLocalDismissal(message) {
38
38
  void normalizeError(_err); /* quota exceeded — ignore */
39
39
  }
40
40
  }
41
- export function AnnouncementBar({ message, link, className = "", onDismiss, overlay = false }) {
41
+ export function AnnouncementBar({ message, link, className = "", onDismiss }) {
42
42
  const { user } = useAuth();
43
43
  const bannerHash = hashBannerMessage(message);
44
44
  const userAlreadyDismissed = !!user?.dismissedBannerHash && user.dismissedBannerHash === bannerHash;
@@ -56,32 +56,26 @@ export function AnnouncementBar({ message, link, className = "", onDismiss, over
56
56
  if (dismissed)
57
57
  return null;
58
58
  /*
59
- * 🛑 THE OVERLAY IS md AND UP ONLY — IT PAINTED OVER THE HERO HEADING ON
60
- * EVERY PHONE WIDTH.
59
+ * 🛑 THE `overlay` PROP IS GONE — DO NOT REINTRODUCE IT.
61
60
  *
62
- * `absolute` reserves no space, which is the whole point of the overlay: the
63
- * hero's own top padding is sized to sit a ONE-LINE banner over it. A real
64
- * announcement wraps on a narrow screen, grows downward, and there is
65
- * nothing to stop it.
66
- *
67
- * Measured on production against the live announcement, against the <h1>:
61
+ * It rendered this bar `absolute inset-x-0 top-0` over the homepage's first
62
+ * section, which reserves no space by design. A banner that reserves no space
63
+ * paints on whatever is beneath it the moment it is taller than the padding
64
+ * someone sized for it. Measured on production against the hero <h1>:
68
65
  *
69
66
  * 320px → 30px overlap 768px → 10px clear
70
67
  * 390px → 10px overlap 1280px → 10px clear
71
68
  * 430px → 10px overlap
72
69
  *
73
- * So it was every phone width and no tablet or desktop width — which is why
74
- * it survived: the breakpoints people check it at are the ones where the
75
- * message still fits on one line.
70
+ * That was patched once by making the overlay `md:` and up, which fixed the
71
+ * phone widths and left the mechanism in place — a one-line message at a
72
+ * width nobody checks is one long announcement away from the same bug.
76
73
  *
77
- * Below `md` it is an ordinary in-flow bar that pushes the hero down, with a
78
- * SOLID background (the translucent + blur treatment only reads as
79
- * deliberate when there is artwork behind it). From `md` up, the designed
80
- * overlay is unchanged.
74
+ * The bar now renders in normal flow, portalled above the sticky header via
75
+ * `TopBannerPortal`. It pushes the page down by exactly its own height at
76
+ * every width, so there is nothing to overlap and no breakpoint to tune.
81
77
  */
82
- const positionCls = overlay
83
- ? "relative md:absolute inset-x-0 top-0 z-20 bg-primary-700 md:bg-primary-700/85 md:backdrop-blur-sm"
84
- : "relative left-1/2 right-1/2 w-screen -translate-x-1/2 bg-primary-700";
78
+ const positionCls = "relative w-full bg-primary-700";
85
79
  return (_jsx(Div, { className: `${positionCls} transition-opacity duration-200 ${mounted ? "opacity-100" : "opacity-0"} ${className}`, role: "banner", children: _jsx(Div, { paddingX: "x-page", className: "container mx-auto max-w-[1920px]", children: _jsxs(Row, { textWeight: "medium", textSize: "sm", className: "relative text-left text-white", padding: "y-xs", align: "center", justify: "start", children: [link ? (_jsx(TextLink, { href: link, className: "text-white underline", children: message })) : (_jsx(Span, { children: message })), _jsx(IconButton, { type: "button", onClick: () => {
86
80
  saveLocalDismissal(message);
87
81
  onDismiss?.(bannerHash);
@@ -2,6 +2,11 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { sieveFilter, SIEVE_OP } from "@mohasinac/appkit";
3
3
  import { sortBy } from "@mohasinac/appkit";
4
4
  import { Div, Main } from "../../../ui/index.js";
5
+ // Deep import, not the `ui` barrel and not `@mohasinac/appkit/client`: this is a
6
+ // Server Component, so a runtime value from the client entry would arrive as a
7
+ // client-reference proxy (Root Cause #76). Rendering it as JSX is the supported
8
+ // boundary; importing it from its defining module is Root Cause #18.
9
+ import { TopBannerPortal } from "../../../ui/components/TopBannerPortal.js";
5
10
  import { carouselRepository } from "../../../repositories/index.js";
6
11
  // Both are React.cache wrappers around a single repository call, shared with
7
12
  // other readers in the same request tree (the locale layout for settings,
@@ -185,5 +190,5 @@ export async function MarketplaceHomepageView({ adSlots, newsletterFormSlot, onB
185
190
  : undefined,
186
191
  };
187
192
  const carouselSlides = toCarouselSlides(slides);
188
- return (_jsx(Main, { children: _jsxs(Div, { className: "relative", children: [showAnnouncement ? (_jsx(AnnouncementBar, { overlay: true, message: announcementMessage, link: siteSettings?.announcementBar?.link, onDismiss: onBannerDismiss })) : null, orderedSections.map((section) => renderSection(section, adSlots, newsletterFormSlot ?? null, faqItems, carouselSlides, liveStats, sectionData, brand))] }) }));
193
+ return (_jsx(Main, { children: _jsxs(Div, { className: "relative", children: [showAnnouncement ? (_jsx(TopBannerPortal, { children: _jsx(AnnouncementBar, { message: announcementMessage, link: siteSettings?.announcementBar?.link, onDismiss: onBannerDismiss }) })) : null, orderedSections.map((section) => renderSection(section, adSlots, newsletterFormSlot ?? null, faqItems, carouselSlides, liveStats, sectionData, brand))] }) }));
189
194
  }
@@ -50,8 +50,6 @@ export { WhatsAppCommunitySection } from "./WhatsAppCommunitySection";
50
50
  export { HomepageSkeleton } from "./HomepageSkeleton";
51
51
  export type { FeaturedResultItem, FeaturedResultsSectionProps, } from "./FeaturedResultsSection";
52
52
  export { FeaturedResultsSection } from "./FeaturedResultsSection";
53
- export type { HowItWorksInfoStep, HowItWorksInfoDetail, HowItWorksInfoViewProps, } from "./HowItWorksInfoView";
54
- export { HowItWorksInfoView } from "./HowItWorksInfoView";
55
53
  export type { AnnouncementBarProps } from "./AnnouncementBar";
56
54
  export { AnnouncementBar, hashBannerMessage } from "./AnnouncementBar";
57
55
  export type { ShopByCategorySectionProps } from "./ShopByCategorySection";
@@ -25,7 +25,6 @@ export { TrustIndicatorsSection } from "./TrustIndicatorsSection.js";
25
25
  export { WhatsAppCommunitySection } from "./WhatsAppCommunitySection.js";
26
26
  export { HomepageSkeleton } from "./HomepageSkeleton.js";
27
27
  export { FeaturedResultsSection } from "./FeaturedResultsSection.js";
28
- export { HowItWorksInfoView } from "./HowItWorksInfoView.js";
29
28
  export { AnnouncementBar, hashBannerMessage } from "./AnnouncementBar.js";
30
29
  export { ShopByCategorySection } from "./ShopByCategorySection.js";
31
30
  export { FeaturedProductsSection } from "./FeaturedProductsSection.js";
@@ -6,7 +6,7 @@ export class HomepageSectionsRepository {
6
6
  return this.repo.findAll({
7
7
  filters: "isVisible==true",
8
8
  sort: "order",
9
- perPage: 50,
9
+ pageSize: 50,
10
10
  ...query,
11
11
  });
12
12
  }
@@ -651,6 +651,12 @@ export interface EventRafflesSectionConfig {
651
651
  title?: string;
652
652
  subtitle?: string;
653
653
  maxItems?: number;
654
+ /**
655
+ * Which prize-event types the strip spans. The two concrete values are
656
+ * `EventType` members, matched against the `type` field — see
657
+ * `EventRafflesSection` for why `hasRaffle` was the wrong field and what it
658
+ * silently did instead.
659
+ */
654
660
  raffleType?: "raffle" | "spin_wheel" | "all";
655
661
  showEntryCount?: boolean;
656
662
  showCountdown?: boolean;
@@ -184,15 +184,15 @@ export declare const carouselCardSchema: z.ZodObject<{
184
184
  }, "strip", z.ZodTypeAny, {
185
185
  title?: string | undefined;
186
186
  description?: string | undefined;
187
- textAlign?: "center" | "left" | "right" | undefined;
188
187
  textColor?: string | undefined;
188
+ textAlign?: "center" | "left" | "right" | undefined;
189
189
  subtitle?: string | undefined;
190
190
  eyebrow?: string | undefined;
191
191
  }, {
192
192
  title?: string | undefined;
193
193
  description?: string | undefined;
194
- textAlign?: "center" | "left" | "right" | undefined;
195
194
  textColor?: string | undefined;
195
+ textAlign?: "center" | "left" | "right" | undefined;
196
196
  subtitle?: string | undefined;
197
197
  eyebrow?: string | undefined;
198
198
  }>>;
@@ -251,8 +251,8 @@ export declare const carouselCardSchema: z.ZodObject<{
251
251
  content?: {
252
252
  title?: string | undefined;
253
253
  description?: string | undefined;
254
- textAlign?: "center" | "left" | "right" | undefined;
255
254
  textColor?: string | undefined;
255
+ textAlign?: "center" | "left" | "right" | undefined;
256
256
  subtitle?: string | undefined;
257
257
  eyebrow?: string | undefined;
258
258
  } | undefined;
@@ -292,8 +292,8 @@ export declare const carouselCardSchema: z.ZodObject<{
292
292
  content?: {
293
293
  title?: string | undefined;
294
294
  description?: string | undefined;
295
- textAlign?: "center" | "left" | "right" | undefined;
296
295
  textColor?: string | undefined;
296
+ textAlign?: "center" | "left" | "right" | undefined;
297
297
  subtitle?: string | undefined;
298
298
  eyebrow?: string | undefined;
299
299
  } | undefined;
@@ -524,15 +524,15 @@ export declare const carouselSlideFirestoreSchema: z.ZodObject<{
524
524
  }, "strip", z.ZodTypeAny, {
525
525
  title?: string | undefined;
526
526
  description?: string | undefined;
527
- textAlign?: "center" | "left" | "right" | undefined;
528
527
  textColor?: string | undefined;
528
+ textAlign?: "center" | "left" | "right" | undefined;
529
529
  subtitle?: string | undefined;
530
530
  eyebrow?: string | undefined;
531
531
  }, {
532
532
  title?: string | undefined;
533
533
  description?: string | undefined;
534
- textAlign?: "center" | "left" | "right" | undefined;
535
534
  textColor?: string | undefined;
535
+ textAlign?: "center" | "left" | "right" | undefined;
536
536
  subtitle?: string | undefined;
537
537
  eyebrow?: string | undefined;
538
538
  }>>;
@@ -591,8 +591,8 @@ export declare const carouselSlideFirestoreSchema: z.ZodObject<{
591
591
  content?: {
592
592
  title?: string | undefined;
593
593
  description?: string | undefined;
594
- textAlign?: "center" | "left" | "right" | undefined;
595
594
  textColor?: string | undefined;
595
+ textAlign?: "center" | "left" | "right" | undefined;
596
596
  subtitle?: string | undefined;
597
597
  eyebrow?: string | undefined;
598
598
  } | undefined;
@@ -632,8 +632,8 @@ export declare const carouselSlideFirestoreSchema: z.ZodObject<{
632
632
  content?: {
633
633
  title?: string | undefined;
634
634
  description?: string | undefined;
635
- textAlign?: "center" | "left" | "right" | undefined;
636
635
  textColor?: string | undefined;
636
+ textAlign?: "center" | "left" | "right" | undefined;
637
637
  subtitle?: string | undefined;
638
638
  eyebrow?: string | undefined;
639
639
  } | undefined;
@@ -771,8 +771,8 @@ export declare const carouselSlideFirestoreSchema: z.ZodObject<{
771
771
  content?: {
772
772
  title?: string | undefined;
773
773
  description?: string | undefined;
774
- textAlign?: "center" | "left" | "right" | undefined;
775
774
  textColor?: string | undefined;
775
+ textAlign?: "center" | "left" | "right" | undefined;
776
776
  subtitle?: string | undefined;
777
777
  eyebrow?: string | undefined;
778
778
  } | undefined;
@@ -880,8 +880,8 @@ export declare const carouselSlideFirestoreSchema: z.ZodObject<{
880
880
  content?: {
881
881
  title?: string | undefined;
882
882
  description?: string | undefined;
883
- textAlign?: "center" | "left" | "right" | undefined;
884
883
  textColor?: string | undefined;
884
+ textAlign?: "center" | "left" | "right" | undefined;
885
885
  subtitle?: string | undefined;
886
886
  eyebrow?: string | undefined;
887
887
  } | undefined;
@@ -8,6 +8,17 @@ export interface AppLayoutShellSidebarLink {
8
8
  label: string;
9
9
  /** Optional icon rendered before the label (emoji string or ReactNode). */
10
10
  icon?: React.ReactNode;
11
+ /**
12
+ * Sub-links, rendered indented beneath this one.
13
+ *
14
+ * 🛑 This mirrors the top navbar's dropdown, and it exists for the same
15
+ * reason the navbar's does: the sidebar and the mobile sheet are built from
16
+ * the SAME nav items, so a parent that gained children in the navbar would
17
+ * otherwise silently lose every one of them here — the merge would read as a
18
+ * deletion on exactly the surface phones use. One level only, matching
19
+ * `NavbarLayoutItem`.
20
+ */
21
+ children?: AppLayoutShellSidebarLink[];
11
22
  }
12
23
  export interface AppLayoutShellSidebarSection {
13
24
  title?: string;
@@ -5,6 +5,7 @@ import { useCallback, useEffect, useRef, useState } from "react";
5
5
  // owns the singleton; nesting another would risk Turbopack chunk-splitting.
6
6
  // The actual 2.8.8 SSR crash was a peer-dep duplicate fixed by the
7
7
  // scripts/dedupe-peer-deps.mjs postinstall hook (see scripts/ and CLAUDE.md #19).
8
+ import { ChevronDown } from "lucide-react";
8
9
  import { AvatarDisplay, BackgroundRenderer, Div, Li, Main, Row, Span, Stack, Text, TextLink, Ul, UnsavedChangesModal } from "../../ui/index.js";
9
10
  // Role indicator dots — distinct hues per role tier.
10
11
  const ROLE_DOT_BG_CLASS = {
@@ -18,7 +19,7 @@ import { useAuth } from "../../react/contexts/SessionContext.js";
18
19
  import { useVisualViewportInset } from "../../react/hooks/useVisualViewportInset.js";
19
20
  import { isBuyerUser } from "../auth/role-predicates.js";
20
21
  import { NavbarWithSettings } from "./NavbarWithSettings.js";
21
- import BottomActions from "./BottomActions.js";
22
+ import SideActionDock from "./SideActionDock.js";
22
23
  import { BottomChrome } from "./BottomChrome.js";
23
24
  import { AutoBreadcrumbs } from "./AutoBreadcrumbs.js";
24
25
  import { BottomNavbar } from "./BottomNavbar.js";
@@ -27,6 +28,7 @@ import { SidebarLayout } from "./SidebarLayout.js";
27
28
  import { TitleBar } from "./TitleBar.js";
28
29
  import { BackToTop } from "./BackToTop.js";
29
30
  import { useDashboardNav } from "./DashboardNavContext.js";
31
+ import { TOP_BANNER_SLOT_ID } from "../../ui/components/top-banner-slot.js";
30
32
  import { usePathname } from "next/navigation.js";
31
33
  import { findActiveNavItem } from "../../_internal/client/features/layout/navActive.js";
32
34
  import { OVERLAY_FALLBACK_COLOR, SEED_DARK_BG as DEFAULT_DARK_BG, SEED_LIGHT_BG as DEFAULT_LIGHT_BG } from "./background-seed-defaults.js";
@@ -44,8 +46,64 @@ function CollapsibleNavGroup({ title, hasActive = false, children, }) {
44
46
  }, [hasActive]);
45
47
  return (_jsxs(Stack, { gap: "none", className: "", children: [_jsxs("button", { type: "button", onClick: () => setOpen((v) => !v), className: "flex w-full items-center justify-between px-[var(--appkit-space-1)] py-[var(--appkit-space-1)] text-[length:var(--appkit-text-xs)] font-semibold uppercase tracking-wider text-[var(--appkit-color-text-muted)] hover:text-[var(--appkit-color-text-muted)] transition-colors", children: [_jsx(Span, { children: title }), _jsx("svg", { className: `w-3.5 h-3.5 transition-transform duration-200 ${open ? "rotate-180" : ""} shrink-0`, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", "aria-hidden": "true", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 9l-7 7-7-7" }) })] }), open && _jsx(Stack, { gap: "none", className: "", children: children })] }));
46
48
  }
49
+ /**
50
+ * Flatten a sidebar section's links for active-item resolution.
51
+ *
52
+ * 🛑 Children MUST be in here. `findActiveNavItem` picks the longest prefix
53
+ * match, so leaving them out means a page that is only reachable as a child —
54
+ * /auctions under "Products" — marks nothing at all, the same lost-your-place
55
+ * bug the navbar's own comment documents.
56
+ */
57
+ function flattenSidebarLinks(items) {
58
+ return items.flatMap((item) => [item, ...(item.children ?? [])]);
59
+ }
60
+ /**
61
+ * A sidebar link that owns sub-links: FIRST tap expands, SECOND tap follows.
62
+ *
63
+ * 🛑 The second tap is what keeps this a link rather than a folder. A parent
64
+ * that only ever toggles makes its own page unreachable from the sidebar — the
65
+ * catalogue index would be the one shop page you could not open from the menu
66
+ * that lists the shop. So the destination is the parent's own href, falling
67
+ * back to its first child when the parent is a grouping with no page of its
68
+ * own, and `preventDefault` applies only on the expanding tap.
69
+ *
70
+ * It differs from the navbar on purpose: there, hover already reveals the menu,
71
+ * so a click can navigate immediately. A sidebar has no hover, and a thumb has
72
+ * no caret small enough to aim at reliably — the tap has to do both jobs, in
73
+ * order.
74
+ */
75
+ function SidebarParentLink({ item, activeItem, activeHref, navItemClass, navItemActiveClass, }) {
76
+ const children = item.children ?? [];
77
+ const containsActive = !!activeItem && children.some((child) => child.href === activeItem.href);
78
+ const [expanded, setExpanded] = useState(containsActive);
79
+ // The sidebar stays mounted across client-side navigation, so the lazy
80
+ // initial state above only ever fires once — re-open when the route moves
81
+ // into this group.
82
+ useEffect(() => {
83
+ if (containsActive)
84
+ setExpanded(true);
85
+ }, [containsActive]);
86
+ const isActive = activeItem?.href === item.href;
87
+ const target = item.href || children[0]?.href || "#";
88
+ return (_jsxs(Li, { children: [_jsxs(TextLink, { href: target, variant: "none", className: isActive ? navItemActiveClass : navItemClass, "aria-current": isActive ? "page" : undefined, "aria-expanded": expanded, onClick: (e) => {
89
+ if (expanded)
90
+ return;
91
+ e.preventDefault();
92
+ setExpanded(true);
93
+ }, children: [item.icon && (_jsx(Span, { className: "flex-shrink-0 w-5 text-center", "aria-hidden": "true", children: item.icon })), item.label, _jsx(ChevronDown, { className: `ms-auto w-3.5 h-3.5 shrink-0 opacity-70 transition-transform duration-200 ${expanded ? "rotate-180" : ""}`, "aria-hidden": "true" })] }), expanded && (_jsx(SidebarSectionLinks, { items: children, activeHref: activeHref, activeItem: activeItem, navItemClass: navItemClass, navItemActiveClass: navItemActiveClass, nested: true }))] }));
94
+ }
95
+ /** One sidebar link plus its indented sub-links. */
96
+ function SidebarSectionLinks({ items, activeHref, activeItem, navItemClass, navItemActiveClass, nested = false, }) {
97
+ return (_jsx(Ul, { spacing: "2xs", className: nested ? "ps-[var(--appkit-space-6)]" : undefined, children: items.map((item) => {
98
+ const isActive = activeItem?.href === item.href;
99
+ if (item.children && item.children.length > 0) {
100
+ return (_jsx(SidebarParentLink, { item: item, activeItem: activeItem, activeHref: activeHref, navItemClass: navItemClass, navItemActiveClass: navItemActiveClass }, `${item.href}-${item.label}`));
101
+ }
102
+ return (_jsx(Li, { children: _jsxs(TextLink, { href: item.href, variant: "none", className: isActive ? navItemActiveClass : navItemClass, "aria-current": isActive ? "page" : undefined, children: [item.icon && (_jsx(Span, { className: "flex-shrink-0 w-5 text-center", "aria-hidden": "true", children: item.icon })), item.label] }) }, `${item.href}-${item.label}`));
103
+ }) }));
104
+ }
47
105
  function CollapsibleSidebarSection({ section, navItemClass, navItemActiveClass, activeHref, }) {
48
- const activeItem = findActiveNavItem(section.items, activeHref);
106
+ const activeItem = findActiveNavItem(flattenSidebarLinks(section.items), activeHref);
49
107
  const hasActive = !!activeItem;
50
108
  const [open, setOpen] = useState((section.defaultOpen ?? false) || hasActive);
51
109
  // Re-sync whenever the route changes — the sidebar stays mounted across
@@ -56,15 +114,9 @@ function CollapsibleSidebarSection({ section, navItemClass, navItemActiveClass,
56
114
  }, [hasActive]);
57
115
  const hasTitle = !!section.title;
58
116
  if (!hasTitle) {
59
- return (_jsx(Ul, { spacing: "2xs", children: section.items.map((item) => {
60
- const isActive = activeItem?.href === item.href;
61
- return (_jsx(Li, { children: _jsxs(TextLink, { href: item.href, variant: "none", className: isActive ? navItemActiveClass : navItemClass, "aria-current": isActive ? "page" : undefined, children: [item.icon && (_jsx(Span, { className: "flex-shrink-0 w-5 text-center", "aria-hidden": "true", children: item.icon })), item.label] }) }, `${item.href}-${item.label}`));
62
- }) }));
117
+ return (_jsx(SidebarSectionLinks, { items: section.items, activeHref: activeHref, activeItem: activeItem, navItemClass: navItemClass, navItemActiveClass: navItemActiveClass }));
63
118
  }
64
- return (_jsxs(Stack, { gap: "none", className: "", children: [_jsxs("button", { type: "button", onClick: () => setOpen((v) => !v), className: "flex w-full items-center justify-between px-[var(--appkit-space-1)] py-[var(--appkit-space-1)] text-[length:var(--appkit-text-xs)] font-semibold uppercase tracking-wider text-[var(--appkit-color-text-muted)] hover:text-[var(--appkit-color-text-muted)] transition-colors", children: [_jsx(Span, { children: section.title }), _jsx("svg", { className: `w-3.5 h-3.5 transition-transform duration-200 ${open ? "rotate-180" : ""} shrink-0`, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", "aria-hidden": "true", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 9l-7 7-7-7" }) })] }), open && (_jsx(Ul, { spacing: "2xs", children: section.items.map((item) => {
65
- const isActive = activeItem?.href === item.href;
66
- return (_jsx(Li, { children: _jsxs(TextLink, { href: item.href, variant: "none", className: isActive ? navItemActiveClass : navItemClass, "aria-current": isActive ? "page" : undefined, children: [item.icon && (_jsx(Span, { className: "flex-shrink-0 w-5 text-center", "aria-hidden": "true", children: item.icon })), item.label] }) }, `${item.href}-${item.label}`));
67
- }) }))] }));
119
+ return (_jsxs(Stack, { gap: "none", className: "", children: [_jsxs("button", { type: "button", onClick: () => setOpen((v) => !v), className: "flex w-full items-center justify-between px-[var(--appkit-space-1)] py-[var(--appkit-space-1)] text-[length:var(--appkit-text-xs)] font-semibold uppercase tracking-wider text-[var(--appkit-color-text-muted)] hover:text-[var(--appkit-color-text-muted)] transition-colors", children: [_jsx(Span, { children: section.title }), _jsx("svg", { className: `w-3.5 h-3.5 transition-transform duration-200 ${open ? "rotate-180" : ""} shrink-0`, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", "aria-hidden": "true", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 9l-7 7-7-7" }) })] }), open && (_jsx(SidebarSectionLinks, { items: section.items, activeHref: activeHref, activeItem: activeItem, navItemClass: navItemClass, navItemActiveClass: navItemActiveClass }))] }));
68
120
  }
69
121
  /** Sidebar header when a user is logged in — avatar + display name + close button. */
70
122
  function SidebarUserHeader({ user, onClose, }) {
@@ -194,7 +246,7 @@ export function AppLayoutShell({ children, navItems, sidebarItems = [], sidebarS
194
246
  opacity: darkBackground.overlay?.opacity ?? 0,
195
247
  },
196
248
  };
197
- return (_jsx(_Fragment, { children: _jsxs(Stack, { className: "min-h-screen w-full overflow-x-clip transition-colors duration-300", children: [_jsx(BackgroundRenderer, { mode: theme === "dark" ? "dark" : "light", lightMode: normalizedLightBackground, darkMode: normalizedDarkBackground }), _jsxs(Div, { ref: headerRef, className: "sticky top-0 z-50 w-full", children: [_jsx(TitleBar, { onToggleSidebar: handleTogglePublicSidebar, sidebarOpen: sidebarOpen, onSearchToggle: () => setSearchOpen((prev) => !prev), searchOpen: searchOpen, brandName: brandName, brandShortName: brandShortName, siteLogoUrl: siteLogoUrl, logoHref: logoHref, promotionsHref: promotionsHref, cartHref: cartHref, wishlistHref: wishlistHref, messagesHref: messagesHref, unreadMessageCount: unreadMessageCount, userId: userId, profileHref: profileHref, loginHref: loginHref, registerHref: registerHref, user: user, navSlot: titleBarNavSlot, notificationSlot: titleBarNotificationSlot, devSlot: titleBarDevSlot, promoStripText: titleBarPromoStripText, isDark: theme === "dark", onToggleTheme: showThemeToggle ? toggleTheme : undefined, onBeforeToggleDashboardNav: handleBeforeDashboardNavToggle, suppressDashboardNav: suppressDashboardNav, hideSidebarToggle: hideSidebarToggle }), _jsx(NavbarWithSettings, { navItems: navItems, hiddenNavItems: hiddenNavItems, permissions: authUser?.permissions }), searchOpen && (searchSlotRenderer ? searchSlotRenderer(() => setSearchOpen(false)) : searchSlot), eventBannerSlot] }), _jsx(AutoBreadcrumbs, {}), _jsxs(Div, { layout: "flex", className: "relative w-full flex-1 overflow-x-clip", children: [_jsx(SidebarLayout, { isOpen: sidebarOpen, ariaLabel: "Secondary navigation", header: user ? (_jsx(SidebarUserHeader, { user: user, onClose: () => setSidebarOpen(false) })) : (_jsx(SidebarGuestHeader, { sidebarTitle: sidebarTitle, onClose: () => setSidebarOpen(false) })), onClose: () => setSidebarOpen(false), children: sidebarContent }), _jsx(Main, { id: "main-content",
249
+ return (_jsx(_Fragment, { children: _jsxs(Stack, { className: "min-h-screen w-full overflow-x-clip transition-colors duration-300", children: [_jsx(BackgroundRenderer, { mode: theme === "dark" ? "dark" : "light", lightMode: normalizedLightBackground, darkMode: normalizedDarkBackground }), _jsx(Div, { id: TOP_BANNER_SLOT_ID, className: "w-full" }), _jsxs(Div, { ref: headerRef, className: "sticky top-0 z-50 w-full", children: [_jsx(TitleBar, { onToggleSidebar: handleTogglePublicSidebar, sidebarOpen: sidebarOpen, onSearchToggle: () => setSearchOpen((prev) => !prev), searchOpen: searchOpen, brandName: brandName, brandShortName: brandShortName, siteLogoUrl: siteLogoUrl, logoHref: logoHref, promotionsHref: promotionsHref, cartHref: cartHref, wishlistHref: wishlistHref, messagesHref: messagesHref, unreadMessageCount: unreadMessageCount, userId: userId, profileHref: profileHref, loginHref: loginHref, registerHref: registerHref, user: user, navSlot: titleBarNavSlot, notificationSlot: titleBarNotificationSlot, devSlot: titleBarDevSlot, promoStripText: titleBarPromoStripText, isDark: theme === "dark", onToggleTheme: showThemeToggle ? toggleTheme : undefined, onBeforeToggleDashboardNav: handleBeforeDashboardNavToggle, suppressDashboardNav: suppressDashboardNav, hideSidebarToggle: hideSidebarToggle }), _jsx(NavbarWithSettings, { navItems: navItems, hiddenNavItems: hiddenNavItems, permissions: authUser?.permissions }), searchOpen && (searchSlotRenderer ? searchSlotRenderer(() => setSearchOpen(false)) : searchSlot), eventBannerSlot] }), _jsx(AutoBreadcrumbs, {}), _jsxs(Div, { layout: "flex", className: "relative w-full flex-1 overflow-x-clip", children: [_jsx(SidebarLayout, { isOpen: sidebarOpen, ariaLabel: "Secondary navigation", header: user ? (_jsx(SidebarUserHeader, { user: user, onClose: () => setSidebarOpen(false) })) : (_jsx(SidebarGuestHeader, { sidebarTitle: sidebarTitle, onClose: () => setSidebarOpen(false) })), onClose: () => setSidebarOpen(false), children: sidebarContent }), _jsx(Main, { id: "main-content",
198
250
  // No bottom-chrome clearance here on purpose. FooterLayout is a
199
251
  // SIBLING rendered after <Main>, so a margin here only gaps
200
252
  // main-to-footer — it never clears the bottom of the page, which is
@@ -207,5 +259,5 @@ export function AppLayoutShell({ children, navItems, sidebarItems = [], sidebarS
207
259
  // is 0 below `lg` and 0 whenever no bar is published, so this
208
260
  // reserves exactly nothing until there is something to reserve —
209
261
  // which is why it can be unconditional rather than route-gated.
210
- className: "w-full flex-1 flex flex-col pt-[var(--top-chrome-height,0px)] transition-[padding-top] duration-300 ease-out", children: _jsx(Div, { padding: "y-lg", className: `flex-1 ${contentClassName ?? "mx-auto w-full max-w-screen-xl px-[var(--appkit-space-5)] md:px-[var(--appkit-space-6)] lg:px-[var(--appkit-space-8)]"}`, children: children }) })] }), _jsx(BackToTop, {}), _jsx(FooterLayout, { ...footer }), _jsx(BottomChrome, { children: _jsx(BottomActions, {}) }), showBottomNav && (_jsx(BottomNavbar, { user: user, userId: userId, homeHref: homeHref, shopHref: shopHref, cartHref: cartHref, wishlistHref: wishlistHref, profileHref: profileHref, loginHref: loginHref, onSearchToggle: () => setSearchOpen((prev) => !prev), navItems: navItems, onMoreToggle: handleTogglePublicSidebar })), _jsx(UnsavedChangesModal, {})] }) }));
262
+ className: "w-full flex-1 flex flex-col pt-[var(--top-chrome-height,0px)] transition-[padding-top] duration-300 ease-out", children: _jsx(Div, { padding: "y-lg", className: `flex-1 ${contentClassName ?? "mx-auto w-full max-w-screen-xl px-[var(--appkit-space-5)] md:px-[var(--appkit-space-6)] lg:px-[var(--appkit-space-8)]"}`, children: children }) })] }), _jsx(BackToTop, {}), _jsx(FooterLayout, { ...footer }), _jsx(BottomChrome, { children: null }), _jsx(SideActionDock, {}), showBottomNav && (_jsx(BottomNavbar, { user: user, userId: userId, homeHref: homeHref, shopHref: shopHref, cartHref: cartHref, wishlistHref: wishlistHref, profileHref: profileHref, loginHref: loginHref, onSearchToggle: () => setSearchOpen((prev) => !prev), navItems: navItems, onMoreToggle: handleTogglePublicSidebar })), _jsx(UnsavedChangesModal, {})] }) }));
211
263
  }