@mohasinac/appkit 2.6.0 → 2.6.2

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 (304) hide show
  1. package/dist/_internal/client/features/layout/DashboardLayoutClient.d.ts +38 -0
  2. package/dist/_internal/client/features/layout/DashboardLayoutClient.js +75 -0
  3. package/dist/_internal/client/features/layout/RoleGuard.d.ts +15 -0
  4. package/dist/_internal/client/features/layout/RoleGuard.js +25 -0
  5. package/dist/_internal/client/features/layout/index.d.ts +5 -0
  6. package/dist/_internal/client/features/layout/index.js +4 -0
  7. package/dist/_internal/server/features/brands/actions.d.ts +3 -3
  8. package/dist/_internal/server/features/brands/actions.js +72 -5
  9. package/dist/_internal/server/features/brands/data.d.ts +8 -8
  10. package/dist/_internal/server/features/brands/data.js +10 -11
  11. package/dist/_internal/server/features/brands/service.d.ts +2 -2
  12. package/dist/_internal/server/features/brands/service.js +5 -5
  13. package/dist/_internal/server/features/categories/og.d.ts +33 -0
  14. package/dist/_internal/server/features/categories/og.js +75 -0
  15. package/dist/_internal/server/features/checkout/actions.d.ts +24 -0
  16. package/dist/_internal/server/features/checkout/actions.js +442 -13
  17. package/dist/_internal/server/features/checkout/index.d.ts +1 -1
  18. package/dist/_internal/server/features/checkout/index.js +1 -1
  19. package/dist/_internal/server/features/checkout/prize-bundle-gates.d.ts +59 -0
  20. package/dist/_internal/server/features/checkout/prize-bundle-gates.js +99 -0
  21. package/dist/_internal/server/features/grouped/data.js +12 -5
  22. package/dist/_internal/server/features/homepage/data.d.ts +1 -1
  23. package/dist/_internal/server/features/homepage/data.js +2 -2
  24. package/dist/_internal/server/features/media/contextGuards.d.ts +52 -0
  25. package/dist/_internal/server/features/media/contextGuards.js +198 -0
  26. package/dist/_internal/server/features/orders/adapters.js +12 -0
  27. package/dist/_internal/server/features/products/data.d.ts +1 -1
  28. package/dist/_internal/server/features/sublisting-categories/data.d.ts +1 -1
  29. package/dist/_internal/server/features/sublisting-categories/data.js +2 -2
  30. package/dist/_internal/server/jobs/handlers/assignSpinPrize.d.ts +24 -0
  31. package/dist/_internal/server/jobs/handlers/assignSpinPrize.js +86 -0
  32. package/dist/_internal/server/jobs/handlers/bundleStockSync.d.ts +18 -0
  33. package/dist/_internal/server/jobs/handlers/bundleStockSync.js +80 -0
  34. package/dist/_internal/server/jobs/handlers/index.d.ts +8 -0
  35. package/dist/_internal/server/jobs/handlers/index.js +13 -0
  36. package/dist/_internal/server/jobs/handlers/listingProcessor.js +13 -3
  37. package/dist/_internal/server/jobs/handlers/onProductStockChange.d.ts +17 -0
  38. package/dist/_internal/server/jobs/handlers/onProductStockChange.js +136 -0
  39. package/dist/_internal/server/jobs/handlers/onProductWrite.js +17 -1
  40. package/dist/_internal/server/jobs/handlers/prizeRevealClose.d.ts +9 -0
  41. package/dist/_internal/server/jobs/handlers/prizeRevealClose.js +29 -0
  42. package/dist/_internal/server/jobs/handlers/prizeRevealExpiry.d.ts +10 -0
  43. package/dist/_internal/server/jobs/handlers/prizeRevealExpiry.js +58 -0
  44. package/dist/_internal/server/jobs/handlers/prizeRevealOpen.d.ts +10 -0
  45. package/dist/_internal/server/jobs/handlers/prizeRevealOpen.js +65 -0
  46. package/dist/_internal/server/jobs/handlers/prizeRevealReminder.d.ts +9 -0
  47. package/dist/_internal/server/jobs/handlers/prizeRevealReminder.js +45 -0
  48. package/dist/_internal/server/jobs/handlers/triggerEventRaffle.d.ts +30 -0
  49. package/dist/_internal/server/jobs/handlers/triggerEventRaffle.js +94 -0
  50. package/dist/_internal/shared/features/brands/schema.d.ts +3 -3
  51. package/dist/_internal/shared/features/cart/schema.d.ts +8 -8
  52. package/dist/_internal/shared/features/cart/schema.js +1 -1
  53. package/dist/_internal/shared/features/categories/bundle-config.d.ts +17 -0
  54. package/dist/_internal/shared/features/categories/bundle-config.js +17 -0
  55. package/dist/_internal/shared/features/layout/config.d.ts +35 -0
  56. package/dist/_internal/shared/features/layout/config.js +58 -0
  57. package/dist/_internal/shared/features/layout/index.d.ts +3 -0
  58. package/dist/_internal/shared/features/layout/index.js +2 -0
  59. package/dist/_internal/shared/features/layout/types.d.ts +137 -0
  60. package/dist/_internal/shared/features/layout/types.js +13 -0
  61. package/dist/_internal/shared/features/products/types.d.ts +1 -1
  62. package/dist/_internal/shared/listing-types/_registry.d.ts +57 -0
  63. package/dist/_internal/shared/listing-types/_registry.js +28 -0
  64. package/dist/_internal/shared/listing-types/auction/config.d.ts +7 -0
  65. package/dist/_internal/shared/listing-types/auction/config.js +8 -0
  66. package/dist/_internal/shared/listing-types/auction/ctas.d.ts +1 -0
  67. package/dist/_internal/shared/listing-types/auction/ctas.js +2 -0
  68. package/dist/_internal/shared/listing-types/auction/og.d.ts +1 -0
  69. package/dist/_internal/shared/listing-types/auction/og.js +1 -0
  70. package/dist/_internal/shared/listing-types/auction/schema.d.ts +1 -0
  71. package/dist/_internal/shared/listing-types/auction/schema.js +1 -0
  72. package/dist/_internal/shared/listing-types/auction/seed-factory.d.ts +1 -0
  73. package/dist/_internal/shared/listing-types/auction/seed-factory.js +1 -0
  74. package/dist/_internal/shared/listing-types/capabilities.d.ts +41 -0
  75. package/dist/_internal/shared/listing-types/capabilities.js +75 -0
  76. package/dist/_internal/shared/listing-types/pre-order/config.d.ts +7 -0
  77. package/dist/_internal/shared/listing-types/pre-order/config.js +8 -0
  78. package/dist/_internal/shared/listing-types/pre-order/ctas.d.ts +1 -0
  79. package/dist/_internal/shared/listing-types/pre-order/ctas.js +2 -0
  80. package/dist/_internal/shared/listing-types/pre-order/og.d.ts +1 -0
  81. package/dist/_internal/shared/listing-types/pre-order/og.js +1 -0
  82. package/dist/_internal/shared/listing-types/pre-order/schema.d.ts +1 -0
  83. package/dist/_internal/shared/listing-types/pre-order/schema.js +1 -0
  84. package/dist/_internal/shared/listing-types/pre-order/seed-factory.d.ts +1 -0
  85. package/dist/_internal/shared/listing-types/pre-order/seed-factory.js +1 -0
  86. package/dist/_internal/shared/listing-types/prize-draw/config.d.ts +7 -0
  87. package/dist/_internal/shared/listing-types/prize-draw/config.js +8 -0
  88. package/dist/_internal/shared/listing-types/prize-draw/ctas.d.ts +1 -0
  89. package/dist/_internal/shared/listing-types/prize-draw/ctas.js +2 -0
  90. package/dist/_internal/shared/listing-types/prize-draw/og.d.ts +1 -0
  91. package/dist/_internal/shared/listing-types/prize-draw/og.js +1 -0
  92. package/dist/_internal/shared/listing-types/prize-draw/schema.d.ts +1 -0
  93. package/dist/_internal/shared/listing-types/prize-draw/schema.js +1 -0
  94. package/dist/_internal/shared/listing-types/prize-draw/seed-factory.d.ts +1 -0
  95. package/dist/_internal/shared/listing-types/prize-draw/seed-factory.js +1 -0
  96. package/dist/_internal/shared/listing-types/standard/config.d.ts +7 -0
  97. package/dist/_internal/shared/listing-types/standard/config.js +8 -0
  98. package/dist/_internal/shared/listing-types/standard/ctas.d.ts +1 -0
  99. package/dist/_internal/shared/listing-types/standard/ctas.js +3 -0
  100. package/dist/_internal/shared/listing-types/standard/og.d.ts +1 -0
  101. package/dist/_internal/shared/listing-types/standard/og.js +1 -0
  102. package/dist/_internal/shared/listing-types/standard/schema.d.ts +1 -0
  103. package/dist/_internal/shared/listing-types/standard/schema.js +1 -0
  104. package/dist/_internal/shared/listing-types/standard/seed-factory.d.ts +1 -0
  105. package/dist/_internal/shared/listing-types/standard/seed-factory.js +1 -0
  106. package/dist/_internal/shared/media/limits.d.ts +33 -0
  107. package/dist/_internal/shared/media/limits.js +97 -0
  108. package/dist/_internal/shared/schema-versions.d.ts +76 -0
  109. package/dist/_internal/shared/schema-versions.js +82 -0
  110. package/dist/client.d.ts +9 -0
  111. package/dist/client.js +7 -0
  112. package/dist/constants/api-endpoints.d.ts +6 -3
  113. package/dist/constants/api-endpoints.js +2 -1
  114. package/dist/errors/messages.d.ts +1 -1
  115. package/dist/errors/messages.js +1 -1
  116. package/dist/features/account/migrations.d.ts +2 -0
  117. package/dist/features/account/migrations.js +10 -0
  118. package/dist/features/admin/components/AdminMediaView.js +1 -1
  119. package/dist/features/admin/components/AdminProductsView.js +7 -3
  120. package/dist/features/admin/migrations.d.ts +2 -0
  121. package/dist/features/admin/migrations.js +10 -0
  122. package/dist/features/admin/types/product.types.d.ts +1 -1
  123. package/dist/features/auctions/components/MarketplaceAuctionCard.d.ts +1 -1
  124. package/dist/features/auctions/migrations.d.ts +2 -0
  125. package/dist/features/auctions/migrations.js +10 -0
  126. package/dist/features/auctions/schemas/index.d.ts +3 -3
  127. package/dist/features/auctions/schemas/index.js +1 -1
  128. package/dist/features/auth/migrations.d.ts +2 -0
  129. package/dist/features/auth/migrations.js +10 -0
  130. package/dist/features/blog/migrations.d.ts +2 -0
  131. package/dist/features/blog/migrations.js +10 -0
  132. package/dist/features/brands/migrations.d.ts +2 -0
  133. package/dist/features/brands/migrations.js +10 -0
  134. package/dist/features/bundles/components/BundlesByCategoryListing.d.ts +6 -0
  135. package/dist/features/bundles/components/BundlesByCategoryListing.js +50 -0
  136. package/dist/features/bundles/components/index.d.ts +2 -0
  137. package/dist/features/bundles/components/index.js +1 -0
  138. package/dist/features/bundles/migrations.d.ts +2 -0
  139. package/dist/features/bundles/migrations.js +10 -0
  140. package/dist/features/bundles/schemas/index.d.ts +1 -0
  141. package/dist/features/bundles/schemas/index.js +1 -0
  142. package/dist/features/bundles/schemas/zod.d.ts +377 -0
  143. package/dist/features/bundles/schemas/zod.js +71 -0
  144. package/dist/features/cart/migrations.d.ts +2 -0
  145. package/dist/features/cart/migrations.js +10 -0
  146. package/dist/features/cart/schemas/firestore.d.ts +2 -2
  147. package/dist/features/categories/components/BrandDetailPageView.js +35 -4
  148. package/dist/features/categories/components/BrandDetailTabs.d.ts +5 -1
  149. package/dist/features/categories/components/BrandDetailTabs.js +22 -8
  150. package/dist/features/categories/components/CategoryBundlesListing.d.ts +6 -0
  151. package/dist/features/categories/components/CategoryBundlesListing.js +74 -0
  152. package/dist/features/categories/components/CategoryDetailPageView.js +29 -4
  153. package/dist/features/categories/components/CategoryDetailTabs.d.ts +5 -1
  154. package/dist/features/categories/components/CategoryDetailTabs.js +22 -8
  155. package/dist/features/categories/migrations.d.ts +2 -0
  156. package/dist/features/categories/migrations.js +10 -0
  157. package/dist/features/categories/repository/categories.repository.d.ts +29 -0
  158. package/dist/features/categories/repository/categories.repository.js +83 -0
  159. package/dist/features/categories/schemas/firestore.d.ts +59 -2
  160. package/dist/features/categories/schemas/firestore.js +6 -0
  161. package/dist/features/categories/types/index.d.ts +11 -3
  162. package/dist/features/events/migrations.d.ts +2 -0
  163. package/dist/features/events/migrations.js +10 -0
  164. package/dist/features/faq/migrations.d.ts +2 -0
  165. package/dist/features/faq/migrations.js +10 -0
  166. package/dist/features/grouped/migrations.d.ts +2 -0
  167. package/dist/features/grouped/migrations.js +10 -0
  168. package/dist/features/grouped/schemas/firestore.d.ts +29 -10
  169. package/dist/features/grouped/schemas/firestore.js +10 -5
  170. package/dist/features/history/migrations.d.ts +2 -0
  171. package/dist/features/history/migrations.js +10 -0
  172. package/dist/features/homepage/hooks/useFeaturedAuctions.js +2 -2
  173. package/dist/features/homepage/hooks/useFeaturedPreOrders.js +2 -2
  174. package/dist/features/homepage/lib/section-renderer.js +5 -3
  175. package/dist/features/media/AvatarUpload.js +6 -28
  176. package/dist/features/media/hooks/useMedia.d.ts +31 -15
  177. package/dist/features/media/hooks/useMedia.js +48 -13
  178. package/dist/features/media/upload/ImageUpload.js +1 -1
  179. package/dist/features/media/upload/MediaUploadField.js +1 -1
  180. package/dist/features/messages/migrations.d.ts +2 -0
  181. package/dist/features/messages/migrations.js +10 -0
  182. package/dist/features/orders/components/OrdersList.js +10 -1
  183. package/dist/features/orders/migrations.d.ts +2 -0
  184. package/dist/features/orders/migrations.js +10 -0
  185. package/dist/features/orders/repository/orders.repository.d.ts +16 -0
  186. package/dist/features/orders/repository/orders.repository.js +49 -0
  187. package/dist/features/orders/schemas/firestore.d.ts +8 -0
  188. package/dist/features/orders/types/index.d.ts +12 -0
  189. package/dist/features/orders/utils/order-splitter.d.ts +2 -2
  190. package/dist/features/orders/utils/order-splitter.js +5 -0
  191. package/dist/features/payments/migrations.d.ts +2 -0
  192. package/dist/features/payments/migrations.js +10 -0
  193. package/dist/features/pre-orders/components/PreOrderDetailPageView.js +4 -1
  194. package/dist/features/products/actions/product-actions.d.ts +1 -1
  195. package/dist/features/products/api/[id]/route.js +34 -0
  196. package/dist/features/products/api/route.js +1 -19
  197. package/dist/features/products/components/CompareOverlay.d.ts +1 -1
  198. package/dist/features/products/components/MarketplacePrizeDrawCard.d.ts +24 -0
  199. package/dist/features/products/components/MarketplacePrizeDrawCard.js +102 -0
  200. package/dist/features/products/components/PrizeDrawCollage.d.ts +32 -0
  201. package/dist/features/products/components/PrizeDrawCollage.js +22 -0
  202. package/dist/features/products/components/PrizeDrawDetailPageView.d.ts +27 -0
  203. package/dist/features/products/components/PrizeDrawDetailPageView.js +118 -0
  204. package/dist/features/products/components/PrizeDrawEntryActions.d.ts +19 -0
  205. package/dist/features/products/components/PrizeDrawEntryActions.js +48 -0
  206. package/dist/features/products/components/PrizeDrawItemsEditor.d.ts +13 -0
  207. package/dist/features/products/components/PrizeDrawItemsEditor.js +97 -0
  208. package/dist/features/products/components/PrizeDrawsIndexListing.d.ts +8 -0
  209. package/dist/features/products/components/PrizeDrawsIndexListing.js +128 -0
  210. package/dist/features/products/components/PrizeDrawsListingView.d.ts +15 -0
  211. package/dist/features/products/components/PrizeDrawsListingView.js +49 -0
  212. package/dist/features/products/components/PrizeRevealModal.d.ts +34 -0
  213. package/dist/features/products/components/PrizeRevealModal.js +124 -0
  214. package/dist/features/products/components/ProductDetailPageView.js +13 -1
  215. package/dist/features/products/components/ProductForm.js +35 -2
  216. package/dist/features/products/components/ProductGrid.js +3 -1
  217. package/dist/features/products/components/index.d.ts +16 -0
  218. package/dist/features/products/components/index.js +8 -0
  219. package/dist/features/products/constants/listing-tabs.d.ts +113 -0
  220. package/dist/features/products/constants/listing-tabs.js +43 -0
  221. package/dist/features/products/index.d.ts +1 -0
  222. package/dist/features/products/index.js +1 -0
  223. package/dist/features/products/migrations.d.ts +2 -0
  224. package/dist/features/products/migrations.js +10 -0
  225. package/dist/features/products/repository/products.repository.d.ts +11 -7
  226. package/dist/features/products/repository/products.repository.js +49 -24
  227. package/dist/features/products/schemas/firestore.d.ts +3 -3
  228. package/dist/features/products/schemas/firestore.js +2 -2
  229. package/dist/features/products/schemas/index.d.ts +5 -5
  230. package/dist/features/products/schemas/index.js +3 -1
  231. package/dist/features/products/schemas/product-features.validators.d.ts +6 -6
  232. package/dist/features/products/types/index.d.ts +17 -1
  233. package/dist/features/products/utils/listing-type.d.ts +7 -4
  234. package/dist/features/products/utils/listing-type.js +8 -4
  235. package/dist/features/promotions/actions/coupon-actions.d.ts +1 -1
  236. package/dist/features/promotions/hooks/useCouponValidate.d.ts +1 -1
  237. package/dist/features/promotions/migrations.d.ts +2 -0
  238. package/dist/features/promotions/migrations.js +10 -0
  239. package/dist/features/promotions/repository/coupons.repository.d.ts +1 -1
  240. package/dist/features/promotions/schemas/index.d.ts +2 -2
  241. package/dist/features/reviews/migrations.d.ts +2 -0
  242. package/dist/features/reviews/migrations.js +10 -0
  243. package/dist/features/scams/migrations.d.ts +2 -0
  244. package/dist/features/scams/migrations.js +10 -0
  245. package/dist/features/search/api/route.d.ts +1 -1
  246. package/dist/features/search/api/route.js +3 -3
  247. package/dist/features/search/components/Search.d.ts +1 -1
  248. package/dist/features/search/schemas/index.d.ts +3 -3
  249. package/dist/features/search/schemas/index.js +3 -1
  250. package/dist/features/search/types/index.d.ts +2 -2
  251. package/dist/features/seller/components/SellerProductShell.d.ts +1 -1
  252. package/dist/features/seller/components/SellerProductsView.js +20 -6
  253. package/dist/features/seller/migrations.d.ts +2 -0
  254. package/dist/features/seller/migrations.js +10 -0
  255. package/dist/features/seller/schemas/index.d.ts +2 -2
  256. package/dist/features/stores/components/StoreBundlesPageView.d.ts +12 -0
  257. package/dist/features/stores/components/StoreBundlesPageView.js +24 -0
  258. package/dist/features/stores/components/StoreDetailLayoutView.js +15 -3
  259. package/dist/features/stores/components/StorePrizeDrawsPageView.d.ts +11 -0
  260. package/dist/features/stores/components/StorePrizeDrawsPageView.js +27 -0
  261. package/dist/features/stores/components/index.d.ts +2 -0
  262. package/dist/features/stores/migrations.d.ts +2 -0
  263. package/dist/features/stores/migrations.js +10 -0
  264. package/dist/features/stores/schemas/index.d.ts +2 -2
  265. package/dist/features/stores/types/index.d.ts +1 -1
  266. package/dist/features/sublisting/migrations.d.ts +2 -0
  267. package/dist/features/sublisting/migrations.js +10 -0
  268. package/dist/features/sublisting/schemas/firestore.d.ts +2 -0
  269. package/dist/features/support/migrations.d.ts +2 -0
  270. package/dist/features/support/migrations.js +10 -0
  271. package/dist/features/wishlist/migrations.d.ts +2 -0
  272. package/dist/features/wishlist/migrations.js +10 -0
  273. package/dist/features/wishlist/types/index.d.ts +1 -1
  274. package/dist/index.d.ts +26 -18
  275. package/dist/index.js +41 -24
  276. package/dist/jobs.d.ts +1 -1
  277. package/dist/jobs.js +4 -0
  278. package/dist/next/api/routeHandler.js +6 -4
  279. package/dist/next/routing/route-map.d.ts +4 -0
  280. package/dist/next/routing/route-map.js +2 -0
  281. package/dist/providers/db-firebase/filter-aliases.d.ts +2 -2
  282. package/dist/repositories/index.d.ts +0 -5
  283. package/dist/repositories/index.js +5 -4
  284. package/dist/seed/actions/demo-seed-actions.d.ts +1 -1
  285. package/dist/seed/categories-seed-data.js +1105 -6
  286. package/dist/seed/faq-seed-data.js +160 -0
  287. package/dist/seed/grouped-listings-seed-data.js +32 -32
  288. package/dist/seed/homepage-sections-seed-data.js +52 -6
  289. package/dist/seed/index.d.ts +1 -3
  290. package/dist/seed/index.js +4 -3
  291. package/dist/seed/manifest.js +8 -13
  292. package/dist/seed/products-prize-draws-seed-data.d.ts +17 -0
  293. package/dist/seed/products-prize-draws-seed-data.js +313 -0
  294. package/dist/seo/json-ld.d.ts +1 -1
  295. package/dist/server-entry.d.ts +2 -2
  296. package/dist/server-entry.js +5 -3
  297. package/dist/server.d.ts +9 -2
  298. package/dist/server.js +11 -5
  299. package/dist/tailwind-utilities.css +1 -1
  300. package/dist/ui/components/Button.js +21 -2
  301. package/dist/ui/components/Button.style.css +34 -0
  302. package/dist/validation/schemas.d.ts +8 -8
  303. package/package.json +1 -1
  304. package/scripts/seed-cli.mjs +2 -4
