@mohasinac/appkit 2.7.58 → 2.8.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 (364) hide show
  1. package/dist/_internal/client/features/filters/filter-load-options.d.ts +4 -5
  2. package/dist/_internal/server/features/auctions/og.js +8 -32
  3. package/dist/_internal/server/features/blog/og.js +10 -49
  4. package/dist/_internal/server/features/checkout/actions.js +6 -0
  5. package/dist/_internal/server/features/classified/og.js +9 -51
  6. package/dist/_internal/server/features/digital-code/actions.d.ts +11 -0
  7. package/dist/_internal/server/features/digital-code/actions.js +30 -0
  8. package/dist/_internal/server/features/digital-code/index.d.ts +1 -0
  9. package/dist/_internal/server/features/digital-code/index.js +1 -0
  10. package/dist/_internal/server/features/digital-code/og.js +9 -51
  11. package/dist/_internal/server/features/events/og.js +10 -49
  12. package/dist/_internal/server/features/item-requests/data.d.ts +17 -0
  13. package/dist/_internal/server/features/item-requests/data.js +20 -0
  14. package/dist/_internal/server/features/item-requests/index.d.ts +2 -0
  15. package/dist/_internal/server/features/item-requests/index.js +2 -0
  16. package/dist/_internal/server/features/item-requests/og.d.ts +40 -0
  17. package/dist/_internal/server/features/item-requests/og.js +136 -0
  18. package/dist/_internal/server/features/live/actions.d.ts +5 -0
  19. package/dist/_internal/server/features/live/actions.js +24 -0
  20. package/dist/_internal/server/features/live/index.d.ts +1 -0
  21. package/dist/_internal/server/features/live/index.js +1 -0
  22. package/dist/_internal/server/features/live/og.js +9 -51
  23. package/dist/_internal/server/features/media/contextGuards.js +19 -8
  24. package/dist/_internal/server/features/pre-orders/og.js +8 -32
  25. package/dist/_internal/server/features/prize-draws/data.d.ts +17 -0
  26. package/dist/_internal/server/features/prize-draws/data.js +20 -0
  27. package/dist/_internal/server/features/prize-draws/index.d.ts +2 -0
  28. package/dist/_internal/server/features/prize-draws/index.js +2 -0
  29. package/dist/_internal/server/features/prize-draws/og.d.ts +30 -0
  30. package/dist/_internal/server/features/prize-draws/og.js +50 -0
  31. package/dist/_internal/server/features/products/og.js +8 -33
  32. package/dist/_internal/server/features/scams/og.js +1 -1
  33. package/dist/_internal/server/features/seo/og-layout.d.ts +42 -0
  34. package/dist/_internal/server/features/seo/og-layout.js +69 -0
  35. package/dist/_internal/server/features/stores/og.js +8 -41
  36. package/dist/_internal/server/features/sublisting-categories/og.js +11 -42
  37. package/dist/_internal/shared/actions/bulk-helpers.d.ts +3 -0
  38. package/dist/_internal/shared/actions/bulk-helpers.js +19 -0
  39. package/dist/_internal/shared/config/schema.d.ts +4 -4
  40. package/dist/client.d.ts +13 -6
  41. package/dist/client.js +9 -3
  42. package/dist/configs/next.js +11 -0
  43. package/dist/constants/index.d.ts +4 -0
  44. package/dist/constants/index.js +2 -0
  45. package/dist/constants/notification-types.d.ts +20 -0
  46. package/dist/constants/notification-types.js +37 -0
  47. package/dist/constants/pagination-presets.d.ts +39 -0
  48. package/dist/constants/pagination-presets.js +38 -0
  49. package/dist/errors/messages.d.ts +0 -4
  50. package/dist/errors/messages.js +0 -4
  51. package/dist/features/account/components/AddressesIndexListing.js +3 -4
  52. package/dist/features/account/components/UserOffersPanel.js +1 -1
  53. package/dist/features/account/components/UserSidebar.js +14 -10
  54. package/dist/features/account/components/UserSupportView.d.ts +1 -2
  55. package/dist/features/account/components/UserSupportView.js +9 -1
  56. package/dist/features/admin/actions/admin-actions.js +16 -1
  57. package/dist/features/admin/components/AdminAllEventEntriesView.d.ts +2 -3
  58. package/dist/features/admin/components/AdminAllEventEntriesView.js +50 -89
  59. package/dist/features/admin/components/AdminBidsView.d.ts +2 -3
  60. package/dist/features/admin/components/AdminBidsView.js +64 -104
  61. package/dist/features/admin/components/AdminBlogView.d.ts +3 -7
  62. package/dist/features/admin/components/AdminBlogView.js +53 -88
  63. package/dist/features/admin/components/AdminBrandEditorView.js +14 -17
  64. package/dist/features/admin/components/AdminBrandsView.d.ts +2 -3
  65. package/dist/features/admin/components/AdminBrandsView.js +85 -89
  66. package/dist/features/admin/components/AdminBundlesView.js +68 -130
  67. package/dist/features/admin/components/AdminCarouselView.d.ts +2 -2
  68. package/dist/features/admin/components/AdminCarouselView.js +22 -70
  69. package/dist/features/admin/components/AdminCartsView.d.ts +2 -3
  70. package/dist/features/admin/components/AdminCartsView.js +39 -89
  71. package/dist/features/admin/components/AdminCategoriesView.d.ts +3 -3
  72. package/dist/features/admin/components/AdminCategoriesView.js +97 -96
  73. package/dist/features/admin/components/AdminCategoryEditorView.js +2 -6
  74. package/dist/features/admin/components/AdminClassifiedView.d.ts +3 -0
  75. package/dist/features/admin/components/AdminClassifiedView.js +44 -0
  76. package/dist/features/admin/components/AdminContactView.d.ts +2 -2
  77. package/dist/features/admin/components/AdminContactView.js +105 -130
  78. package/dist/features/admin/components/AdminCouponEditorView.js +14 -17
  79. package/dist/features/admin/components/AdminCouponsView.d.ts +3 -6
  80. package/dist/features/admin/components/AdminCouponsView.js +69 -97
  81. package/dist/features/admin/components/AdminDigitalCodesView.d.ts +3 -0
  82. package/dist/features/admin/components/AdminDigitalCodesView.js +51 -0
  83. package/dist/features/admin/components/AdminFaqEditorView.js +14 -17
  84. package/dist/features/admin/components/AdminFaqsView.d.ts +4 -4
  85. package/dist/features/admin/components/AdminFaqsView.js +79 -86
  86. package/dist/features/admin/components/AdminFeatureEditorView.js +7 -9
  87. package/dist/features/admin/components/AdminFeaturesView.d.ts +2 -3
  88. package/dist/features/admin/components/AdminFeaturesView.js +57 -70
  89. package/dist/features/admin/components/AdminGroupedListingsView.d.ts +3 -0
  90. package/dist/features/admin/components/AdminGroupedListingsView.js +43 -0
  91. package/dist/features/admin/components/AdminHistoryView.d.ts +2 -3
  92. package/dist/features/admin/components/AdminHistoryView.js +35 -52
  93. package/dist/features/admin/components/AdminListingScaffold.d.ts +2 -2
  94. package/dist/features/admin/components/AdminListingScaffold.js +3 -3
  95. package/dist/features/admin/components/AdminLiveView.d.ts +3 -0
  96. package/dist/features/admin/components/AdminLiveView.js +50 -0
  97. package/dist/features/admin/components/AdminNewsletterView.d.ts +2 -2
  98. package/dist/features/admin/components/AdminNewsletterView.js +68 -108
  99. package/dist/features/admin/components/AdminNotificationsView.d.ts +2 -3
  100. package/dist/features/admin/components/AdminNotificationsView.js +67 -99
  101. package/dist/features/admin/components/AdminOrderEditorView.js +10 -10
  102. package/dist/features/admin/components/AdminOrdersView.d.ts +2 -3
  103. package/dist/features/admin/components/AdminOrdersView.js +93 -113
  104. package/dist/features/admin/components/AdminPayoutsView.d.ts +2 -3
  105. package/dist/features/admin/components/AdminPayoutsView.js +51 -97
  106. package/dist/features/admin/components/AdminPrizeDrawsView.d.ts +2 -3
  107. package/dist/features/admin/components/AdminPrizeDrawsView.js +41 -83
  108. package/dist/features/admin/components/AdminProductEditorView.js +3 -7
  109. package/dist/features/admin/components/AdminProductsView.d.ts +4 -4
  110. package/dist/features/admin/components/AdminProductsView.js +166 -167
  111. package/dist/features/admin/components/AdminReturnRequestsView.d.ts +1 -1
  112. package/dist/features/admin/components/AdminReturnRequestsView.js +64 -66
  113. package/dist/features/admin/components/AdminReviewsView.d.ts +3 -7
  114. package/dist/features/admin/components/AdminReviewsView.js +94 -116
  115. package/dist/features/admin/components/AdminScammersView.d.ts +2 -3
  116. package/dist/features/admin/components/AdminScammersView.js +53 -103
  117. package/dist/features/admin/components/AdminSectionsView.js +1 -1
  118. package/dist/features/admin/components/AdminSessionsView.d.ts +2 -3
  119. package/dist/features/admin/components/AdminSessionsView.js +62 -95
  120. package/dist/features/admin/components/AdminStoreAddressesView.d.ts +1 -1
  121. package/dist/features/admin/components/AdminStoreAddressesView.js +39 -53
  122. package/dist/features/admin/components/AdminStoreEditorView.js +21 -8
  123. package/dist/features/admin/components/AdminStoresView.d.ts +2 -3
  124. package/dist/features/admin/components/AdminStoresView.js +67 -105
  125. package/dist/features/admin/components/AdminSublistingCategoriesView.d.ts +1 -1
  126. package/dist/features/admin/components/AdminSublistingCategoriesView.js +29 -49
  127. package/dist/features/admin/components/AdminSublistingCategoryEditorView.js +17 -20
  128. package/dist/features/admin/components/AdminSupportTicketDetailView.d.ts +10 -1
  129. package/dist/features/admin/components/AdminSupportTicketDetailView.js +191 -5
  130. package/dist/features/admin/components/AdminSupportTicketsView.d.ts +2 -3
  131. package/dist/features/admin/components/AdminSupportTicketsView.js +65 -102
  132. package/dist/features/admin/components/AdminTeamView.d.ts +2 -2
  133. package/dist/features/admin/components/AdminTeamView.js +42 -85
  134. package/dist/features/admin/components/AdminUserEditorView.d.ts +11 -1
  135. package/dist/features/admin/components/AdminUserEditorView.js +80 -6
  136. package/dist/features/admin/components/AdminUsersView.d.ts +2 -3
  137. package/dist/features/admin/components/AdminUsersView.js +108 -106
  138. package/dist/features/admin/components/AdminViewCards.d.ts +1 -1
  139. package/dist/features/admin/components/AdminWishlistsView.d.ts +2 -3
  140. package/dist/features/admin/components/AdminWishlistsView.js +36 -62
  141. package/dist/features/admin/components/DataListingView.d.ts +122 -0
  142. package/dist/features/admin/components/DataListingView.js +66 -0
  143. package/dist/features/admin/components/index.d.ts +10 -4
  144. package/dist/features/admin/components/index.js +6 -2
  145. package/dist/features/admin/constants/filter-tabs.d.ts +23 -17
  146. package/dist/features/admin/constants/filter-tabs.js +21 -17
  147. package/dist/features/admin/hooks/useAdminListing.d.ts +59 -0
  148. package/dist/features/admin/hooks/useAdminListing.js +71 -0
  149. package/dist/features/admin/schemas/firestore.js +6 -7
  150. package/dist/features/auctions/server.d.ts +0 -1
  151. package/dist/features/auctions/server.js +0 -1
  152. package/dist/features/auth/actions/realtime-token-actions.js +1 -1
  153. package/dist/features/auth/repository/user.repository.js +1 -1
  154. package/dist/features/auth/schemas/firestore.d.ts +1 -0
  155. package/dist/features/blog/components/BlogIndexListing.js +3 -6
  156. package/dist/features/cart/repository/cart.repository.d.ts +4 -1
  157. package/dist/features/cart/repository/cart.repository.js +12 -0
  158. package/dist/features/categories/components/CategoriesIndexListing.js +3 -6
  159. package/dist/features/checkout/hooks/useCheckoutApi.d.ts +0 -2
  160. package/dist/features/checkout/index.d.ts +1 -1
  161. package/dist/features/events/components/AdminEventsView.d.ts +3 -3
  162. package/dist/features/events/components/AdminEventsView.js +50 -86
  163. package/dist/features/events/components/EventOfferCard.d.ts +19 -0
  164. package/dist/features/events/components/EventOfferCard.js +29 -0
  165. package/dist/features/events/components/EventRaffleEntryForm.d.ts +25 -0
  166. package/dist/features/events/components/EventRaffleEntryForm.js +37 -0
  167. package/dist/features/events/components/EventRafflesSection.d.ts +1 -4
  168. package/dist/features/events/components/EventRafflesSection.js +17 -6
  169. package/dist/features/events/components/EventSaleBanner.d.ts +21 -0
  170. package/dist/features/events/components/EventSaleBanner.js +18 -0
  171. package/dist/features/events/components/EventsIndexListing.js +3 -4
  172. package/dist/features/events/components/index.d.ts +6 -0
  173. package/dist/features/events/components/index.js +4 -0
  174. package/dist/features/events/repository/event-entry.repository.d.ts +5 -0
  175. package/dist/features/events/repository/event-entry.repository.js +7 -0
  176. package/dist/features/filters/AsyncFacetSection.d.ts +1 -1
  177. package/dist/features/homepage/components/AnnouncementBar.d.ts +4 -1
  178. package/dist/features/homepage/components/AnnouncementBar.js +51 -4
  179. package/dist/features/homepage/components/FAQSection.d.ts +0 -5
  180. package/dist/features/homepage/components/MarketplaceHomepageView.d.ts +3 -1
  181. package/dist/features/homepage/components/MarketplaceHomepageView.js +2 -2
  182. package/dist/features/homepage/components/index.d.ts +1 -1
  183. package/dist/features/homepage/components/index.js +1 -1
  184. package/dist/features/homepage/lib/live-stats.js +1 -1
  185. package/dist/features/homepage/lib/section-renderer.d.ts +2 -2
  186. package/dist/features/homepage/lib/section-renderer.js +2 -2
  187. package/dist/features/homepage/schemas/firestore.d.ts +0 -2
  188. package/dist/features/layout/index.d.ts +0 -2
  189. package/dist/features/layout/index.js +0 -1
  190. package/dist/features/orders/repository/orders.repository.d.ts +0 -1
  191. package/dist/features/orders/repository/orders.repository.js +0 -1
  192. package/dist/features/orders/server.d.ts +1 -1
  193. package/dist/features/orders/server.js +1 -1
  194. package/dist/features/pre-orders/server.d.ts +0 -1
  195. package/dist/features/pre-orders/server.js +0 -1
  196. package/dist/features/products/components/GroupSettingsPanel.js +65 -49
  197. package/dist/features/products/components/PrizeDrawItemsEditor.js +2 -2
  198. package/dist/features/products/components/PrizeDrawsSection.d.ts +1 -4
  199. package/dist/features/products/components/PrizeDrawsSection.js +17 -6
  200. package/dist/features/products/components/PrizeRevealModal.js +1 -1
  201. package/dist/features/products/components/ProductCardMetadataSection.d.ts +11 -0
  202. package/dist/features/products/components/ProductCardMetadataSection.js +25 -0
  203. package/dist/features/products/components/ProductDetailPageView.js +3 -1
  204. package/dist/features/products/components/ProductFeaturesSelector.js +1 -1
  205. package/dist/features/products/components/ProductGradingTab.d.ts +13 -0
  206. package/dist/features/products/components/ProductGradingTab.js +25 -0
  207. package/dist/features/products/components/ProductGrid.js +14 -2
  208. package/dist/features/products/components/ProductTabsShell.d.ts +5 -1
  209. package/dist/features/products/components/ProductTabsShell.js +6 -1
  210. package/dist/features/products/components/index.d.ts +4 -0
  211. package/dist/features/products/components/index.js +3 -0
  212. package/dist/features/products/constants/action-defs.d.ts +5 -0
  213. package/dist/features/products/constants/action-defs.js +52 -32
  214. package/dist/features/products/constants/sieve.d.ts +24 -4
  215. package/dist/features/products/constants/sieve.js +20 -11
  216. package/dist/features/products/repository/products.repository.d.ts +0 -2
  217. package/dist/features/products/repository/products.repository.js +0 -2
  218. package/dist/features/products/schemas/firestore.d.ts +17 -0
  219. package/dist/features/products/schemas/product-features.validators.d.ts +2 -2
  220. package/dist/features/products/schemas/product-templates.d.ts +2 -4
  221. package/dist/features/products/server.d.ts +1 -1
  222. package/dist/features/products/server.js +1 -1
  223. package/dist/features/products/types/index.d.ts +4 -0
  224. package/dist/features/promotions/components/CouponCard.js +5 -5
  225. package/dist/features/promotions/components/CouponsIndexListing.js +3 -2
  226. package/dist/features/promotions/server.d.ts +0 -1
  227. package/dist/features/promotions/server.js +0 -1
  228. package/dist/features/reviews/components/ReviewsIndexListing.js +3 -4
  229. package/dist/features/reviews/repository/reviews.repository.d.ts +0 -1
  230. package/dist/features/reviews/repository/reviews.repository.js +0 -1
  231. package/dist/features/reviews/server.d.ts +1 -1
  232. package/dist/features/reviews/server.js +1 -1
  233. package/dist/features/search/api/route.js +44 -1
  234. package/dist/features/search/components/Search.js +2 -0
  235. package/dist/features/search/hooks/useNavSuggestions.d.ts +5 -1
  236. package/dist/features/search/hooks/useNavSuggestions.js +31 -4
  237. package/dist/features/seller/components/BrandInlineSelect.js +2 -2
  238. package/dist/features/seller/components/CategoryInlineSelect.js +2 -2
  239. package/dist/features/seller/components/SellerAddressesView.js +10 -20
  240. package/dist/features/seller/components/SellerAuctionsView.d.ts +3 -3
  241. package/dist/features/seller/components/SellerAuctionsView.js +67 -106
  242. package/dist/features/seller/components/SellerBidsView.js +6 -6
  243. package/dist/features/seller/components/SellerBundlesView.js +72 -105
  244. package/dist/features/seller/components/SellerClassifiedView.js +74 -105
  245. package/dist/features/seller/components/SellerCouponEditorView.js +1 -1
  246. package/dist/features/seller/components/SellerCouponsView.d.ts +2 -2
  247. package/dist/features/seller/components/SellerCouponsView.js +51 -96
  248. package/dist/features/seller/components/SellerDigitalCodesView.js +70 -103
  249. package/dist/features/seller/components/SellerGroupedListingsView.js +34 -54
  250. package/dist/features/seller/components/SellerLiveView.js +70 -99
  251. package/dist/features/seller/components/SellerOffersPanel.js +1 -1
  252. package/dist/features/seller/components/SellerOffersView.d.ts +2 -2
  253. package/dist/features/seller/components/SellerOffersView.js +37 -70
  254. package/dist/features/seller/components/SellerOrdersView.d.ts +2 -2
  255. package/dist/features/seller/components/SellerOrdersView.js +10 -24
  256. package/dist/features/seller/components/SellerPayoutMethodsView.js +12 -24
  257. package/dist/features/seller/components/SellerPayoutsView.d.ts +2 -2
  258. package/dist/features/seller/components/SellerPayoutsView.js +34 -69
  259. package/dist/features/seller/components/SellerPreOrdersView.d.ts +2 -2
  260. package/dist/features/seller/components/SellerPreOrdersView.js +55 -97
  261. package/dist/features/seller/components/SellerPrizeDrawsView.d.ts +2 -2
  262. package/dist/features/seller/components/SellerPrizeDrawsView.js +55 -97
  263. package/dist/features/seller/components/SellerProductShell.d.ts +1 -1
  264. package/dist/features/seller/components/SellerProductsFilterDrawer.d.ts +1 -1
  265. package/dist/features/seller/components/SellerProductsFilterDrawer.js +3 -6
  266. package/dist/features/seller/components/SellerProductsView.d.ts +2 -2
  267. package/dist/features/seller/components/SellerProductsView.js +24 -32
  268. package/dist/features/seller/components/SellerShippingConfigsView.js +12 -24
  269. package/dist/features/seller/components/SellerSidebar.d.ts +0 -4
  270. package/dist/features/seller/components/SellerSidebar.js +0 -2
  271. package/dist/features/seller/components/SellerStoreCategoriesView.js +15 -34
  272. package/dist/features/seller/components/SellerTemplatesView.js +27 -43
  273. package/dist/features/seller/components/SellersListView.d.ts +1 -2
  274. package/dist/features/seller/components/analytics/SellerAnalyticsStats.d.ts +5 -0
  275. package/dist/features/seller/components/analytics/SellerAnalyticsStats.js +2 -8
  276. package/dist/features/seller/components/index.d.ts +0 -3
  277. package/dist/features/seller/components/index.js +0 -2
  278. package/dist/features/seller/server.d.ts +0 -1
  279. package/dist/features/seller/server.js +0 -1
  280. package/dist/features/shell/FormShell.d.ts +1 -1
  281. package/dist/features/shell/FormShell.js +4 -1
  282. package/dist/features/shell/field-groups/ImageFieldGroup.d.ts +18 -0
  283. package/dist/features/shell/field-groups/ImageFieldGroup.js +15 -0
  284. package/dist/features/shell/field-groups/SeoFieldGroup.d.ts +22 -0
  285. package/dist/features/shell/field-groups/SeoFieldGroup.js +16 -0
  286. package/dist/features/shell/field-groups/StatusFieldGroup.d.ts +35 -0
  287. package/dist/features/shell/field-groups/StatusFieldGroup.js +16 -0
  288. package/dist/features/shell/field-groups/TitleDescriptionGroup.d.ts +40 -0
  289. package/dist/features/shell/field-groups/TitleDescriptionGroup.js +16 -0
  290. package/dist/features/shell/field-groups/index.d.ts +13 -0
  291. package/dist/features/shell/field-groups/index.js +9 -0
  292. package/dist/features/shell/index.d.ts +2 -0
  293. package/dist/features/shell/index.js +1 -0
  294. package/dist/features/stores/components/StoreCapabilitiesGuideView.d.ts +1 -2
  295. package/dist/features/stores/components/StoreFinanceGuideView.d.ts +1 -2
  296. package/dist/features/stores/components/StoreHeader.js +2 -1
  297. package/dist/features/stores/components/StoreListingsGuideView.d.ts +1 -2
  298. package/dist/features/stores/components/StoreOrdersGuideView.d.ts +1 -2
  299. package/dist/features/stores/components/StoreReviewsListing.js +3 -4
  300. package/dist/features/stores/components/StoreScopedSearch.d.ts +16 -0
  301. package/dist/features/stores/components/StoreScopedSearch.js +27 -0
  302. package/dist/features/stores/components/StoreSettingsGuideView.d.ts +1 -2
  303. package/dist/features/stores/components/StoresIndexListing.js +3 -4
  304. package/dist/features/stores/server.d.ts +0 -1
  305. package/dist/features/stores/server.js +0 -1
  306. package/dist/features/support/schemas/firestore.d.ts +22 -1
  307. package/dist/features/support/schemas/firestore.js +10 -0
  308. package/dist/features/wishlist/server.d.ts +0 -1
  309. package/dist/features/wishlist/server.js +0 -1
  310. package/dist/index.d.ts +11 -33
  311. package/dist/index.js +17 -62
  312. package/dist/next/routing/route-map.d.ts +8 -0
  313. package/dist/next/routing/route-map.js +4 -0
  314. package/dist/react/contexts/SessionContext.d.ts +2 -0
  315. package/dist/react/contexts/SessionContext.js +2 -0
  316. package/dist/react/hooks/useEntityDelete.d.ts +15 -0
  317. package/dist/react/hooks/useEntityDelete.js +39 -0
  318. package/dist/react/hooks/useListingTypeFlags.d.ts +32 -0
  319. package/dist/react/hooks/useListingTypeFlags.js +19 -0
  320. package/dist/react/index.d.ts +2 -0
  321. package/dist/react/index.js +2 -0
  322. package/dist/repositories/index.d.ts +3 -3
  323. package/dist/repositories/index.js +3 -3
  324. package/dist/security/index.d.ts +1 -1
  325. package/dist/security/index.js +1 -1
  326. package/dist/security/pii-redact.d.ts +8 -0
  327. package/dist/security/pii-redact.js +10 -1
  328. package/dist/seed/grouped-listings-seed-data.d.ts +4 -0
  329. package/dist/seed/products-preorders-seed-data.d.ts +4 -0
  330. package/dist/seed/products-prize-draws-seed-data.js +3 -0
  331. package/dist/seed/site-settings-seed-data.js +5 -5
  332. package/dist/seed/sub-listings-seed-data.d.ts +4 -0
  333. package/dist/server.d.ts +2 -0
  334. package/dist/server.js +4 -0
  335. package/dist/styles.css +54 -395
  336. package/dist/tailwind-utilities.css +1 -1
  337. package/dist/ui/components/BaseListingCard.d.ts +10 -0
  338. package/dist/ui/components/BaseListingCard.js +17 -1
  339. package/dist/ui/components/DetailPageGallery.d.ts +32 -0
  340. package/dist/ui/components/DetailPageGallery.js +47 -0
  341. package/dist/ui/components/DetailPageHero.d.ts +30 -0
  342. package/dist/ui/components/DetailPageHero.js +22 -0
  343. package/dist/ui/components/DetailPageTabs.d.ts +34 -0
  344. package/dist/ui/components/DetailPageTabs.js +38 -0
  345. package/dist/ui/components/HorizontalScroller.style.css +15 -2
  346. package/dist/ui/components/ListingFilterDrawer.d.ts +10 -0
  347. package/dist/ui/components/ListingFilterDrawer.js +8 -0
  348. package/dist/ui/components/ListingLayout.d.ts +11 -2
  349. package/dist/ui/components/ListingLayout.js +12 -6
  350. package/dist/ui/components/PaginatedSelect.d.ts +66 -0
  351. package/dist/ui/components/PaginatedSelect.js +201 -0
  352. package/dist/ui/components/PaginatedSelect.style.css +254 -0
  353. package/dist/ui/components/Semantic.d.ts +0 -4
  354. package/dist/ui/components/Semantic.js +0 -2
  355. package/dist/ui/components/SettingsSection.d.ts +47 -0
  356. package/dist/ui/components/SettingsSection.js +38 -0
  357. package/dist/ui/components/index.style.css +1 -4
  358. package/dist/ui/index.d.ts +14 -14
  359. package/dist/ui/index.js +7 -7
  360. package/dist/utils/id-generators.d.ts +1 -18
  361. package/dist/utils/id-generators.js +51 -18
  362. package/dist/validation/schemas.d.ts +25 -0
  363. package/dist/validation/schemas.js +28 -0
  364. package/package.json +1 -1
