@mohasinac/appkit 2.3.1 → 2.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (253) hide show
  1. package/dist/client.d.ts +12 -8
  2. package/dist/client.js +7 -4
  3. package/dist/constants/api-endpoints.d.ts +4 -0
  4. package/dist/constants/api-endpoints.js +2 -0
  5. package/dist/core/contact-submissions.repository.d.ts +32 -0
  6. package/dist/core/contact-submissions.repository.js +49 -0
  7. package/dist/core/index.d.ts +2 -0
  8. package/dist/core/index.js +1 -0
  9. package/dist/features/about/components/HowPayoutsWorkView.js +1 -1
  10. package/dist/features/account/components/AddressFilters.d.ts +5 -0
  11. package/dist/features/account/components/AddressFilters.js +20 -0
  12. package/dist/features/account/components/AddressesIndexListing.d.ts +6 -0
  13. package/dist/features/account/components/AddressesIndexListing.js +51 -0
  14. package/dist/features/account/components/UserSidebar.d.ts +7 -3
  15. package/dist/features/account/components/UserSidebar.js +55 -7
  16. package/dist/features/account/hooks/useAddresses.d.ts +7 -0
  17. package/dist/features/account/hooks/useAddresses.js +12 -1
  18. package/dist/features/admin/actions/admin-read-actions.d.ts +12 -0
  19. package/dist/features/admin/actions/admin-read-actions.js +18 -0
  20. package/dist/features/admin/components/AdminBlogView.js +26 -2
  21. package/dist/features/admin/components/AdminCarouselView.js +18 -2
  22. package/dist/features/admin/components/AdminCategoriesView.js +27 -2
  23. package/dist/features/admin/components/AdminContactView.d.ts +4 -0
  24. package/dist/features/admin/components/AdminContactView.js +50 -0
  25. package/dist/features/admin/components/AdminFaqsView.js +19 -2
  26. package/dist/features/admin/components/AdminListingScaffold.d.ts +11 -2
  27. package/dist/features/admin/components/AdminListingScaffold.js +14 -3
  28. package/dist/features/admin/components/AdminNewsletterView.d.ts +4 -0
  29. package/dist/features/admin/components/AdminNewsletterView.js +50 -0
  30. package/dist/features/admin/components/AdminProductsView.js +30 -2
  31. package/dist/features/admin/components/AdminReviewsView.js +26 -2
  32. package/dist/features/admin/components/AdminStoresView.js +17 -2
  33. package/dist/features/admin/components/AdminUsersView.js +27 -2
  34. package/dist/features/admin/components/DataTable.d.ts +2 -1
  35. package/dist/features/admin/components/DataTable.js +18 -4
  36. package/dist/features/admin/components/index.d.ts +6 -0
  37. package/dist/features/admin/components/index.js +3 -0
  38. package/dist/features/admin/hooks/useAdminListingData.d.ts +3 -1
  39. package/dist/features/admin/hooks/useAdminListingData.js +12 -7
  40. package/dist/features/admin/server.d.ts +3 -0
  41. package/dist/features/admin/server.js +2 -0
  42. package/dist/features/auctions/components/AuctionDetailPageView.js +93 -47
  43. package/dist/features/auctions/components/AuctionFilters.d.ts +8 -0
  44. package/dist/features/auctions/components/AuctionFilters.js +12 -0
  45. package/dist/features/auctions/components/AuctionsListView.d.ts +6 -1
  46. package/dist/features/auctions/components/AuctionsListView.js +37 -5
  47. package/dist/features/auctions/schemas/index.d.ts +4 -4
  48. package/dist/features/blog/components/BlogFeaturedCard.d.ts +1 -7
  49. package/dist/features/blog/components/BlogFeaturedCard.js +4 -5
  50. package/dist/features/blog/components/BlogFilters.js +2 -1
  51. package/dist/features/blog/components/BlogIndexListing.js +14 -9
  52. package/dist/features/blog/components/BlogIndexPageView.d.ts +6 -1
  53. package/dist/features/blog/components/BlogIndexPageView.js +10 -2
  54. package/dist/features/blog/components/BlogListView.d.ts +2 -1
  55. package/dist/features/blog/components/BlogListView.js +10 -3
  56. package/dist/features/categories/components/CategoriesIndexListing.d.ts +1 -1
  57. package/dist/features/categories/components/CategoriesIndexListing.js +41 -38
  58. package/dist/features/categories/components/CategoriesIndexPageView.d.ts +6 -1
  59. package/dist/features/categories/components/CategoriesIndexPageView.js +41 -2
  60. package/dist/features/categories/components/CategoryDetailPageView.js +13 -6
  61. package/dist/features/categories/components/CategoryDetailTabs.d.ts +5 -0
  62. package/dist/features/categories/components/CategoryDetailTabs.js +17 -0
  63. package/dist/features/categories/components/CategoryFilters.js +2 -1
  64. package/dist/features/categories/components/CategoryGrid.d.ts +2 -1
  65. package/dist/features/categories/components/CategoryGrid.js +8 -6
  66. package/dist/features/categories/components/CategoryProductsListing.js +22 -11
  67. package/dist/features/categories/components/index.d.ts +2 -0
  68. package/dist/features/categories/components/index.js +1 -0
  69. package/dist/features/categories/hooks/useCategories.d.ts +20 -0
  70. package/dist/features/categories/hooks/useCategories.js +50 -1
  71. package/dist/features/categories/hooks/useCategoryTree.d.ts +17 -0
  72. package/dist/features/categories/hooks/useCategoryTree.js +65 -0
  73. package/dist/features/events/components/AdminEventEditorView.d.ts +6 -0
  74. package/dist/features/events/components/AdminEventEditorView.js +203 -0
  75. package/dist/features/events/components/AdminEventsView.js +28 -2
  76. package/dist/features/events/components/EventCard.js +4 -2
  77. package/dist/features/events/components/EventFilters.js +2 -1
  78. package/dist/features/events/components/EventsIndexListing.js +40 -10
  79. package/dist/features/events/components/EventsListPageView.d.ts +6 -1
  80. package/dist/features/events/components/EventsListPageView.js +40 -7
  81. package/dist/features/events/components/index.d.ts +2 -0
  82. package/dist/features/events/components/index.js +1 -0
  83. package/dist/features/events/hooks/useEvents.js +2 -0
  84. package/dist/features/events/types/index.d.ts +1 -0
  85. package/dist/features/homepage/components/BlogArticlesSection.js +1 -1
  86. package/dist/features/homepage/components/EventsSection.js +1 -1
  87. package/dist/features/homepage/components/FeaturedAuctionsSection.js +1 -1
  88. package/dist/features/homepage/components/FeaturedPreOrdersSection.js +1 -1
  89. package/dist/features/homepage/components/FeaturedProductsSection.js +1 -1
  90. package/dist/features/homepage/components/FeaturedStoresSection.js +1 -1
  91. package/dist/features/homepage/components/HeroCarousel.js +1 -1
  92. package/dist/features/homepage/components/MarketplaceHomepageView.js +27 -17
  93. package/dist/features/homepage/components/SectionCarousel.js +4 -4
  94. package/dist/features/homepage/components/ShopByCategorySection.js +2 -2
  95. package/dist/features/homepage/schemas/firestore.d.ts +1 -1
  96. package/dist/features/homepage/schemas/firestore.js +2 -1
  97. package/dist/features/layout/AppLayoutShell.d.ts +6 -2
  98. package/dist/features/layout/AppLayoutShell.js +7 -3
  99. package/dist/features/pre-orders/components/MarketplacePreorderCard.d.ts +3 -1
  100. package/dist/features/pre-orders/components/MarketplacePreorderCard.js +6 -2
  101. package/dist/features/pre-orders/components/PreOrderDetailPageView.js +80 -12
  102. package/dist/features/pre-orders/components/PreOrderFilters.d.ts +8 -0
  103. package/dist/features/pre-orders/components/PreOrderFilters.js +21 -0
  104. package/dist/features/pre-orders/components/PreOrdersIndexListing.d.ts +2 -1
  105. package/dist/features/pre-orders/components/PreOrdersIndexListing.js +69 -10
  106. package/dist/features/pre-orders/components/PreOrdersListView.d.ts +6 -1
  107. package/dist/features/pre-orders/components/PreOrdersListView.js +26 -7
  108. package/dist/features/pre-orders/components/index.d.ts +2 -0
  109. package/dist/features/pre-orders/components/index.js +1 -0
  110. package/dist/features/products/components/AuctionsIndexListing.d.ts +2 -1
  111. package/dist/features/products/components/AuctionsIndexListing.js +61 -9
  112. package/dist/features/products/components/InteractiveProductCard.d.ts +2 -4
  113. package/dist/features/products/components/InteractiveProductCard.js +2 -2
  114. package/dist/features/products/components/ProductDetailPageView.d.ts +1 -1
  115. package/dist/features/products/components/ProductDetailPageView.js +116 -25
  116. package/dist/features/products/components/ProductFilters.d.ts +6 -11
  117. package/dist/features/products/components/ProductFilters.js +5 -3
  118. package/dist/features/products/components/ProductGrid.d.ts +8 -2
  119. package/dist/features/products/components/ProductGrid.js +20 -5
  120. package/dist/features/products/components/ProductTabsShell.d.ts +3 -11
  121. package/dist/features/products/components/ProductTabsShell.js +14 -14
  122. package/dist/features/products/components/ProductsIndexListing.js +73 -9
  123. package/dist/features/products/components/ProductsIndexPageView.d.ts +6 -1
  124. package/dist/features/products/components/ProductsIndexPageView.js +39 -6
  125. package/dist/features/products/components/RelatedProductsCarousel.d.ts +7 -0
  126. package/dist/features/products/components/RelatedProductsCarousel.js +11 -0
  127. package/dist/features/products/components/index.d.ts +1 -0
  128. package/dist/features/products/components/index.js +1 -0
  129. package/dist/features/products/hooks/useProducts.js +16 -0
  130. package/dist/features/products/repository/products.repository.d.ts +8 -0
  131. package/dist/features/products/repository/products.repository.js +2 -0
  132. package/dist/features/products/schemas/index.d.ts +8 -8
  133. package/dist/features/products/types/index.d.ts +12 -0
  134. package/dist/features/promotions/components/CouponsIndexListing.d.ts +9 -0
  135. package/dist/features/promotions/components/CouponsIndexListing.js +86 -0
  136. package/dist/features/promotions/components/PromotionsView.d.ts +11 -5
  137. package/dist/features/promotions/components/PromotionsView.js +6 -1
  138. package/dist/features/promotions/components/index.d.ts +4 -2
  139. package/dist/features/promotions/components/index.js +2 -1
  140. package/dist/features/reviews/components/ReviewDetailPageView.d.ts +4 -0
  141. package/dist/features/reviews/components/ReviewDetailPageView.js +20 -0
  142. package/dist/features/reviews/components/ReviewDetailShell.d.ts +7 -0
  143. package/dist/features/reviews/components/ReviewDetailShell.js +80 -0
  144. package/dist/features/reviews/components/ReviewFilters.d.ts +3 -3
  145. package/dist/features/reviews/components/ReviewFilters.js +5 -4
  146. package/dist/features/reviews/components/ReviewsIndexListing.d.ts +4 -3
  147. package/dist/features/reviews/components/ReviewsIndexListing.js +35 -51
  148. package/dist/features/reviews/components/ReviewsIndexPageView.d.ts +6 -1
  149. package/dist/features/reviews/components/ReviewsIndexPageView.js +49 -3
  150. package/dist/features/reviews/components/ReviewsList.js +9 -1
  151. package/dist/features/reviews/components/index.d.ts +1 -0
  152. package/dist/features/reviews/hooks/useReviews.js +15 -1
  153. package/dist/features/reviews/types/index.d.ts +6 -1
  154. package/dist/features/seller/components/SellerSidebar.d.ts +8 -4
  155. package/dist/features/seller/components/SellerSidebar.js +6 -4
  156. package/dist/features/seller/components/index.d.ts +30 -0
  157. package/dist/features/seller/components/index.js +17 -0
  158. package/dist/features/seller/hooks/useSellerStore.d.ts +2 -0
  159. package/dist/features/seller/hooks/useSellerStore.js +2 -0
  160. package/dist/features/seller/permission-map.d.ts +4 -2
  161. package/dist/features/seller/permission-map.js +16 -14
  162. package/dist/features/seller/schemas/index.d.ts +2 -2
  163. package/dist/features/stores/api/[storeSlug]/reviews/route.d.ts +1 -1
  164. package/dist/features/stores/api/[storeSlug]/reviews/route.js +24 -19
  165. package/dist/features/stores/components/InteractiveStoreCard.d.ts +0 -5
  166. package/dist/features/stores/components/InteractiveStoreCard.js +9 -9
  167. package/dist/features/stores/components/StoreAuctionsListing.js +27 -9
  168. package/dist/features/stores/components/StoreDetailLayoutView.js +2 -0
  169. package/dist/features/stores/components/StoreFilters.d.ts +5 -0
  170. package/dist/features/stores/components/StoreFilters.js +20 -0
  171. package/dist/features/stores/components/StoreHeader.js +2 -2
  172. package/dist/features/stores/components/StorePreOrdersListing.d.ts +5 -0
  173. package/dist/features/stores/components/StorePreOrdersListing.js +40 -0
  174. package/dist/features/stores/components/StorePreOrdersPageView.d.ts +4 -0
  175. package/dist/features/stores/components/StorePreOrdersPageView.js +21 -0
  176. package/dist/features/stores/components/StoreProductsListing.js +21 -11
  177. package/dist/features/stores/components/StoreReviewsListing.js +2 -7
  178. package/dist/features/stores/components/StoresIndexListing.js +42 -8
  179. package/dist/features/stores/components/StoresIndexPageView.d.ts +6 -1
  180. package/dist/features/stores/components/StoresIndexPageView.js +9 -2
  181. package/dist/features/stores/components/index.d.ts +3 -0
  182. package/dist/features/stores/components/index.js +1 -0
  183. package/dist/features/stores/hooks/useStores.d.ts +7 -1
  184. package/dist/features/stores/hooks/useStores.js +16 -3
  185. package/dist/features/stores/schemas/index.d.ts +2 -2
  186. package/dist/features/stores/types/index.d.ts +3 -0
  187. package/dist/features/wishlist/hooks/useGuestWishlist.d.ts +20 -0
  188. package/dist/features/wishlist/hooks/useGuestWishlist.js +49 -0
  189. package/dist/features/wishlist/hooks/useWishlistCount.d.ts +7 -0
  190. package/dist/features/wishlist/hooks/useWishlistCount.js +31 -0
  191. package/dist/features/wishlist/hooks/useWishlistWithGuest.d.ts +56 -0
  192. package/dist/features/wishlist/hooks/useWishlistWithGuest.js +57 -0
  193. package/dist/features/wishlist/index.d.ts +3 -0
  194. package/dist/features/wishlist/index.js +3 -0
  195. package/dist/features/wishlist/utils/guest-wishlist.d.ts +22 -0
  196. package/dist/features/wishlist/utils/guest-wishlist.js +70 -0
  197. package/dist/index.d.ts +50 -1
  198. package/dist/index.js +63 -1
  199. package/dist/next/routing/route-map.d.ts +70 -36
  200. package/dist/next/routing/route-map.js +30 -22
  201. package/dist/seed/addresses-seed-data.js +62 -261
  202. package/dist/seed/beyblade-seed-data.d.ts +7 -0
  203. package/dist/seed/beyblade-seed-data.js +947 -0
  204. package/dist/seed/bids-seed-data.d.ts +10 -2
  205. package/dist/seed/bids-seed-data.js +220 -1071
  206. package/dist/seed/blog-posts-seed-data.d.ts +2 -2
  207. package/dist/seed/blog-posts-seed-data.js +455 -117
  208. package/dist/seed/cart-seed-data.d.ts +9 -9
  209. package/dist/seed/cart-seed-data.js +73 -74
  210. package/dist/seed/coupons-seed-data.d.ts +3 -4
  211. package/dist/seed/coupons-seed-data.js +3 -509
  212. package/dist/seed/events-seed-data.d.ts +2 -2
  213. package/dist/seed/events-seed-data.js +315 -476
  214. package/dist/seed/faq-seed-data.d.ts +18 -41
  215. package/dist/seed/faq-seed-data.js +1059 -1172
  216. package/dist/seed/hot-wheels-seed-data.d.ts +7 -0
  217. package/dist/seed/hot-wheels-seed-data.js +1365 -0
  218. package/dist/seed/index.d.ts +6 -1
  219. package/dist/seed/index.js +6 -1
  220. package/dist/seed/pokemon-carousel-slides-seed-data.d.ts +4 -2
  221. package/dist/seed/pokemon-carousel-slides-seed-data.js +152 -268
  222. package/dist/seed/pokemon-categories-seed-data.d.ts +18 -21
  223. package/dist/seed/pokemon-categories-seed-data.js +424 -1004
  224. package/dist/seed/pokemon-coupons-seed-data.d.ts +6 -0
  225. package/dist/seed/pokemon-coupons-seed-data.js +465 -0
  226. package/dist/seed/pokemon-homepage-sections-seed-data.d.ts +3 -2
  227. package/dist/seed/pokemon-homepage-sections-seed-data.js +67 -289
  228. package/dist/seed/pokemon-products-seed-data.js +662 -0
  229. package/dist/seed/pokemon-seed-bundle.d.ts +32 -11
  230. package/dist/seed/pokemon-seed-bundle.js +41 -11
  231. package/dist/seed/pokemon-stores-seed-data.d.ts +2 -3
  232. package/dist/seed/pokemon-stores-seed-data.js +56 -31
  233. package/dist/seed/pokemon-users-seed-data.d.ts +2 -2
  234. package/dist/seed/pokemon-users-seed-data.js +245 -261
  235. package/dist/seed/reviews-seed-data.d.ts +17 -2
  236. package/dist/seed/reviews-seed-data.js +519 -483
  237. package/dist/seed/site-settings-seed-data.js +14 -14
  238. package/dist/seed/store-addresses-seed-data.js +68 -50
  239. package/dist/seed/transformers-seed-data.d.ts +7 -0
  240. package/dist/seed/transformers-seed-data.js +510 -0
  241. package/dist/seed/wishlists-seed-data.d.ts +5 -1
  242. package/dist/seed/wishlists-seed-data.js +82 -4
  243. package/dist/server.d.ts +1 -0
  244. package/dist/server.js +2 -0
  245. package/dist/tokens/index.d.ts +6 -0
  246. package/dist/tokens/index.js +2 -0
  247. package/dist/ui/components/BaseListingCard.js +24 -26
  248. package/dist/ui/components/BaseListingCard.style.css +5 -5
  249. package/dist/ui/components/HorizontalScroller.d.ts +1 -1
  250. package/dist/ui/components/HorizontalScroller.js +19 -5
  251. package/dist/ui/components/SideDrawer.style.css +3 -11
  252. package/dist/ui/rich-text/RichText.js +19 -1
  253. package/package.json +1 -1
