@mohasinac/appkit 3.0.3 → 3.0.6

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 (402) hide show
  1. package/dist/_internal/client/features/filters/filter-load-options.js +11 -1
  2. package/dist/_internal/client/features/layout/filterNavItems.js +0 -1
  3. package/dist/_internal/client/features/layout/index.js +0 -1
  4. package/dist/_internal/client/features/maintenance/views/MaintenanceDashboardView.js +0 -1
  5. package/dist/_internal/client/features/maintenance/views/ServerErrorDetailView.js +0 -1
  6. package/dist/_internal/server/features/auctions/data.d.ts +2 -4
  7. package/dist/_internal/server/features/auctions/data.js +3 -9
  8. package/dist/_internal/server/features/checkout/actions.js +9 -9
  9. package/dist/_internal/server/features/classified/adapters.d.ts +2 -15
  10. package/dist/_internal/server/features/classified/adapters.js +2 -17
  11. package/dist/_internal/server/features/classified/data.d.ts +1 -6
  12. package/dist/_internal/server/features/classified/data.js +2 -10
  13. package/dist/_internal/server/features/digital-code/adapters.d.ts +2 -15
  14. package/dist/_internal/server/features/digital-code/adapters.js +2 -17
  15. package/dist/_internal/server/features/digital-code/data.d.ts +1 -6
  16. package/dist/_internal/server/features/digital-code/data.js +2 -10
  17. package/dist/_internal/server/features/live/adapters.d.ts +2 -15
  18. package/dist/_internal/server/features/live/adapters.js +2 -17
  19. package/dist/_internal/server/features/live/data.d.ts +1 -6
  20. package/dist/_internal/server/features/live/data.js +2 -10
  21. package/dist/_internal/server/features/pre-orders/data.d.ts +2 -4
  22. package/dist/_internal/server/features/pre-orders/data.js +3 -9
  23. package/dist/_internal/server/features/prize-draws/actions.d.ts +2 -0
  24. package/dist/_internal/server/features/prize-draws/actions.js +22 -0
  25. package/dist/_internal/server/features/prize-draws/data.d.ts +1 -17
  26. package/dist/_internal/server/features/prize-draws/data.js +2 -20
  27. package/dist/_internal/server/features/prize-draws/index.d.ts +3 -1
  28. package/dist/_internal/server/features/prize-draws/index.js +2 -0
  29. package/dist/_internal/server/features/prize-draws/service.d.ts +3 -0
  30. package/dist/_internal/server/features/prize-draws/service.js +19 -0
  31. package/dist/_internal/server/features/shared/listing-adapters.d.ts +19 -0
  32. package/dist/_internal/server/features/shared/listing-adapters.js +20 -0
  33. package/dist/_internal/server/features/shared/listing-data-factory.d.ts +9 -0
  34. package/dist/_internal/server/features/shared/listing-data-factory.js +33 -0
  35. package/dist/_internal/server/features/stores/data.d.ts +3 -14
  36. package/dist/_internal/server/features/stores/data.js +6 -44
  37. package/dist/_internal/server/jobs/core/cleanupRtdbEvents.js +1 -1
  38. package/dist/_internal/shared/features/cart/schema.d.ts +8 -8
  39. package/dist/_internal/shared/features/cart/schema.js +3 -0
  40. package/dist/_internal/shared/listing-types/_registry.js +2 -0
  41. package/dist/_internal/shared/listing-types/action-tracker.js +1 -1
  42. package/dist/_internal/shared/listing-types/auction/schema.d.ts +3 -1
  43. package/dist/_internal/shared/listing-types/auction/schema.js +7 -1
  44. package/dist/_internal/shared/listing-types/classified/schema.d.ts +2 -1
  45. package/dist/_internal/shared/listing-types/classified/schema.js +3 -1
  46. package/dist/_internal/shared/listing-types/digital-code/schema.d.ts +3 -1
  47. package/dist/_internal/shared/listing-types/digital-code/schema.js +7 -1
  48. package/dist/_internal/shared/listing-types/live/schema.d.ts +2 -1
  49. package/dist/_internal/shared/listing-types/live/schema.js +3 -1
  50. package/dist/_internal/shared/listing-types/pre-order/schema.d.ts +3 -1
  51. package/dist/_internal/shared/listing-types/pre-order/schema.js +7 -1
  52. package/dist/_internal/shared/listing-types/prize-draw/schema.d.ts +3 -1
  53. package/dist/_internal/shared/listing-types/prize-draw/schema.js +13 -1
  54. package/dist/_internal/shared/listing-types/standard/schema.d.ts +2 -1
  55. package/dist/_internal/shared/listing-types/standard/schema.js +4 -1
  56. package/dist/_internal/shared/types/base-document.d.ts +15 -0
  57. package/dist/_internal/shared/types/base-document.js +1 -0
  58. package/dist/_internal/shared/types/index.d.ts +2 -0
  59. package/dist/_internal/shared/types/index.js +1 -0
  60. package/dist/client/api/ApiError.d.ts +10 -4
  61. package/dist/client/api/surface-error.js +0 -1
  62. package/dist/client.d.ts +8 -4
  63. package/dist/client.js +4 -2
  64. package/dist/constants/api-endpoints.d.ts +12 -0
  65. package/dist/constants/api-endpoints.js +4 -0
  66. package/dist/core/hooks/useSyncManager.js +4 -4
  67. package/dist/features/_guide-cls.d.ts +1 -1
  68. package/dist/features/_guide-cls.js +1 -1
  69. package/dist/features/about/components/AboutView.js +1 -4
  70. package/dist/features/about/components/FAQPageView.js +1 -1
  71. package/dist/features/about/components/FeesView.js +1 -1
  72. package/dist/features/about/components/HelpPageView.js +1 -1
  73. package/dist/features/about/components/HowOrdersWorkView.js +1 -1
  74. package/dist/features/about/components/PublicProfileView.js +6 -6
  75. package/dist/features/about/components/TrackOrderView.js +1 -1
  76. package/dist/features/account/components/AddressBook.js +1 -1
  77. package/dist/features/account/components/AddressForm.js +10 -2
  78. package/dist/features/account/components/AddressesIndexListing.js +1 -1
  79. package/dist/features/account/components/BuyerAccountGuideView.js +1 -1
  80. package/dist/features/account/components/BuyerAuctionsGuideView.js +1 -1
  81. package/dist/features/account/components/BuyerOrdersGuideView.js +1 -1
  82. package/dist/features/account/components/BuyerShoppingGuideView.js +1 -1
  83. package/dist/features/account/components/ChatWindow.js +1 -1
  84. package/dist/features/account/components/MessagesView.js +1 -1
  85. package/dist/features/account/components/NotificationBell.js +25 -10
  86. package/dist/features/account/components/NotificationPreferencesPanel.js +2 -2
  87. package/dist/features/account/components/UserOffersPanel.js +1 -0
  88. package/dist/features/account/components/UserSidebar.js +1 -6
  89. package/dist/features/account/components/UserSupportView.js +1 -1
  90. package/dist/features/addresses/schemas/firestore.d.ts +2 -4
  91. package/dist/features/admin/components/AdminAnalyticsGuideView.js +2 -2
  92. package/dist/features/admin/components/AdminBlogEditorView.js +1 -1
  93. package/dist/features/admin/components/AdminBundlesView.js +1 -1
  94. package/dist/features/admin/components/AdminCarouselEditorView.js +1 -1
  95. package/dist/features/admin/components/AdminCatalogGuideView.js +2 -2
  96. package/dist/features/admin/components/AdminContentGuideView.js +2 -2
  97. package/dist/features/admin/components/AdminEmployeeEditorView.js +2 -2
  98. package/dist/features/admin/components/AdminFulfillmentView.d.ts +6 -0
  99. package/dist/features/admin/components/AdminFulfillmentView.js +107 -0
  100. package/dist/features/admin/components/AdminGuideHubView.js +1 -5
  101. package/dist/features/admin/components/AdminMediaView.js +1 -1
  102. package/dist/features/admin/components/AdminNavigationView.js +1 -1
  103. package/dist/features/admin/components/AdminOrdersGuideView.js +3 -3
  104. package/dist/features/admin/components/AdminPayoutsView.js +1 -4
  105. package/dist/features/admin/components/AdminProductEditorView.js +21 -9
  106. package/dist/features/admin/components/AdminProductsView.js +3 -0
  107. package/dist/features/admin/components/AdminSidebar.js +1 -6
  108. package/dist/features/admin/components/AdminSiteConfigGuideView.js +1 -1
  109. package/dist/features/admin/components/AdminSiteSettingsView.js +9 -1
  110. package/dist/features/admin/components/AdminStoreEditorView.js +1 -1
  111. package/dist/features/admin/components/AdminStoresGuideView.js +2 -2
  112. package/dist/features/admin/components/AdminSupportTicketDetailView.js +7 -7
  113. package/dist/features/admin/components/AdminTeamGuideView.js +2 -2
  114. package/dist/features/admin/components/AdminTrustGuideView.js +3 -3
  115. package/dist/features/admin/components/AdminUsersGuideView.js +3 -3
  116. package/dist/features/admin/components/DashboardStats.js +6 -5
  117. package/dist/features/admin/components/DataListingView.d.ts +1 -0
  118. package/dist/features/admin/components/DataTable.js +2 -2
  119. package/dist/features/admin/components/analytics/AdminAnalyticsCharts.js +4 -6
  120. package/dist/features/admin/components/analytics/AdminStatCard.js +4 -3
  121. package/dist/features/admin/components/analytics/AdminTopProductsTable.js +1 -1
  122. package/dist/features/admin/components/index.d.ts +2 -0
  123. package/dist/features/admin/components/index.js +1 -0
  124. package/dist/features/admin/schemas/firestore.d.ts +3 -8
  125. package/dist/features/auctions/components/AuctionBidsTable.js +1 -1
  126. package/dist/features/auctions/components/AuctionDetailPageView.js +1 -1
  127. package/dist/features/auctions/components/MarketplaceAuctionCard.js +3 -3
  128. package/dist/features/auctions/schemas/firestore.d.ts +2 -4
  129. package/dist/features/auctions/schemas/index.d.ts +2 -2
  130. package/dist/features/auth/components/ForgotPasswordView.js +19 -8
  131. package/dist/features/auth/components/LoginForm.js +10 -2
  132. package/dist/features/auth/components/RegisterForm.js +10 -2
  133. package/dist/features/auth/components/ResetPasswordView.js +19 -8
  134. package/dist/features/auth/components/SocialAuthButtons.js +1 -1
  135. package/dist/features/before-after/components/BeforeAfterSlider.js +1 -1
  136. package/dist/features/before-after/schemas/index.d.ts +2 -2
  137. package/dist/features/blog/api/[slug]/route.js +1 -1
  138. package/dist/features/blog/components/BlogFeaturedCard.js +1 -1
  139. package/dist/features/blog/components/BlogListView.js +1 -1
  140. package/dist/features/blog/components/BlogPostView.js +1 -1
  141. package/dist/features/blog/schemas/firestore.d.ts +2 -4
  142. package/dist/features/blog/schemas/index.d.ts +6 -6
  143. package/dist/features/cart/components/CartDrawer.js +2 -2
  144. package/dist/features/cart/components/CartView.js +1 -1
  145. package/dist/features/cart/components/CheckoutView.js +1 -1
  146. package/dist/features/cart/schemas/firestore.d.ts +2 -4
  147. package/dist/features/categories/components/BrandDetailPageView.js +2 -1
  148. package/dist/features/categories/components/BundleDetailView.js +1 -1
  149. package/dist/features/categories/components/BundleItemsPicker.js +1 -1
  150. package/dist/features/categories/components/CategoryBundlesListing.js +3 -1
  151. package/dist/features/categories/components/CategoryDetailPageView.js +1 -1
  152. package/dist/features/categories/components/CategoryGrid.js +2 -1
  153. package/dist/features/categories/components/CategoryTableColumns.js +5 -2
  154. package/dist/features/categories/components/CategoryTree.js +3 -2
  155. package/dist/features/categories/components/ConcernCard.js +1 -1
  156. package/dist/features/categories/schemas/firestore.d.ts +2 -4
  157. package/dist/features/categories/schemas/index.d.ts +6 -6
  158. package/dist/features/checkout/components/CheckoutStepper.js +1 -1
  159. package/dist/features/collections/components/CollectionCard.js +1 -1
  160. package/dist/features/contact/components/ContactPageView.js +27 -27
  161. package/dist/features/contact/email.js +4 -4
  162. package/dist/features/copilot/components/AdminCopilotView.js +3 -3
  163. package/dist/features/email/primitives.d.ts +4 -0
  164. package/dist/features/email/primitives.js +4 -0
  165. package/dist/features/events/components/EventCard.js +2 -2
  166. package/dist/features/events/components/EventOfferCard.js +1 -1
  167. package/dist/features/events/components/EventRaffleEntryForm.js +1 -1
  168. package/dist/features/events/components/EventRaffleWinnerView.js +2 -2
  169. package/dist/features/events/components/EventSaleBanner.js +0 -1
  170. package/dist/features/events/schemas/firestore.d.ts +2 -4
  171. package/dist/features/events/schemas/index.d.ts +4 -4
  172. package/dist/features/faq/components/ContactCTA.js +1 -1
  173. package/dist/features/faq/components/FAQAccordion.js +2 -2
  174. package/dist/features/faq/components/FAQCategorySidebar.js +2 -2
  175. package/dist/features/faq/components/FAQHelpfulButtons.js +2 -2
  176. package/dist/features/faq/components/RelatedFAQs.js +1 -1
  177. package/dist/features/faq/schemas/firestore.d.ts +2 -4
  178. package/dist/features/faq/schemas/index.d.ts +4 -4
  179. package/dist/features/filters/AsyncFacetSection.js +3 -3
  180. package/dist/features/filters/FilterFacetSection.js +6 -6
  181. package/dist/features/filters/RangeFilter.js +2 -2
  182. package/dist/features/filters/SwitchFilter.js +1 -1
  183. package/dist/features/forms/Checkbox.js +1 -1
  184. package/dist/features/forms/Slider.js +7 -2
  185. package/dist/features/forms/utils.d.ts +2 -2
  186. package/dist/features/forms/utils.js +2 -2
  187. package/dist/features/grouped/schemas/index.d.ts +2 -2
  188. package/dist/features/history/hooks/useHistory.js +1 -1
  189. package/dist/features/homepage/components/AdSlot.js +3 -3
  190. package/dist/features/homepage/components/AdvertisementBanner.js +5 -4
  191. package/dist/features/homepage/components/BeforeAfterCard.js +9 -1
  192. package/dist/features/homepage/components/CharacterHotspot.js +42 -49
  193. package/dist/features/homepage/components/CharacterHotspotForm.js +18 -20
  194. package/dist/features/homepage/components/CollectionCardsSection.js +2 -2
  195. package/dist/features/homepage/components/CustomCardsSection.js +3 -6
  196. package/dist/features/homepage/components/CustomerReviewsSection.js +1 -1
  197. package/dist/features/homepage/components/FAQSection.js +2 -2
  198. package/dist/features/homepage/components/FeaturedResultsSection.js +1 -1
  199. package/dist/features/homepage/components/GoogleReviewsSection.js +4 -4
  200. package/dist/features/homepage/components/HeroBanner.js +12 -63
  201. package/dist/features/homepage/components/HeroCarousel.js +6 -6
  202. package/dist/features/homepage/components/HeroSection.js +1 -1
  203. package/dist/features/homepage/components/HowItWorksInfoView.js +1 -1
  204. package/dist/features/homepage/components/HowItWorksSection.js +5 -3
  205. package/dist/features/homepage/components/NewsletterBanner.js +3 -7
  206. package/dist/features/homepage/components/PromoGrid.js +2 -26
  207. package/dist/features/homepage/components/SectionCarousel.js +1 -1
  208. package/dist/features/homepage/components/SecurityHighlightsSection.js +6 -3
  209. package/dist/features/homepage/components/ShopByCategorySection.js +3 -3
  210. package/dist/features/homepage/components/SiteFeaturesSection.js +1 -1
  211. package/dist/features/homepage/components/SocialPostCard.js +2 -3
  212. package/dist/features/homepage/components/StatsCounterSection.js +6 -3
  213. package/dist/features/homepage/components/TestimonialsCarousel.js +2 -25
  214. package/dist/features/homepage/components/TrustBadges.js +1 -9
  215. package/dist/features/homepage/components/TrustFeaturesSection.js +6 -3
  216. package/dist/features/homepage/components/TrustIndicatorsSection.js +1 -1
  217. package/dist/features/homepage/components/WelcomeSection.js +2 -2
  218. package/dist/features/homepage/components/WhatsAppCommunitySection.js +1 -1
  219. package/dist/features/homepage/lib/franchise-colors.d.ts +7 -0
  220. package/dist/features/homepage/lib/franchise-colors.js +7 -0
  221. package/dist/features/homepage/lib/live-stats.js +5 -5
  222. package/dist/features/homepage/schemas/firestore.d.ts +4 -12
  223. package/dist/features/homepage/schemas/index.d.ts +2 -2
  224. package/dist/features/layout/AppLayoutShell.js +7 -9
  225. package/dist/features/layout/BottomNavbar.js +1 -2
  226. package/dist/features/messages/hooks/useConversation.js +2 -1
  227. package/dist/features/messages/hooks/useConversations.js +1 -0
  228. package/dist/features/messages/schemas/firestore.d.ts +2 -4
  229. package/dist/features/messages/schemas/index.d.ts +2 -2
  230. package/dist/features/orders/components/OrdersList.js +1 -1
  231. package/dist/features/orders/components/RefundHistoryTable.d.ts +6 -0
  232. package/dist/features/orders/components/RefundHistoryTable.js +3 -2
  233. package/dist/features/orders/repository/orders.repository.d.ts +5 -0
  234. package/dist/features/orders/repository/orders.repository.js +26 -0
  235. package/dist/features/orders/schemas/firestore.d.ts +9 -5
  236. package/dist/features/orders/schemas/firestore.js +3 -0
  237. package/dist/features/payments/schemas/firestore.d.ts +2 -4
  238. package/dist/features/pre-orders/components/MarketplacePreorderCard.js +2 -2
  239. package/dist/features/pre-orders/components/PreOrderBadge.js +1 -1
  240. package/dist/features/pre-orders/components/PreOrderDetailPageView.js +2 -1
  241. package/dist/features/pre-orders/schemas/index.d.ts +2 -2
  242. package/dist/features/products/components/CompareOverlay.js +11 -8
  243. package/dist/features/products/components/CustomSectionTabContent.js +1 -1
  244. package/dist/features/products/components/FeatureBadge.js +11 -1
  245. package/dist/features/products/components/GroupSettingsPanel.js +2 -2
  246. package/dist/features/products/components/MarketplaceBundleCard.js +1 -1
  247. package/dist/features/products/components/MarketplacePrizeDrawCard.js +2 -2
  248. package/dist/features/products/components/PrizeDrawItemsEditor.js +1 -1
  249. package/dist/features/products/components/PrizeDrawsIndexListing.js +1 -1
  250. package/dist/features/products/components/ProductCardMetadataSection.js +0 -1
  251. package/dist/features/products/components/ProductDetailPageView.js +1 -1
  252. package/dist/features/products/components/ProductFeatureBadges.js +1 -1
  253. package/dist/features/products/components/ProductGalleryClient.js +1 -1
  254. package/dist/features/products/components/ProductGrid.js +7 -7
  255. package/dist/features/products/components/ShareButton.js +1 -1
  256. package/dist/features/products/components/ShowGroupSection.js +7 -5
  257. package/dist/features/products/components/SublistingCarouselSection.js +2 -2
  258. package/dist/features/products/constants/action-defs.d.ts +16 -0
  259. package/dist/features/products/constants/action-defs.js +16 -0
  260. package/dist/features/products/constants/listing-tabs.d.ts +48 -0
  261. package/dist/features/products/constants/listing-tabs.js +12 -0
  262. package/dist/features/products/repository/products.repository.d.ts +37 -0
  263. package/dist/features/products/repository/products.repository.js +28 -1
  264. package/dist/features/products/schemas/firestore.d.ts +8 -6
  265. package/dist/features/products/schemas/firestore.js +2 -0
  266. package/dist/features/products/schemas/index.d.ts +8 -8
  267. package/dist/features/products/types/index.d.ts +2 -0
  268. package/dist/features/promotions/components/CouponCard.js +2 -2
  269. package/dist/features/promotions/schemas/firestore.d.ts +2 -4
  270. package/dist/features/promotions/schemas/index.d.ts +6 -6
  271. package/dist/features/reviews/components/ReviewDetailShell.js +3 -3
  272. package/dist/features/reviews/components/ReviewModal.js +2 -4
  273. package/dist/features/reviews/components/ReviewSummary.js +3 -2
  274. package/dist/features/reviews/components/ReviewsList.js +1 -1
  275. package/dist/features/reviews/schemas/firestore.d.ts +2 -4
  276. package/dist/features/reviews/schemas/index.d.ts +2 -2
  277. package/dist/features/scams/actions/scam-actions.js +1 -1
  278. package/dist/features/scams/components/ScamProfileView.js +1 -1
  279. package/dist/features/scams/schemas/firestore.d.ts +2 -4
  280. package/dist/features/scams/schemas/index.d.ts +4 -4
  281. package/dist/features/search/components/Search.js +2 -2
  282. package/dist/features/search/components/SearchFiltersRow.js +1 -1
  283. package/dist/features/search/schemas/index.d.ts +3 -3
  284. package/dist/features/seller/components/BarcodeField.d.ts +17 -0
  285. package/dist/features/seller/components/BarcodeField.js +30 -0
  286. package/dist/features/seller/components/FulfillmentView.d.ts +5 -0
  287. package/dist/features/seller/components/FulfillmentView.js +120 -0
  288. package/dist/features/seller/components/PhysicalLocationModal.js +2 -3
  289. package/dist/features/seller/components/PrintCenterView.d.ts +3 -1
  290. package/dist/features/seller/components/PrintCenterView.js +52 -4
  291. package/dist/features/seller/components/SellerAddressesView.js +2 -1
  292. package/dist/features/seller/components/SellerAnalyticsAlertsView.js +1 -1
  293. package/dist/features/seller/components/SellerBidsView.js +1 -1
  294. package/dist/features/seller/components/SellerCouponEditorView.js +1 -1
  295. package/dist/features/seller/components/SellerGoogleReviewsView.js +1 -1
  296. package/dist/features/seller/components/SellerLiveView.js +1 -1
  297. package/dist/features/seller/components/SellerOffersPanel.js +1 -0
  298. package/dist/features/seller/components/SellerOrdersView.js +1 -1
  299. package/dist/features/seller/components/SellerPayoutMethodsView.js +8 -2
  300. package/dist/features/seller/components/SellerPayoutRequestView.js +1 -1
  301. package/dist/features/seller/components/SellerPayoutSettingsView.js +1 -1
  302. package/dist/features/seller/components/SellerProductShell.d.ts +2 -0
  303. package/dist/features/seller/components/SellerProductShell.js +4 -3
  304. package/dist/features/seller/components/SellerProductsCards.js +1 -1
  305. package/dist/features/seller/components/SellerProductsView.js +1 -1
  306. package/dist/features/seller/components/SellerReviewsView.js +2 -1
  307. package/dist/features/seller/components/SellerShippingConfigsView.js +9 -3
  308. package/dist/features/seller/components/SellerShippingView.js +1 -1
  309. package/dist/features/seller/components/SellerSidebar.js +3 -8
  310. package/dist/features/seller/components/SellerStoreCategoriesView.js +11 -3
  311. package/dist/features/seller/components/SellerTemplatesView.js +8 -2
  312. package/dist/features/seller/components/analytics/SellerRevenueChart.js +1 -1
  313. package/dist/features/seller/components/analytics/SellerTopProducts.js +1 -1
  314. package/dist/features/seller/components/index.d.ts +4 -0
  315. package/dist/features/seller/components/index.js +2 -0
  316. package/dist/features/seller/schemas/index.d.ts +4 -4
  317. package/dist/features/shell/FormShell.js +2 -2
  318. package/dist/features/shell/QuickFormDrawer.js +1 -1
  319. package/dist/features/site-settings/components/NavPermissionsManager.js +1 -1
  320. package/dist/features/store-extensions/schemas/firestore.d.ts +12 -44
  321. package/dist/features/stores/components/StoreCapabilitiesGuideView.js +1 -1
  322. package/dist/features/stores/components/StoreClassifiedsListing.d.ts +5 -0
  323. package/dist/features/stores/components/StoreClassifiedsListing.js +48 -0
  324. package/dist/features/stores/components/StoreClassifiedsPageView.d.ts +4 -0
  325. package/dist/features/stores/components/StoreClassifiedsPageView.js +20 -0
  326. package/dist/features/stores/components/StoreDetailLayoutView.js +23 -2
  327. package/dist/features/stores/components/StoreDigitalCodesListing.d.ts +5 -0
  328. package/dist/features/stores/components/StoreDigitalCodesListing.js +48 -0
  329. package/dist/features/stores/components/StoreDigitalCodesPageView.d.ts +4 -0
  330. package/dist/features/stores/components/StoreDigitalCodesPageView.js +20 -0
  331. package/dist/features/stores/components/StoreGuideHubView.js +2 -9
  332. package/dist/features/stores/components/StoreHeader.js +1 -1
  333. package/dist/features/stores/components/StoreListingsGuideView.js +4 -4
  334. package/dist/features/stores/components/StoreLiveItemsListing.d.ts +5 -0
  335. package/dist/features/stores/components/StoreLiveItemsListing.js +48 -0
  336. package/dist/features/stores/components/StoreLiveItemsPageView.d.ts +4 -0
  337. package/dist/features/stores/components/StoreLiveItemsPageView.js +20 -0
  338. package/dist/features/stores/components/StoreOrdersGuideView.js +2 -2
  339. package/dist/features/stores/components/StoresIndexListing.js +1 -1
  340. package/dist/features/stores/components/index.d.ts +9 -0
  341. package/dist/features/stores/components/index.js +3 -0
  342. package/dist/features/stores/schemas/firestore.d.ts +2 -4
  343. package/dist/features/stores/schemas/index.d.ts +4 -4
  344. package/dist/features/support/schemas/firestore.d.ts +2 -4
  345. package/dist/features/support/schemas/index.d.ts +2 -2
  346. package/dist/features/whatsapp-bot/components/SellerWhatsAppSettingsView.js +2 -2
  347. package/dist/features/wishlist/components/WishlistPage.js +1 -1
  348. package/dist/features/wishlist/components/WishlistToggleButton.js +3 -3
  349. package/dist/features/wishlist/hooks/useWishlistCount.js +1 -1
  350. package/dist/http/ApiClient.d.ts +1 -0
  351. package/dist/http/ApiClient.js +20 -0
  352. package/dist/monitoring/error-tracking.d.ts +0 -3
  353. package/dist/monitoring/error-tracking.js +1 -1
  354. package/dist/monitoring/server-logger.js +3 -3
  355. package/dist/next/components/GlobalError.js +1 -1
  356. package/dist/next/routing/route-map.d.ts +11 -0
  357. package/dist/next/routing/route-map.js +5 -0
  358. package/dist/react/ErrorBoundary.js +1 -1
  359. package/dist/schemas/registry.d.ts +24 -24
  360. package/dist/seed/grouped-listings-seed-data.d.ts +2 -1
  361. package/dist/seed/products-preorders-seed-data.d.ts +2 -1
  362. package/dist/seed/products-standard-seed-data.js +8 -0
  363. package/dist/server-entry.d.ts +3 -0
  364. package/dist/server-entry.js +3 -0
  365. package/dist/server.d.ts +4 -4
  366. package/dist/styles.css +45 -7
  367. package/dist/tailwind-utilities.css +1 -1
  368. package/dist/tokens/themes/default-light.js +3 -0
  369. package/dist/tokens/tokens.css +43 -6
  370. package/dist/ui/components/Anchor.d.ts +8 -1
  371. package/dist/ui/components/Anchor.js +16 -2
  372. package/dist/ui/components/Button.d.ts +5 -2
  373. package/dist/ui/components/Button.js +5 -2
  374. package/dist/ui/components/Details.d.ts +33 -2
  375. package/dist/ui/components/Details.js +73 -4
  376. package/dist/ui/components/Div.d.ts +3 -0
  377. package/dist/ui/components/Div.js +12 -1
  378. package/dist/ui/components/DynamicBgDiv.d.ts +13 -0
  379. package/dist/ui/components/DynamicBgDiv.js +18 -0
  380. package/dist/ui/components/Form.d.ts +3 -19
  381. package/dist/ui/components/Form.js +8 -1
  382. package/dist/ui/components/Layout.d.ts +12 -1
  383. package/dist/ui/components/Layout.js +9 -1
  384. package/dist/ui/components/Progress.d.ts +1 -1
  385. package/dist/ui/components/Progress.js +1 -0
  386. package/dist/ui/components/Progress.style.css +1 -0
  387. package/dist/ui/components/ProgressBarFill.d.ts +6 -0
  388. package/dist/ui/components/ProgressBarFill.js +11 -0
  389. package/dist/ui/components/Semantic.d.ts +26 -7
  390. package/dist/ui/components/Semantic.js +33 -8
  391. package/dist/ui/components/TextLink.d.ts +36 -1
  392. package/dist/ui/components/TextLink.js +30 -2
  393. package/dist/ui/components/Typography.d.ts +26 -6
  394. package/dist/ui/components/Typography.js +37 -13
  395. package/dist/ui/components/VacationBanner.js +0 -1
  396. package/dist/ui/components/surface-tokens.d.ts +12 -2
  397. package/dist/ui/components/surface-tokens.js +19 -1
  398. package/dist/ui/rich-text/RichText.js +1 -1
  399. package/dist/utils/id-generators.d.ts +8 -0
  400. package/dist/utils/id-generators.js +14 -0
  401. package/dist/validation/schemas.d.ts +1 -1
  402. package/package.json +2 -1
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { useState } from "react";
4
- import { Button, Div, Heading, IconButton, Modal, RichText, Row, Stack, Text } from "../../../ui";
4
+ import { Button, Div, Heading, Modal, RichText, Row, Stack, Text } from "../../../ui";
5
5
  import { StarRating } from "../../../ui";