@@ -0,0 +1,38 @@
1
+ /**
2
+ * DashboardLayoutClient — unified client island that replaces the ~75 lines of
3
+ * boilerplate previously duplicated across admin/store/user layout.tsx files.
4
+ *
5
+ * Responsibilities:
6
+ * - Manage desktop + mobile drawer state (matchMedia-aware).
7
+ * - Register handlers with `useDashboardNav()` so the public TitleBar's
8
+ * hamburger forwards to this dashboard sidebar.
9
+ * - Pick the correct sidebar component for the supplied `variant`.
10
+ * - Resolve `activeHref` from `usePathname()` so consumers do not have to.
11
+ *
12
+ * Consumers pass:
13
+ * <DashboardLayoutClient variant="admin" groups={ADMIN_NAV_GROUPS}>
14
+ * {children}
15
+ * </DashboardLayoutClient>
16
+ *
17
+ * Theming: each variant uses its accent token map from shared/features/layout/config.
18
+ * Responsive: sidebar is overlay on <md, persistent rail on ≥lg — controlled by
19
+ * the underlying *Sidebar components.
20
+ */
21
+ import { type ReactNode } from "react";
22
+ import type { DashboardVariant, SidebarNavGroup, SectionResponsive } from "../../../shared/features/layout/types";
23
+ export interface DashboardLayoutClientProps {
24
+ /** Drives sidebar component selection + accent colour. */
25
+ variant: DashboardVariant;
26
+ /** Grouped nav items. Shape matches all three sidebar components. */
27
+ groups: SidebarNavGroup[];
28
+ /** Override active-link highlight. Defaults to usePathname(). */
29
+ activeHref?: string;
30
+ /** Responsive controls — currently only hideAt is honoured. */
31
+ responsive?: SectionResponsive;
32
+ /** Optional render-prop slot for additional sidebar footer content. */
33
+ renderSidebarFooter?: () => ReactNode;
34
+ /** Optional className passed through to the sidebar component. */
35
+ className?: string;
36
+ children: ReactNode;
37
+ }
38
+ export declare function DashboardLayoutClient({ variant, groups, activeHref: explicitActiveHref, responsive: _responsive, className, children, }: DashboardLayoutClientProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,75 @@
1
+ "use client";
2
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
3
+ /**
4
+ * DashboardLayoutClient — unified client island that replaces the ~75 lines of
5
+ * boilerplate previously duplicated across admin/store/user layout.tsx files.
6
+ *
7
+ * Responsibilities:
8
+ * - Manage desktop + mobile drawer state (matchMedia-aware).
9
+ * - Register handlers with `useDashboardNav()` so the public TitleBar's
10
+ * hamburger forwards to this dashboard sidebar.
11
+ * - Pick the correct sidebar component for the supplied `variant`.
12
+ * - Resolve `activeHref` from `usePathname()` so consumers do not have to.
13
+ *
14
+ * Consumers pass:
15
+ * <DashboardLayoutClient variant="admin" groups={ADMIN_NAV_GROUPS}>
16
+ * {children}
17
+ * </DashboardLayoutClient>
18
+ *
19
+ * Theming: each variant uses its accent token map from shared/features/layout/config.
20
+ * Responsive: sidebar is overlay on <md, persistent rail on ≥lg — controlled by
21
+ * the underlying *Sidebar components.
22
+ */
23
+ import { useCallback, useEffect, useState, startTransition } from "react";
24
+ import { usePathname } from "next/navigation";
25
+ import { useDashboardNav } from "../../../../features/layout/DashboardNavContext";
26
+ import { AdminSidebar } from "../../../../features/admin/components/AdminSidebar";
27
+ import { StoreSidebar } from "../../../../features/seller/components/SellerSidebar";
28
+ import { UserSidebar } from "../../../../features/account/components/UserSidebar";
29
+ import { DASHBOARD_DESKTOP_MEDIA_QUERY } from "../../../shared/features/layout/config";
30
+ /**
31
+ * Hoisted drawer-state hook — the matchMedia-aware open/close logic that was
32
+ * triplicated across admin/store/user layouts. Used internally by
33
+ * DashboardLayoutClient; not exported because it's not generically useful.
34
+ */
35
+ function useResponsiveDrawer() {
36
+ const [desktopOpen, setDesktopOpen] = useState(false);
37
+ const [mobileOpen, setMobileOpen] = useState(false);
38
+ const { registerNav, unregisterNav } = useDashboardNav();
39
+ const isDesktop = useCallback(() => typeof window !== "undefined" && window.matchMedia(DASHBOARD_DESKTOP_MEDIA_QUERY).matches, []);
40
+ const open = useCallback(() => {
41
+ startTransition(() => {
42
+ if (isDesktop())
43
+ setDesktopOpen(true);
44
+ else
45
+ setMobileOpen(true);
46
+ });
47
+ }, [isDesktop]);
48
+ const close = useCallback(() => {
49
+ startTransition(() => {
50
+ if (isDesktop())
51
+ setDesktopOpen(false);
52
+ else
53
+ setMobileOpen(false);
54
+ });
55
+ }, [isDesktop]);
56
+ const toggle = useCallback(() => {
57
+ startTransition(() => {
58
+ if (isDesktop())
59
+ setDesktopOpen((prev) => !prev);
60
+ else
61
+ setMobileOpen((prev) => !prev);
62
+ });
63
+ }, [isDesktop]);
64
+ useEffect(() => {
65
+ registerNav({ open, close, toggle });
66
+ return () => unregisterNav();
67
+ }, [registerNav, unregisterNav, open, close, toggle]);
68
+ return { desktopOpen, mobileOpen, close, toggle };
69
+ }
70
+ export function DashboardLayoutClient({ variant, groups, activeHref: explicitActiveHref, responsive: _responsive, className, children, }) {
71
+ const pathname = usePathname();
72
+ const activeHref = explicitActiveHref ?? pathname ?? "";
73
+ const { desktopOpen, mobileOpen, close, toggle } = useResponsiveDrawer();
74
+ return (_jsxs(_Fragment, { children: [variant === "admin" && (_jsx(AdminSidebar, { variant: "sidebar", desktopOpen: desktopOpen, mobileOpen: mobileOpen, activePath: activeHref, groups: groups, onCloseMobile: close, onToggle: toggle, className: className })), variant === "store" && (_jsx(StoreSidebar, { variant: "sidebar", desktopOpen: desktopOpen, mobileOpen: mobileOpen, activeHref: activeHref, items: [], groups: groups, onCloseMobile: close, onToggle: toggle, className: className })), variant === "user" && (_jsx(UserSidebar, { variant: "sidebar", desktopOpen: desktopOpen, mobileOpen: mobileOpen, items: groups.flatMap((g) => g.items), groups: groups, onCloseMobile: close, onToggle: toggle, className: className })), children] }));
75
+ }
@@ -0,0 +1,15 @@
1
+ import type { ReactNode } from "react";
2
+ import type { LayoutRole } from "../../../shared/features/layout/types";
3
+ export interface RoleGuardProps {
4
+ /** Single role or array. Omit for auth-only (any signed-in user). */
5
+ role?: LayoutRole | LayoutRole[];
6
+ /** When true, unauthenticated users are redirected (default true). */
7
+ requireAuth?: boolean;
8
+ /** Optional route overrides (defaults come from appkit ROUTES). */
9
+ loginPath?: string;
10
+ unauthorizedPath?: string;
11
+ /** Render while loading the session. */
12
+ loadingComponent?: ReactNode;
13
+ children: ReactNode;
14
+ }
15
+ export declare function RoleGuard({ role, requireAuth, loginPath, unauthorizedPath, loadingComponent, children, }: RoleGuardProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,25 @@
1
+ "use client";
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ /**
4
+ * RoleGuard — preset wrapper over ProtectedRoute.
5
+ *
6
+ * Collapses the boilerplate that every dashboard layout repeats:
7
+ * - reading `useSession()`
8
+ * - resolving `onNavigate` against the i18n router
9
+ * - passing default `routes.loginPath` / `routes.unauthorizedPath`
10
+ *
11
+ * Consumers supply only the `role` (or none, for auth-only) plus optional
12
+ * route overrides. Everything else defaults to appkit's ROUTES.
13
+ */
14
+ import { useRouter } from "next/navigation";
15
+ import { ProtectedRoute } from "../../../../features/auth/components/Guards";
16
+ import { useSession } from "../../../../react/contexts/SessionContext";
17
+ import { ROUTES } from "../../../../next/routing/route-map";
18
+ export function RoleGuard({ role, requireAuth = true, loginPath, unauthorizedPath, loadingComponent, children, }) {
19
+ const { user, loading } = useSession();
20
+ const router = useRouter();
21
+ return (_jsx(ProtectedRoute, { user: user, loading: loading, requireAuth: requireAuth, requireRole: role, onNavigate: (path) => router.push(path), routes: {
22
+ loginPath: loginPath ?? String(ROUTES.AUTH.LOGIN),
23
+ unauthorizedPath: unauthorizedPath ?? String(ROUTES.ERRORS.UNAUTHORIZED),
24
+ }, loadingComponent: loadingComponent, children: children }));
25
+ }
@@ -0,0 +1,5 @@
1
+ /** Layout feature — client islands barrel. */
2
+ export { DashboardLayoutClient } from "./DashboardLayoutClient";
3
+ export type { DashboardLayoutClientProps } from "./DashboardLayoutClient";
4
+ export { RoleGuard } from "./RoleGuard";
5
+ export type { RoleGuardProps } from "./RoleGuard";
@@ -0,0 +1,4 @@
1
+ "use client";
2
+ /** Layout feature — client islands barrel. */
3
+ export { DashboardLayoutClient } from "./DashboardLayoutClient";
4
+ export { RoleGuard } from "./RoleGuard";
@@ -1,4 +1,4 @@
1
- export declare function createBrandAction(input: unknown): Promise<import("../../../..").BrandDocument>;
2
- export declare function updateBrandAction(brandId: string, input: unknown): Promise<import("../../../..").BrandDocument>;
1
+ export declare function createBrandAction(input: unknown): Promise<import("../../../..").CategoryDocument>;
2
+ export declare function updateBrandAction(brandId: string, input: unknown): Promise<import("../../../..").CategoryDocument>;
3
3
  export declare function deleteBrandAction(brandId: string): Promise<void>;
4
- export declare function toggleBrandActiveAction(brandId: string, isActive: boolean): Promise<import("../../../..").BrandDocument>;
4
+ export declare function toggleBrandActiveAction(brandId: string, isActive: boolean): Promise<import("../../../..").CategoryDocument>;
@@ -1,16 +1,83 @@
1
1
  "use server";
2
- import { brandsRepository } from "../../../../repositories";
2
+ import { categoriesRepository } from "../../../../repositories";
3
3
  import { requireRoleUser } from "../../../../providers/auth-firebase/helpers";
4
4
  import { brandInputSchema, brandUpdateSchema } from "../../../shared/features/brands/schema";
5
5
  import { assertBrandExists, assertBrandSlugUnique } from "./service";
6
6
  import { ValidationError } from "../../../shared/errors/index";
7
+ /**
8
+ * Translate the brand-input wire format (logoURL / bannerURL / website /
9
+ * country / founded) to the CategoryDocument storage shape after
10
+ * SB-UNI-C consolidated brands into the categories collection.
11
+ */
12
+ function brandInputToCategoryFields(input) {
13
+ const out = {};
14
+ if ("name" in input && input.name !== undefined)
15
+ out.name = input.name;
16
+ if ("slug" in input && input.slug !== undefined) {
17
+ out.slug = input.slug;
18
+ out.path = input.slug;
19
+ }
20
+ if (input.description !== undefined)
21
+ out.description = input.description;
22
+ if (input.website !== undefined)
23
+ out.brandWebsite = input.website;
24
+ if (input.country !== undefined)
25
+ out.brandCountry = input.country;
26
+ if (input.founded !== undefined)
27
+ out.brandFounded = input.founded;
28
+ if (input.bannerURL !== undefined)
29
+ out.brandBannerImage = input.bannerURL;
30
+ if (input.logoURL !== undefined) {
31
+ out.display = { coverImage: input.logoURL, showInMenu: false, showInFooter: false };
32
+ }
33
+ if (input.isActive !== undefined)
34
+ out.isActive = input.isActive;
35
+ if (input.displayOrder !== undefined)
36
+ out.order = input.displayOrder;
37
+ return out;
38
+ }
7
39
  export async function createBrandAction(input) {
8
40
  await requireRoleUser("admin");
9
41
  const parsed = brandInputSchema.safeParse(input);
10
42
  if (!parsed.success)
11
43
  throw new ValidationError(parsed.error.errors[0]?.message ?? "Invalid brand input");
12
44
  await assertBrandSlugUnique(parsed.data.slug);
13
- return brandsRepository.createWithId(parsed.data.slug, parsed.data);
45
+ const fields = brandInputToCategoryFields(parsed.data);
46
+ return categoriesRepository.createWithId(parsed.data.slug, {
47
+ id: parsed.data.slug,
48
+ name: parsed.data.name,
49
+ slug: parsed.data.slug,
50
+ categoryType: "brand",
51
+ rootId: parsed.data.slug,
52
+ parentIds: [],
53
+ childrenIds: [],
54
+ tier: 0,
55
+ path: parsed.data.slug,
56
+ position: 0,
57
+ subtreeSize: 1,
58
+ order: parsed.data.displayOrder,
59
+ isLeaf: true,
60
+ isFeatured: false,
61
+ isBrand: true,
62
+ isActive: parsed.data.isActive,
63
+ isSearchable: true,
64
+ metrics: {
65
+ productCount: 0,
66
+ productIds: [],
67
+ auctionCount: 0,
68
+ auctionIds: [],
69
+ totalProductCount: 0,
70
+ totalAuctionCount: 0,
71
+ totalItemCount: 0,
72
+ lastUpdated: new Date(),
73
+ },
74
+ seo: { title: parsed.data.name, description: parsed.data.description ?? "", keywords: [parsed.data.name] },
75
+ ancestors: [],
76
+ createdBy: "admin",
77
+ createdAt: new Date(),
78
+ updatedAt: new Date(),
79
+ ...fields,
80
+ });
14
81
  }
15
82
  export async function updateBrandAction(brandId, input) {
16
83
  await requireRoleUser("admin");
@@ -18,15 +85,15 @@ export async function updateBrandAction(brandId, input) {
18
85
  const parsed = brandUpdateSchema.safeParse(input);
19
86
  if (!parsed.success)
20
87
  throw new ValidationError(parsed.error.errors[0]?.message ?? "Invalid brand input");
21
- return brandsRepository.update(brandId, parsed.data);
88
+ return categoriesRepository.update(brandId, brandInputToCategoryFields(parsed.data));
22
89
  }
23
90
  export async function deleteBrandAction(brandId) {
24
91
  await requireRoleUser("admin");
25
92
  await assertBrandExists(brandId);
26
- return brandsRepository.delete(brandId);
93
+ return categoriesRepository.delete(brandId);
27
94
  }
28
95
  export async function toggleBrandActiveAction(brandId, isActive) {
29
96
  await requireRoleUser("admin");
30
97
  await assertBrandExists(brandId);
31
- return brandsRepository.update(brandId, { isActive });
98
+ return categoriesRepository.update(brandId, { isActive });
32
99
  }
@@ -1,12 +1,12 @@
1
- import type { BrandDocument } from "../../../../features/brands/schemas";
2
1
  import type { CategoryDocument } from "../../../../features/categories/schemas/firestore";
3
- export declare const getBrandForDetail: (slug: string) => Promise<BrandDocument | null>;
4
2
  /**
5
- * Brand-as-category lookup for the brand detail view, deduped per request.
6
- *
7
- * BrandDetailPageView renders the categories-collection record (display + metrics
8
- * fields), not the brands-collection record. Keep both fetchers so
9
- * generateMetadata can pull BrandDocument fields (logoURL) while the view pulls
10
- * CategoryDocument.
3
+ * Brand detail loader SB-UNI-C moved brands into the `categories`
4
+ * collection with `categoryType: "brand"`. Both `generateMetadata` and
5
+ * `BrandDetailPageView` consume the same `CategoryDocument` shape.
6
+ */
7
+ export declare const getBrandForDetail: (slug: string) => Promise<CategoryDocument | null>;
8
+ /**
9
+ * @deprecated Identical to getBrandForDetail after SB-UNI-C. Kept as an
10
+ * alias so existing imports don't break.
11
11
  */
12
12
  export declare const getBrandCategoryForDetail: (slug: string) => Promise<CategoryDocument | null>;
@@ -1,16 +1,15 @@
1
1
  import { cache } from "react";
2
- import { brandsRepository, categoriesRepository } from "../../../../repositories";
2
+ import { categoriesRepository } from "../../../../repositories";
3
+ /**
4
+ * Brand detail loader — SB-UNI-C moved brands into the `categories`
5
+ * collection with `categoryType: "brand"`. Both `generateMetadata` and
6
+ * `BrandDetailPageView` consume the same `CategoryDocument` shape.
7
+ */
3
8
  export const getBrandForDetail = cache(async (slug) => {
4
- return (await brandsRepository.findBySlug(slug).catch(() => undefined)) ?? null;
9
+ return categoriesRepository.findBySlugAndType(slug, "brand").catch(() => null);
5
10
  });
6
11
  /**
7
- * Brand-as-category lookup for the brand detail view, deduped per request.
8
- *
9
- * BrandDetailPageView renders the categories-collection record (display + metrics
10
- * fields), not the brands-collection record. Keep both fetchers so
11
- * generateMetadata can pull BrandDocument fields (logoURL) while the view pulls
12
- * CategoryDocument.
12
+ * @deprecated Identical to getBrandForDetail after SB-UNI-C. Kept as an
13
+ * alias so existing imports don't break.
13
14
  */
14
- export const getBrandCategoryForDetail = cache(async (slug) => {
15
- return categoriesRepository.getCategoryBySlug(slug).catch(() => null);
16
- });
15
+ export const getBrandCategoryForDetail = getBrandForDetail;
@@ -1,3 +1,3 @@
1
- import type { BrandDocument } from "../../../../features/brands/schemas";
2
- export declare function assertBrandExists(slugOrId: string): Promise<BrandDocument>;
1
+ import type { CategoryDocument } from "../../../../features/categories/schemas/firestore";
2
+ export declare function assertBrandExists(slugOrId: string): Promise<CategoryDocument>;
3
3
  export declare function assertBrandSlugUnique(slug: string): Promise<void>;
@@ -1,14 +1,14 @@
1
- import { brandsRepository } from "../../../../repositories";
1
+ import { categoriesRepository } from "../../../../repositories";
2
2
  import { BrandNotFoundError, BrandSlugConflictError } from "../../../shared/features/brands/errors";
3
3
  export async function assertBrandExists(slugOrId) {
4
- const brand = await brandsRepository.findBySlug(slugOrId).catch(() => null)
5
- ?? await brandsRepository.findById(slugOrId).catch(() => null);
6
- if (!brand)
4
+ const brand = (await categoriesRepository.findBySlugAndType(slugOrId, "brand").catch(() => null)) ??
5
+ (await categoriesRepository.findById(slugOrId).catch(() => null));
6
+ if (!brand || brand.categoryType !== "brand")
7
7
  throw new BrandNotFoundError(slugOrId);
8
8
  return brand;
9
9
  }
10
10
  export async function assertBrandSlugUnique(slug) {
11
- const existing = await brandsRepository.findBySlug(slug).catch(() => null);
11
+ const existing = await categoriesRepository.findBySlugAndType(slug, "brand").catch(() => null);
12
12
  if (existing)
13
13
  throw new BrandSlugConflictError(slug);
14
14
  }
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Category OG image renderer — S6 OG1.
3
+ *
4
+ * Two layers:
5
+ * - `renderCategoryOg(doc, opts)` — high-level: maps a raw category doc
6
+ * (from `getCategoryForDetail`) into the OG data shape.
7
+ * - `renderCategoryOgImage(data, siteName)` — pure JSX primitive, no
8
+ * next/og dependency; consumer wraps with `new ImageResponse(...)`.
9
+ *
10
+ * Mirrors the brand/store OG layout so the public catalog feels uniform.
11
+ */
12
+ import type { ReactElement } from "react";
13
+ export interface CategoryOgData {
14
+ name: string;
15
+ description?: string | null;
16
+ coverImageUrl?: string | null;
17
+ productCount?: number | null;
18
+ }
19
+ interface CategoryDocLike {
20
+ name?: string | null;
21
+ description?: string | null;
22
+ display?: {
23
+ coverImage?: string | null;
24
+ } | null;
25
+ metrics?: {
26
+ totalItemCount?: number | null;
27
+ } | null;
28
+ }
29
+ export declare function renderCategoryOg(doc: CategoryDocLike | null | undefined, opts: {
30
+ siteName: string;
31
+ }): ReactElement;
32
+ export declare function renderCategoryOgImage(data: CategoryOgData, siteName: string): ReactElement;
33
+ export {};
@@ -0,0 +1,75 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ export function renderCategoryOg(doc, opts) {
3
+ const name = doc?.name ?? "Category";
4
+ return renderCategoryOgImage({
5
+ name,
6
+ description: doc?.description?.slice(0, 140) ??
7
+ `Browse ${name} on ${opts.siteName}.`,
8
+ coverImageUrl: doc?.display?.coverImage ?? null,
9
+ productCount: doc?.metrics?.totalItemCount ?? null,
10
+ }, opts.siteName);
11
+ }
12
+ export function renderCategoryOgImage(data, siteName) {
13
+ const { name, description, coverImageUrl, productCount } = data;
14
+ const itemLabel = typeof productCount === "number" && productCount > 0
15
+ ? `${productCount.toLocaleString("en-IN")} item${productCount === 1 ? "" : "s"}`
16
+ : null;
17
+ return (_jsxs("div", { style: {
18
+ display: "flex",
19
+ width: "100%",
20
+ height: "100%",
21
+ background: "#0f172a",
22
+ fontFamily: "sans-serif",
23
+ position: "relative",
24
+ overflow: "hidden",
25
+ }, children: [coverImageUrl && (_jsx("img", { src: coverImageUrl, alt: "", style: {
26
+ position: "absolute",
27
+ inset: 0,
28
+ width: "100%",
29
+ height: "100%",
30
+ objectFit: "cover",
31
+ opacity: 0.35,
32
+ } })), _jsx("div", { style: {
33
+ position: "absolute",
34
+ inset: 0,
35
+ background: "linear-gradient(135deg, rgba(15, 23, 42, 0.85) 0%, rgba(30, 41, 59, 0.7) 100%)",
36
+ } }), _jsxs("div", { style: {
37
+ position: "relative",
38
+ display: "flex",
39
+ flexDirection: "column",
40
+ gap: 24,
41
+ padding: "80px 72px",
42
+ width: "100%",
43
+ height: "100%",
44
+ justifyContent: "flex-end",
45
+ }, children: [_jsxs("div", { style: {
46
+ fontSize: 18,
47
+ color: "#94a3b8",
48
+ fontWeight: 600,
49
+ letterSpacing: 2,
50
+ textTransform: "uppercase",
51
+ }, children: [siteName, " \u00B7 Category"] }), _jsx("div", { style: {
52
+ fontSize: 76,
53
+ fontWeight: 800,
54
+ color: "#f8fafc",
55
+ lineHeight: 1.05,
56
+ letterSpacing: -1,
57
+ }, children: name }), description && (_jsx("div", { style: {
58
+ fontSize: 26,
59
+ color: "#cbd5e1",
60
+ fontWeight: 400,
61
+ lineHeight: 1.35,
62
+ maxWidth: 960,
63
+ }, children: description })), itemLabel && (_jsx("div", { style: {
64
+ display: "inline-flex",
65
+ alignSelf: "flex-start",
66
+ padding: "10px 22px",
67
+ borderRadius: 999,
68
+ background: "rgba(56, 189, 248, 0.18)",
69
+ color: "#e0f2fe",
70
+ fontSize: 22,
71
+ fontWeight: 600,
72
+ border: "1px solid rgba(56, 189, 248, 0.4)",
73
+ marginTop: 8,
74
+ }, children: itemLabel }))] })] }));
75
+ }
@@ -33,3 +33,27 @@ export declare function attachPaymentAction(input: {
33
33
  paymentId: string;
34
34
  paidAmount: number;
35
35
  }): Promise<void>;
36
+ export interface VerifyAndPlaceRazorpayOrderInput {
37
+ userId: string;
38
+ userName: string;
39
+ userEmail: string;
40
+ razorpay_order_id: string;
41
+ razorpay_payment_id: string;
42
+ razorpay_signature: string;
43
+ addressId: string;
44
+ notes?: string;
45
+ }
46
+ /**
47
+ * Place order(s) from the user's cart after a Razorpay payment is verified.
48
+ * Mirrors the existing /api/payment/verify route handler.
49
+ *
50
+ * Consumers must authenticate the user before calling. The action performs:
51
+ * 1. HMAC signature verification (rejects forged callbacks)
52
+ * 2. Cart re-validation against current product prices/stock
53
+ * 3. Amount cross-check against the Razorpay order record
54
+ * 4. Atomic stock decrement + cart clear via unitOfWork batch
55
+ * 5. Multi-coupon pro-rating per order group
56
+ * 6. order_placed notifications (buyer + seller)
57
+ * 7. Confirmation email + RTDB success signal (both fire-and-forget)
58
+ */
59
+ export declare function verifyAndPlaceRazorpayOrderAction(input: VerifyAndPlaceRazorpayOrderInput): Promise<CheckoutOrderResult>;