@@ -21,6 +21,8 @@
21
21
  import { NextResponse } from "next/server.js";
22
22
  import { getProviders } from "../../../contracts";
23
23
  import { SearchRepository } from "../repository/search.repository";
24
+ import { isListingTypeEnabled, enabledListingTypes, } from "../../../_internal/shared/listing-types/feature-flags";
25
+ import { getSiteSettingsGlobal } from "../../admin/utils/getSiteSettingsGlobal";
24
26
  function param(url, key) {
25
27
  return url.searchParams.get(key);
26
28
  }
@@ -55,6 +57,32 @@ export async function GET(request) {
55
57
  const maxPriceRaw = numParam(url, "maxPrice", 0);
56
58
  const page = numParam(url, "page", 1);
57
59
  const pageSize = Math.min(numParam(url, "pageSize", 20), 100);
60
+ // W1-43 — listing-type feature flag gating. Reject a search scoped to a
61
+ // disabled listing type with an empty result; for unscoped searches,
62
+ // strip disabled types post-query so search-bar suggestions stay clean.
63
+ let siteSettings = null;
64
+ try {
65
+ siteSettings = await getSiteSettingsGlobal();
66
+ }
67
+ catch {
68
+ siteSettings = null;
69
+ }
70
+ if (listingType && siteSettings && !isListingTypeEnabled(listingType, siteSettings)) {
71
+ return NextResponse.json({
72
+ success: true,
73
+ data: {
74
+ items: [],
75
+ total: 0,
76
+ page,
77
+ pageSize,
78
+ totalPages: 0,
79
+ hasMore: false,
80
+ backend: "firestore",
81
+ listingTypeDisabled: true,
82
+ },
83
+ });
84
+ }
85
+ const enabledSet = new Set(siteSettings ? enabledListingTypes(siteSettings) : []);
58
86
  const repo = new SearchRepository(db.getRepository("products"));
59
87
  const result = await repo.search({
60
88
  q: param(url, "q") ?? undefined,
@@ -70,9 +98,24 @@ export async function GET(request) {
70
98
  page,
71
99
  pageSize,
72
100
  });
101
+ // W1-43 — when no specific listingType filter, strip disabled types from
102
+ // the surface. Skipped when all types are enabled or settings failed to load.
103
+ let filteredItems = result.items;
104
+ let filteredTotal = result.total;
105
+ if (!listingType && enabledSet.size > 0 && enabledSet.size < 7) {
106
+ const before = filteredItems.length;
107
+ filteredItems = filteredItems.filter((it) => enabledSet.has(it.listingType ?? "standard"));
108
+ const removed = before - filteredItems.length;
109
+ filteredTotal = Math.max(0, filteredTotal - removed);
110
+ }
73
111
  return NextResponse.json({
74
112
  success: true,
75
- data: { ...result, backend: "firestore" },
113
+ data: {
114
+ ...result,
115
+ items: filteredItems,
116
+ total: filteredTotal,
117
+ backend: "firestore",
118
+ },
76
119
  });
77
120
  }
78
121
  catch (error) {
@@ -12,12 +12,14 @@ const DEFAULT_TYPE_ICONS = {
12
12
  category: "🗂️",
13
13
  blog: "✍️",
14
14
  event: "🎉",
15
+ product: "📦",
15
16
  };
16
17
  const DEFAULT_TYPE_BADGES = {
17
18
  page: "bg-zinc-100 text-zinc-600 dark:bg-zinc-800 dark:text-zinc-300",
18
19
  category: "bg-blue-100 text-blue-600 dark:bg-blue-900/40 dark:text-blue-300",
19
20
  blog: "bg-fuchsia-100 text-fuchsia-600 dark:bg-fuchsia-900/40 dark:text-fuchsia-300",
20
21
  event: "bg-amber-100 text-amber-600 dark:bg-amber-900/40 dark:text-amber-300",
22
+ product: "bg-emerald-100 text-emerald-600 dark:bg-emerald-900/40 dark:text-emerald-300",
21
23
  };
22
24
  function SuggestionItem({ suggestion, itemIndex, activeIndex, onSelect, onHover, typeIcons, typeBadges, }) {
23
25
  const isActive = activeIndex === itemIndex;
@@ -1,10 +1,14 @@
1
1
  export interface NavSuggestionRecord {
2
2
  objectID: string;
3
- type: "page" | "category" | "blog" | "event";
3
+ type: "page" | "category" | "blog" | "event" | "product";
4
4
  title: string;
5
5
  subtitle?: string;
6
6
  url: string;
7
7
  }
8
+ /**
9
+ * W1-19 — wired to `/api/search/suggestions` 2026-05-23. Fetches up to 20
10
+ * matches (5 per resource type) and surfaces them as typeahead rows.
11
+ */
8
12
  export declare function useNavSuggestions(query: string, selectedType?: string, debounceMs?: number): {
9
13
  suggestions: NavSuggestionRecord[];
10
14
  isLoading: boolean;
@@ -1,23 +1,48 @@
1
1
  "use client";
2
2
  import { useEffect, useRef, useState } from "react";
3
+ const SUGGESTIONS_ENDPOINT = "/api/search/suggestions";
4
+ /**
5
+ * W1-19 — wired to `/api/search/suggestions` 2026-05-23. Fetches up to 20
6
+ * matches (5 per resource type) and surfaces them as typeahead rows.
7
+ */
3
8
  export function useNavSuggestions(query, selectedType, debounceMs = 250) {
4
9
  const [suggestions, setSuggestions] = useState([]);
5
10
  const [isLoading, setIsLoading] = useState(false);
6
11
  const timerRef = useRef(null);
12
+ const abortRef = useRef(null);
7
13
  useEffect(() => {
8
14
  if (timerRef.current)
9
15
  clearTimeout(timerRef.current);
10
- if (!query.trim()) {
16
+ if (abortRef.current)
17
+ abortRef.current.abort();
18
+ const trimmed = query.trim();
19
+ if (!trimmed) {
11
20
  setSuggestions([]);
21
+ setIsLoading(false);
12
22
  return;
13
23
  }
14
24
  timerRef.current = setTimeout(async () => {
15
25
  setIsLoading(true);
26
+ const ctrl = new AbortController();
27
+ abortRef.current = ctrl;
16
28
  try {
17
- setSuggestions([]);
29
+ const params = new URLSearchParams({ q: trimmed });
30
+ if (selectedType && selectedType !== "all") {
31
+ params.set("type", selectedType);
32
+ }
33
+ const res = await fetch(`${SUGGESTIONS_ENDPOINT}?${params.toString()}`, { signal: ctrl.signal, credentials: "same-origin" });
34
+ if (!res.ok) {
35
+ setSuggestions([]);
36
+ return;
37
+ }
38
+ const body = (await res.json());
39
+ const items = body.data?.suggestions ?? body.suggestions ?? [];
40
+ setSuggestions(items);
18
41
  }
19
- catch {
20
- setSuggestions([]);
42
+ catch (err) {
43
+ if (err.name !== "AbortError") {
44
+ setSuggestions([]);
45
+ }
21
46
  }
22
47
  finally {
23
48
  setIsLoading(false);
@@ -26,6 +51,8 @@ export function useNavSuggestions(query, selectedType, debounceMs = 250) {
26
51
  return () => {
27
52
  if (timerRef.current)
28
53
  clearTimeout(timerRef.current);
54
+ if (abortRef.current)
55
+ abortRef.current.abort();
29
56
  };
30
57
  }, [query, selectedType, debounceMs]);
31
58
  return { suggestions, isLoading };
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
  import { jsx as _jsx } from "react/jsx-runtime";
3
- import { InlineCreateSelect } from "../../../ui/components/InlineCreateSelect";
3
+ import { PaginatedSelect } from "../../../ui/components/PaginatedSelect";
4
4
  import { BrandQuickCreateForm } from "../../admin/components/BrandQuickCreateForm";
5
5
  import { apiClient } from "../../../http";
6
6
  import { ADMIN_ENDPOINTS } from "../../../constants/api-endpoints";
@@ -40,7 +40,7 @@ async function loadPublicBrandOptions(query, page) {
40
40
  }
41
41
  export function BrandInlineSelect({ value, onChange, placeholder = "Search brands…", disabled, allowCreate = true, }) {
42
42
  const loadOptions = allowCreate ? loadAdminBrandOptions : loadPublicBrandOptions;
43
- return (_jsx(InlineCreateSelect, { value: value || null, onChange: (v) => onChange(v ?? ""), loadOptions: loadOptions, placeholder: placeholder, disabled: disabled, createLabel: "brand", drawerTitle: "Create Brand", renderCreateForm: allowCreate
43
+ return (_jsx(PaginatedSelect, { value: value || null, onChange: (v) => onChange(v ?? ""), loadOptions: loadOptions, placeholder: placeholder, disabled: disabled, createLabel: "brand", drawerTitle: "Create Brand", renderCreateForm: allowCreate
44
44
  ? ({ onCreated, onCancel }) => (_jsx(BrandQuickCreateForm, { onSaved: (id, name) => onCreated({ value: id, label: name }), onCancel: onCancel }))
45
45
  : undefined }));
46
46
  }
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
  import { jsx as _jsx } from "react/jsx-runtime";
3
- import { InlineCreateSelect } from "../../../ui/components/InlineCreateSelect";
3
+ import { PaginatedSelect } from "../../../ui/components/PaginatedSelect";
4
4
  import { CategoryQuickCreateForm } from "../../admin/components/CategoryQuickCreateForm";
5
5
  import { apiClient } from "../../../http";
6
6
  import { ADMIN_ENDPOINTS } from "../../../constants/api-endpoints";
@@ -37,7 +37,7 @@ async function loadPublicCategoryOptions(query, _page) {
37
37
  }
38
38
  export function CategoryInlineSelect({ value, onChange, placeholder = "Search categories…", disabled, allowCreate = false, }) {
39
39
  const loadOptions = allowCreate ? loadAdminCategoryOptions : loadPublicCategoryOptions;
40
- return (_jsx(InlineCreateSelect, { value: value || null, onChange: (v) => onChange(v ?? ""), loadOptions: loadOptions, placeholder: placeholder, disabled: disabled, createLabel: "category", drawerTitle: "Create Category", renderCreateForm: allowCreate
40
+ return (_jsx(PaginatedSelect, { value: value || null, onChange: (v) => onChange(v ?? ""), loadOptions: loadOptions, placeholder: placeholder, disabled: disabled, createLabel: "category", drawerTitle: "Create Category", renderCreateForm: allowCreate
41
41
  ? ({ onCreated, onCancel }) => (_jsx(CategoryQuickCreateForm, { onSaved: (id, name) => onCreated({ value: id, label: name }), onCancel: onCancel }))
42
42
  : undefined }));
43
43
  }
@@ -2,9 +2,10 @@
2
2
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
3
  import { useCallback, useEffect, useState } from "react";
4
4
  import { MapPin, Pencil, Plus, Trash2, Star } from "lucide-react";
5
- import { Button, Div, Heading, Row, SideDrawer, Text } from "../../../ui";
5
+ import { Button, ConfirmDeleteModal, Div, Heading, Row, SideDrawer, Text } from "../../../ui";
6
6
  import { ROW_ACTION_META, ROW_ACTION_ID } from "../../../features/products/constants/action-defs";
7
7
  import { SELLER_ENDPOINTS } from "../../../constants/api-endpoints";
8
+ import { useEntityDelete } from "../../../react/hooks/useEntityDelete";
8
9
  const INPUT_CLS = "w-full rounded-lg border border-zinc-300 dark:border-slate-600 bg-white dark:bg-slate-800 px-3 py-2 text-sm text-zinc-900 dark:text-zinc-100 placeholder-zinc-400 dark:placeholder-zinc-500 focus:outline-none focus:ring-2 focus:ring-[var(--appkit-color-primary)]";
9
10
  const CLS_GRID_2_COL = "grid grid-cols-2 gap-3";
10
11
  function Field({ label, hint, children }) {
@@ -57,7 +58,7 @@ export function SellerAddressesView({ apiBase = SELLER_ENDPOINTS.STORE_ADDRESSES
57
58
  const [draft, setDraft] = useState(BLANK);
58
59
  const [saving, setSaving] = useState(false);
59
60
  const [saveError, setSaveError] = useState(null);
60
- const [deletingId, setDeletingId] = useState(null);
61
+ const [deleteTargetAddr, setDeleteTargetAddr] = useState(null);
61
62
  const load = useCallback(async () => {
62
63
  setIsLoading(true);
63
64
  setErrorMessage(null);
@@ -126,24 +127,13 @@ export function SellerAddressesView({ apiBase = SELLER_ENDPOINTS.STORE_ADDRESSES
126
127
  setSaving(false);
127
128
  }
128
129
  };
129
- const handleDelete = async (addr) => {
130
- if (!confirm(`Delete address "${addr.label}"? This cannot be undone.`))
131
- return;
132
- setDeletingId(addr.id);
133
- try {
134
- const res = await fetch(`${apiBase}/${addr.id}`, { method: "DELETE" });
135
- if (!res.ok)
136
- throw new Error("Delete failed");
137
- await load();
138
- }
139
- catch {
140
- alert("Failed to delete address. Please try again.");
141
- }
142
- finally {
143
- setDeletingId(null);
144
- }
145
- };
130
+ const { deletingId, handleDelete: deleteById } = useEntityDelete({
131
+ endpoint: apiBase,
132
+ successMessage: "Address deleted.",
133
+ onSuccess: () => { load(); },
134
+ });
135
+ const handleDelete = (addr) => setDeleteTargetAddr(addr);
146
136
  const set = (key, value) => setDraft((p) => ({ ...p, [key]: value }));
147
137
  const handleTextField = (key) => (e) => set(key, e.target.value);
148
- return (_jsxs("div", { className: "min-h-screen", children: [_jsxs("div", { className: "sticky z-10 bg-white/95 dark:bg-slate-900/95 backdrop-blur-sm border-b border-zinc-200 dark:border-slate-700 px-4 py-3 flex items-center justify-between", style: { top: "var(--header-height, 0px)" }, children: [_jsxs(_Fragment, { children: [_jsx(Heading, { level: 2, className: "text-base font-semibold text-zinc-900 dark:text-zinc-100", children: "Pickup Addresses" }), _jsx(Text, { className: "text-xs text-zinc-500 dark:text-zinc-400 mt-0.5", children: "Manage your store's pickup and return locations" })] }), _jsxs(Button, { size: "sm", onClick: openAdd, className: "flex items-center gap-1.5", children: [_jsx(Plus, { className: "h-4 w-4" }), _jsx("span", { children: "Add Address" })] })] }), _jsxs("div", { className: "py-6 px-4 sm:px-6 max-w-2xl", children: [errorMessage && (_jsx(Div, { className: "mb-4 rounded-xl border border-red-200 bg-error-surface dark:border-red-900/60 px-4 py-3 text-sm text-error", children: errorMessage })), isLoading ? (_jsx("div", { className: "flex justify-center py-16", children: _jsx("div", { className: "h-6 w-6 animate-spin rounded-full border-2 border-[var(--appkit-color-primary)] border-t-transparent" }) })) : addresses.length === 0 ? (_jsxs(Div, { className: "rounded-xl border-2 border-dashed border-zinc-200 dark:border-slate-700 py-16 flex flex-col items-center gap-3", children: [_jsx(MapPin, { className: "h-8 w-8 text-zinc-300 dark:text-slate-600" }), _jsx(Text, { className: "text-sm text-zinc-500 dark:text-zinc-400", children: "No pickup addresses yet" }), _jsx(Button, { size: "sm", variant: "outline", onClick: openAdd, children: "Add your first address" })] })) : (_jsxs(_Fragment, { children: [_jsxs(Row, { justify: "end", className: "mb-2", children: [_jsx(Button, { size: "sm", variant: listView === "table" ? "primary" : "ghost", onClick: () => setListView("table"), children: "Table" }), _jsx(Button, { size: "sm", variant: listView === "cards" ? "primary" : "ghost", onClick: () => setListView("cards"), children: "Cards" })] }), listView === "cards" ? (_jsx("div", { className: "grid gap-3", children: addresses.map((addr) => (_jsx("div", { className: deletingId === addr.id ? "opacity-50 pointer-events-none" : "", children: _jsx(AddressCard, { address: addr, onEdit: () => openEdit(addr), onDelete: () => handleDelete(addr) }) }, addr.id))) })) : (_jsx("div", { className: "overflow-x-auto rounded-lg border border-zinc-200 dark:border-slate-700", children: _jsxs("table", { className: "w-full text-sm", children: [_jsx("thead", { className: "bg-zinc-50 dark:bg-slate-800", children: _jsxs("tr", { children: [_jsx("th", { className: "text-left px-3 py-2 font-semibold", children: "Label" }), _jsx("th", { className: "text-left px-3 py-2 font-semibold", children: "Name" }), _jsx("th", { className: "text-left px-3 py-2 font-semibold", children: "City" }), _jsx("th", { className: "text-left px-3 py-2 font-semibold", children: "Phone" }), _jsx("th", { className: "text-right px-3 py-2 font-semibold", children: "Actions" })] }) }), _jsx("tbody", { children: addresses.map((addr) => (_jsxs("tr", { className: `border-t border-zinc-100 dark:border-slate-700 ${deletingId === addr.id ? "opacity-50" : ""}`, children: [_jsx("td", { className: "px-3 py-2", children: addr.label }), _jsx("td", { className: "px-3 py-2", children: addr.fullName }), _jsxs("td", { className: "px-3 py-2", children: [addr.city, ", ", addr.state] }), _jsx("td", { className: "px-3 py-2 tabular-nums", children: addr.phone }), _jsx("td", { className: "px-3 py-2 text-right", children: _jsxs(Row, { justify: "end", className: "gap-1", children: [_jsx(Button, { size: "sm", variant: "ghost", onClick: () => openEdit(addr), children: ROW_ACTION_META[ROW_ACTION_ID.EDIT].label }), _jsx(Button, { size: "sm", variant: "ghost", onClick: () => handleDelete(addr), children: ROW_ACTION_META[ROW_ACTION_ID.DELETE].label })] }) })] }, addr.id))) })] }) }))] }))] }), _jsx(SideDrawer, { isOpen: drawerOpen, onClose: closeDrawer, title: editingId ? "Edit Address" : "Add Address", footer: _jsxs("div", { className: "flex gap-2", children: [_jsx(Button, { variant: "outline", onClick: closeDrawer, className: "flex-1", children: "Cancel" }), _jsx(Button, { onClick: handleSave, disabled: saving, className: "flex-1", children: saving ? "Saving…" : editingId ? "Save Changes" : "Add Address" })] }), children: _jsxs("div", { className: "space-y-4 py-1", children: [saveError && (_jsx(Div, { className: "rounded-lg border border-red-200 bg-error-surface dark:border-red-900/60 px-3 py-2 text-sm text-error", children: saveError })), _jsx(Field, { label: "Label *", hint: "e.g. Warehouse, Shop, Home", children: _jsx("input", { type: "text", value: draft.label, onChange: handleTextField("label"), placeholder: "Warehouse", maxLength: 60, className: INPUT_CLS }) }), _jsxs("div", { className: CLS_GRID_2_COL, children: [_jsx(Field, { label: "Full Name *", children: _jsx("input", { type: "text", value: draft.fullName, onChange: handleTextField("fullName"), placeholder: "Ravi Kumar", maxLength: 100, className: INPUT_CLS }) }), _jsx(Field, { label: "Phone *", children: _jsx("input", { type: "tel", value: draft.phone, onChange: handleTextField("phone"), placeholder: "+91 98765 43210", maxLength: 20, className: INPUT_CLS }) })] }), _jsx(Field, { label: "Address Line 1 *", children: _jsx("input", { type: "text", value: draft.addressLine1, onChange: handleTextField("addressLine1"), placeholder: "Shop 12, Main Market", maxLength: 200, className: INPUT_CLS }) }), _jsx(Field, { label: "Address Line 2", children: _jsx("input", { type: "text", value: draft.addressLine2, onChange: handleTextField("addressLine2"), placeholder: "Building / Floor (optional)", maxLength: 200, className: INPUT_CLS }) }), _jsx(Field, { label: "Landmark", children: _jsx("input", { type: "text", value: draft.landmark, onChange: handleTextField("landmark"), placeholder: "Near metro station (optional)", maxLength: 100, className: INPUT_CLS }) }), _jsxs("div", { className: CLS_GRID_2_COL, children: [_jsx(Field, { label: "City *", children: _jsx("input", { type: "text", value: draft.city, onChange: handleTextField("city"), placeholder: "Mumbai", maxLength: 100, className: INPUT_CLS }) }), _jsx(Field, { label: "State *", children: _jsx("input", { type: "text", value: draft.state, onChange: handleTextField("state"), placeholder: "Maharashtra", maxLength: 100, className: INPUT_CLS }) })] }), _jsxs("div", { className: CLS_GRID_2_COL, children: [_jsx(Field, { label: "Postal Code *", children: _jsx("input", { type: "text", value: draft.postalCode, onChange: handleTextField("postalCode"), placeholder: "400001", maxLength: 10, className: INPUT_CLS }) }), _jsx(Field, { label: "Country *", children: _jsx("input", { type: "text", value: draft.country, onChange: handleTextField("country"), placeholder: "India", maxLength: 60, className: INPUT_CLS }) })] }), _jsxs("label", { className: "flex items-center gap-3 cursor-pointer", children: [_jsx("input", { type: "checkbox", checked: draft.isDefault, onChange: (e) => set("isDefault", e.target.checked), className: "h-4 w-4 rounded border-zinc-300 dark:border-slate-600 text-[var(--appkit-color-primary)] focus:ring-[var(--appkit-color-primary)]" }), _jsx("span", { className: "text-sm text-zinc-700 dark:text-zinc-300", children: "Set as default pickup address" })] })] }) })] }));
138
+ return (_jsxs("div", { className: "min-h-screen", children: [_jsxs("div", { className: "sticky z-10 bg-white/95 dark:bg-slate-900/95 backdrop-blur-sm border-b border-zinc-200 dark:border-slate-700 px-4 py-3 flex items-center justify-between", style: { top: "var(--header-height, 0px)" }, children: [_jsxs(_Fragment, { children: [_jsx(Heading, { level: 2, className: "text-base font-semibold text-zinc-900 dark:text-zinc-100", children: "Pickup Addresses" }), _jsx(Text, { className: "text-xs text-zinc-500 dark:text-zinc-400 mt-0.5", children: "Manage your store's pickup and return locations" })] }), _jsxs(Button, { size: "sm", onClick: openAdd, className: "flex items-center gap-1.5", children: [_jsx(Plus, { className: "h-4 w-4" }), _jsx("span", { children: "Add Address" })] })] }), _jsxs("div", { className: "py-6 px-4 sm:px-6 max-w-2xl", children: [errorMessage && (_jsx(Div, { className: "mb-4 rounded-xl border border-error/20 bg-error-surface px-4 py-3 text-sm text-error", children: errorMessage })), isLoading ? (_jsx("div", { className: "flex justify-center py-16", children: _jsx("div", { className: "h-6 w-6 animate-spin rounded-full border-2 border-[var(--appkit-color-primary)] border-t-transparent" }) })) : addresses.length === 0 ? (_jsxs(Div, { className: "rounded-xl border-2 border-dashed border-zinc-200 dark:border-slate-700 py-16 flex flex-col items-center gap-3", children: [_jsx(MapPin, { className: "h-8 w-8 text-zinc-300 dark:text-slate-600" }), _jsx(Text, { className: "text-sm text-zinc-500 dark:text-zinc-400", children: "No pickup addresses yet" }), _jsx(Button, { size: "sm", variant: "outline", onClick: openAdd, children: "Add your first address" })] })) : (_jsxs(_Fragment, { children: [_jsxs(Row, { justify: "end", className: "mb-2", children: [_jsx(Button, { size: "sm", variant: listView === "table" ? "primary" : "ghost", onClick: () => setListView("table"), children: "Table" }), _jsx(Button, { size: "sm", variant: listView === "cards" ? "primary" : "ghost", onClick: () => setListView("cards"), children: "Cards" })] }), listView === "cards" ? (_jsx("div", { className: "grid gap-3", children: addresses.map((addr) => (_jsx("div", { className: deletingId === addr.id ? "opacity-50 pointer-events-none" : "", children: _jsx(AddressCard, { address: addr, onEdit: () => openEdit(addr), onDelete: () => handleDelete(addr) }) }, addr.id))) })) : (_jsx("div", { className: "overflow-x-auto rounded-lg border border-zinc-200 dark:border-slate-700", children: _jsxs("table", { className: "w-full text-sm", children: [_jsx("thead", { className: "bg-zinc-50 dark:bg-slate-800", children: _jsxs("tr", { children: [_jsx("th", { className: "text-left px-3 py-2 font-semibold", children: "Label" }), _jsx("th", { className: "text-left px-3 py-2 font-semibold", children: "Name" }), _jsx("th", { className: "text-left px-3 py-2 font-semibold", children: "City" }), _jsx("th", { className: "text-left px-3 py-2 font-semibold", children: "Phone" }), _jsx("th", { className: "text-right px-3 py-2 font-semibold", children: "Actions" })] }) }), _jsx("tbody", { children: addresses.map((addr) => (_jsxs("tr", { className: `border-t border-zinc-100 dark:border-slate-700 ${deletingId === addr.id ? "opacity-50" : ""}`, children: [_jsx("td", { className: "px-3 py-2", children: addr.label }), _jsx("td", { className: "px-3 py-2", children: addr.fullName }), _jsxs("td", { className: "px-3 py-2", children: [addr.city, ", ", addr.state] }), _jsx("td", { className: "px-3 py-2 tabular-nums", children: addr.phone }), _jsx("td", { className: "px-3 py-2 text-right", children: _jsxs(Row, { justify: "end", className: "gap-1", children: [_jsx(Button, { size: "sm", variant: "ghost", onClick: () => openEdit(addr), children: ROW_ACTION_META[ROW_ACTION_ID.EDIT].label }), _jsx(Button, { size: "sm", variant: "ghost", onClick: () => handleDelete(addr), children: ROW_ACTION_META[ROW_ACTION_ID.DELETE].label })] }) })] }, addr.id))) })] }) }))] }))] }), _jsx(SideDrawer, { isOpen: drawerOpen, onClose: closeDrawer, title: editingId ? "Edit Address" : "Add Address", footer: _jsxs("div", { className: "flex gap-2", children: [_jsx(Button, { variant: "outline", onClick: closeDrawer, className: "flex-1", children: "Cancel" }), _jsx(Button, { onClick: handleSave, disabled: saving, className: "flex-1", children: saving ? "Saving…" : editingId ? "Save Changes" : "Add Address" })] }), children: _jsxs("div", { className: "space-y-4 py-1", children: [saveError && (_jsx(Div, { className: "rounded-lg border border-error/20 bg-error-surface px-3 py-2 text-sm text-error", children: saveError })), _jsx(Field, { label: "Label *", hint: "e.g. Warehouse, Shop, Home", children: _jsx("input", { type: "text", value: draft.label, onChange: handleTextField("label"), placeholder: "Warehouse", maxLength: 60, className: INPUT_CLS }) }), _jsxs("div", { className: CLS_GRID_2_COL, children: [_jsx(Field, { label: "Full Name *", children: _jsx("input", { type: "text", value: draft.fullName, onChange: handleTextField("fullName"), placeholder: "Ravi Kumar", maxLength: 100, className: INPUT_CLS }) }), _jsx(Field, { label: "Phone *", children: _jsx("input", { type: "tel", value: draft.phone, onChange: handleTextField("phone"), placeholder: "+91 98765 43210", maxLength: 20, className: INPUT_CLS }) })] }), _jsx(Field, { label: "Address Line 1 *", children: _jsx("input", { type: "text", value: draft.addressLine1, onChange: handleTextField("addressLine1"), placeholder: "Shop 12, Main Market", maxLength: 200, className: INPUT_CLS }) }), _jsx(Field, { label: "Address Line 2", children: _jsx("input", { type: "text", value: draft.addressLine2, onChange: handleTextField("addressLine2"), placeholder: "Building / Floor (optional)", maxLength: 200, className: INPUT_CLS }) }), _jsx(Field, { label: "Landmark", children: _jsx("input", { type: "text", value: draft.landmark, onChange: handleTextField("landmark"), placeholder: "Near metro station (optional)", maxLength: 100, className: INPUT_CLS }) }), _jsxs("div", { className: CLS_GRID_2_COL, children: [_jsx(Field, { label: "City *", children: _jsx("input", { type: "text", value: draft.city, onChange: handleTextField("city"), placeholder: "Mumbai", maxLength: 100, className: INPUT_CLS }) }), _jsx(Field, { label: "State *", children: _jsx("input", { type: "text", value: draft.state, onChange: handleTextField("state"), placeholder: "Maharashtra", maxLength: 100, className: INPUT_CLS }) })] }), _jsxs("div", { className: CLS_GRID_2_COL, children: [_jsx(Field, { label: "Postal Code *", children: _jsx("input", { type: "text", value: draft.postalCode, onChange: handleTextField("postalCode"), placeholder: "400001", maxLength: 10, className: INPUT_CLS }) }), _jsx(Field, { label: "Country *", children: _jsx("input", { type: "text", value: draft.country, onChange: handleTextField("country"), placeholder: "India", maxLength: 60, className: INPUT_CLS }) })] }), _jsxs("label", { className: "flex items-center gap-3 cursor-pointer", children: [_jsx("input", { type: "checkbox", checked: draft.isDefault, onChange: (e) => set("isDefault", e.target.checked), className: "h-4 w-4 rounded border-zinc-300 dark:border-slate-600 text-[var(--appkit-color-primary)] focus:ring-[var(--appkit-color-primary)]" }), _jsx("span", { className: "text-sm text-zinc-700 dark:text-zinc-300", children: "Set as default pickup address" })] })] }) }), deleteTargetAddr && (_jsx(ConfirmDeleteModal, { isOpen: true, title: "Delete Address", message: `Delete address "${deleteTargetAddr.label}"? This cannot be undone.`, onConfirm: () => { deleteById(deleteTargetAddr.id); setDeleteTargetAddr(null); }, onClose: () => setDeleteTargetAddr(null), isDeleting: deletingId === deleteTargetAddr.id }))] }));
149
139
  }
@@ -1,9 +1,9 @@
1
1
  import React from "react";
2
- import type { ListingViewShellProps } from "../../../ui";
3
- export interface SellerAuctionsViewProps extends ListingViewShellProps {
2
+ import type { ListingLayoutProps } from "../../../ui";
3
+ export interface SellerAuctionsViewProps extends ListingLayoutProps {
4
4
  renderHeader?: (onAdd: () => void) => React.ReactNode;
5
5
  onEditClick?: (id: string) => void;
6
6
  onDelete?: (id: string) => Promise<void>;
7
7
  onBulkDelete?: (ids: string[]) => Promise<void>;
8
8
  }
9
- export declare function SellerAuctionsView({ renderHeader, children, onEditClick, onDelete, onBulkDelete, ...props }: SellerAuctionsViewProps): import("react/jsx-runtime").JSX.Element;
9
+ export declare function SellerAuctionsView({ children, onEditClick, onDelete, onBulkDelete, ...props }: SellerAuctionsViewProps): import("react/jsx-runtime").JSX.Element;
@@ -1,74 +1,50 @@
1
1
  "use client";
2
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import React, { useState, useCallback } from "react";
4
- import { X } from "lucide-react";
5
- import { useUrlTable } from "../../../react/hooks/useUrlTable";
6
- import { useBulkSelection } from "../../../react/hooks/useBulkSelection";
7
- import { AdminViewCards } from "../../admin/components/AdminViewCards";
8
- import { BulkActionBar, ConfirmDeleteModal, FilterChipGroup, ListingToolbar, Pagination, ListingViewShell, RowActionMenu, useToast } from "../../../ui";
9
- import { useBottomActions } from "../../layout";
4
+ import { useEntityDelete } from "../../../react/hooks/useEntityDelete";
5
+ import { ConfirmDeleteModal, FilterChipGroup, ListingLayout, RowActionMenu } from "../../../ui";
10
6
  import { SELLER_ENDPOINTS } from "../../../constants/api-endpoints";
11
7
  import { SELLER_AUCTION_STATUS_TABS } from "../../admin/constants/filter-tabs";
12
8
  import { ACTIONS } from "../../../_internal/shared/actions/action-registry";
13
9
  import { ROUTES } from "../../../constants";
14
- import { toRecordArray, toRelativeDate, toRupees, toStringValue, useSellerListingData, } from "../hooks/useSellerListingData";
15
- import { DataTable } from "../../admin/components/DataTable";
16
- const PAGE_SIZE = 25;
17
- const FILTER_KEYS = ["status"];
18
- const DEFAULT_SORT = "endsAt";
19
- const SORT_OPTIONS = [
20
- { value: "endsAt", label: "Ending soon" },
21
- { value: "-endsAt", label: "Ending latest" },
22
- { value: "-createdAt", label: "Newest" },
23
- { value: "createdAt", label: "Oldest" },
24
- ];
25
- const STATUS_OPTIONS = SELLER_AUCTION_STATUS_TABS;
26
- export function SellerAuctionsView({ renderHeader, children, onEditClick, onDelete, onBulkDelete, ...props }) {
27
- const hasChildren = React.Children.count(children) > 0;
28
- const [view, setView] = useState("table");
10
+ import { toRecordArray, toRelativeDate, toRupees, toStringValue, } from "../../admin/hooks/useAdminListingData";
11
+ import { DataListingView } from "../../admin/components/DataListingView";
12
+ export function SellerAuctionsView({ children, onEditClick, onDelete, onBulkDelete, ...props }) {
29
13
  const [deleteTargetId, setDeleteTargetId] = useState(null);
30
- const [deletingId, setDeletingId] = useState(null);
31
- const { showToast } = useToast();
32
- const table = useUrlTable({ defaults: { pageSize: String(PAGE_SIZE), sort: DEFAULT_SORT } });
33
- const [searchInput, setSearchInput] = useState(table.get("q") || "");
34
- const [filterOpen, setFilterOpen] = useState(false);
35
- const [pendingFilters, setPendingFilters] = useState(() => Object.fromEntries(FILTER_KEYS.map((k) => [k, table.get(k)])));
36
- const openFilters = useCallback(() => {
37
- setPendingFilters(Object.fromEntries(FILTER_KEYS.map((k) => [k, table.get(k)])));
38
- setFilterOpen(true);
39
- }, [table]);
40
- const applyFilters = useCallback(() => {
41
- const updates = { page: "1" };
42
- for (const k of FILTER_KEYS)
43
- updates[k] = pendingFilters[k] ?? "";
44
- table.setMany(updates);
45
- setFilterOpen(false);
46
- }, [pendingFilters, table]);
47
- const clearFilters = useCallback(() => {
48
- setPendingFilters(Object.fromEntries(FILTER_KEYS.map((k) => [k, ""])));
49
- }, []);
50
- const resetAll = useCallback(() => {
51
- const updates = { q: "", sort: "" };
52
- for (const k of FILTER_KEYS)
53
- updates[k] = "";
54
- table.setMany(updates);
55
- setSearchInput("");
56
- }, [table]);
57
- const commitSearch = useCallback(() => {
58
- table.set("q", searchInput.trim());
59
- }, [searchInput, table]);
60
- const activeFilterCount = FILTER_KEYS.filter((k) => !!table.get(k)).length;
61
- const hasActiveState = !!table.get("q") || table.get("sort") !== DEFAULT_SORT || activeFilterCount > 0;
62
- const statusRaw = table.get("status");
63
- const filters = statusRaw && statusRaw !== "All" ? `status==${statusRaw}` : undefined;
64
- const { rows, total, isLoading, errorMessage } = useSellerListingData({
14
+ const { deletingId, handleDelete: performDelete } = useEntityDelete({
15
+ endpoint: (id) => `/api/store/products/${id}`,
16
+ deleteFn: onDelete,
17
+ successMessage: "Auction deleted.",
18
+ fetchOptions: { credentials: "include" },
19
+ });
20
+ const handleDelete = useCallback(async (id) => {
21
+ await performDelete(id);
22
+ setDeleteTargetId(null);
23
+ }, [performDelete]);
24
+ const handleEdit = useCallback((id) => {
25
+ if (onEditClick)
26
+ onEditClick(id);
27
+ else
28
+ window.location.href = String(ROUTES.STORE.PRODUCTS_EDIT(id));
29
+ }, [onEditClick]);
30
+ if (React.Children.count(children) > 0) {
31
+ return (_jsx(ListingLayout, { portal: "seller", ...props, children: children }));
32
+ }
33
+ const config = {
34
+ portal: "seller",
35
+ title: "Auctions",
36
+ searchPlaceholder: "Search auctions by product name",
37
+ emptyLabel: "No auctions found",
38
+ filterKeys: ["status"],
39
+ defaultSort: "endsAt",
65
40
  queryKey: ["seller", "auctions", "listing"],
66
41
  endpoint: SELLER_ENDPOINTS.AUCTIONS,
67
- page: table.getNumber("page", 1),
68
- pageSize: PAGE_SIZE,
69
- sorts: table.get("sort") || DEFAULT_SORT,
70
- filters,
71
- q: table.get("q") || undefined,
42
+ sortOptions: [
43
+ { value: "endsAt", label: "Ending soon" },
44
+ { value: "-endsAt", label: "Ending latest" },
45
+ { value: "-createdAt", label: "Newest" },
46
+ { value: "createdAt", label: "Oldest" },
47
+ ],
72
48
  mapRows: (response) => toRecordArray(response.auctions).map((item, index) => ({
73
49
  id: toStringValue(item.id, `auction-${index}`),
74
50
  primary: toStringValue(item.productTitle ?? item.title, "Untitled auction"),
@@ -79,48 +55,33 @@ export function SellerAuctionsView({ renderHeader, children, onEditClick, onDele
79
55
  status: toStringValue(item.status, "Unknown"),
80
56
  updatedAt: toRelativeDate(item.endsAt ?? item.updatedAt ?? item.createdAt),
81
57
  })),
82
- getTotal: (response, mappedRows) => typeof response.meta?.total === "number" ? response.meta.total : mappedRows.length,
83
- });
84
- const currentPage = table.getNumber("page", 1);
85
- const totalPages = Math.ceil(total / PAGE_SIZE);
86
- const selection = useBulkSelection({ items: rows, keyExtractor: (r) => r.id });
87
- const bulkActions = onBulkDelete
88
- ? [{
89
- id: "bulk-delete",
90
- label: ACTIONS.STORE["delete-listing"].label,
91
- variant: "danger",
92
- onClick: async () => { await onBulkDelete(selection.selectedIds); selection.clearSelection(); },
93
- }]
94
- : [];
95
- const handleDelete = useCallback(async (id) => {
96
- setDeletingId(id);
97
- try {
98
- if (onDelete)
99
- await onDelete(id);
100
- else
101
- await fetch(`/api/store/products/${id}`, { method: "DELETE", credentials: "include" });
102
- showToast("Auction deleted.", "success");
103
- }
104
- catch (err) {
105
- showToast(err instanceof Error ? err.message : "Failed to delete auction.", "error");
106
- }
107
- finally {
108
- setDeletingId(null);
109
- setDeleteTargetId(null);
110
- }
111
- }, [onDelete, showToast]);
112
- const handleEdit = useCallback((id) => {
113
- if (onEditClick)
114
- onEditClick(id);
115
- else
116
- window.location.href = String(ROUTES.STORE.PRODUCTS_EDIT(id));
117
- }, [onEditClick]);
118
- useBottomActions(selection.selectedCount > 0 ? { bulk: { selectedCount: selection.selectedCount, onClearSelection: selection.clearSelection, actions: bulkActions } } : {});
119
- if (hasChildren) {
120
- return _jsx(ListingViewShell, { portal: "seller", ...props, children: children });
121
- }
122
- return (_jsxs("div", { className: "min-h-screen", children: [_jsx(ListingToolbar, { filterCount: activeFilterCount, onFiltersClick: openFilters, searchValue: searchInput, searchPlaceholder: "Search auctions by product name", onSearchChange: setSearchInput, onSearchCommit: commitSearch, sortValue: table.get("sort") || DEFAULT_SORT, sortOptions: SORT_OPTIONS, onSortChange: (v) => { table.set("sort", v); }, showTableView: true, view: view, onViewChange: (v) => setView(v), onResetAll: resetAll, hasActiveState: hasActiveState }), totalPages > 1 && (_jsx("div", { className: "sticky top-[calc(var(--header-height,0px)+44px)] z-10 flex justify-center bg-white/95 dark:bg-slate-900/95 backdrop-blur-sm border-b border-zinc-200 dark:border-slate-700 px-3 py-1.5", children: _jsx(Pagination, { currentPage: currentPage, totalPages: totalPages, onPageChange: (p) => table.setPage(p) }) })), selection.selectedCount > 0 && bulkActions.length > 0 && (_jsx(BulkActionBar, { selectedCount: selection.selectedCount, actions: bulkActions, onClearSelection: selection.clearSelection })), _jsxs("div", { className: "py-4 px-3 sm:px-4", children: [errorMessage && (_jsx("div", { className: "mb-4 rounded-xl border border-red-200 bg-error-surface px-4 py-3 text-sm text-error dark:border-red-900/60", children: errorMessage })), view === "table" ? (_jsx(DataTable, { rows: rows, isLoading: isLoading, emptyLabel: "No auctions found", selectedIds: selection.selectedIdSet, onToggleSelect: (id) => selection.toggle(id), onToggleSelectAll: () => selection.toggleAll(), renderRowActions: (row) => (_jsx(RowActionMenu, { actions: [
123
- { label: ACTIONS.STORE["edit-listing"].label, onClick: () => handleEdit(row.id) },
124
- { label: ACTIONS.STORE["delete-listing"].label, destructive: true, onClick: () => setDeleteTargetId(row.id), disabled: deletingId === row.id },
125
- ] })) })) : (_jsx(AdminViewCards, { rows: rows, view: view, isLoading: isLoading, emptyLabel: "No auctions found", onRowClick: undefined, selectedIdSet: selection.selectedIdSet, onToggleSelect: selection.toggle }))] }), filterOpen && (_jsxs(_Fragment, { children: [_jsx("div", { className: "fixed inset-0 z-40 bg-black/40", "aria-hidden": "true", onClick: () => setFilterOpen(false) }), _jsxs("div", { className: "fixed inset-y-0 left-0 z-50 flex w-80 flex-col bg-white dark:bg-slate-900 shadow-2xl", children: [_jsxs("div", { className: "flex items-center justify-between border-b border-zinc-200 dark:border-slate-700 px-4 py-3.5", children: [_jsx("span", { className: "text-base font-semibold text-zinc-900 dark:text-zinc-100", children: "Filters" }), _jsxs("div", { className: "flex items-center gap-2", children: [activeFilterCount > 0 && (_jsx("button", { type: "button", onClick: clearFilters, className: "text-xs text-zinc-500 hover:text-rose-500 dark:text-zinc-400 transition-colors", children: "Clear all" })), _jsx("button", { type: "button", onClick: () => setFilterOpen(false), "aria-label": "Close", className: "rounded-lg p-1.5 text-zinc-500 dark:text-zinc-400 hover:bg-zinc-100 dark:hover:bg-zinc-800 transition-colors", children: _jsx(X, { className: "h-5 w-5" }) })] })] }), _jsx("div", { className: "flex-1 overflow-y-auto px-4 py-4 space-y-5", children: _jsx(FilterChipGroup, { label: "Status", tabs: STATUS_OPTIONS, value: pendingFilters.status ?? "", onChange: (id) => setPendingFilters((p) => ({ ...p, status: id })) }) }), _jsx("div", { className: "border-t border-zinc-200 dark:border-slate-700 px-4 py-3.5", children: _jsxs("button", { type: "button", onClick: applyFilters, className: "w-full rounded-lg bg-primary py-2.5 text-sm font-semibold text-white hover:bg-primary-600 transition-colors active:scale-[0.98]", children: ["Apply Filters", activeFilterCount > 0 ? ` (${activeFilterCount})` : ""] }) })] })] })), deleteTargetId && (_jsx(ConfirmDeleteModal, { isOpen: true, title: "Delete Auction", message: "Are you sure you want to delete this auction? This cannot be undone.", onConfirm: () => handleDelete(deleteTargetId), onClose: () => setDeleteTargetId(null), isDeleting: deletingId === deleteTargetId }))] }));
58
+ getTotal: (response, mappedRows) => typeof response.meta?.total === "number"
59
+ ? response.meta.total
60
+ : mappedRows.length,
61
+ buildFilters: (state) => state.status && state.status !== "All" ? `status==${state.status}` : undefined,
62
+ buildBulkActions: onBulkDelete
63
+ ? (selection) => [
64
+ {
65
+ id: "bulk-delete",
66
+ label: ACTIONS.STORE["delete-listing"].label,
67
+ variant: "danger",
68
+ onClick: async () => {
69
+ await onBulkDelete(selection.selectedIds);
70
+ selection.clearSelection();
71
+ },
72
+ },
73
+ ]
74
+ : undefined,
75
+ renderRowActions: (row) => (_jsx(RowActionMenu, { actions: [
76
+ { label: ACTIONS.STORE["edit-listing"].label, onClick: () => handleEdit(row.id) },
77
+ {
78
+ label: ACTIONS.STORE["delete-listing"].label,
79
+ destructive: true,
80
+ onClick: () => setDeleteTargetId(row.id),
81
+ disabled: deletingId === row.id,
82
+ },
83
+ ] })),
84
+ renderFilterPanel: ({ pendingFilters, setPendingFilters }) => (_jsx(FilterChipGroup, { label: "Status", tabs: SELLER_AUCTION_STATUS_TABS, value: pendingFilters.status ?? "", onChange: (id) => setPendingFilters((p) => ({ ...p, status: id })) })),
85
+ };
86
+ return (_jsxs(_Fragment, { children: [_jsx(DataListingView, { config: config }), deleteTargetId && (_jsx(ConfirmDeleteModal, { isOpen: true, title: "Delete Auction", message: "Are you sure you want to delete this auction? This cannot be undone.", onConfirm: () => handleDelete(deleteTargetId), onClose: () => setDeleteTargetId(null), isDeleting: deletingId === deleteTargetId }))] }));
126
87
  }
@@ -1,12 +1,12 @@
1
1
  "use client";
2
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import React, { useState, useCallback } from "react";
4
- import { X } from "lucide-react";
5
4
  import { useUrlTable } from "../../../react/hooks/useUrlTable";
6
5
  import { useBulkSelection } from "../../../react/hooks/useBulkSelection";
7
- import { Badge, BulkActionBar, Div, FilterChipGroup, ListingToolbar, Pagination, Text, useToast } from "../../../ui";
6
+ import { Badge, BulkActionBar, Div, FilterChipGroup, ListingFilterDrawer, ListingToolbar, Pagination, Text, useToast } from "../../../ui";
8
7
  import { SELLER_ENDPOINTS } from "../../../constants/api-endpoints";
9
8
  import { ACTIONS } from "../../../_internal/shared/actions/action-registry";
9
+ import { buildBulkAction } from "../../../_internal/shared/actions/bulk-helpers";
10
10
  import { SELLER_BID_STATUS_TABS } from "../../admin/constants/filter-tabs";
11
11
  import { toRecordArray, toRelativeDate, toRupees, toStringValue, useSellerListingData, } from "../hooks/useSellerListingData";
12
12
  import { DataTable } from "../../admin/components/DataTable";
@@ -162,11 +162,11 @@ export function SellerBidsView({ endpoint = SELLER_ENDPOINTS.BIDS }) {
162
162
  }
163
163
  }, [selection, showToast]);
164
164
  const bulkActions = [
165
- { id: "cancel", label: ACTIONS.SELLER["cancel-bid"].label, onClick: () => void bulkCancel(), variant: "danger" },
165
+ buildBulkAction(ACTIONS.SELLER["cancel-bid"], () => void bulkCancel()),
166
166
  ];
167
167
  useBottomActions(selection.selectedCount > 0 ? { bulk: { selectedCount: selection.selectedCount, onClearSelection: selection.clearSelection, actions: bulkActions } } : {});
168
- return (_jsxs("div", { className: "min-h-screen", children: [_jsx(ListingToolbar, { filterCount: activeFilterCount, onFiltersClick: openFilters, searchValue: searchInput, searchPlaceholder: "Search by bidder name", onSearchChange: setSearchInput, onSearchCommit: commitSearch, sortValue: table.get("sort") || DEFAULT_SORT, sortOptions: SORT_OPTIONS, onSortChange: (v) => { table.set("sort", v); }, showTableView: true, view: view, onViewChange: (v) => setView(v), onResetAll: resetAll, hasActiveState: hasActiveState }), totalPages > 1 && (_jsx("div", { className: "sticky top-[calc(var(--header-height,0px)+44px)] z-10 flex justify-center bg-white/95 dark:bg-slate-900/95 backdrop-blur-sm border-b border-zinc-200 dark:border-slate-700 px-3 py-1.5", children: _jsx(Pagination, { currentPage: currentPage, totalPages: totalPages, onPageChange: (p) => table.setPage(p) }) })), selection.selectedIds.length > 0 && (_jsx("div", { className: "sticky z-20 px-3 sm:px-4 py-2 bg-white/95 dark:bg-slate-900/95 backdrop-blur-sm border-b border-zinc-200 dark:border-slate-700", style: { top: "calc(var(--header-height, 0px) + 88px)" }, children: _jsx(BulkActionBar, { selectedCount: selection.selectedIds.length, onClearSelection: selection.clearSelection, actions: bulkActions }) })), _jsxs("div", { className: "py-4 px-3 sm:px-4", children: [errorMessage && (_jsx(Div, { className: "mb-4 rounded-xl border border-red-200 bg-error-surface dark:border-red-900/60 px-4 py-3 text-sm text-error", children: errorMessage })), table.get("grouped") === "0" ? (_jsx(DataTable, { rows: rows, columns: columns, isLoading: isLoading, emptyLabel: "No bids found for your auctions", selectedIds: selection.selectedIdSet, onToggleSelect: selection.toggle, onToggleSelectAll: () => selection.toggleAll() })) : (_jsxs("div", { className: "space-y-3", children: [groupedRows.length === 0 && !isLoading && (_jsx(Text, { className: "text-sm text-zinc-500 dark:text-zinc-400", children: "No bids found for your auctions." })), groupedRows.map((group) => {
168
+ return (_jsxs("div", { className: "min-h-screen", children: [_jsx(ListingToolbar, { filterCount: activeFilterCount, onFiltersClick: openFilters, searchValue: searchInput, searchPlaceholder: "Search by bidder name", onSearchChange: setSearchInput, onSearchCommit: commitSearch, sortValue: table.get("sort") || DEFAULT_SORT, sortOptions: SORT_OPTIONS, onSortChange: (v) => { table.set("sort", v); }, showTableView: true, view: view, onViewChange: (v) => setView(v), onResetAll: resetAll, hasActiveState: hasActiveState }), totalPages > 1 && (_jsx("div", { className: "sticky top-[calc(var(--header-height,0px)+44px)] z-10 flex justify-center bg-white/95 dark:bg-slate-900/95 backdrop-blur-sm border-b border-zinc-200 dark:border-slate-700 px-3 py-1.5", children: _jsx(Pagination, { currentPage: currentPage, totalPages: totalPages, onPageChange: (p) => table.setPage(p) }) })), selection.selectedIds.length > 0 && (_jsx("div", { className: "sticky z-20 px-3 sm:px-4 py-2 bg-white/95 dark:bg-slate-900/95 backdrop-blur-sm border-b border-zinc-200 dark:border-slate-700", style: { top: "calc(var(--header-height, 0px) + 88px)" }, children: _jsx(BulkActionBar, { selectedCount: selection.selectedIds.length, onClearSelection: selection.clearSelection, actions: bulkActions }) })), _jsxs("div", { className: "py-4 px-3 sm:px-4", children: [errorMessage && (_jsx(Div, { className: "mb-4 rounded-xl border border-error/20 bg-error-surface px-4 py-3 text-sm text-error", children: errorMessage })), table.get("grouped") === "0" ? (_jsx(DataTable, { rows: rows, columns: columns, isLoading: isLoading, emptyLabel: "No bids found for your auctions", selectedIds: selection.selectedIdSet, onToggleSelect: selection.toggle, onToggleSelectAll: () => selection.toggleAll() })) : (_jsxs("div", { className: "space-y-3", children: [groupedRows.length === 0 && !isLoading && (_jsx(Text, { className: "text-sm text-zinc-500 dark:text-zinc-400", children: "No bids found for your auctions." })), groupedRows.map((group) => {
169
169
  const collapsed = collapsedGroups.has(group.id);
170
170
  return (_jsxs(Div, { className: "rounded-lg border border-[var(--appkit-color-border)] bg-[var(--appkit-color-surface)]", children: [_jsxs("button", { type: "button", onClick: () => toggleGroup(group.id), className: "w-full flex items-center justify-between px-4 py-2.5 text-sm font-semibold text-[var(--appkit-color-text)] hover:bg-[var(--appkit-color-surface-raised)]", children: [_jsxs("span", { className: "truncate", children: [group.title, " ", _jsxs("span", { className: "text-xs text-[var(--appkit-color-text-muted)] font-normal", children: ["\u00B7 ", group.bids.length, " bid", group.bids.length === 1 ? "" : "s"] })] }), _jsx("span", { "aria-hidden": true, className: "text-[var(--appkit-color-text-muted)]", children: collapsed ? "▸" : "▾" })] }), !collapsed && (_jsx("div", { className: "border-t border-[var(--appkit-color-border)]", children: _jsx(DataTable, { rows: group.bids, columns: columns, isLoading: false, emptyLabel: "", selectedIds: selection.selectedIdSet, onToggleSelect: selection.toggle }) }))] }, group.id));
171
- })] }))] }), filterOpen && (_jsxs(_Fragment, { children: [_jsx("div", { className: "fixed inset-0 z-40 bg-black/40", "aria-hidden": "true", onClick: () => setFilterOpen(false) }), _jsxs("div", { className: "fixed inset-y-0 left-0 z-50 flex w-80 flex-col bg-white dark:bg-slate-900 shadow-2xl", children: [_jsxs("div", { className: "flex items-center justify-between border-b border-zinc-200 dark:border-slate-700 px-4 py-3.5", children: [_jsx("span", { className: "text-base font-semibold text-zinc-900 dark:text-zinc-100", children: "Filters" }), _jsxs("div", { className: "flex items-center gap-2", children: [activeFilterCount > 0 && (_jsx("button", { type: "button", onClick: clearFilters, className: "text-xs text-zinc-500 dark:text-zinc-400 hover:text-rose-500 transition-colors", children: "Clear all" })), _jsx("button", { type: "button", onClick: () => setFilterOpen(false), "aria-label": "Close", className: "rounded-lg p-1.5 text-zinc-500 dark:text-zinc-400 hover:bg-zinc-100 dark:hover:bg-zinc-800 transition-colors", children: _jsx(X, { className: "h-5 w-5" }) })] })] }), _jsx("div", { className: "flex-1 overflow-y-auto px-4 py-4 space-y-5", children: _jsx(FilterChipGroup, { label: "Bid Status", tabs: STATUS_OPTIONS, value: pendingFilters.status ?? "", onChange: (id) => setPendingFilters((p) => ({ ...p, status: id })), allId: "" }) }), _jsx("div", { className: "border-t border-zinc-200 dark:border-slate-700 px-4 py-3.5", children: _jsxs("button", { type: "button", onClick: applyFilters, className: "w-full rounded-lg bg-[var(--appkit-color-primary)] py-2.5 text-sm font-semibold text-white transition-colors active:scale-[0.98]", children: ["Apply", activeFilterCount > 0 ? ` (${activeFilterCount})` : ""] }) })] })] }))] }));
171
+ })] }))] }), _jsx(ListingFilterDrawer, { open: filterOpen, onClose: () => setFilterOpen(false), onApply: applyFilters, onClear: clearFilters, activeCount: activeFilterCount, children: _jsx(FilterChipGroup, { label: "Bid Status", tabs: STATUS_OPTIONS, value: pendingFilters.status ?? "", onChange: (id) => setPendingFilters((p) => ({ ...p, status: id })), allId: "" }) })] }));
172
172
  }