6
6
  import { maskName } from "../../../security";
7
7
  import { THEMED_TEXT_SUCCESS } from "../../../_internal/shared/styles/themed";
@@ -23,7 +23,5 @@ export function ViewReviewModal({ review, isOpen, onClose, }) {
23
23
  day: "numeric",
24
24
  })
25
25
  : "";
26
- return (_jsx(Modal, { isOpen: isOpen, onClose: onClose, title: "Review Details", children: _jsxs(Stack, { gap: "md", children: [_jsxs(Row, { gap: "3", children: [review.userAvatar ? (_jsx(Div, { role: "img", "aria-label": displayName, className: "h-10 w-10 flex-shrink-0 bg-center bg-cover", rounded: "full", style: { backgroundImage: `url(${review.userAvatar})` } })) : (_jsx(Row, { textWeight: "medium", textSize: "sm", className: "h-10 w-10 flex-shrink-0 bg-neutral-200 text-neutral-600 dark:text-neutral-400", align: "center", justify: "center", rounded: "full", children: displayName.charAt(0).toUpperCase() })), _jsxs(Div, { children: [_jsxs(Row, { gap: "sm", children: [_jsx(Text, { color: "inverse", className: "text-neutral-900 dark:text-neutral-100 dark:", weight: "medium", children: displayName }), review.verified && (_jsx(Text, { className: THEMED_TEXT_SUCCESS, size: "xs", children: "\u2713 Verified purchase" }))] }), _jsxs(Row, { className: "mt-0.5", gap: "sm", children: [_jsx(StarRating, { value: review.rating, size: "sm", readOnly: true }), date && (_jsx(Text, { size: "xs", color: "faint", children: date }))] })] })] }), review.title && (_jsx(Heading, { color: "inverse", level: 4, className: "text-neutral-900 dark:text-neutral-100 dark:", weight: "semibold", children: review.title })), review.comment && (_jsx(RichText, { html: normalizeRichTextHtml(review.comment), proseClass: "prose prose-sm max-w-none dark:prose-invert prose-p:my-0", className: "text-sm leading-relaxed text-neutral-600 dark:text-zinc-400" })), review.images && review.images.length > 0 && (_jsx(Row, { wrap: true, gap: "sm", children: review.images.map((img, i) => (_jsx(IconButton, { "aria-label": `View image ${i + 1}`, onClick: () => setLightboxIdx(i), variant: "ghost", className: `h-20 w-20 rounded-lg border bg-center bg-cover transition hover:opacity-80 p-0 ${lightboxIdx === i ? "ring-2 ring-primary-500" : "border-neutral-100 dark:border-zinc-700"}`, style: {
27
- backgroundImage: `url(${img.thumbnailUrl ?? img.url})`,
28
- }, icon: _jsx(Div, {}) }, i))) })), (review.helpfulCount ?? 0) > 0 && (_jsxs(Text, { size: "xs", color: "faint", children: [review.helpfulCount, " people found this helpful"] })), _jsx(Row, { justify: "end", padding: "t-xs", children: _jsx(Button, { variant: "ghost", onClick: onClose, children: "Close" }) })] }) }));
26
+ return (_jsx(Modal, { isOpen: isOpen, onClose: onClose, title: "Review Details", children: _jsxs(Stack, { gap: "md", children: [_jsxs(Row, { gap: "3", children: [review.userAvatar ? (_jsx("img", { src: review.userAvatar, alt: displayName, className: "h-10 w-10 flex-shrink-0 object-cover rounded-full" })) : (_jsx(Row, { textWeight: "medium", textSize: "sm", className: "h-10 w-10 flex-shrink-0 bg-neutral-200 text-neutral-600 dark:text-neutral-400", align: "center", justify: "center", rounded: "full", children: displayName.charAt(0).toUpperCase() })), _jsxs(Div, { children: [_jsxs(Row, { gap: "sm", children: [_jsx(Text, { color: "inverse", className: "text-neutral-900 dark:text-neutral-100 dark:", weight: "medium", children: displayName }), review.verified && (_jsx(Text, { className: THEMED_TEXT_SUCCESS, size: "xs", children: "\u2713 Verified purchase" }))] }), _jsxs(Row, { className: "mt-0.5", gap: "sm", children: [_jsx(StarRating, { value: review.rating, size: "sm", readOnly: true }), date && (_jsx(Text, { size: "xs", color: "faint", children: date }))] })] })] }), review.title && (_jsx(Heading, { color: "inverse", level: 4, className: "text-neutral-900 dark:text-neutral-100 dark:", weight: "semibold", children: review.title })), review.comment && (_jsx(RichText, { html: normalizeRichTextHtml(review.comment), proseClass: "prose prose-sm max-w-none dark:prose-invert prose-p:my-0", className: "text-sm leading-relaxed text-neutral-600 dark:text-zinc-400" })), review.images && review.images.length > 0 && (_jsx(Row, { wrap: true, gap: "sm", children: review.images.map((img, i) => (_jsx("button", { type: "button", "aria-label": `View image ${i + 1}`, onClick: () => setLightboxIdx(i), className: `h-20 w-20 rounded-lg border overflow-hidden transition hover:opacity-80 p-0 flex-shrink-0 ${lightboxIdx === i ? "ring-2 ring-primary-500" : "border-neutral-100 dark:border-zinc-700"}`, children: _jsx("img", { src: img.thumbnailUrl ?? img.url, alt: `Review thumbnail ${i + 1}`, className: "w-full h-full object-cover" }) }, i))) })), (review.helpfulCount ?? 0) > 0 && (_jsxs(Text, { size: "xs", color: "faint", children: [review.helpfulCount, " people found this helpful"] })), _jsx(Row, { justify: "end", padding: "t-xs", children: _jsx(Button, { variant: "ghost", onClick: onClose, children: "Close" }) })] }) }));
29
27
  }