@@ -9,7 +9,7 @@ export function useReviews(params = {}, opts) {
9
9
  sp.set("userId", params.userId);
10
10
  if (params.status)
11
11
  sp.set("status", params.status);
12
- if (params.rating)
12
+ if (params.rating !== undefined)
13
13
  sp.set("rating", String(params.rating));
14
14
  if (params.featured !== undefined)
15
15
  sp.set("featured", String(params.featured));
@@ -19,6 +19,20 @@ export function useReviews(params = {}, opts) {
19
19
  sp.set("perPage", String(params.perPage));
20
20
  if (params.sort)
21
21
  sp.set("sort", params.sort);
22
+ if (params.q)
23
+ sp.set("q", params.q);
24
+ if (params.dateFrom)
25
+ sp.set("dateFrom", params.dateFrom);
26
+ if (params.dateTo)
27
+ sp.set("dateTo", params.dateTo);
28
+ if (params.minVotes !== undefined)
29
+ sp.set("minVotes", String(params.minVotes));
30
+ if (params.maxVotes !== undefined)
31
+ sp.set("maxVotes", String(params.maxVotes));
32
+ // General listing mode (no productId)
33
+ if (!params.productId && !params.userId && !params.sellerId) {
34
+ sp.set("latest", "true");
35
+ }
22
36
  const qs = sp.toString();
23
37
  const query = useQuery({
24
38
  queryKey: ["reviews", qs],
@@ -46,11 +46,16 @@ export interface ReviewListParams {
46
46
  userId?: string;
47
47
  sellerId?: string;
48
48
  status?: ReviewStatus;
49
- rating?: number;
49
+ rating?: number | string;
50
50
  featured?: boolean;
51
51
  page?: number;
52
52
  perPage?: number;
53
53
  sort?: string;
54
+ q?: string;
55
+ dateFrom?: string;
56
+ dateTo?: string;
57
+ minVotes?: number;
58
+ maxVotes?: number;
54
59
  }
55
60
  export interface CreateReviewInput {
56
61
  productId: string;
@@ -1,12 +1,12 @@
1
1
  import React from "react";
2
- export interface SellerNavItem {
2
+ export interface StoreNavItem {
3
3
  href: string;
4
4
  label: string;
5
5
  icon?: React.ReactNode;
6
6
  badge?: number;
7
7
  }
8
- interface SellerSidebarProps {
9
- items: SellerNavItem[];
8
+ interface StoreSidebarProps {
9
+ items: StoreNavItem[];
10
10
  activeHref: string;
11
11
  storeName?: string;
12
12
  storeLogoURL?: string;
@@ -16,5 +16,9 @@ interface SellerSidebarProps {
16
16
  onCloseMobile?: () => void;
17
17
  className?: string;
18
18
  }
19
- export declare function SellerSidebar({ items, activeHref, storeName, storeLogoURL, mobileOpen, onCloseMobile, className, }: SellerSidebarProps): import("react/jsx-runtime").JSX.Element;
19
+ export declare function StoreSidebar({ items, activeHref, storeName, storeLogoURL, mobileOpen, onCloseMobile, className, }: StoreSidebarProps): import("react/jsx-runtime").JSX.Element;
20
+ /** @deprecated Use StoreSidebar */
21
+ export declare const SellerSidebar: typeof StoreSidebar;
22
+ /** @deprecated Use StoreNavItem */
23
+ export type SellerNavItem = StoreNavItem;
20
24
  export {};
@@ -3,14 +3,16 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
3
3
  import Link from "next/link";
4
4
  import { Aside, Div, Li, Nav, Row, Span, Text, Ul } from "../../../ui";
5
5
  import { BottomSheet } from "../../layout/BottomSheet";
6
- function SellerNavContent({ items, activeHref, storeName, storeLogoURL, onItemClick, }) {
7
- return (_jsxs(_Fragment, { children: [storeName && (_jsxs(Row, { gap: "3", className: "px-5 py-4 border-b border-gray-100 dark:border-slate-700", children: [storeLogoURL ? (_jsx(Div, { role: "img", "aria-label": storeName, className: "h-8 w-8 rounded-full bg-center bg-cover", style: { backgroundImage: `url(${storeLogoURL})` } })) : (_jsx(Div, { className: "h-8 w-8 rounded-full bg-orange-100 dark:bg-orange-900/30 flex items-center justify-center text-orange-600 dark:text-orange-400 font-bold text-sm", children: storeName[0]?.toUpperCase() })), _jsx(Text, { className: "font-semibold text-gray-900 dark:text-zinc-100 text-sm truncate", children: storeName })] })), _jsx(Nav, { "aria-label": "Seller navigation", className: "flex-1 overflow-y-auto py-3", children: _jsx(Ul, { className: "space-y-0.5 px-2", children: items.map((item) => {
6
+ function StoreNavContent({ items, activeHref, storeName, storeLogoURL, onItemClick, }) {
7
+ return (_jsxs(_Fragment, { children: [storeName && (_jsxs(Row, { gap: "3", className: "px-5 py-4 border-b border-gray-100 dark:border-slate-700", children: [storeLogoURL ? (_jsx(Div, { role: "img", "aria-label": storeName, className: "h-8 w-8 rounded-full bg-center bg-cover", style: { backgroundImage: `url(${storeLogoURL})` } })) : (_jsx(Div, { className: "h-8 w-8 rounded-full bg-orange-100 dark:bg-orange-900/30 flex items-center justify-center text-orange-600 dark:text-orange-400 font-bold text-sm", children: storeName[0]?.toUpperCase() })), _jsx(Text, { className: "font-semibold text-gray-900 dark:text-zinc-100 text-sm truncate", children: storeName })] })), _jsx(Nav, { "aria-label": "Store navigation", className: "flex-1 overflow-y-auto py-3", children: _jsx(Ul, { className: "space-y-0.5 px-2", children: items.map((item) => {
8
8
  const isActive = activeHref === item.href;
9
9
  return (_jsx(Li, { children: _jsxs(Link, { href: item.href, onClick: onItemClick, className: `flex items-center gap-3 rounded-lg px-3 py-2 text-sm transition-colors ${isActive
10
10
  ? "bg-orange-50 dark:bg-orange-900/20 text-orange-600 dark:text-orange-400 font-medium"
11
11
  : "text-gray-600 dark:text-zinc-300 hover:bg-gray-50 dark:hover:bg-slate-800 hover:text-gray-900 dark:hover:text-zinc-100"}`, children: [item.icon && (_jsx(Span, { className: "shrink-0 text-[1.1rem]", children: item.icon })), _jsx(Span, { className: "flex-1 truncate", children: item.label }), item.badge != null && item.badge > 0 && (_jsx(Span, { className: "shrink-0 rounded-full bg-orange-500 px-1.5 py-0.5 text-[10px] font-bold text-white", children: item.badge }))] }) }, item.href));
12
12
  }) }) })] }));
13
13
  }
14
- export function SellerSidebar({ items, activeHref, storeName, storeLogoURL, mobileOpen = false, onCloseMobile, className = "", }) {
15
- return (_jsxs(_Fragment, { children: [_jsx(Aside, { className: `hidden md:flex w-64 shrink-0 flex-col bg-white dark:bg-slate-900 border-r border-gray-200 dark:border-slate-700 ${className}`, children: _jsx(SellerNavContent, { items: items, activeHref: activeHref, storeName: storeName, storeLogoURL: storeLogoURL }) }), _jsx(BottomSheet, { open: mobileOpen, onClose: onCloseMobile ?? (() => { }), title: storeName ?? "Seller Panel", children: _jsx(SellerNavContent, { items: items, activeHref: activeHref, storeName: storeName, storeLogoURL: storeLogoURL, onItemClick: onCloseMobile }) })] }));
14
+ export function StoreSidebar({ items, activeHref, storeName, storeLogoURL, mobileOpen = false, onCloseMobile, className = "", }) {
15
+ return (_jsxs(_Fragment, { children: [_jsx(Aside, { className: `hidden md:flex w-64 shrink-0 flex-col bg-white dark:bg-slate-900 border-r border-gray-200 dark:border-slate-700 ${className}`, children: _jsx(StoreNavContent, { items: items, activeHref: activeHref, storeName: storeName, storeLogoURL: storeLogoURL }) }), _jsx(BottomSheet, { open: mobileOpen, onClose: onCloseMobile ?? (() => { }), title: storeName ?? "Store Panel", children: _jsx(StoreNavContent, { items: items, activeHref: activeHref, storeName: storeName, storeLogoURL: storeLogoURL, onItemClick: onCloseMobile }) })] }));
16
16
  }
17
+ /** @deprecated Use StoreSidebar */
18
+ export const SellerSidebar = StoreSidebar;
@@ -42,3 +42,33 @@ export type { SellerAddressesViewProps } from "./SellerAddressesView";
42
42
  export { SellerGuideView } from "./SellerGuideView";
43
43
  export type { SellerGuideViewProps } from "./SellerGuideView";
44
44
  export * from "./analytics";
45
+ export { StoreSidebar } from "./SellerSidebar";
46
+ export type { StoreNavItem } from "./SellerSidebar";
47
+ export { SellerDashboardView as StoreDashboardView } from "./SellerDashboardView";
48
+ export type { SellerDashboardViewProps as StoreDashboardViewProps } from "./SellerDashboardView";
49
+ export { SellerProductsView as StoreProductListingsView } from "./SellerProductsView";
50
+ export type { SellerProductsViewProps as StoreProductListingsViewProps } from "./SellerProductsView";
51
+ export { SellerAuctionsView as StoreAuctionsView } from "./SellerAuctionsView";
52
+ export type { SellerAuctionsViewProps as StoreAuctionsViewProps } from "./SellerAuctionsView";
53
+ export { SellerOrdersView as StoreOrdersView } from "./SellerOrdersView";
54
+ export type { SellerOrdersViewProps as StoreOrdersViewProps } from "./SellerOrdersView";
55
+ export { SellerOffersView as StoreOffersView } from "./SellerOffersView";
56
+ export type { SellerOffersViewProps as StoreOffersViewProps } from "./SellerOffersView";
57
+ export { SellerCouponsView as StoreCouponsView } from "./SellerCouponsView";
58
+ export type { SellerCouponsViewProps as StoreCouponsViewProps } from "./SellerCouponsView";
59
+ export { SellerPayoutsView as StorePayoutsView } from "./SellerPayoutsView";
60
+ export type { SellerPayoutsViewProps as StorePayoutsViewProps } from "./SellerPayoutsView";
61
+ export { SellerPayoutSettingsView as StorePayoutSettingsView } from "./SellerPayoutSettingsView";
62
+ export type { SellerPayoutSettingsViewProps as StorePayoutSettingsViewProps } from "./SellerPayoutSettingsView";
63
+ export { SellerAnalyticsView as StoreAnalyticsView } from "./SellerAnalyticsView";
64
+ export type { SellerAnalyticsViewProps as StoreAnalyticsViewProps } from "./SellerAnalyticsView";
65
+ export { SellerCreateProductView as StoreCreateProductView } from "./SellerCreateProductView";
66
+ export type { SellerCreateProductViewProps as StoreCreateProductViewProps } from "./SellerCreateProductView";
67
+ export { SellerEditProductView as StoreEditProductView } from "./SellerEditProductView";
68
+ export type { SellerEditProductViewProps as StoreEditProductViewProps } from "./SellerEditProductView";
69
+ export { SellerStoreView as StoreStorefrontView } from "./SellerStoreView";
70
+ export type { SellerStoreViewProps as StoreStorefrontViewProps } from "./SellerStoreView";
71
+ export { SellerShippingView as StoreShippingView } from "./SellerShippingView";
72
+ export type { SellerShippingViewProps as StoreShippingViewProps } from "./SellerShippingView";
73
+ export { SellerAddressesView as StoreAddressesView } from "./SellerAddressesView";
74
+ export type { SellerAddressesViewProps as StoreAddressesViewProps } from "./SellerAddressesView";
@@ -21,3 +21,20 @@ export { SellerShippingView } from "./SellerShippingView";
21
21
  export { SellerAddressesView } from "./SellerAddressesView";
22
22
  export { SellerGuideView } from "./SellerGuideView";
23
23
  export * from "./analytics";
24
+ // Store* aliases — same components, renamed for store-centric terminology
25
+ export { StoreSidebar } from "./SellerSidebar";
26
+ export { SellerDashboardView as StoreDashboardView } from "./SellerDashboardView";
27
+ // SellerProductsView aliased as StoreProductListingsView (StoreProductsView is the public customer-facing store listing)
28
+ export { SellerProductsView as StoreProductListingsView } from "./SellerProductsView";
29
+ export { SellerAuctionsView as StoreAuctionsView } from "./SellerAuctionsView";
30
+ export { SellerOrdersView as StoreOrdersView } from "./SellerOrdersView";
31
+ export { SellerOffersView as StoreOffersView } from "./SellerOffersView";
32
+ export { SellerCouponsView as StoreCouponsView } from "./SellerCouponsView";
33
+ export { SellerPayoutsView as StorePayoutsView } from "./SellerPayoutsView";
34
+ export { SellerPayoutSettingsView as StorePayoutSettingsView } from "./SellerPayoutSettingsView";
35
+ export { SellerAnalyticsView as StoreAnalyticsView } from "./SellerAnalyticsView";
36
+ export { SellerCreateProductView as StoreCreateProductView } from "./SellerCreateProductView";
37
+ export { SellerEditProductView as StoreEditProductView } from "./SellerEditProductView";
38
+ export { SellerStoreView as StoreStorefrontView } from "./SellerStoreView";
39
+ export { SellerShippingView as StoreShippingView } from "./SellerShippingView";
40
+ export { SellerAddressesView as StoreAddressesView } from "./SellerAddressesView";
@@ -26,3 +26,5 @@ export declare function useSellerAnalytics(period?: string, opts?: {
26
26
  error: string | null;
27
27
  refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<SellerAnalytics, Error>>;
28
28
  };
29
+ /** @deprecated Use useStoreDashboard */
30
+ export { useSellerDashboard as useStoreDashboard };
@@ -45,3 +45,5 @@ export function useSellerAnalytics(period = "30d", opts) {
45
45
  refetch,
46
46
  };
47
47
  }
48
+ /** @deprecated Use useStoreDashboard */
49
+ export { useSellerDashboard as useStoreDashboard };
@@ -1,3 +1,5 @@
1
1
  import type { Permission } from "../../security";
2
- /** Required permission for each seller route path */
3
- export declare const SELLER_PAGE_PERMISSIONS: Record<string, Permission>;
2
+ /** Required permission for each store management route path */
3
+ export declare const STORE_PAGE_PERMISSIONS: Record<string, Permission>;
4
+ /** @deprecated Use STORE_PAGE_PERMISSIONS */
5
+ export declare const SELLER_PAGE_PERMISSIONS: Record<string, string>;
@@ -1,15 +1,17 @@
1
- /** Required permission for each seller route path */
2
- export const SELLER_PAGE_PERMISSIONS = {
3
- "/seller": "seller:access",
4
- "/seller/dashboard": "seller:analytics",
5
- "/seller/products": "seller:products:read",
6
- "/seller/products/new": "seller:products:write",
7
- "/seller/products/[id]": "seller:products:write",
8
- "/seller/orders": "seller:orders:read",
9
- "/seller/orders/[id]": "seller:orders:read",
10
- "/seller/analytics": "seller:analytics",
11
- "/seller/coupons": "seller:coupons",
12
- "/seller/store": "seller:store",
13
- "/seller/payouts": "seller:payouts:read",
14
- "/seller/shipping": "seller:shipping",
1
+ /** Required permission for each store management route path */
2
+ export const STORE_PAGE_PERMISSIONS = {
3
+ "/store": "seller:access",
4
+ "/store/dashboard": "seller:analytics",
5
+ "/store/products": "seller:products:read",
6
+ "/store/products/new": "seller:products:write",
7
+ "/store/products/[id]": "seller:products:write",
8
+ "/store/orders": "seller:orders:read",
9
+ "/store/orders/[id]": "seller:orders:read",
10
+ "/store/analytics": "seller:analytics",
11
+ "/store/coupons": "seller:coupons",
12
+ "/store/storefront": "seller:store",
13
+ "/store/payouts": "seller:payouts:read",
14
+ "/store/shipping": "seller:shipping",
15
15
  };
16
+ /** @deprecated Use STORE_PAGE_PERMISSIONS */
17
+ export const SELLER_PAGE_PERMISSIONS = STORE_PAGE_PERMISSIONS;
@@ -108,9 +108,9 @@ export declare const sellerStoreSchema: z.ZodObject<{
108
108
  } | undefined;
109
109
  bio?: string | undefined;
110
110
  returnPolicy?: string | undefined;
111
- storeLogoURL?: string | undefined;
112
111
  storeDescription?: string | undefined;
113
112
  storeCategory?: string | undefined;
113
+ storeLogoURL?: string | undefined;
114
114
  storeBannerURL?: string | undefined;
115
115
  website?: string | undefined;
116
116
  shippingPolicy?: string | undefined;
@@ -140,9 +140,9 @@ export declare const sellerStoreSchema: z.ZodObject<{
140
140
  } | undefined;
141
141
  bio?: string | undefined;
142
142
  returnPolicy?: string | undefined;
143
- storeLogoURL?: string | undefined;
144
143
  storeDescription?: string | undefined;
145
144
  storeCategory?: string | undefined;
145
+ storeLogoURL?: string | undefined;
146
146
  storeBannerURL?: string | undefined;
147
147
  website?: string | undefined;
148
148
  shippingPolicy?: string | undefined;
@@ -19,5 +19,5 @@ type RouteContext = {
19
19
  storeSlug: string;
20
20
  }>;
21
21
  };
22
- export declare function GET(_request: Request, context: RouteContext): Promise<NextResponse>;
22
+ export declare function GET(request: Request, context: RouteContext): Promise<NextResponse>;
23
23
  export {};
@@ -16,9 +16,14 @@
16
16
  import { NextResponse } from "next/server.js";
17
17
  import { getProviders } from "../../../../../contracts";
18
18
  // --- GET /api/stores/[storeSlug]/reviews --------------------------------------
19
- export async function GET(_request, context) {
19
+ export async function GET(request, context) {
20
20
  try {
21
21
  const { storeSlug } = await context.params;
22
+ const url = new URL(request.url);
23
+ const ratingParam = url.searchParams.get("rating");
24
+ const ratingFilter = ratingParam ? Number(ratingParam) : 0;
25
+ const page = Math.max(1, Number(url.searchParams.get("page") || "1"));
26
+ const pageSize = Math.min(50, Math.max(1, Number(url.searchParams.get("pageSize") || "12")));
22
27
  const { db } = getProviders();
23
28
  if (!db) {
24
29
  return NextResponse.json({ success: false, error: "Database provider not registered" }, { status: 503 });
@@ -52,34 +57,32 @@ export async function GET(_request, context) {
52
57
  perPage: 50,
53
58
  })
54
59
  .then((r) => r.data)));
55
- // Flatten, sort by date desc, cap to 10 most recent
56
- const allReviews = reviewArrays
57
- .flat()
58
- .sort((a, b) => new Date(b.createdAt ?? 0).getTime() -
59
- new Date(a.createdAt ?? 0).getTime())
60
- .slice(0, 10);
61
- // Compute aggregate metrics
62
- const ratingDistribution = {
63
- 1: 0,
64
- 2: 0,
65
- 3: 0,
66
- 4: 0,
67
- 5: 0,
68
- };
60
+ // Compute aggregate metrics from ALL reviews (unfiltered)
61
+ const ratingDistribution = { 1: 0, 2: 0, 3: 0, 4: 0, 5: 0 };
69
62
  let ratingSum = 0;
70
63
  let totalReviews = 0;
71
64
  for (const reviews of reviewArrays) {
72
65
  for (const review of reviews) {
73
66
  totalReviews++;
74
67
  ratingSum += review.rating;
75
- ratingDistribution[review.rating] =
76
- (ratingDistribution[review.rating] ?? 0) + 1;
68
+ ratingDistribution[review.rating] = (ratingDistribution[review.rating] ?? 0) + 1;
77
69
  }
78
70
  }
79
71
  const averageRating = totalReviews > 0 ? ratingSum / totalReviews : 0;
80
- // Enrich reviews with product title + main image
72
+ // Flatten and sort all reviews by date desc
81
73
  const productMap = new Map(products.map((p) => [p.id, p]));
82
- const reviewsWithProduct = allReviews.map((review) => ({
74
+ const allSorted = reviewArrays
75
+ .flat()
76
+ .sort((a, b) => new Date(b.createdAt ?? 0).getTime() - new Date(a.createdAt ?? 0).getTime());
77
+ // Apply rating filter
78
+ const filtered = ratingFilter > 0
79
+ ? allSorted.filter((r) => Math.round(r.rating) === ratingFilter)
80
+ : allSorted;
81
+ const totalFiltered = filtered.length;
82
+ const totalPages = Math.max(1, Math.ceil(totalFiltered / pageSize));
83
+ const pageSlice = filtered.slice((page - 1) * pageSize, page * pageSize);
84
+ // Enrich with product title + main image
85
+ const reviewsWithProduct = pageSlice.map((review) => ({
83
86
  ...review,
84
87
  productTitle: productMap.get(review.productId)?.title ?? review.productTitle,
85
88
  productMainImage: productMap.get(review.productId)?.mainImage ?? null,
@@ -90,6 +93,8 @@ export async function GET(_request, context) {
90
93
  reviews: reviewsWithProduct,
91
94
  averageRating: Math.round(averageRating * 10) / 10,
92
95
  totalReviews,
96
+ totalFiltered,
97
+ totalPages,
93
98
  ratingDistribution,
94
99
  },
95
100
  });
@@ -1,7 +1,6 @@
1
1
  import type { StoreListItem } from "../types";
2
2
  export interface InteractiveStoreCardProps {
3
3
  store: StoreListItem;
4
- /** Resolved href for the store detail page. */
5
4
  href: string;
6
5
  selectable?: boolean;
7
6
  selected?: boolean;
@@ -14,8 +13,4 @@ export interface InteractiveStoreCardProps {
14
13
  };
15
14
  className?: string;
16
15
  }
17
- /**
18
- * Generic store card with optional selection.
19
- * Callers compute `href` using their locale-aware routing helper.
20
- */
21
16
  export declare function InteractiveStoreCard({ store, href, selectable, selected, onSelect, labels, className, }: InteractiveStoreCardProps): import("react/jsx-runtime").JSX.Element;
@@ -1,16 +1,16 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import Link from "next/link";
3
- import { Heading, Text, Span, Row, Button, RichText, Div } from "../../../ui";
4
- import { THEME_CONSTANTS, LAYOUT } from "../../../tokens";
5
- import { MediaImage } from "../../media/MediaImage";
3
+ import { Heading, Span, Row, Button, RichText } from "../../../ui";
4
+ import { THEME_CONSTANTS } from "../../../tokens";
6
5
  import { normalizeRichTextHtml } from "../../../utils";
7
- /**
8
- * Generic store card with optional selection.
9
- * Callers compute `href` using their locale-aware routing helper.
10
- */
11
6
  export function InteractiveStoreCard({ store, href, selectable, selected, onSelect, labels = {}, className = "", }) {
12
- return (_jsxs(Div, { className: `relative flex ${LAYOUT.cardHeight.store} min-w-[190px] flex-col overflow-hidden rounded-xl border border-zinc-200 bg-white shadow-sm transition-shadow hover:shadow-md dark:border-slate-700 dark:bg-slate-900 ${className}`, children: [selectable && (_jsx(Button, { type: "button", size: "sm", variant: "outline", "aria-label": selected ? "Deselect store" : "Select store", onClick: (e) => {
7
+ const initial = store.storeName[0]?.toUpperCase() ?? "S";
8
+ const hasLogo = Boolean(store.storeLogoURL);
9
+ const hasBanner = Boolean(store.storeBannerURL);
10
+ return (_jsxs("div", { className: `group relative flex flex-col h-full overflow-hidden rounded-xl border bg-white dark:bg-zinc-900 shadow-sm transition-shadow hover:shadow-lg ${selected
11
+ ? "border-primary outline outline-2 outline-primary"
12
+ : "border-zinc-200 dark:border-zinc-700"} ${className}`, children: [selectable && (_jsx(Button, { type: "button", "aria-label": selected ? "Deselect store" : "Select store", onClick: (e) => {
13
13
  e.preventDefault();
14
14
  onSelect?.(store.id, !selected);
15
- }, className: `absolute top-2 left-2 z-10 h-5 w-5 rounded border-2 ${selected ? "bg-primary-500 border-primary-500" : "bg-white border-gray-300"} flex items-center justify-center`, children: selected && (_jsx(Span, { className: "text-white text-xs leading-none", children: "\u2713" })) })), _jsxs(Link, { href: href, className: "block", children: [store.storeBannerURL ? (_jsx(Div, { className: "aspect-video overflow-hidden bg-zinc-100 dark:bg-slate-800", children: _jsx(MediaImage, { src: store.storeBannerURL, alt: `${store.storeName} banner`, size: "banner", className: "h-full w-full object-cover" }) })) : (_jsx(Div, { className: "aspect-video bg-gradient-to-br from-zinc-100 to-zinc-200 dark:from-slate-800 dark:to-slate-700" })), _jsxs(Div, { className: "flex flex-1 flex-col px-4 pb-4", children: [_jsx(Div, { className: "-mt-6 mb-3", children: store.storeLogoURL ? (_jsx(MediaImage, { src: store.storeLogoURL, alt: store.storeName, size: "avatar", className: "h-12 w-12 rounded-lg border-2 border-white object-cover shadow-sm" })) : (_jsx(Div, { className: "flex h-12 w-12 items-center justify-center rounded-lg border-2 border-white bg-primary-100 text-lg font-bold text-primary-700 shadow-sm dark:bg-primary-900/40 dark:text-primary-300", children: store.storeName[0]?.toUpperCase() })) }), _jsx(Heading, { level: 3, className: `${THEME_CONSTANTS.utilities.textClamp2} text-sm font-semibold text-zinc-900 dark:text-zinc-100`, children: store.storeName }), _jsx(RichText, { html: normalizeRichTextHtml(store.storeDescription ?? ""), proseClass: "prose prose-sm max-w-none dark:prose-invert prose-p:my-0", className: `mt-1 ${THEME_CONSTANTS.utilities.textClamp2} min-h-9 text-xs text-zinc-500 dark:text-zinc-400` }), _jsxs(Row, { gap: "sm", className: "mt-2 text-xs text-zinc-500 dark:text-zinc-500", children: [store.totalProducts != null && store.totalProducts > 0 && (_jsxs(Span, { children: [store.totalProducts, " ", labels.products ?? "products"] })), store.itemsSold != null && store.itemsSold > 0 && (_jsxs(Span, { children: [store.itemsSold, " ", labels.sold ?? "sold"] })), store.averageRating != null && store.averageRating > 0 && (_jsxs(Span, { children: ["\u2605 ", store.averageRating.toFixed(1)] }))] }), _jsxs(Text, { className: "mt-auto pt-3 text-xs font-medium text-primary dark:text-primary-400", children: [labels.visitStore ?? "Visit store", " \u2192"] })] })] })] }));
15
+ }, className: `absolute top-2.5 left-2.5 z-10 h-5 w-5 rounded border-2 flex items-center justify-center bg-white/90 dark:bg-zinc-800/90 ${selected ? "bg-primary border-primary" : "border-zinc-300 dark:border-zinc-600"}`, children: selected && _jsx(Span, { className: "text-white text-xs leading-none", children: "\u2713" }) })), _jsxs(Link, { href: href, className: "flex flex-col flex-1 min-h-0", children: [_jsxs("div", { className: "relative aspect-video w-full overflow-hidden bg-gradient-to-br from-zinc-100 via-zinc-200 to-zinc-300 dark:from-zinc-800 dark:via-zinc-700 dark:to-zinc-900 flex-shrink-0", children: [hasBanner ? (_jsx("div", { className: "absolute inset-0 bg-center bg-cover transition-transform duration-500 group-hover:scale-105", style: { backgroundImage: `url(${store.storeBannerURL})` }, role: "img", "aria-label": `${store.storeName} banner` })) : (_jsx("div", { className: "absolute inset-0 flex items-center justify-center", children: _jsx("span", { className: "text-5xl opacity-20 select-none", "aria-hidden": "true", children: "\uD83C\uDFEA" }) })), _jsx("div", { className: "absolute inset-x-0 bottom-0 h-12 bg-gradient-to-t from-black/40 to-transparent pointer-events-none" }), store.averageRating != null && store.averageRating > 0 && (_jsxs("div", { className: "absolute top-2 right-2 flex items-center gap-1 rounded-full bg-black/50 backdrop-blur-sm px-2 py-0.5 text-xs font-semibold text-yellow-300", children: ["\u2605 ", store.averageRating.toFixed(1)] }))] }), _jsxs("div", { className: "flex flex-col flex-1 px-4 pb-4", children: [_jsx("div", { className: "-mt-5 mb-2 flex items-end justify-between", children: _jsx("div", { className: "flex-shrink-0", children: hasLogo ? (_jsx("div", { className: "h-10 w-10 rounded-lg border-2 border-white dark:border-zinc-800 bg-center bg-cover shadow-md", style: { backgroundImage: `url(${store.storeLogoURL})` }, role: "img", "aria-label": store.storeName })) : (_jsx("div", { className: "flex h-10 w-10 items-center justify-center rounded-lg border-2 border-white dark:border-zinc-800 bg-primary/10 dark:bg-primary/20 text-base font-bold text-primary shadow-md", children: initial })) }) }), _jsx(Heading, { level: 3, className: `${THEME_CONSTANTS.utilities.textClamp1} text-sm font-bold text-zinc-900 dark:text-zinc-100 group-hover:text-primary transition-colors`, children: store.storeName }), store.storeDescription ? (_jsx(RichText, { html: normalizeRichTextHtml(store.storeDescription), proseClass: "prose prose-sm max-w-none dark:prose-invert prose-p:my-0", className: `mt-1 ${THEME_CONSTANTS.utilities.textClamp2} text-xs text-zinc-500 dark:text-zinc-400 flex-1` })) : (_jsx("div", { className: "flex-1" })), _jsxs(Row, { gap: "sm", className: "mt-2.5 flex-wrap text-xs text-zinc-500 dark:text-zinc-400", children: [store.totalProducts != null && store.totalProducts > 0 && (_jsxs(Span, { className: "flex items-center gap-0.5", children: [_jsx("span", { "aria-hidden": "true", children: "\uD83D\uDCE6" }), " ", store.totalProducts, " ", labels.products ?? "products"] })), store.itemsSold != null && store.itemsSold > 0 && (_jsxs(Span, { className: "flex items-center gap-0.5", children: [_jsx("span", { "aria-hidden": "true", children: "\uD83D\uDECD\uFE0F" }), " ", store.itemsSold, " ", labels.sold ?? "sold"] }))] }), _jsxs("div", { className: "mt-3 pt-2.5 border-t border-zinc-100 dark:border-zinc-800 flex items-center justify-between", children: [_jsxs("span", { className: "text-xs font-semibold text-primary group-hover:underline transition-colors", children: [labels.visitStore ?? "Visit store", " \u2192"] }), store.totalReviews != null && store.totalReviews > 0 && (_jsxs("span", { className: "text-xs text-zinc-400 dark:text-zinc-500", children: [store.totalReviews, " ", labels.reviews ?? "reviews"] }))] })] })] })] }));
16
16
  }
@@ -1,14 +1,30 @@
1
1
  "use client";
2
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
+ import { useState, useCallback } from "react";
4
+ import { Search, SlidersHorizontal, LayoutGrid, List, X } from "lucide-react";
3
5
  import { useUrlTable } from "../../../react/hooks/useUrlTable";
4
6
  import { useProducts } from "../../products/hooks/useProducts";
5
- import { Container, Grid, Input, Pagination, Section, SlottedListingView, SortDropdown, Stack, Text, } from "../../../ui";
6
- import { MarketplaceAuctionCard } from "../../auctions/components/MarketplaceAuctionCard";
7
+ import { Pagination, SortDropdown } from "../../../ui";
8
+ import { MarketplaceAuctionGrid } from "../../auctions/components/MarketplaceAuctionGrid";
9
+ import { ProductFilters } from "../../products/components/ProductFilters";
7
10
  import { getDefaultCurrency } from "../../../core/baseline-resolver";
11
+ const AUCTION_SORT_OPTIONS = [
12
+ { value: "auctionEndDate", label: "Ending Soonest" },
13
+ { value: "-createdAt", label: "Newest" },
14
+ { value: "-currentBid", label: "Highest Bid" },
15
+ { value: "price", label: "Price: Low to High" },
16
+ { value: "-price", label: "Price: High to Low" },
17
+ ];
8
18
  export function StoreAuctionsListing({ sellerId, initialData }) {
9
19
  const table = useUrlTable({ defaults: { pageSize: "24", sort: "auctionEndDate" } });
20
+ const [searchInput, setSearchInput] = useState(table.get("q") || "");
21
+ const [filterOpen, setFilterOpen] = useState(false);
22
+ const [view, setView] = useState(table.get("view") || "grid");
10
23
  const params = {
11
- sort: table.get("sort") || undefined,
24
+ q: table.get("q") || undefined,
25
+ minPrice: table.get("minPrice") ? Number(table.get("minPrice")) : undefined,
26
+ maxPrice: table.get("maxPrice") ? Number(table.get("maxPrice")) : undefined,
27
+ sort: table.get("sort") || "auctionEndDate",
12
28
  page: table.getNumber("page", 1),
13
29
  perPage: table.getNumber("pageSize", 24),
14
30
  sellerId,
@@ -33,9 +49,11 @@ export function StoreAuctionsListing({ sellerId, initialData }) {
33
49
  slug: p.slug,
34
50
  buyNowPrice: p.buyNowPrice,
35
51
  }));
36
- return (_jsx(Section, { children: _jsx(Container, { size: "xl", children: _jsx(SlottedListingView, { portal: "public", manageSearch: true, manageSort: true, inlineToolbar: true, renderSearch: (search, setSearch) => (_jsx(Input, { value: search, onChange: (e) => setSearch(e.target.value), placeholder: "Search auctions...", className: "max-w-sm" })), renderSort: (value, onChange) => (_jsx(SortDropdown, { value: value, onChange: onChange, options: [
37
- { value: "auctionEndDate", label: "Ending Soonest" },
38
- { value: "-createdAt", label: "Newest" },
39
- { value: "-currentBid", label: "Highest Bid" },
40
- ] })), renderTable: () => auctions.length === 0 && !isLoading ? (_jsxs(Stack, { align: "center", gap: "3", className: "justify-center py-24 text-center", children: [_jsx(Text, { className: "text-xl font-medium text-zinc-900 dark:text-zinc-50", children: "No auctions yet" }), _jsx(Text, { className: "text-sm text-zinc-500", children: "This store has no active auctions." })] })) : (_jsx(Grid, { cols: "productCards", gap: "md", children: auctions.map((item) => (_jsx(MarketplaceAuctionCard, { product: item }, item.id))) })), renderPagination: () => (_jsx(Pagination, { currentPage: page, totalPages: totalPages, onPageChange: (p) => table.setPage(p) })), total: total, isLoading: isLoading }) }) }));
52
+ const commitSearch = useCallback(() => {
53
+ table.set("q", searchInput.trim());
54
+ table.setPage(1);
55
+ }, [searchInput, table]);
56
+ const closeFilters = () => setFilterOpen(false);
57
+ const gridClass = "grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 gap-4";
58
+ return (_jsxs("div", { className: "min-h-[200px]", children: [_jsx("div", { className: "sticky top-0 z-20 border-b border-zinc-200 dark:border-slate-700 bg-white/95 dark:bg-slate-900/95 backdrop-blur-sm py-2.5 px-4", children: _jsxs("div", { className: "flex items-center gap-2.5 max-w-full", children: [_jsxs("button", { type: "button", onClick: () => setFilterOpen(true), className: "flex shrink-0 items-center gap-2 rounded-lg border border-zinc-300 dark:border-slate-600 px-3.5 py-2 text-sm font-medium text-zinc-700 dark:text-zinc-200 hover:bg-zinc-50 dark:hover:bg-slate-800 transition-colors", children: [_jsx(SlidersHorizontal, { className: "h-4 w-4" }), _jsx("span", { className: "hidden sm:inline", children: "Filters" })] }), _jsxs("div", { className: "flex flex-1 items-center overflow-hidden rounded-lg border border-zinc-300 dark:border-slate-600 bg-white dark:bg-slate-900", children: [_jsx("input", { type: "text", value: searchInput, onChange: (e) => setSearchInput(e.target.value), onKeyDown: (e) => e.key === "Enter" && commitSearch(), placeholder: "Search store auctions...", className: "min-w-0 flex-1 bg-transparent px-3 py-2 text-sm text-zinc-900 dark:text-zinc-100 placeholder-zinc-400 outline-none" }), _jsx("button", { type: "button", onClick: commitSearch, className: "flex shrink-0 items-center justify-center px-3 py-2 text-zinc-400 hover:text-primary dark:hover:text-primary-400 transition-colors", "aria-label": "Search", children: _jsx(Search, { className: "h-4 w-4" }) })] }), _jsxs("div", { className: "flex shrink-0 items-center gap-1.5 text-sm text-zinc-500 dark:text-zinc-400", children: [_jsx("span", { className: "hidden md:inline whitespace-nowrap", children: "Sort by" }), _jsx(SortDropdown, { value: table.get("sort") || "auctionEndDate", onChange: (v) => { table.set("sort", v); table.setPage(1); }, options: AUCTION_SORT_OPTIONS })] }), _jsxs("div", { className: "flex shrink-0 items-center rounded-lg border border-zinc-300 dark:border-slate-600 overflow-hidden", children: [_jsx("button", { type: "button", onClick: () => { setView("grid"); table.set("view", "grid"); }, "aria-label": "Grid view", className: `p-2 transition-colors ${view === "grid" ? "bg-primary text-white" : "text-zinc-500 hover:bg-zinc-50 dark:hover:bg-slate-800 dark:text-zinc-400"}`, children: _jsx(LayoutGrid, { className: "h-4 w-4" }) }), _jsx("button", { type: "button", onClick: () => { setView("list"); table.set("view", "list"); }, "aria-label": "List view", className: `p-2 transition-colors ${view === "list" ? "bg-primary text-white" : "text-zinc-500 hover:bg-zinc-50 dark:hover:bg-slate-800 dark:text-zinc-400"}`, children: _jsx(List, { className: "h-4 w-4" }) })] })] }) }), _jsxs("div", { className: "py-6", children: [isLoading ? (_jsx("div", { className: gridClass, children: Array.from({ length: 8 }).map((_, i) => (_jsxs("div", { className: "rounded-xl border border-zinc-100 dark:border-slate-700 overflow-hidden animate-pulse", children: [_jsx("div", { className: "aspect-square bg-zinc-200 dark:bg-slate-700" }), _jsxs("div", { className: "p-3 space-y-2", children: [_jsx("div", { className: "h-3 bg-zinc-200 dark:bg-slate-700 rounded w-3/4" }), _jsx("div", { className: "h-4 bg-zinc-200 dark:bg-slate-700 rounded w-1/2" }), _jsx("div", { className: "h-8 bg-zinc-200 dark:bg-slate-700 rounded" })] })] }, i))) })) : (_jsx(MarketplaceAuctionGrid, { auctions: auctions, variant: view === "list" ? "list" : "grid", gridClassName: view === "list" ? "flex flex-col gap-4" : gridClass, labels: { emptyTitle: "No auctions yet", emptyDescription: "This store has no active auctions." } })), totalPages > 1 && (_jsx("div", { className: "mt-8 flex justify-center", children: _jsx(Pagination, { currentPage: page, totalPages: totalPages, onPageChange: (p) => table.setPage(p) }) }))] }), filterOpen && (_jsxs(_Fragment, { children: [_jsx("div", { className: "fixed inset-0 z-40 bg-black/40", "aria-hidden": "true", onClick: closeFilters }), _jsxs("div", { className: "fixed inset-y-0 left-0 z-50 flex w-80 flex-col bg-white dark:bg-slate-900 shadow-2xl", children: [_jsxs("div", { className: "flex items-center justify-between border-b border-zinc-200 dark:border-slate-700 px-4 py-3.5", children: [_jsxs("span", { className: "flex items-center gap-2 text-base font-semibold text-zinc-900 dark:text-zinc-100", children: [_jsx(SlidersHorizontal, { className: "h-4 w-4" }), "Filters"] }), _jsx("button", { type: "button", onClick: closeFilters, "aria-label": "Close filters", className: "rounded-lg p-1.5 text-zinc-500 hover:bg-zinc-100 dark:hover:bg-slate-800 transition-colors", children: _jsx(X, { className: "h-5 w-5" }) })] }), _jsx("div", { className: "flex-1 overflow-y-auto px-4 py-4", children: _jsx(ProductFilters, { table: table, currencyPrefix: "\u20B9" }) }), _jsx("div", { className: "border-t border-zinc-200 dark:border-slate-700 px-4 py-3.5", children: _jsx("button", { type: "button", onClick: closeFilters, className: "w-full rounded-lg bg-primary py-2.5 text-sm font-semibold text-white hover:bg-primary-600 transition-colors", children: "Apply filters" }) })] })] }))] }));
41
59
  }
@@ -12,6 +12,8 @@ export async function StoreDetailLayoutView({ storeSlug, activeTab, children, })
12
12
  const tabs = [
13
13
  { value: "products", label: "Products", href: String(ROUTES.PUBLIC.STORE_PRODUCTS(storeSlug)) },
14
14
  { value: "auctions", label: "Auctions", href: String(ROUTES.PUBLIC.STORE_AUCTIONS(storeSlug)) },
15
+ { value: "pre-orders", label: "Pre-Orders", href: String(ROUTES.PUBLIC.STORE_PRE_ORDERS(storeSlug)) },
16
+ { value: "coupons", label: "Coupons", href: String(ROUTES.PUBLIC.STORE_COUPONS(storeSlug)) },
15
17
  { value: "reviews", label: "Reviews", href: String(ROUTES.PUBLIC.STORE_REVIEWS(storeSlug)) },
16
18
  { value: "about", label: "About", href: String(ROUTES.PUBLIC.STORE_ABOUT(storeSlug)) },
17
19
  ];
@@ -0,0 +1,5 @@
1
+ import type { UrlTable } from "../../filters/FilterPanel";
2
+ export interface StoreFiltersProps {
3
+ table: UrlTable;
4
+ }
5
+ export declare function StoreFilters({ table }: StoreFiltersProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,20 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useTranslations } from "next-intl";
3
+ import { FilterFacetSection } from "../../filters/FilterFacetSection";
4
+ import { RangeFilter } from "../../filters/RangeFilter";
5
+ import { SwitchFilter } from "../../filters/SwitchFilter";
6
+ import { Div } from "../../../ui";
7
+ export function StoreFilters({ table }) {
8
+ const t = useTranslations("filters");
9
+ const ratingOptions = [
10
+ { value: "5", label: t("rating5Stars") },
11
+ { value: "4", label: t("rating4Stars") },
12
+ { value: "3", label: t("rating3Stars") },
13
+ { value: "2", label: t("rating2Stars") },
14
+ { value: "1", label: t("rating1Star") },
15
+ ];
16
+ const selectedRatings = table.get("rating")
17
+ ? table.get("rating").split("|").filter(Boolean)
18
+ : [];
19
+ return (_jsxs(Div, { children: [_jsx(FilterFacetSection, { title: t("rating"), options: ratingOptions, selected: selectedRatings, onChange: (vals) => table.set("rating", vals.join("|")), searchable: false, defaultCollapsed: false }), _jsx(RangeFilter, { title: t("productCount"), minValue: table.get("minProductCount"), maxValue: table.get("maxProductCount"), onMinChange: (v) => table.set("minProductCount", v), onMaxChange: (v) => table.set("maxProductCount", v), minBound: 0, maxBound: 10000, step: 10, minPlaceholder: t("minProductCount"), maxPlaceholder: t("maxProductCount"), defaultCollapsed: true }), _jsx(SwitchFilter, { title: t("featured"), label: t("showFeaturedOnly"), checked: table.get("featured") === "true", onChange: (v) => table.set("featured", v ? "true" : ""), defaultCollapsed: true })] }));
20
+ }
@@ -2,7 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { Button, Div, Heading, RichText, Row, Section, Span, Text, } from "../../../ui";
3
3
  import { normalizeRichTextHtml } from "../../../utils/string.formatter";
4
4
  export function StoreHeader({ store, labels = {}, onFollow, className = "", }) {
5
- return (_jsxs(Section, { className: `bg-white dark:bg-slate-900 border-b border-gray-200 dark:border-slate-700 ${className}`, children: [store.storeBannerURL && (_jsx(Div, { className: "h-40 md:h-56 overflow-hidden bg-gray-100 dark:bg-slate-800", children: _jsx(Div, { role: "img", "aria-label": `${store.storeName} banner`, className: "h-full w-full bg-center bg-cover", style: { backgroundImage: `url(${store.storeBannerURL})` } }) })), _jsxs(Div, { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-4", children: [_jsxs(Div, { className: "flex items-end gap-4", children: [store.storeLogoURL ? (_jsx(Div, { role: "img", "aria-label": store.storeName, className: "-mt-8 h-16 w-16 rounded-xl border-2 border-white dark:border-slate-800 bg-center bg-cover shadow-sm", style: { backgroundImage: `url(${store.storeLogoURL})` } })) : (_jsx(Div, { className: "-mt-8 h-16 w-16 rounded-xl border-2 border-white dark:border-slate-800 bg-orange-100 dark:bg-orange-900/30 flex items-center justify-center text-orange-600 dark:text-orange-400 font-bold text-2xl shadow-sm", children: store.storeName[0]?.toUpperCase() })), _jsxs(Div, { className: "flex-1 min-w-0", children: [_jsx(Heading, { level: 1, className: "text-xl font-bold text-gray-900 dark:text-zinc-100 truncate", children: store.storeName }), store.storeDescription && (_jsx(RichText, { html: normalizeRichTextHtml(store.storeDescription), copyableCode: true, className: "text-sm text-gray-500 dark:text-zinc-400 mt-0.5" }))] }), onFollow && (_jsx(Button, { type: "button", variant: "outline", size: "sm", onClick: () => onFollow(store.storeSlug), className: "shrink-0 rounded-lg border border-orange-500 px-4 py-2 text-sm font-medium text-orange-500 hover:bg-orange-50 transition-colors", children: labels.follow ?? "Follow" }))] }), store.isVacationMode && (_jsx(Text, { className: "mt-3 rounded-lg bg-yellow-50 dark:bg-yellow-900/20 border border-yellow-200 dark:border-yellow-800 px-3 py-2 text-sm text-yellow-700 dark:text-yellow-300", children: store.vacationMessage ??
5
+ return (_jsxs(Section, { className: `bg-white dark:bg-slate-900 border-b border-gray-200 dark:border-slate-700 ${className}`, children: [store.storeBannerURL && (_jsx(Div, { className: "h-40 md:h-56 overflow-hidden bg-gray-100 dark:bg-slate-800", children: _jsx(Div, { role: "img", "aria-label": `${store.storeName} banner`, className: "h-full w-full bg-center bg-cover", style: { backgroundImage: `url(${store.storeBannerURL})` } }) })), _jsxs(Div, { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-4", children: [_jsxs(Div, { className: "flex items-end gap-4", children: [store.storeLogoURL ? (_jsx(Div, { role: "img", "aria-label": store.storeName, className: "-mt-8 h-16 w-16 rounded-xl border-2 border-white dark:border-slate-800 bg-center bg-cover shadow-sm", style: { backgroundImage: `url(${store.storeLogoURL})` } })) : (_jsx(Div, { className: "-mt-8 h-16 w-16 rounded-xl border-2 border-white dark:border-slate-800 bg-orange-100 dark:bg-orange-900/30 flex items-center justify-center text-orange-600 dark:text-orange-400 font-bold text-2xl shadow-sm", children: store.storeName[0]?.toUpperCase() })), _jsxs(Div, { className: "flex-1 min-w-0", children: [_jsxs(Div, { className: "flex flex-wrap items-center gap-2 mb-0.5", children: [_jsx(Heading, { level: 1, className: "text-xl font-bold text-gray-900 dark:text-zinc-100", children: store.storeName }), store.averageRating != null && store.averageRating > 0 && (_jsxs(Span, { className: "inline-flex items-center gap-1 text-sm font-medium text-amber-500", children: ["\u2605 ", store.averageRating.toFixed(1)] }))] }), _jsxs(Row, { className: "gap-3 text-xs text-gray-500 dark:text-zinc-400 mb-0.5", children: [store.category && _jsx(Span, { className: "capitalize", children: store.category }), store.totalProducts != null && store.totalProducts > 0 && (_jsxs(Span, { children: [store.totalProducts, " ", labels.products ?? "products"] })), store.totalReviews != null && store.totalReviews > 0 && (_jsxs(Span, { children: [store.totalReviews, " ", labels.reviews ?? "reviews"] })), store.itemsSold != null && store.itemsSold > 0 && (_jsxs(Span, { children: [store.itemsSold, " ", labels.sold ?? "sold"] }))] }), store.storeDescription && (_jsx(RichText, { html: normalizeRichTextHtml(store.storeDescription), copyableCode: true, className: "text-sm text-gray-500 dark:text-zinc-400 mt-0.5" }))] }), onFollow && (_jsx(Button, { type: "button", variant: "outline", size: "sm", onClick: () => onFollow(store.storeSlug), className: "shrink-0 rounded-lg border border-orange-500 px-4 py-2 text-sm font-medium text-orange-500 hover:bg-orange-50 transition-colors", children: labels.follow ?? "Follow" }))] }), store.isVacationMode && (_jsx(Text, { className: "mt-3 rounded-lg bg-yellow-50 dark:bg-yellow-900/20 border border-yellow-200 dark:border-yellow-800 px-3 py-2 text-sm text-yellow-700 dark:text-yellow-300", children: store.vacationMessage ??
6
6
  labels.vacationMode ??
7
- "Store is on vacation mode" })), _jsxs(Row, { className: "gap-4 mt-3 text-sm text-gray-500 dark:text-zinc-400", children: [store.totalProducts != null && (_jsxs(Span, { children: [store.totalProducts, " ", labels.products ?? "products"] })), store.itemsSold != null && (_jsxs(Span, { children: [store.itemsSold, " ", labels.sold ?? "sold"] })), store.averageRating != null && (_jsxs(Span, { children: ["\u2605 ", store.averageRating.toFixed(1), " (", store.totalReviews, " ", labels.reviews ?? "reviews", ")"] }))] })] })] }));
7
+ "Store is on vacation mode" }))] })] }));
8
8
  }
@@ -0,0 +1,5 @@
1
+ export interface StorePreOrdersListingProps {
2
+ sellerId: string;
3
+ initialData?: any;
4
+ }
5
+ export declare function StorePreOrdersListing({ sellerId, initialData }: StorePreOrdersListingProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,40 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
+ import { useState, useCallback } from "react";
4
+ import { Search, SlidersHorizontal, LayoutGrid, List, X } from "lucide-react";
5
+ import { useUrlTable } from "../../../react/hooks/useUrlTable";
6
+ import { useProducts } from "../../products/hooks/useProducts";
7
+ import { Pagination, SortDropdown } from "../../../ui";
8
+ import { MarketplacePreorderCard } from "../../pre-orders/components/MarketplacePreorderCard";
9
+ import { ProductFilters } from "../../products/components/ProductFilters";
10
+ import { ROUTES } from "../../../next";
11
+ const PREORDER_SORT_OPTIONS = [
12
+ { value: "-createdAt", label: "Newest First" },
13
+ { value: "preOrderDeliveryDate", label: "Delivery Soon" },
14
+ { value: "price", label: "Price: Low to High" },
15
+ { value: "-price", label: "Price: High to Low" },
16
+ ];
17
+ export function StorePreOrdersListing({ sellerId, initialData }) {
18
+ const table = useUrlTable({ defaults: { pageSize: "24", sort: "-createdAt" } });
19
+ const [searchInput, setSearchInput] = useState(table.get("q") || "");
20
+ const [filterOpen, setFilterOpen] = useState(false);
21
+ const [view, setView] = useState(table.get("view") || "grid");
22
+ const params = {
23
+ q: table.get("q") || undefined,
24
+ minPrice: table.get("minPrice") ? Number(table.get("minPrice")) : undefined,
25
+ maxPrice: table.get("maxPrice") ? Number(table.get("maxPrice")) : undefined,
26
+ sort: table.get("sort") || "-createdAt",
27
+ page: table.getNumber("page", 1),
28
+ perPage: table.getNumber("pageSize", 24),
29
+ sellerId,
30
+ isPreOrder: true,
31
+ };
32
+ const { products: preOrders, total, totalPages, page, isLoading } = useProducts(params, { initialData });
33
+ const commitSearch = useCallback(() => {
34
+ table.set("q", searchInput.trim());
35
+ table.setPage(1);
36
+ }, [searchInput, table]);
37
+ const closeFilters = () => setFilterOpen(false);
38
+ const gridClass = "grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5 gap-4";
39
+ return (_jsxs("div", { className: "min-h-[200px]", children: [_jsx("div", { className: "sticky top-0 z-20 border-b border-zinc-200 dark:border-slate-700 bg-white/95 dark:bg-slate-900/95 backdrop-blur-sm py-2.5 px-4", children: _jsxs("div", { className: "flex items-center gap-2.5 max-w-full", children: [_jsxs("button", { type: "button", onClick: () => setFilterOpen(true), className: "flex shrink-0 items-center gap-2 rounded-lg border border-zinc-300 dark:border-slate-600 px-3.5 py-2 text-sm font-medium text-zinc-700 dark:text-zinc-200 hover:bg-zinc-50 dark:hover:bg-slate-800 transition-colors", children: [_jsx(SlidersHorizontal, { className: "h-4 w-4" }), _jsx("span", { className: "hidden sm:inline", children: "Filters" })] }), _jsxs("div", { className: "flex flex-1 items-center overflow-hidden rounded-lg border border-zinc-300 dark:border-slate-600 bg-white dark:bg-slate-900", children: [_jsx("input", { type: "text", value: searchInput, onChange: (e) => setSearchInput(e.target.value), onKeyDown: (e) => e.key === "Enter" && commitSearch(), placeholder: "Search store pre-orders...", className: "min-w-0 flex-1 bg-transparent px-3 py-2 text-sm text-zinc-900 dark:text-zinc-100 placeholder-zinc-400 outline-none" }), _jsx("button", { type: "button", onClick: commitSearch, className: "flex shrink-0 items-center justify-center px-3 py-2 text-zinc-400 hover:text-primary dark:hover:text-primary-400 transition-colors", "aria-label": "Search", children: _jsx(Search, { className: "h-4 w-4" }) })] }), _jsxs("div", { className: "flex shrink-0 items-center gap-1.5 text-sm text-zinc-500 dark:text-zinc-400", children: [_jsx("span", { className: "hidden md:inline whitespace-nowrap", children: "Sort by" }), _jsx(SortDropdown, { value: table.get("sort") || "-createdAt", onChange: (v) => { table.set("sort", v); table.setPage(1); }, options: PREORDER_SORT_OPTIONS })] }), _jsxs("div", { className: "flex shrink-0 items-center rounded-lg border border-zinc-300 dark:border-slate-600 overflow-hidden", children: [_jsx("button", { type: "button", onClick: () => { setView("grid"); table.set("view", "grid"); }, "aria-label": "Grid view", className: `p-2 transition-colors ${view === "grid" ? "bg-primary text-white" : "text-zinc-500 hover:bg-zinc-50 dark:hover:bg-slate-800 dark:text-zinc-400"}`, children: _jsx(LayoutGrid, { className: "h-4 w-4" }) }), _jsx("button", { type: "button", onClick: () => { setView("list"); table.set("view", "list"); }, "aria-label": "List view", className: `p-2 transition-colors ${view === "list" ? "bg-primary text-white" : "text-zinc-500 hover:bg-zinc-50 dark:hover:bg-slate-800 dark:text-zinc-400"}`, children: _jsx(List, { className: "h-4 w-4" }) })] })] }) }), _jsxs("div", { className: "py-6", children: [isLoading ? (_jsx("div", { className: gridClass, children: Array.from({ length: 8 }).map((_, i) => (_jsxs("div", { className: "rounded-xl border border-zinc-100 dark:border-slate-700 overflow-hidden animate-pulse", children: [_jsx("div", { className: "aspect-square bg-zinc-200 dark:bg-slate-700" }), _jsxs("div", { className: "p-3 space-y-2", children: [_jsx("div", { className: "h-3 bg-zinc-200 dark:bg-slate-700 rounded w-3/4" }), _jsx("div", { className: "h-3 bg-zinc-200 dark:bg-slate-700 rounded w-1/2" }), _jsx("div", { className: "h-8 bg-zinc-200 dark:bg-slate-700 rounded" })] })] }, i))) })) : preOrders.length === 0 ? (_jsx("p", { className: "py-12 text-center text-sm text-zinc-500 dark:text-zinc-400", children: "This store has no pre-orders yet." })) : view === "list" ? (_jsx("div", { className: "flex flex-col divide-y divide-zinc-100 dark:divide-zinc-800 rounded-xl border border-zinc-100 dark:border-zinc-800", children: preOrders.map((product) => (_jsx(MarketplacePreorderCard, { product: product, variant: "list", hrefBuilder: (p) => String(ROUTES.PUBLIC.PRE_ORDER_DETAIL(p.id)) }, product.id))) })) : (_jsx("div", { className: gridClass, children: preOrders.map((product) => (_jsx(MarketplacePreorderCard, { product: product, variant: "grid", hrefBuilder: (p) => String(ROUTES.PUBLIC.PRE_ORDER_DETAIL(p.id)) }, product.id))) })), totalPages > 1 && (_jsx("div", { className: "mt-8 flex justify-center", children: _jsx(Pagination, { currentPage: page, totalPages: totalPages, onPageChange: (p) => table.setPage(p) }) }))] }), filterOpen && (_jsxs(_Fragment, { children: [_jsx("div", { className: "fixed inset-0 z-40 bg-black/40", "aria-hidden": "true", onClick: closeFilters }), _jsxs("div", { className: "fixed inset-y-0 left-0 z-50 flex w-80 flex-col bg-white dark:bg-slate-900 shadow-2xl", children: [_jsxs("div", { className: "flex items-center justify-between border-b border-zinc-200 dark:border-slate-700 px-4 py-3.5", children: [_jsxs("span", { className: "flex items-center gap-2 text-base font-semibold text-zinc-900 dark:text-zinc-100", children: [_jsx(SlidersHorizontal, { className: "h-4 w-4" }), "Filters"] }), _jsx("button", { type: "button", onClick: closeFilters, "aria-label": "Close filters", className: "rounded-lg p-1.5 text-zinc-500 hover:bg-zinc-100 dark:hover:bg-slate-800 transition-colors", children: _jsx(X, { className: "h-5 w-5" }) })] }), _jsx("div", { className: "flex-1 overflow-y-auto px-4 py-4", children: _jsx(ProductFilters, { table: table, currencyPrefix: "\u20B9" }) }), _jsx("div", { className: "border-t border-zinc-200 dark:border-slate-700 px-4 py-3.5", children: _jsx("button", { type: "button", onClick: closeFilters, className: "w-full rounded-lg bg-primary py-2.5 text-sm font-semibold text-white hover:bg-primary-600 transition-colors", children: "Apply filters" }) })] })] }))] }));
40
+ }
@@ -0,0 +1,4 @@
1
+ export interface StorePreOrdersPageViewProps {
2
+ storeSlug: string;
3
+ }
4
+ export declare function StorePreOrdersPageView({ storeSlug }: StorePreOrdersPageViewProps): Promise<import("react/jsx-runtime").JSX.Element | null>;
@@ -0,0 +1,21 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { productRepository, storeRepository } from "../../../repositories";
3
+ import { StorePreOrdersListing } from "./StorePreOrdersListing";
4
+ export async function StorePreOrdersPageView({ storeSlug }) {
5
+ const store = await storeRepository.findBySlug(storeSlug).catch(() => undefined);
6
+ const ownerId = store?.ownerId;
7
+ const result = ownerId
8
+ ? await productRepository
9
+ .list({
10
+ filters: `sellerId==${ownerId},status==published,isPreOrder==true`,
11
+ sorts: "-createdAt",
12
+ page: 1,
13
+ pageSize: 24,
14
+ })
15
+ .catch(() => null)
16
+ : null;
17
+ if (!ownerId) {
18
+ return null;
19
+ }
20
+ return (_jsx(StorePreOrdersListing, { sellerId: ownerId, initialData: result ?? undefined }));
21
+ }