@@ -1,6 +1,7 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { Div, Row, Span, Stack, Text } from "../../../ui";
3
3
  import { StarRating } from "../../../ui";
4
+ import { ProgressBarFill } from "../../../ui/components/ProgressBarFill";
4
5
  const CLS_STAR = "text-warning";
5
6
  const CLS_BAR = "h-full rounded-full bg-warning-surface transition-all duration-300";
6
7
  /**
@@ -13,9 +14,9 @@ const CLS_BAR = "h-full rounded-full bg-warning-surface transition-all duration-
13
14
  */
14
15
  export function ReviewSummary({ averageRating, totalReviews, distribution, className = "", }) {
15
16
  const stars = [5, 4, 3, 2, 1];
16
- return (_jsxs(Stack, { align: "center", className: `sm:flex-row sm: sm:gap-8 ${className}`, gap: "md", children: [_jsxs(Stack, { className: "sm:items-start", align: "center", gap: "xs", children: [_jsx(Span, { color: "inverse", weight: "bold", className: "leading-none text-neutral-900 dark:text-neutral-100 dark:", size: "5xl", children: averageRating.toFixed(1) }), _jsx(StarRating, { value: averageRating, size: "md", readOnly: true }), _jsxs(Text, { size: "sm", className: "text-neutral-500 dark:text-neutral-400", children: [totalReviews.toLocaleString(), " review", totalReviews !== 1 ? "s" : ""] })] }), _jsx(Stack, { className: "flex-1", gap: "sm", children: stars.map((star) => {
17
+ return (_jsxs(Stack, { align: "center", className: `sm:[flex-direction:row] sm: sm:gap-[2rem] ${className}`, gap: "md", children: [_jsxs(Stack, { className: "sm:items-[flex-start]", align: "center", gap: "xs", children: [_jsx(Span, { color: "inverse", weight: "bold", className: "leading-none text-neutral-900 dark:text-neutral-100 dark:", size: "5xl", children: averageRating.toFixed(1) }), _jsx(StarRating, { value: averageRating, size: "md", readOnly: true }), _jsxs(Text, { size: "sm", className: "text-neutral-500 dark:text-neutral-400", children: [totalReviews.toLocaleString(), " review", totalReviews !== 1 ? "s" : ""] })] }), _jsx(Stack, { className: "flex-1", gap: "sm", children: stars.map((star) => {
17
18
  const count = distribution[star] ?? 0;
18
19
  const pct = totalReviews > 0 ? Math.round((count / totalReviews) * 100) : 0;
19
- return (_jsxs(Row, { align: "center", gap: "sm", children: [_jsx(Span, { size: "xs", weight: "medium", className: "w-4 text-neutral-600 dark:text-neutral-400 tabular-nums", align: "end", children: star }), _jsx(Span, { size: "xs", className: CLS_STAR, children: "\u2605" }), _jsx(Div, { className: "flex-1 h-2 bg-neutral-100 dark:bg-neutral-800 overflow-hidden", rounded: "full", role: "progressbar", "aria-valuenow": pct, "aria-valuemin": 0, "aria-valuemax": 100, "aria-label": `${star} star: ${pct}%`, children: _jsx(Div, { className: CLS_BAR, style: { width: `${pct}%` } }) }), _jsxs(Span, { size: "xs", className: "w-8 tabular-nums", color: "faint", align: "end", children: [pct, "%"] })] }, star));
20
+ return (_jsxs(Row, { align: "center", gap: "sm", children: [_jsx(Span, { size: "xs", weight: "medium", className: "w-4 text-neutral-600 dark:text-neutral-400 tabular-nums", align: "end", children: star }), _jsx(Span, { size: "xs", className: CLS_STAR, children: "\u2605" }), _jsx(Div, { className: "flex-1 h-2 bg-neutral-100 dark:bg-neutral-800 overflow-hidden", rounded: "full", role: "progressbar", "aria-valuenow": pct, "aria-valuemin": 0, "aria-valuemax": 100, "aria-label": `${star} star: ${pct}%`, children: _jsx(ProgressBarFill, { pct: pct, className: CLS_BAR }) }), _jsxs(Span, { size: "xs", className: "w-8 tabular-nums", color: "faint", align: "end", children: [pct, "%"] })] }, star));
20
21
  }) })] }));
21
22
  }
@@ -27,7 +27,7 @@ export function ReviewCard({ review, context = "general", className = "" }) {
27
27
  const showProductLink = context !== "listing" && !!productHref;
28
28
  const showProfileLink = !!profileHref;
29
29
  const hasFooter = showStoreLink || showProductLink || showProfileLink;
30
- return (_jsxs(Stack, { padding: "5", className: `group h-full border border-neutral-200 transition-shadow hover:shadow-md ${className}`, rounded: "xl", surface: "default", children: [_jsxs(Link, { href: reviewHref, className: "flex flex-col flex-1 min-h-0", children: [_jsxs(Row, { align: "start", gap: "3", children: [review.userAvatar ? (_jsx(Div, { role: "img", "aria-label": displayName, className: "h-9 w-9 flex-shrink-0 bg-center bg-cover", rounded: "full", style: { backgroundImage: `url(${review.userAvatar})` } })) : (_jsx(Row, { textWeight: "medium", textSize: "sm", className: "h-9 w-9 flex-shrink-0 bg-neutral-200 text-neutral-600 dark:text-neutral-400", align: "center", justify: "center", rounded: "full", children: initials })), _jsxs(Div, { className: "flex-1 min-w-0", children: [_jsxs(Row, { wrap: true, gap: "sm", children: [_jsx(Span, { color: "inverse", weight: "medium", className: "text-neutral-900 dark:text-neutral-100 dark:", children: displayName }), review.verified && (_jsx(Span, { color: "success", surface: "success-surface", size: "xs", weight: "medium", rounded: "full", padding: "pill-xs", children: "Verified" })), date && (_jsx(Span, { size: "xs", color: "muted", children: date }))] }), _jsx(Div, { className: "mt-1", children: _jsx(StarRating, { value: review.rating, size: "sm", readOnly: true }) })] })] }), review.title && (_jsx(Heading, { color: "inverse", level: 4, className: "mt-3 text-neutral-900 dark:text-neutral-100 dark:", weight: "semibold", children: review.title })), review.comment && (_jsx(RichText, { html: normalizeRichTextHtml(review.comment), proseClass: "prose prose-sm max-w-none dark:prose-invert prose-p:my-0", className: "mt-2 text-sm leading-relaxed text-neutral-600 dark:text-zinc-400" })), review.images && review.images.length > 0 && (_jsx(Row, { wrap: true, gap: "sm", className: "mt-3", children: review.images.map((img, i) => (_jsx(Div, { role: "img", "aria-label": `Review image ${i + 1}`, className: "h-16 w-16 bg-center bg-cover border border-neutral-100", rounded: "lg", style: { backgroundImage: `url(${img.thumbnailUrl ?? img.url})` } }, i))) })), (review.helpfulCount ?? 0) > 0 && (_jsxs(Text, { className: "mt-3", color: "faint", size: "xs", children: [review.helpfulCount, " found this helpful"] }))] }), hasFooter && (_jsxs(Stack, { gap: "xs", className: "mt-3 border-t border-neutral-100", padding: "t-sm", children: [showStoreLink && (_jsxs(Link, { href: String(ROUTES.PUBLIC.STORE_DETAIL(review.storeSlug)), className: "flex items-center gap-1.5 text-xs font-medium text-primary hover:underline", children: [_jsx(Span, { "aria-hidden": "true", children: "\uD83C\uDFEA" }), _jsx(Span, { truncate: true, children: review.storeName })] })), showProductLink && (_jsxs(Link, { href: productHref, className: "flex items-center gap-1.5 text-xs font-medium text-neutral-500 dark:text-zinc-400 hover:text-neutral-700 dark:hover:text-zinc-200", children: [_jsx(Span, { "aria-hidden": "true", children: "\uD83D\uDCE6" }), _jsx(Span, { truncate: true, children: review.productTitle ?? "View Product" }), _jsx(Span, { "aria-hidden": "true", className: "ml-auto text-primary group-hover:translate-x-0.5 transition-transform", children: "\u2192" })] })), showProfileLink && (_jsxs(Link, { href: profileHref, className: "flex items-center gap-1.5 text-xs font-medium text-neutral-500 dark:text-zinc-400 hover:text-neutral-700 dark:hover:text-zinc-200", children: [_jsx(Span, { "aria-hidden": "true", children: "\uD83D\uDC64" }), _jsx(Span, { truncate: true, children: displayName })] }))] }))] }));
30
+ return (_jsxs(Stack, { padding: "5", shadow: "hover-md", className: `group h-full border border-neutral-200 transition ${className}`, rounded: "xl", surface: "default", children: [_jsxs(Link, { href: reviewHref, className: "flex flex-col flex-1 min-h-0", children: [_jsxs(Row, { align: "start", gap: "3", children: [review.userAvatar ? (_jsx("img", { src: review.userAvatar, alt: displayName, className: "h-9 w-9 flex-shrink-0 object-cover rounded-full" })) : (_jsx(Row, { textWeight: "medium", textSize: "sm", className: "h-9 w-9 flex-shrink-0 bg-neutral-200 text-neutral-600 dark:text-neutral-400", align: "center", justify: "center", rounded: "full", children: initials })), _jsxs(Div, { className: "flex-1 min-w-0", children: [_jsxs(Row, { wrap: true, gap: "sm", children: [_jsx(Span, { color: "inverse", weight: "medium", className: "text-neutral-900 dark:text-neutral-100 dark:", children: displayName }), review.verified && (_jsx(Span, { color: "success", surface: "success-surface", size: "xs", weight: "medium", rounded: "full", padding: "pill-xs", children: "Verified" })), date && (_jsx(Span, { size: "xs", color: "muted", children: date }))] }), _jsx(Div, { className: "mt-1", children: _jsx(StarRating, { value: review.rating, size: "sm", readOnly: true }) })] })] }), review.title && (_jsx(Heading, { color: "inverse", level: 4, className: "mt-3 text-neutral-900 dark:text-neutral-100 dark:", weight: "semibold", children: review.title })), review.comment && (_jsx(RichText, { html: normalizeRichTextHtml(review.comment), proseClass: "prose prose-sm max-w-none dark:prose-invert prose-p:my-0", className: "mt-2 text-sm leading-relaxed text-neutral-600 dark:text-zinc-400" })), review.images && review.images.length > 0 && (_jsx(Row, { wrap: true, gap: "sm", className: "mt-3", children: review.images.map((img, i) => (_jsx("img", { src: img.thumbnailUrl ?? img.url, alt: `Review image ${i + 1}`, className: "h-16 w-16 object-cover rounded-lg border border-neutral-100" }, i))) })), (review.helpfulCount ?? 0) > 0 && (_jsxs(Text, { className: "mt-3", color: "faint", size: "xs", children: [review.helpfulCount, " found this helpful"] }))] }), hasFooter && (_jsxs(Stack, { gap: "xs", className: "mt-3 border-t border-neutral-100", padding: "t-sm", children: [showStoreLink && (_jsxs(Link, { href: String(ROUTES.PUBLIC.STORE_DETAIL(review.storeSlug)), className: "flex items-center gap-1.5 text-xs font-medium text-primary hover:underline", children: [_jsx(Span, { "aria-hidden": "true", children: "\uD83C\uDFEA" }), _jsx(Span, { truncate: true, children: review.storeName })] })), showProductLink && (_jsxs(Link, { href: productHref, className: "flex items-center gap-1.5 text-xs font-medium text-neutral-500 dark:text-zinc-400 hover:text-neutral-700 dark:hover:text-zinc-200", children: [_jsx(Span, { "aria-hidden": "true", children: "\uD83D\uDCE6" }), _jsx(Span, { truncate: true, children: review.productTitle ?? "View Product" }), _jsx(Span, { "aria-hidden": "true", className: "ml-auto text-primary group-hover:translate-x-0.5 transition-transform", children: "\u2192" })] })), showProfileLink && (_jsxs(Link, { href: profileHref, className: "flex items-center gap-1.5 text-xs font-medium text-neutral-500 dark:text-zinc-400 hover:text-neutral-700 dark:hover:text-zinc-200", children: [_jsx(Span, { "aria-hidden": "true", children: "\uD83D\uDC64" }), _jsx(Span, { truncate: true, children: displayName })] }))] }))] }));
31
31
  }
32
32
  export function ReviewsList({ reviews, context = "general", isLoading, totalPages = 1, currentPage = 1, onPageChange, emptyLabel = "No reviews yet", }) {
33
33
  if (isLoading) {
@@ -2,6 +2,7 @@
2
2
  * Reviews Firestore Document Types & Constants
3
3
  */
4
4
  import type { ReviewStatus } from "../types";
5
+ import type { BaseDocument } from "../../../_internal/shared/types/base-document";
5
6
  /** Runtime-accessible review status values — use instead of bare string literals. */
6
7
  export declare const ReviewStatusValues: {
7
8
  readonly PENDING: "pending";
@@ -15,8 +16,7 @@ export interface ReviewVideoField {
15
16
  trimStart?: number;
16
17
  trimEnd?: number;
17
18
  }
18
- export interface ReviewDocument {
19
- id: string;
19
+ export interface ReviewDocument extends BaseDocument {
20
20
  productId: string;
21
21
  productTitle: string;
22
22
  storeId?: string;
@@ -44,8 +44,6 @@ export interface ReviewDocument {
44
44
  isAnonymous?: boolean;
45
45
  sellerReply?: string;
46
46
  sellerRepliedAt?: Date;
47
- createdAt: Date;
48
- updatedAt: Date;
49
47
  approvedAt?: Date;
50
48
  rejectedAt?: Date;
51
49
  }
@@ -103,8 +103,8 @@ export declare const reviewFirestoreSchema: z.ZodObject<{
103
103
  createdAt: string | Date | z.objectOutputType<{
104
104
  toDate: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodDate>;
105
105
  }, z.ZodTypeAny, "passthrough">;
106
- id: string;
107
106
  title: string;
107
+ id: string;
108
108
  updatedAt: string | Date | z.objectOutputType<{
109
109
  toDate: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodDate>;
110
110
  }, z.ZodTypeAny, "passthrough">;
@@ -150,8 +150,8 @@ export declare const reviewFirestoreSchema: z.ZodObject<{
150
150
  createdAt: string | Date | z.objectInputType<{
151
151
  toDate: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodDate>;
152
152
  }, z.ZodTypeAny, "passthrough">;
153
- id: string;
154
153
  title: string;
154
+ id: string;
155
155
  updatedAt: string | Date | z.objectInputType<{
156
156
  toDate: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodDate>;
157
157
  }, z.ZodTypeAny, "passthrough">;
@@ -43,7 +43,7 @@ export async function getPublicScammerById(id) {
43
43
  if (!doc || doc.status !== "verified")
44
44
  return null;
45
45
  // Increment views — non-blocking.
46
- scammerRepository.incrementViews(doc.id).catch(() => { });
46
+ scammerRepository.incrementViews(doc.id).catch(console.error);
47
47
  return doc;
48
48
  }
49
49
  /**
@@ -57,5 +57,5 @@ export function ScamProfileView({ scammer, isAuthenticated, incidents = [], comm
57
57
  { label: "Home", href: "/" },
58
58
  { label: "Scam Registry", href: registryHref },
59
59
  { label: scammer.displayNames[0] ?? "Profile" },
60
- ] }) }) }), _jsx(Section, { padding: "y-2xl", children: _jsx(Container, { size: "xl", children: _jsxs(Grid, { cols: "twoThird", gap: "lg", children: [_jsxs(Stack, { gap: "lg", children: [_jsx(ScammerHeaderCard, { scammer: scammer }), (scammer.phones.length > 0 || scammer.upiIds.length > 0 || scammer.emails.length > 0) && (_jsxs(Stack, { gap: "sm", children: [_jsx(Heading, { level: 2, size: "base", weight: "semibold", children: "Contact Identifiers" }), _jsxs(Grid, { cols: 2, gap: "sm", children: [scammer.phones.map((p) => (_jsx(IdentityChip, { label: "Phone", value: p, icon: _jsx(Phone, { className: "h-4 w-4" }) }, p))), scammer.upiIds.map((u) => (_jsx(IdentityChip, { label: "UPI ID", value: u, icon: _jsx(Wallet, { className: "h-4 w-4" }) }, u))), scammer.emails.map((e) => (_jsx(IdentityChip, { label: "Email", value: e, icon: _jsx(Mail, { className: "h-4 w-4" }) }, e)))] })] })), scammer.socialMedia.length > 0 && (_jsxs(Stack, { gap: "sm", children: [_jsx(Heading, { level: 2, size: "base", weight: "semibold", children: "Social Media Profiles" }), _jsx(Stack, { gap: "xs", children: scammer.socialMedia.map((sm, i) => (_jsxs(Row, { gap: "sm", align: "center", children: [_jsx(ExternalLink, { className: "h-4 w-4 shrink-0 text-[color:var(--appkit-color-text-muted,theme(colors.zinc.400))]" }), _jsxs(Text, { size: "sm", weight: "medium", children: [SOCIAL_PLATFORM_LABELS[sm.platform] ?? sm.platform, ":"] }), sm.url ? (_jsx(Anchor, { href: sm.url, size: "sm", children: sm.handle })) : (_jsx(Text, { variant: "secondary", size: "sm", children: sm.handle }))] }, i))) })] })), scammer.itemInvolved && (_jsxs(Stack, { gap: "xs", children: [_jsx(Heading, { level: 2, size: "base", weight: "semibold", children: "Item Involved" }), _jsx(Text, { variant: "secondary", size: "sm", children: scammer.itemInvolved })] })), _jsxs(Stack, { gap: "sm", children: [_jsx(Heading, { level: 2, size: "base", weight: "semibold", children: "What Happened" }), _jsx(Card, { variant: "flat", padding: "md", children: _jsx(Text, { className: "leading-relaxed", size: "sm", children: scammer.description }) })] }), scamTypeDef && scamTypeDef.howToAvoid.length > 0 && (_jsxs(Stack, { gap: "sm", children: [_jsx(Heading, { level: 2, size: "base", weight: "semibold", children: "How to Avoid This Scam" }), _jsx(Card, { variant: "flat", padding: "md", children: _jsx(Stack, { gap: "xs", as: "ol", children: scamTypeDef.howToAvoid.map((tip, i) => (_jsxs(Row, { gap: "sm", align: "start", as: "li", children: [_jsx(Span, { layout: "flex-center", size: "xs", weight: "bold", className: "h-5 w-5 shrink-0 bg-[color:var(--appkit-color-success,theme(colors.green.600))]/10 text-[color:var(--appkit-color-success,theme(colors.green.700))]", rounded: "full", children: i + 1 }), _jsx(Text, { variant: "secondary", className: "leading-relaxed", size: "sm", children: tip })] }, i))) }) })] })), scammer.evidence.length > 0 && (_jsxs(Stack, { gap: "sm", children: [_jsx(Heading, { level: 2, size: "base", weight: "semibold", children: "Evidence" }), _jsx(Row, { gap: "sm", wrap: true, children: scammer.evidence.map((url, i) => (_jsx(Anchor, { href: url, underline: "none", className: "block h-32 w-32 rounded-lg overflow-hidden border shadow-sm hover:opacity-90", children: _jsx(MediaImage, { src: url, alt: `Evidence ${i + 1}`, size: "thumbnail" }) }, i))) })] })), _jsx(ScammerIncidentsSection, { incidents: incidents }), _jsx(ScammerCommentsSection, { comments: comments, isAuthenticated: isAuthenticated, scammerId: scammer.id }), relatedScammers.length > 0 && (_jsxs(Stack, { gap: "sm", children: [_jsx(Heading, { level: 2, size: "base", weight: "semibold", children: "Related Profiles" }), _jsx(Stack, { gap: "sm", children: relatedScammers.map((rel) => (_jsx(Link, { href: String(ROUTES.PUBLIC.SCAM_DETAIL(rel.id)), className: "block", children: _jsx(Card, { variant: "outlined", padding: "sm", className: "hover:opacity-80 transition-opacity", children: _jsxs(Row, { gap: "sm", align: "center", justify: "between", children: [_jsxs(Stack, { gap: "none", children: [_jsx(Text, { size: "sm", weight: "medium", children: rel.displayNames[0] }), _jsx(Text, { variant: "secondary", size: "xs", children: SCAM_TYPE_LABELS[rel.scamType] ?? rel.scamType })] }), _jsxs(Row, { gap: "xs", align: "center", children: [_jsx(Badge, { variant: statusVariant(rel.status), children: SCAMMER_STATUS_LABELS[rel.status] ?? rel.status }), _jsx(Link2, { className: "h-4 w-4 text-[color:var(--appkit-color-text-muted,theme(colors.zinc.400))]" })] })] }) }) }, rel.id))) })] }))] }), _jsx(ScammerActionsColumn, { scammer: scammer, isAuthenticated: isAuthenticated, reportHref: reportHref, contestLoginHref: contestLoginHref })] }) }) })] }));
60
+ ] }) }) }), _jsx(Section, { padding: "y-2xl", children: _jsx(Container, { size: "xl", children: _jsxs(Grid, { cols: "twoThird", gap: "lg", children: [_jsxs(Stack, { gap: "lg", children: [_jsx(ScammerHeaderCard, { scammer: scammer }), (scammer.phones.length > 0 || scammer.upiIds.length > 0 || scammer.emails.length > 0) && (_jsxs(Stack, { gap: "sm", children: [_jsx(Heading, { level: 2, size: "base", weight: "semibold", children: "Contact Identifiers" }), _jsxs(Grid, { cols: 2, gap: "sm", children: [scammer.phones.map((p) => (_jsx(IdentityChip, { label: "Phone", value: p, icon: _jsx(Phone, { className: "h-4 w-4" }) }, p))), scammer.upiIds.map((u) => (_jsx(IdentityChip, { label: "UPI ID", value: u, icon: _jsx(Wallet, { className: "h-4 w-4" }) }, u))), scammer.emails.map((e) => (_jsx(IdentityChip, { label: "Email", value: e, icon: _jsx(Mail, { className: "h-4 w-4" }) }, e)))] })] })), scammer.socialMedia.length > 0 && (_jsxs(Stack, { gap: "sm", children: [_jsx(Heading, { level: 2, size: "base", weight: "semibold", children: "Social Media Profiles" }), _jsx(Stack, { gap: "xs", children: scammer.socialMedia.map((sm, i) => (_jsxs(Row, { gap: "sm", align: "center", children: [_jsx(ExternalLink, { className: "h-4 w-4 shrink-0 text-[color:var(--appkit-color-text-muted,theme(colors.zinc.400))]" }), _jsxs(Text, { size: "sm", weight: "medium", children: [SOCIAL_PLATFORM_LABELS[sm.platform] ?? sm.platform, ":"] }), sm.url ? (_jsx(Anchor, { href: sm.url, size: "sm", children: sm.handle })) : (_jsx(Text, { variant: "secondary", size: "sm", children: sm.handle }))] }, i))) })] })), scammer.itemInvolved && (_jsxs(Stack, { gap: "xs", children: [_jsx(Heading, { level: 2, size: "base", weight: "semibold", children: "Item Involved" }), _jsx(Text, { variant: "secondary", size: "sm", children: scammer.itemInvolved })] })), _jsxs(Stack, { gap: "sm", children: [_jsx(Heading, { level: 2, size: "base", weight: "semibold", children: "What Happened" }), _jsx(Card, { variant: "flat", padding: "md", children: _jsx(Text, { className: "leading-relaxed", size: "sm", children: scammer.description }) })] }), scamTypeDef && scamTypeDef.howToAvoid.length > 0 && (_jsxs(Stack, { gap: "sm", children: [_jsx(Heading, { level: 2, size: "base", weight: "semibold", children: "How to Avoid This Scam" }), _jsx(Card, { variant: "flat", padding: "md", children: _jsx(Stack, { gap: "xs", as: "ol", children: scamTypeDef.howToAvoid.map((tip, i) => (_jsxs(Row, { gap: "sm", align: "start", as: "li", children: [_jsx(Span, { layout: "flex-center", size: "xs", weight: "bold", className: "h-5 w-5 shrink-0 bg-[color:var(--appkit-color-success,theme(colors.green.600))]/10 text-[color:var(--appkit-color-success,theme(colors.green.700))]", rounded: "full", children: i + 1 }), _jsx(Text, { variant: "secondary", className: "leading-relaxed", size: "sm", children: tip })] }, i))) }) })] })), scammer.evidence.length > 0 && (_jsxs(Stack, { gap: "sm", children: [_jsx(Heading, { level: 2, size: "base", weight: "semibold", children: "Evidence" }), _jsx(Row, { gap: "sm", wrap: true, children: scammer.evidence.map((url, i) => (_jsx(Anchor, { href: url, underline: "none", rounded: "lg", shadow: "sm", className: "block h-32 w-32 overflow-hidden border hover:opacity-90", children: _jsx(MediaImage, { src: url, alt: `Evidence ${i + 1}`, size: "thumbnail" }) }, i))) })] })), _jsx(ScammerIncidentsSection, { incidents: incidents }), _jsx(ScammerCommentsSection, { comments: comments, isAuthenticated: isAuthenticated, scammerId: scammer.id }), relatedScammers.length > 0 && (_jsxs(Stack, { gap: "sm", children: [_jsx(Heading, { level: 2, size: "base", weight: "semibold", children: "Related Profiles" }), _jsx(Stack, { gap: "sm", children: relatedScammers.map((rel) => (_jsx(Link, { href: String(ROUTES.PUBLIC.SCAM_DETAIL(rel.id)), className: "block", children: _jsx(Card, { variant: "outlined", padding: "sm", className: "hover:opacity-80 transition-opacity", children: _jsxs(Row, { gap: "sm", align: "center", justify: "between", children: [_jsxs(Stack, { gap: "none", children: [_jsx(Text, { size: "sm", weight: "medium", children: rel.displayNames[0] }), _jsx(Text, { variant: "secondary", size: "xs", children: SCAM_TYPE_LABELS[rel.scamType] ?? rel.scamType })] }), _jsxs(Row, { gap: "xs", align: "center", children: [_jsx(Badge, { variant: statusVariant(rel.status), children: SCAMMER_STATUS_LABELS[rel.status] ?? rel.status }), _jsx(Link2, { className: "h-4 w-4 text-[color:var(--appkit-color-text-muted,theme(colors.zinc.400))]" })] })] }) }) }, rel.id))) })] }))] }), _jsx(ScammerActionsColumn, { scammer: scammer, isAuthenticated: isAuthenticated, reportHref: reportHref, contestLoginHref: contestLoginHref })] }) }) })] }));
61
61
  }
@@ -25,6 +25,7 @@
25
25
  * - SCAMMER_MATCH_FIELDS lists the Firestore array-contains fields used for this query
26
26
  */
27
27
  import type { ScamType } from "../constants/scam-types";
28
+ import type { BaseDocument } from "../../../_internal/shared/types/base-document";
28
29
  export declare const ScammerStatusValues: {
29
30
  readonly PENDING_REVIEW: "pending_review";
30
31
  readonly VERIFIED: "verified";
@@ -83,8 +84,7 @@ export interface ScammerSocialMedia {
83
84
  handle: string;
84
85
  url?: string;
85
86
  }
86
- export interface ScammerDocument {
87
- id: string;
87
+ export interface ScammerDocument extends BaseDocument {
88
88
  /** URL-safe slug — used in /scams/[slug]. Same as id. */
89
89
  seoSlug: string;
90
90
  /**
@@ -159,8 +159,6 @@ export interface ScammerDocument {
159
159
  * Reset to false when all contests are reviewed.
160
160
  */
161
161
  isContested?: boolean;
162
- createdAt: Date;
163
- updatedAt: Date;
164
162
  }
165
163
  /**
166
164
  * One victim's report linked to an existing scammer profile.
@@ -83,9 +83,9 @@ export declare const scammerFirestoreSchema: z.ZodObject<{
83
83
  createdAt: string | Date | z.objectOutputType<{
84
84
  toDate: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodDate>;
85
85
  }, z.ZodTypeAny, "passthrough">;
86
- id: string;
87
86
  description: string;
88
87
  tags: string[];
88
+ id: string;
89
89
  updatedAt: string | Date | z.objectOutputType<{
90
90
  toDate: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodDate>;
91
91
  }, z.ZodTypeAny, "passthrough">;
@@ -123,9 +123,9 @@ export declare const scammerFirestoreSchema: z.ZodObject<{
123
123
  createdAt: string | Date | z.objectInputType<{
124
124
  toDate: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodDate>;
125
125
  }, z.ZodTypeAny, "passthrough">;
126
- id: string;
127
126
  description: string;
128
127
  tags: string[];
128
+ id: string;
129
129
  updatedAt: string | Date | z.objectInputType<{
130
130
  toDate: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodDate>;
131
131
  }, z.ZodTypeAny, "passthrough">;
@@ -195,8 +195,8 @@ export declare const scammerIncidentFirestoreSchema: z.ZodObject<{
195
195
  createdAt: string | Date | z.objectOutputType<{
196
196
  toDate: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodDate>;
197
197
  }, z.ZodTypeAny, "passthrough">;
198
- id: string;
199
198
  description: string;
199
+ id: string;
200
200
  scamType: string;
201
201
  reportedBy: string;
202
202
  scammerId: string;
@@ -218,8 +218,8 @@ export declare const scammerIncidentFirestoreSchema: z.ZodObject<{
218
218
  createdAt: string | Date | z.objectInputType<{
219
219
  toDate: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodDate>;
220
220
  }, z.ZodTypeAny, "passthrough">;
221
- id: string;
222
221
  description: string;
222
+ id: string;
223
223
  scamType: string;
224
224
  reportedBy: string;
225
225
  scammerId: string;
@@ -216,7 +216,7 @@ export function Search({ isOpen, onClose, onSearch, onOpen, value, onChange, pla
216
216
  if (inlineBlurRef.current)
217
217
  clearTimeout(inlineBlurRef.current);
218
218
  inlineBlurRef.current = setTimeout(() => setIsInlineOpen(false), 120);
219
- }, placeholder: placeholder ?? labels.placeholder, className: "w-full rounded-lg border border-zinc-300 bg-white pl-9 text-zinc-900 placeholder:text-zinc-400 focus:border-primary focus:ring-2 focus:ring-primary/20 dark:border-slate-700 dark:bg-slate-900 dark:text-white dark:placeholder:text-slate-500" }), query && (_jsx(Button, { rounded: "full", textColor: "faint", type: "button", variant: "ghost", onClick: handleClear, className: "absolute right-3 p-0.5 hover:text-zinc-600 dark:hover:text-zinc-200 transition-colors", "aria-label": labels.clearAriaLabel, children: _jsx("svg", { className: "w-4 h-4", "aria-hidden": "true", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) }) }))] }), resourceTypes && resourceTypes.length > 0 && (_jsx("select", { value: selectedType, onChange: (e) => handleTypeChange(e.target.value), "aria-label": labels.resourceTypeLabel ?? "Search in", className: "flex-shrink-0 rounded-lg border border-zinc-300 bg-white px-2 py-2 text-sm text-zinc-700 focus:border-primary focus:outline-none focus:ring-2 focus:ring-primary/20 dark:border-slate-700 dark:bg-slate-900 dark:text-zinc-300 cursor-pointer", children: resourceTypes.map((opt) => (_jsx("option", { value: opt.value, children: opt.label }, opt.value))) })), deferred && (_jsx(Button, { rounded: "lg", paddingX: "sm", paddingY: "sm", type: "button", variant: "primary", onClick: handleDeferredSubmit, "aria-label": labels.ariaLabel, className: "flex-shrink-0", children: _jsx("svg", { className: "w-4 h-4", "aria-hidden": "true", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: SVG_PATH_SEARCH }) }) })), isInlineOpen && (filteredQuickLinks.length > 0 || query) && (_jsxs("div", { className: "absolute top-full left-0 right-0 mt-2 rounded-xl overflow-hidden border border-zinc-200 bg-white shadow-lg dark:border-slate-700 dark:bg-slate-900", style: { zIndex: "var(--appkit-z-dropdown)" }, onMouseDown: (event) => event.preventDefault(), children: [filteredQuickLinks.length > 0 && (_jsx(Ul, { children: filteredQuickLinks.map((link, index) => renderInlineQuickLink(link, index)) })), query && suggestionsLoading && (_jsx(Div, { padding: "inline", children: _jsx(Text, { variant: "secondary", size: "sm", children: labels.searching }) })), query &&
219
+ }, placeholder: placeholder ?? labels.placeholder, className: "w-full rounded-lg border border-zinc-300 bg-white pl-9 text-zinc-900 placeholder:text-zinc-400 focus:border-primary focus:ring-2 focus:ring-primary/20 dark:border-slate-700 dark:bg-slate-900 dark:text-white dark:placeholder:text-slate-500" }), query && (_jsx(Button, { rounded: "full", textColor: "faint", type: "button", variant: "ghost", onClick: handleClear, className: "absolute right-3 p-[0.125rem] hover:text-[var(--appkit-color-text-muted)] dark:hover:text-[var(--appkit-color-text)] transition-colors", "aria-label": labels.clearAriaLabel, children: _jsx("svg", { className: "w-4 h-4", "aria-hidden": "true", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) }) }))] }), resourceTypes && resourceTypes.length > 0 && (_jsx("select", { value: selectedType, onChange: (e) => handleTypeChange(e.target.value), "aria-label": labels.resourceTypeLabel ?? "Search in", className: "flex-shrink-0 rounded-lg border border-zinc-300 bg-white px-2 py-2 text-sm text-zinc-700 focus:border-primary focus:outline-none focus:ring-2 focus:ring-primary/20 dark:border-slate-700 dark:bg-slate-900 dark:text-zinc-300 cursor-pointer", children: resourceTypes.map((opt) => (_jsx("option", { value: opt.value, children: opt.label }, opt.value))) })), deferred && (_jsx(Button, { rounded: "lg", paddingX: "sm", paddingY: "sm", type: "button", variant: "primary", onClick: handleDeferredSubmit, "aria-label": labels.ariaLabel, className: "flex-shrink-0", children: _jsx("svg", { className: "w-4 h-4", "aria-hidden": "true", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: SVG_PATH_SEARCH }) }) })), isInlineOpen && (filteredQuickLinks.length > 0 || query) && (_jsxs("div", { className: "absolute top-full left-0 right-0 mt-2 rounded-xl overflow-hidden border border-zinc-200 bg-white shadow-lg dark:border-slate-700 dark:bg-slate-900 [z-index:var(--appkit-z-dropdown)]", onMouseDown: (event) => event.preventDefault(), children: [filteredQuickLinks.length > 0 && (_jsx(Ul, { children: filteredQuickLinks.map((link, index) => renderInlineQuickLink(link, index)) })), query && suggestionsLoading && (_jsx(Div, { padding: "inline", children: _jsx(Text, { variant: "secondary", size: "sm", children: labels.searching }) })), query &&
220
220
  suggestions.slice(0, 5).map((suggestion, suggestionIndex) => {
221
221
  const itemIndex = inlineQuickLinkItems.length + suggestionIndex;
222
222
  const isActive = activeIndex === itemIndex;
@@ -292,7 +292,7 @@ export function Search({ isOpen, onClose, onSearch, onOpen, value, onChange, pla
292
292
  };
293
293
  if (!isOpen)
294
294
  return null;
295
- return (_jsx(Div, { border: "bottom-subtle", className: "animate-[fadeIn_150ms_ease-out]", surface: "default", shadow: "md", children: _jsxs(Div, { className: "container mx-auto md:py-4 relative", padding: "inline", children: [_jsxs(Row, { gap: "sm", className: "md:gap-3", children: [_jsx(Div, { className: "flex-1 relative", children: _jsx(Input, { ref: inputRef, bare: true, type: "search", placeholder: placeholder ?? labels.placeholder, value: query, onChange: (event) => setQuery(event.target.value), onKeyDown: handleOverlayKeyDown, className: "w-full rounded-lg border border-zinc-300 bg-white text-zinc-900 placeholder:text-zinc-400 focus:border-primary focus:ring-2 focus:ring-primary/20 dark:border-slate-700 dark:bg-slate-900 dark:text-white dark:placeholder:text-slate-500" }) }), resourceTypes && resourceTypes.length > 0 && (_jsx("select", { value: selectedType, onChange: (e) => handleTypeChange(e.target.value), "aria-label": labels.resourceTypeLabel ?? "Search in", className: "flex-shrink-0 rounded-lg border border-zinc-300 bg-white px-2 py-2 text-sm text-zinc-700 focus:border-primary focus:outline-none focus:ring-2 focus:ring-primary/20 dark:border-slate-700 dark:bg-slate-900 dark:text-zinc-300 cursor-pointer", children: resourceTypes.map((opt) => (_jsx("option", { value: opt.value, children: opt.label }, opt.value))) })), _jsxs(Button, { gap: "md", onClick: handleOverlaySearch, variant: "primary", size: "md", className: "hidden sm:", children: [_jsx("svg", { className: "w-5 h-5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: SVG_PATH_SEARCH }) }), labels.title] }), _jsx(Button, { rounded: "xl", variant: "ghost", onClick: () => onClose?.(), className: "p-2.5 md:p-3 transition-colors text-zinc-500 hover:bg-zinc-100 hover:text-zinc-700 dark:text-zinc-400 dark:hover:bg-slate-800 dark:hover:text-zinc-200 flex-shrink-0", "aria-label": labels.closeAriaLabel, children: _jsx("svg", { className: "w-6 h-6 md:w-7 md:h-7", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) }) })] }), (filteredSiteLinks.length > 0 || query) && (_jsxs(Stack, { className: "absolute top-full left-0 right-0 pt-2 pb-4 z-50", padding: "x-md", gap: "sm", children: [filteredSiteLinks.length > 0 && !suggestionsLoading && (_jsxs(Div, { className: `${__O.hidden}`, rounded: "xl", shadow: "lg", surface: "default", border: "default", children: [_jsx(Div, { border: "default", className: "border-b", paddingY: "y-xs", paddingX: "x-md", children: _jsx(Text, { variant: "secondary", size: "xs", className: "uppercase tracking-wider", weight: "semibold", children: labels.quickLinks }) }), _jsx(Ul, { children: filteredSiteLinks.map((link) => {
295
+ return (_jsx(Div, { border: "bottom-subtle", className: "animate-[fadeIn_150ms_ease-out]", surface: "default", shadow: "md", children: _jsxs(Div, { className: "container mx-auto md:py-[1rem] relative", padding: "inline", children: [_jsxs(Row, { gap: "sm", className: "md:gap-[0.75rem]", children: [_jsx(Div, { className: "flex-1 relative", children: _jsx(Input, { ref: inputRef, bare: true, type: "search", placeholder: placeholder ?? labels.placeholder, value: query, onChange: (event) => setQuery(event.target.value), onKeyDown: handleOverlayKeyDown, className: "w-full rounded-lg border border-zinc-300 bg-white text-zinc-900 placeholder:text-zinc-400 focus:border-primary focus:ring-2 focus:ring-primary/20 dark:border-slate-700 dark:bg-slate-900 dark:text-white dark:placeholder:text-slate-500" }) }), resourceTypes && resourceTypes.length > 0 && (_jsx("select", { value: selectedType, onChange: (e) => handleTypeChange(e.target.value), "aria-label": labels.resourceTypeLabel ?? "Search in", className: "flex-shrink-0 rounded-lg border border-zinc-300 bg-white px-2 py-2 text-sm text-zinc-700 focus:border-primary focus:outline-none focus:ring-2 focus:ring-primary/20 dark:border-slate-700 dark:bg-slate-900 dark:text-zinc-300 cursor-pointer", children: resourceTypes.map((opt) => (_jsx("option", { value: opt.value, children: opt.label }, opt.value))) })), _jsxs(Button, { gap: "md", onClick: handleOverlaySearch, variant: "primary", size: "md", className: "hidden sm:", children: [_jsx("svg", { className: "w-5 h-5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: SVG_PATH_SEARCH }) }), labels.title] }), _jsx(Button, { rounded: "xl", variant: "ghost", onClick: () => onClose?.(), className: "p-2.5 md:p-3 transition-colors text-zinc-500 hover:bg-zinc-100 hover:text-zinc-700 dark:text-zinc-400 dark:hover:bg-slate-800 dark:hover:text-zinc-200 flex-shrink-0", "aria-label": labels.closeAriaLabel, children: _jsx("svg", { className: "w-6 h-6 md:w-7 md:h-7", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) }) })] }), (filteredSiteLinks.length > 0 || query) && (_jsxs(Stack, { className: "absolute top-full left-0 right-0 z-50 pt-[0.5rem] pb-[1rem]", padding: "x-md", gap: "sm", children: [filteredSiteLinks.length > 0 && !suggestionsLoading && (_jsxs(Div, { className: `${__O.hidden}`, rounded: "xl", shadow: "lg", surface: "default", border: "default", children: [_jsx(Div, { border: "default", className: "border-b", paddingY: "y-xs", paddingX: "x-md", children: _jsx(Text, { variant: "secondary", size: "xs", className: "uppercase tracking-wider", weight: "semibold", children: labels.quickLinks }) }), _jsx(Ul, { children: filteredSiteLinks.map((link) => {
296
296
  const Icon = link.icon;
297
297
  const itemIndex = quickLinkItems.findIndex((item) => item.link.href === link.href);
298
298
  const isActive = activeIndex === itemIndex;
@@ -17,5 +17,5 @@ export function SearchFiltersRow({ urlCategory, categories, urlMinPrice, urlMaxP
17
17
  return (_jsxs(Row, { wrap: true, gap: "md", align: "end", children: [_jsxs(Stack, { gap: "xs", children: [_jsx(Label, { size: "sm", weight: "medium", color: "muted", children: L.categoryFilter }), _jsx(Select, { value: urlCategory, onValueChange: (value) => onCategoryChange(value), options: [
18
18
  { value: "", label: L.allCategories },
19
19
  ...categories.map((cat) => ({ value: cat.id, label: cat.name })),
20
- ], className: "rounded-lg border border-zinc-200 dark:border-slate-700 bg-white dark:bg-slate-800/60 px-3 py-2 text-sm text-zinc-900 dark:text-zinc-100 focus:outline-none focus:ring-2 focus:ring-primary-500/20" })] }), _jsxs(Stack, { gap: "xs", children: [_jsx(Label, { size: "sm", weight: "medium", color: "muted", children: L.priceRange }), _jsxs(Row, { align: "center", gap: "sm", children: [_jsx(Input, { type: "number", min: 0, value: minPrice, onChange: (e) => setMinPrice(e.target.value), placeholder: L.minPrice, className: "w-28 rounded-lg border border-zinc-200 dark:border-slate-700 bg-white dark:bg-slate-800/60 px-3 py-2 text-sm text-zinc-900 dark:text-zinc-100 focus:outline-none focus:ring-2 focus:ring-primary-500/20" }), _jsx(Span, { size: "sm", color: "muted", children: "\u2013" }), _jsx(Input, { type: "number", min: 0, value: maxPrice, onChange: (e) => setMaxPrice(e.target.value), placeholder: L.maxPrice, className: "w-28 rounded-lg border border-zinc-200 dark:border-slate-700 bg-white dark:bg-slate-800/60 px-3 py-2 text-sm text-zinc-900 dark:text-zinc-100 focus:outline-none focus:ring-2 focus:ring-primary-500/20" }), _jsx(Button, { rounded: "lg", type: "button", variant: "primary", size: "sm", onClick: () => onPriceFilter(minPrice, maxPrice), className: "h-10 px-4 bg-primary-600 hover:bg-primary-700 text-white text-sm font-medium transition-colors", children: L.apply })] })] }), showClear && (_jsx(Button, { rounded: "lg", type: "button", variant: "outline", size: "sm", onClick: onClearFilters, paddingX: "md", textSize: "sm", className: "h-10 border border-zinc-200 dark:border-slate-700 text-zinc-700 dark:text-zinc-300 hover:bg-zinc-100 dark:hover:bg-slate-800 transition-colors", children: L.clearFilters }))] }));
20
+ ], className: "rounded-lg border border-zinc-200 dark:border-slate-700 bg-white dark:bg-slate-800/60 px-3 py-2 text-sm text-zinc-900 dark:text-zinc-100 focus:outline-none focus:ring-2 focus:ring-primary-500/20" })] }), _jsxs(Stack, { gap: "xs", children: [_jsx(Label, { size: "sm", weight: "medium", color: "muted", children: L.priceRange }), _jsxs(Row, { align: "center", gap: "sm", children: [_jsx(Input, { type: "number", min: 0, value: minPrice, onChange: (e) => setMinPrice(e.target.value), placeholder: L.minPrice, className: "w-28 rounded-lg border border-zinc-200 dark:border-slate-700 bg-white dark:bg-slate-800/60 px-3 py-2 text-sm text-zinc-900 dark:text-zinc-100 focus:outline-none focus:ring-2 focus:ring-primary-500/20" }), _jsx(Span, { size: "sm", color: "muted", children: "\u2013" }), _jsx(Input, { type: "number", min: 0, value: maxPrice, onChange: (e) => setMaxPrice(e.target.value), placeholder: L.maxPrice, className: "w-28 rounded-lg border border-zinc-200 dark:border-slate-700 bg-white dark:bg-slate-800/60 px-3 py-2 text-sm text-zinc-900 dark:text-zinc-100 focus:outline-none focus:ring-2 focus:ring-primary-500/20" }), _jsx(Button, { rounded: "lg", type: "button", variant: "primary", size: "sm", onClick: () => onPriceFilter(minPrice, maxPrice), className: "h-10 px-4 bg-primary-600 hover:bg-primary-700 text-white text-sm font-medium transition-colors", children: L.apply })] })] }), showClear && (_jsx(Button, { rounded: "lg", type: "button", variant: "outline", size: "sm", onClick: onClearFilters, paddingX: "md", textSize: "sm", className: "h-10 border border-[var(--appkit-color-border)] text-[var(--appkit-color-text)] hover:bg-[var(--appkit-color-surface-elevated)] transition-colors", children: L.clearFilters }))] }));
21
21
  }
@@ -21,9 +21,9 @@ export declare const searchProductItemSchema: z.ZodObject<{
21
21
  isPromoted: z.ZodOptional<z.ZodBoolean>;
22
22
  slug: z.ZodString;
23
23
  }, "strip", z.ZodTypeAny, {
24
- id: string;
25
24
  title: string;
26
25
  slug: string;
26
+ id: string;
27
27
  status?: string | undefined;
28
28
  currency?: string | undefined;
29
29
  featured?: boolean | undefined;
@@ -32,9 +32,9 @@ export declare const searchProductItemSchema: z.ZodObject<{
32
32
  price?: number | undefined;
33
33
  mainImage?: string | undefined;
34
34
  }, {
35
- id: string;
36
35
  title: string;
37
36
  slug: string;
37
+ id: string;
38
38
  status?: string | undefined;
39
39
  currency?: string | undefined;
40
40
  featured?: boolean | undefined;
@@ -54,8 +54,8 @@ export declare const searchQuerySchema: z.ZodObject<{
54
54
  sort: z.ZodOptional<z.ZodString>;
55
55
  page: z.ZodDefault<z.ZodNumber>;
56
56
  }, "strip", z.ZodTypeAny, {
57
- q: string;
58
57
  page: number;
58
+ q: string;
59
59
  sort?: string | undefined;
60
60
  category?: string | undefined;
61
61
  minPrice?: number | undefined;
@@ -0,0 +1,17 @@
1
+ export interface BarcodeFieldProps {
2
+ label?: string;
3
+ value: string;
4
+ onChange: (value: string) => void;
5
+ /** Called when the scanner fires Enter after rapid character input (< 50 ms between keys). */
6
+ onScan?: (value: string) => void;
7
+ placeholder?: string;
8
+ helperText?: string;
9
+ autoFocus?: boolean;
10
+ readOnly?: boolean;
11
+ }
12
+ /**
13
+ * Text field that detects USB/Bluetooth barcode scanner input.
14
+ * Scanners type characters rapidly (< 50 ms per keydown) then send Enter.
15
+ * onScan is called when Enter follows rapid input; manual typing is ignored.
16
+ */
17
+ export declare function BarcodeField({ label, value, onChange, onScan, placeholder, helperText, autoFocus, readOnly, }: BarcodeFieldProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,30 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useRef, useCallback } from "react";
4
+ import { FieldInput } from "../../../ui/forms/FieldInput";
5
+ import { Text } from "../../../ui/components/Typography";
6
+ import { Stack } from "../../../ui/components/Layout";
7
+ /**
8
+ * Text field that detects USB/Bluetooth barcode scanner input.
9
+ * Scanners type characters rapidly (< 50 ms per keydown) then send Enter.
10
+ * onScan is called when Enter follows rapid input; manual typing is ignored.
11
+ */
12
+ export function BarcodeField({ label = "Barcode / Sticker ID", value, onChange, onScan, placeholder = "Scan or type barcode…", helperText, autoFocus, readOnly, }) {
13
+ const lastKeyTime = useRef(0);
14
+ const buffer = useRef("");
15
+ const handleKeyDown = useCallback((e) => {
16
+ const now = Date.now();
17
+ if (e.key === "Enter") {
18
+ e.preventDefault();
19
+ if (buffer.current) {
20
+ onScan?.(buffer.current);
21
+ buffer.current = "";
22
+ }
23
+ return;
24
+ }
25
+ const interval = now - lastKeyTime.current;
26
+ buffer.current = interval < 50 ? buffer.current + e.key : e.key;
27
+ lastKeyTime.current = now;
28
+ }, [onScan]);
29
+ return (_jsxs(Stack, { gap: "xs", children: [_jsx(FieldInput, { name: "barcodeId", label: label, type: "text", value: value, onChange: onChange, onKeyDown: handleKeyDown, placeholder: placeholder, autoFocus: autoFocus, readOnly: readOnly }), helperText && (_jsx(Text, { size: "xs", color: "muted", children: helperText }))] }));
30
+ }
@@ -0,0 +1,5 @@
1
+ export interface FulfillmentViewProps {
2
+ currentUserId?: string;
3
+ currentUserName?: string;
4
+ }
5
+ export declare function FulfillmentView({ currentUserId, }: FulfillmentViewProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,120 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
+ import { useCallback, useEffect, useState } from "react";
4
+ import { Heading, Text } from "../../../ui/components/Typography";
5
+ import { Stack, Row } from "../../../ui/components/Layout";
6
+ import { Button } from "../../../ui/components/Button";
7
+ import { Badge } from "../../../ui/components/Badge";
8
+ import { apiClient } from "../../../http";
9
+ import { SELLER_ENDPOINTS } from "../../../constants/api-endpoints";
10
+ import { BarcodeField } from "./BarcodeField";
11
+ import { normalizeError } from "../../../errors/normalize";
12
+ import { useToast } from "../../../ui";
13
+ function statusBadgeVariant(status) {
14
+ if (status === "confirmed")
15
+ return "warning";
16
+ if (status === "processing")
17
+ return "info";
18
+ if (status === "shipped")
19
+ return "success";
20
+ return "default";
21
+ }
22
+ export function FulfillmentView({ currentUserId, }) {
23
+ const [mode, setMode] = useState("scan");
24
+ const [orders, setOrders] = useState([]);
25
+ const [scanValue, setScanValue] = useState("");
26
+ const [scanResult, setScanResult] = useState(null);
27
+ const [scanError, setScanError] = useState(null);
28
+ const [filterMine, setFilterMine] = useState(false);
29
+ const [isLoadingOrders, setIsLoadingOrders] = useState(true);
30
+ const [isConfirming, setIsConfirming] = useState(false);
31
+ const [actionLoadingId, setActionLoadingId] = useState(null);
32
+ const { showToast } = useToast();
33
+ const fetchOrders = useCallback(async () => {
34
+ // toast-intentionally-silent: background data loader — stale list is kept on error
35
+ setIsLoadingOrders(true);
36
+ try {
37
+ const res = await apiClient.get(SELLER_ENDPOINTS.ORDERS_FULFILLMENT);
38
+ setOrders(res.orders ?? []);
39
+ }
40
+ catch {
41
+ // keep stale list on error
42
+ }
43
+ finally {
44
+ setIsLoadingOrders(false);
45
+ }
46
+ }, []);
47
+ useEffect(() => {
48
+ void fetchOrders();
49
+ }, [fetchOrders]);
50
+ const handleScan = useCallback(async (barcode) => {
51
+ setScanError(null);
52
+ setScanResult(null);
53
+ try {
54
+ const product = await apiClient.get(SELLER_ENDPOINTS.PRODUCTS_SCAN(barcode));
55
+ const matchedOrder = orders.find((o) => o.productId === product.id ||
56
+ o.items?.some((i) => i.productId === product.id));
57
+ if (!matchedOrder) {
58
+ setScanError(`No pending order found for barcode "${barcode}".`);
59
+ return;
60
+ }
61
+ setScanResult({ product, order: matchedOrder });
62
+ }
63
+ catch (err) {
64
+ setScanError(normalizeError(err).message);
65
+ }
66
+ }, [orders]);
67
+ const confirmPick = useCallback(async () => {
68
+ if (!scanResult)
69
+ return;
70
+ setIsConfirming(true);
71
+ try {
72
+ await apiClient.patch(SELLER_ENDPOINTS.ORDERS_BY_ID(scanResult.order.id), { markPicked: true });
73
+ setScanResult(null);
74
+ setScanValue("");
75
+ setScanError(null);
76
+ showToast("Order marked as picked!", "success");
77
+ await fetchOrders();
78
+ }
79
+ catch (err) {
80
+ setScanError(normalizeError(err).message);
81
+ }
82
+ finally {
83
+ setIsConfirming(false);
84
+ }
85
+ }, [scanResult, fetchOrders, showToast]);
86
+ const handleMarkPicked = useCallback(async (orderId) => {
87
+ setActionLoadingId(orderId + ":picked");
88
+ try {
89
+ await apiClient.patch(SELLER_ENDPOINTS.ORDERS_BY_ID(orderId), {
90
+ markPicked: true,
91
+ });
92
+ await fetchOrders();
93
+ }
94
+ finally {
95
+ setActionLoadingId(null);
96
+ }
97
+ }, [fetchOrders]);
98
+ const handleMarkPacked = useCallback(async (orderId) => {
99
+ setActionLoadingId(orderId + ":packed");
100
+ try {
101
+ await apiClient.patch(SELLER_ENDPOINTS.ORDERS_BY_ID(orderId), {
102
+ markPacked: true,
103
+ });
104
+ await fetchOrders();
105
+ }
106
+ finally {
107
+ setActionLoadingId(null);
108
+ }
109
+ }, [fetchOrders]);
110
+ const visibleOrders = filterMine
111
+ ? orders.filter((o) => o.assignedWorkerId === currentUserId)
112
+ : orders;
113
+ return (_jsxs(Stack, { gap: "md", padding: "md", children: [_jsxs(Row, { align: "center", justify: "between", gap: "sm", wrap: true, children: [_jsx(Heading, { level: 3, children: "Pick & Pack" }), _jsxs(Row, { gap: "xs", children: [_jsx(Button, { onClick: () => setMode("scan"), variant: mode === "scan" ? "primary" : "secondary", size: "sm", children: "Scan Mode" }), _jsx(Button, { onClick: () => setMode("list"), variant: mode === "list" ? "primary" : "secondary", size: "sm", children: "List Mode" })] })] }), mode === "scan" && (_jsxs(Stack, { gap: "md", children: [_jsx(BarcodeField, { autoFocus: true, value: scanValue, onChange: setScanValue, onScan: handleScan, helperText: "Point scanner at an item sticker or type the barcode and press Enter." }), scanError && (_jsx(Text, { color: "error", size: "sm", children: scanError })), scanResult && (_jsxs(Stack, { surface: "card", padding: "md", rounded: "md", gap: "sm", children: [_jsx(Text, { size: "xs", color: "muted", children: "Scanned item" }), _jsx(Heading, { level: 5, children: scanResult.product.title ?? scanResult.product.id }), _jsxs(Row, { gap: "md", wrap: true, children: [_jsxs(Stack, { gap: "xs", children: [_jsx(Text, { size: "xs", color: "muted", children: "Order" }), _jsxs(Text, { size: "sm", weight: "medium", children: ["#", scanResult.order.id] })] }), _jsxs(Stack, { gap: "xs", children: [_jsx(Text, { size: "xs", color: "muted", children: "Buyer" }), _jsx(Text, { size: "sm", weight: "medium", children: scanResult.order.userName })] }), _jsxs(Stack, { gap: "xs", children: [_jsx(Text, { size: "xs", color: "muted", children: "Status" }), _jsx(Badge, { variant: statusBadgeVariant(scanResult.order.status), children: scanResult.order.status })] })] }), _jsxs(Row, { gap: "xs", children: [_jsx(Button, { variant: "primary", onClick: confirmPick, isLoading: isConfirming, children: "Confirm Pick" }), _jsx(Button, { variant: "secondary", onClick: () => {
114
+ setScanResult(null);
115
+ setScanValue("");
116
+ setScanError(null);
117
+ }, children: "Cancel" })] })] })), !scanResult && !scanError && (_jsx(Text, { color: "muted", size: "sm", children: orders.length === 0 && !isLoadingOrders
118
+ ? "No orders waiting — great work!"
119
+ : `${orders.length} order${orders.length === 1 ? "" : "s"} in queue.` }))] })), mode === "list" && (_jsxs(Stack, { gap: "sm", children: [_jsxs(Row, { align: "center", gap: "sm", children: [_jsx(Button, { variant: filterMine ? "primary" : "secondary", size: "sm", onClick: () => setFilterMine((v) => !v), children: filterMine ? "Showing My Orders" : "My Orders" }), _jsx(Text, { size: "xs", color: "muted", children: isLoadingOrders ? "Loading…" : `${visibleOrders.length} order${visibleOrders.length === 1 ? "" : "s"}` })] }), visibleOrders.length === 0 && !isLoadingOrders && (_jsx(Text, { color: "muted", children: "No orders waiting \u2014 great work!" })), visibleOrders.map((order) => (_jsxs(Stack, { surface: "card", padding: "sm", rounded: "md", gap: "xs", children: [_jsxs(Row, { align: "center", gap: "xs", wrap: true, children: [_jsxs(Text, { size: "sm", weight: "medium", children: ["#", order.id] }), _jsx(Badge, { variant: statusBadgeVariant(order.status), children: order.status }), order.pickedAt && (_jsx(Badge, { variant: "success", children: "Picked" })), order.packedAt && (_jsx(Badge, { variant: "success", children: "Packed" }))] }), _jsxs(Text, { size: "xs", color: "muted", children: [order.userName, order.items && order.items.length > 0 && (_jsxs(_Fragment, { children: [" \u00B7 ", order.items.map((i) => i.productTitle).join(", ")] }))] }), order.assignedWorkerId && (_jsxs(Text, { size: "xs", color: "muted", children: ["Assigned: ", order.assignedWorkerId === currentUserId ? "Me" : order.assignedWorkerId] })), _jsxs(Row, { gap: "xs", children: [!order.pickedAt && (_jsx(Button, { size: "sm", variant: "secondary", onClick: () => handleMarkPicked(order.id), isLoading: actionLoadingId === order.id + ":picked", children: "Mark Picked" })), order.pickedAt && !order.packedAt && (_jsx(Button, { size: "sm", variant: "secondary", onClick: () => handleMarkPacked(order.id), isLoading: actionLoadingId === order.id + ":packed", children: "Mark Packed" }))] })] }, order.id)))] }))] }));
120
+ }
@@ -4,8 +4,7 @@ import { useState } from "react";
4
4
  import { Modal } from "../../../ui/components/Modal";
5
5
  import { Input } from "../../../ui/components/Input";
6
6
  import { Button } from "../../../ui/components/Button";
7
- import { Row } from "../../../ui/components/Layout";
8
- import { Div } from "../../../ui/components/Div";
7
+ import { Row, Stack } from "../../../ui/components/Layout";
9
8
  import { Text } from "../../../ui/components/Typography";
10
9
  import { normalizeError } from "../../../errors/normalize";
11
10
  export function PhysicalLocationModal({ count, onSave, onClose }) {
@@ -29,5 +28,5 @@ export function PhysicalLocationModal({ count, onSave, onClose }) {
29
28
  setSaving(false);
30
29
  }
31
30
  };
32
- return (_jsx(Modal, { isOpen: true, onClose: onClose, title: `Set Location — ${count} item${count !== 1 ? "s" : ""}`, size: "sm", actions: _jsxs(Row, { gap: "sm", justify: "end", children: [_jsx(Button, { variant: "ghost", onClick: onClose, disabled: saving, children: "Cancel" }), _jsx(Button, { variant: "primary", onClick: handleSave, disabled: saving, children: saving ? "Saving..." : "Save" })] }), children: _jsxs(Div, { style: { display: "flex", flexDirection: "column", gap: "12px" }, children: [_jsx(Text, { variant: "muted", children: "Assign a physical storage location to the selected items. All fields are optional." }), _jsx(Input, { label: "Zone (e.g. A, B, Storage-1)", value: zone, onChange: e => setZone(e.target.value), placeholder: "A" }), _jsx(Input, { label: "Shelf (e.g. 3, Top, Middle)", value: shelf, onChange: e => setShelf(e.target.value), placeholder: "3" }), _jsx(Input, { label: "Bin (e.g. Blue, Box-12)", value: bin, onChange: e => setBin(e.target.value), placeholder: "Blue" }), error && _jsx(Text, { variant: "error", children: error })] }) }));
31
+ return (_jsx(Modal, { isOpen: true, onClose: onClose, title: `Set Location — ${count} item${count !== 1 ? "s" : ""}`, size: "sm", actions: _jsxs(Row, { gap: "sm", justify: "end", children: [_jsx(Button, { variant: "ghost", onClick: onClose, disabled: saving, children: "Cancel" }), _jsx(Button, { variant: "primary", onClick: handleSave, disabled: saving, children: saving ? "Saving..." : "Save" })] }), children: _jsxs(Stack, { gap: "3", children: [_jsx(Text, { variant: "muted", children: "Assign a physical storage location to the selected items. All fields are optional." }), _jsx(Input, { label: "Zone (e.g. A, B, Storage-1)", value: zone, onChange: e => setZone(e.target.value), placeholder: "A" }), _jsx(Input, { label: "Shelf (e.g. 3, Top, Middle)", value: shelf, onChange: e => setShelf(e.target.value), placeholder: "3" }), _jsx(Input, { label: "Bin (e.g. Blue, Box-12)", value: bin, onChange: e => setBin(e.target.value), placeholder: "Blue" }), error && _jsx(Text, { variant: "error", children: error })] }) }));
33
32
  }
@@ -14,6 +14,7 @@ interface PrintCenterProduct {
14
14
  condition?: string;
15
15
  stockCount?: number;
16
16
  physicalLocation?: string;
17
+ barcodeId?: string;
17
18
  }
18
19
  interface PrintCenterOrder {
19
20
  id: string;
@@ -25,6 +26,7 @@ interface PrintCenterOrder {
25
26
  productName: string;
26
27
  quantity: number;
27
28
  price: number;
29
+ barcodeId?: string;
28
30
  }[];
29
31
  physicalLocation?: string;
30
32
  }
@@ -36,5 +38,5 @@ interface PrintCenterViewProps {
36
38
  initialProducts?: PrintCenterProduct[];
37
39
  initialOrders?: PrintCenterOrder[];
38
40
  }
39
- export declare function PrintCenterView({ store, brandName }: PrintCenterViewProps): import("react/jsx-runtime").JSX.Element;
41
+ export declare function PrintCenterView({ store, brandName, initialProducts, initialOrders, }: PrintCenterViewProps): import("react/jsx-runtime").JSX.Element;
40
42
  export {};