@mohasinac/appkit 4.11.2 → 4.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (246) hide show
  1. package/dist/_internal/server/features/checkout/actions.d.ts +40 -3
  2. package/dist/_internal/server/features/checkout/actions.js +232 -47
  3. package/dist/_internal/server/features/checkout/data.d.ts +10 -0
  4. package/dist/_internal/server/features/orders/adapters.js +20 -0
  5. package/dist/_internal/server/features/products/data.d.ts +12 -3
  6. package/dist/_internal/server/features/products/data.js +55 -4
  7. package/dist/_internal/server/features/products/index.d.ts +1 -1
  8. package/dist/_internal/server/features/products/index.js +1 -1
  9. package/dist/_internal/server/features/products/list-public.d.ts +47 -0
  10. package/dist/_internal/server/features/products/list-public.js +131 -6
  11. package/dist/_internal/server/features/reviews/data.d.ts +1 -1
  12. package/dist/_internal/server/features/reviews/data.js +3 -2
  13. package/dist/_internal/server/features/tester/visibility.js +3 -3
  14. package/dist/_internal/server/jobs/core/auctionSettlement.js +5 -2
  15. package/dist/_internal/server/jobs/core/testerSandboxCleanup.d.ts +1 -1
  16. package/dist/_internal/server/jobs/core/testerSandboxCleanup.js +4 -1
  17. package/dist/_internal/server/jobs/core/testerSandboxRefresh.js +2 -0
  18. package/dist/_internal/server/jobs/handlers/_helpers.js +4 -1
  19. package/dist/_internal/shared/checkout/lanes.d.ts +20 -0
  20. package/dist/_internal/shared/checkout/lanes.js +28 -0
  21. package/dist/_internal/shared/features/checkout/config.d.ts +4 -0
  22. package/dist/_internal/shared/features/checkout/config.js +8 -0
  23. package/dist/_internal/shared/features/promotions/schema.d.ts +0 -16
  24. package/dist/_internal/shared/features/promotions/schema.js +0 -2
  25. package/dist/_internal/shared/features/reviews/config.d.ts +8 -1
  26. package/dist/_internal/shared/features/reviews/config.js +8 -1
  27. package/dist/_internal/shared/fees/calculator.d.ts +34 -2
  28. package/dist/_internal/shared/fees/calculator.js +45 -1
  29. package/dist/_internal/shared/listing-types/_registry.d.ts +88 -1
  30. package/dist/_internal/shared/listing-types/_registry.js +63 -1
  31. package/dist/_internal/shared/listing-types/art/config.d.ts +59 -0
  32. package/dist/_internal/shared/listing-types/art/config.js +12 -0
  33. package/dist/_internal/shared/listing-types/auction/config.d.ts +53 -0
  34. package/dist/_internal/shared/listing-types/auction/config.js +17 -0
  35. package/dist/_internal/shared/listing-types/classified/config.d.ts +59 -0
  36. package/dist/_internal/shared/listing-types/classified/config.js +14 -0
  37. package/dist/_internal/shared/listing-types/digital-code/config.d.ts +59 -0
  38. package/dist/_internal/shared/listing-types/digital-code/config.js +12 -0
  39. package/dist/_internal/shared/listing-types/live/config.d.ts +59 -0
  40. package/dist/_internal/shared/listing-types/live/config.js +14 -0
  41. package/dist/_internal/shared/listing-types/pre-order/config.d.ts +110 -0
  42. package/dist/_internal/shared/listing-types/pre-order/config.js +14 -0
  43. package/dist/_internal/shared/listing-types/prize-draw/config.d.ts +44 -0
  44. package/dist/_internal/shared/listing-types/prize-draw/config.js +10 -0
  45. package/dist/_internal/shared/listing-types/standard/config.d.ts +59 -0
  46. package/dist/_internal/shared/listing-types/standard/config.js +9 -0
  47. package/dist/_internal/shared/listing-types/stickers/config.d.ts +59 -0
  48. package/dist/_internal/shared/listing-types/stickers/config.js +12 -0
  49. package/dist/client.d.ts +12 -2
  50. package/dist/client.js +8 -2
  51. package/dist/constants/api-endpoints.d.ts +6 -0
  52. package/dist/constants/api-endpoints.js +2 -0
  53. package/dist/constants/field-names.d.ts +12 -0
  54. package/dist/constants/field-names.js +12 -0
  55. package/dist/constants/table-keys.d.ts +2 -0
  56. package/dist/constants/table-keys.js +2 -0
  57. package/dist/features/account/components/UserOrdersView.js +27 -5
  58. package/dist/features/admin/components/AdminAddressesView.js +21 -11
  59. package/dist/features/admin/components/AdminArtView.d.ts +9 -0
  60. package/dist/features/admin/components/AdminArtView.js +11 -35
  61. package/dist/features/admin/components/AdminClassifiedView.d.ts +9 -0
  62. package/dist/features/admin/components/AdminClassifiedView.js +11 -35
  63. package/dist/features/admin/components/AdminCouponEditorView.js +1 -4
  64. package/dist/features/admin/components/AdminDigitalCodesView.d.ts +9 -0
  65. package/dist/features/admin/components/AdminDigitalCodesView.js +11 -42
  66. package/dist/features/admin/components/AdminLiveView.d.ts +9 -0
  67. package/dist/features/admin/components/AdminLiveView.js +11 -41
  68. package/dist/features/admin/components/AdminOrderEditorView.d.ts +8 -1
  69. package/dist/features/admin/components/AdminOrderEditorView.js +4 -3
  70. package/dist/features/admin/components/AdminOrdersView.js +14 -1
  71. package/dist/features/admin/components/AdminPaymentMethodsView.js +18 -11
  72. package/dist/features/admin/components/AdminProductsView.js +34 -18
  73. package/dist/features/admin/components/AdminSiteConfigGuideView.js +1 -1
  74. package/dist/features/admin/components/AdminSiteSettingsView.js +4 -2
  75. package/dist/features/admin/components/AdminStickersView.d.ts +9 -0
  76. package/dist/features/admin/components/AdminStickersView.js +11 -35
  77. package/dist/features/admin/constants/filter-tabs.d.ts +26 -9
  78. package/dist/features/admin/constants/filter-tabs.js +22 -9
  79. package/dist/features/admin/hooks/useAdminListing.js +7 -2
  80. package/dist/features/admin/schemas/firestore.d.ts +5 -0
  81. package/dist/features/admin/schemas/firestore.js +1 -0
  82. package/dist/features/auctions/actions/bid-actions.js +2 -2
  83. package/dist/features/auctions/components/AuctionBidsTable.js +1 -1
  84. package/dist/features/auctions/components/AuctionBottomActions.js +1 -0
  85. package/dist/features/auctions/components/AuctionDetailPageView.js +13 -11
  86. package/dist/features/cart/components/CartDrawer.d.ts +9 -1
  87. package/dist/features/cart/components/CartDrawer.js +4 -3
  88. package/dist/features/cart/components/CartPriceBreakdown.d.ts +61 -0
  89. package/dist/features/cart/components/CartPriceBreakdown.js +25 -0
  90. package/dist/features/cart/components/StoreAddonsPicker.d.ts +47 -0
  91. package/dist/features/cart/components/StoreAddonsPicker.js +21 -0
  92. package/dist/features/cart/components/index.d.ts +4 -0
  93. package/dist/features/cart/components/index.js +2 -0
  94. package/dist/features/cart/repository/cart.repository.d.ts +20 -2
  95. package/dist/features/cart/repository/cart.repository.js +49 -0
  96. package/dist/features/cart/schemas/firestore.d.ts +26 -2
  97. package/dist/features/categories/components/BrandDetailTabs.js +31 -11
  98. package/dist/features/categories/components/CategoryDetailTabs.js +27 -7
  99. package/dist/features/categories/components/CategoryProductsListing.d.ts +9 -1
  100. package/dist/features/categories/components/CategoryProductsListing.js +5 -2
  101. package/dist/features/classified/components/ClassifiedDetailPageView.js +2 -1
  102. package/dist/features/contact/email.js +5 -1
  103. package/dist/features/digital-codes/components/DigitalCodeDetailPageView.js +17 -16
  104. package/dist/features/homepage/components/FeaturedResultsSection.js +1 -1
  105. package/dist/features/homepage/components/SectionCarousel.js +1 -1
  106. package/dist/features/homepage/components/ShopByCategorySection.js +1 -1
  107. package/dist/features/layout/AppLayoutShell.js +9 -2
  108. package/dist/features/layout/BottomActions.js +62 -6
  109. package/dist/features/layout/BottomActionsContext.d.ts +26 -0
  110. package/dist/features/layout/BottomActionsContext.js +18 -1
  111. package/dist/features/layout/hooks/useBottomActions.d.ts +12 -1
  112. package/dist/features/layout/hooks/useBottomActions.js +14 -1
  113. package/dist/features/layout/index.d.ts +1 -1
  114. package/dist/features/live/components/LiveItemDetailPageView.js +7 -6
  115. package/dist/features/orders/components/OrderAddonBadges.d.ts +36 -0
  116. package/dist/features/orders/components/OrderAddonBadges.js +28 -0
  117. package/dist/features/orders/components/index.d.ts +1 -0
  118. package/dist/features/orders/components/index.js +1 -0
  119. package/dist/features/orders/repository/orders.repository.d.ts +36 -0
  120. package/dist/features/orders/repository/orders.repository.js +18 -0
  121. package/dist/features/orders/types/index.d.ts +38 -0
  122. package/dist/features/pre-orders/components/PreOrderBottomActions.d.ts +1 -1
  123. package/dist/features/pre-orders/components/PreOrderBottomActions.js +3 -19
  124. package/dist/features/products/components/ArtStickersListView.js +5 -4
  125. package/dist/features/products/components/AuctionsIndexListing.js +1 -2
  126. package/dist/features/products/components/ListingBottomActions.d.ts +28 -0
  127. package/dist/features/products/components/ListingBottomActions.js +25 -0
  128. package/dist/features/products/components/PrizeDrawBottomActions.d.ts +1 -1
  129. package/dist/features/products/components/PrizeDrawBottomActions.js +3 -21
  130. package/dist/features/products/components/PrizeDrawsListingView.js +18 -33
  131. package/dist/features/products/components/ProductDetailActions.js +4 -0
  132. package/dist/features/products/components/ProductDetailPageView.js +7 -7
  133. package/dist/features/products/components/ProductsIndexListing.js +87 -11
  134. package/dist/features/products/components/ProductsIndexPageView.js +14 -2
  135. package/dist/features/products/config/listing-type-listing-config.d.ts +31 -0
  136. package/dist/features/products/config/listing-type-listing-config.js +74 -0
  137. package/dist/features/products/constants/listing-tabs.d.ts +43 -198
  138. package/dist/features/products/constants/listing-tabs.js +71 -58
  139. package/dist/features/products/constants/sieve.d.ts +104 -1
  140. package/dist/features/products/constants/sieve.js +27 -7
  141. package/dist/features/products/hooks/useProducts.js +14 -0
  142. package/dist/features/products/repository/products.repository.d.ts +45 -1
  143. package/dist/features/products/repository/products.repository.js +26 -3
  144. package/dist/features/products/types/index.d.ts +15 -0
  145. package/dist/features/products/utils/listing-badge-variant.d.ts +20 -1
  146. package/dist/features/products/utils/listing-badge-variant.js +26 -1
  147. package/dist/features/products/utils/listing-type.d.ts +24 -0
  148. package/dist/features/products/utils/listing-type.js +48 -0
  149. package/dist/features/promotions/actions/coupon-actions.d.ts +7 -0
  150. package/dist/features/promotions/actions/coupon-actions.js +12 -1
  151. package/dist/features/promotions/actions/coupon-stacking.d.ts +24 -0
  152. package/dist/features/promotions/actions/coupon-stacking.js +21 -0
  153. package/dist/features/promotions/actions/index.d.ts +1 -0
  154. package/dist/features/promotions/actions/index.js +1 -0
  155. package/dist/features/promotions/actions/seller-coupon-actions.d.ts +0 -1
  156. package/dist/features/promotions/actions/seller-coupon-actions.js +0 -1
  157. package/dist/features/promotions/components/CouponHelpDetails.d.ts +20 -0
  158. package/dist/features/promotions/components/CouponHelpDetails.js +17 -0
  159. package/dist/features/promotions/components/CouponsIndexListing.js +2 -1
  160. package/dist/features/promotions/components/index.d.ts +2 -0
  161. package/dist/features/promotions/components/index.js +1 -0
  162. package/dist/features/promotions/constants/coupon-help.d.ts +27 -0
  163. package/dist/features/promotions/constants/coupon-help.js +42 -0
  164. package/dist/features/promotions/repository/coupons.repository.d.ts +10 -1
  165. package/dist/features/promotions/repository/coupons.repository.js +22 -8
  166. package/dist/features/promotions/schemas/firestore.d.ts +0 -1
  167. package/dist/features/promotions/schemas/firestore.js +1 -1
  168. package/dist/features/promotions/schemas/index.d.ts +0 -20
  169. package/dist/features/promotions/schemas/index.js +0 -1
  170. package/dist/features/reviews/actions/review-actions.js +5 -1
  171. package/dist/features/reviews/components/ReviewDetailPageView.js +2 -1
  172. package/dist/features/reviews/components/ReviewFilters.d.ts +7 -1
  173. package/dist/features/reviews/components/ReviewFilters.js +4 -3
  174. package/dist/features/reviews/components/ReviewsIndexListing.d.ts +6 -0
  175. package/dist/features/reviews/components/ReviewsIndexListing.js +9 -109
  176. package/dist/features/reviews/components/ReviewsListingPanel.d.ts +41 -0
  177. package/dist/features/reviews/components/ReviewsListingPanel.js +226 -0
  178. package/dist/features/reviews/components/index.d.ts +2 -0
  179. package/dist/features/reviews/components/index.js +1 -0
  180. package/dist/features/reviews/hooks/useReviews.d.ts +8 -0
  181. package/dist/features/reviews/hooks/useReviews.js +14 -6
  182. package/dist/features/reviews/repository/reviews.repository.d.ts +29 -1
  183. package/dist/features/reviews/repository/reviews.repository.js +77 -41
  184. package/dist/features/reviews/types/index.d.ts +8 -1
  185. package/dist/features/seller/components/SellerOrdersView.js +2 -1
  186. package/dist/features/seller/components/SellerProductsCards.js +2 -2
  187. package/dist/features/seller/components/SellerProductsView.js +21 -18
  188. package/dist/features/stores/actions/store-query-actions.js +1 -1
  189. package/dist/features/stores/components/StoreArtStickersPageView.d.ts +21 -0
  190. package/dist/features/stores/components/StoreArtStickersPageView.js +30 -0
  191. package/dist/features/stores/components/StoreAuctionsListing.js +5 -11
  192. package/dist/features/stores/components/StoreAuctionsPageView.d.ts +4 -1
  193. package/dist/features/stores/components/StoreAuctionsPageView.js +17 -17
  194. package/dist/features/stores/components/StoreClassifiedsListing.js +7 -0
  195. package/dist/features/stores/components/StoreClassifiedsPageView.d.ts +4 -1
  196. package/dist/features/stores/components/StoreClassifiedsPageView.js +16 -12
  197. package/dist/features/stores/components/StoreDetailLayoutView.js +4 -3
  198. package/dist/features/stores/components/StoreDigitalCodesListing.js +5 -0
  199. package/dist/features/stores/components/StoreDigitalCodesPageView.d.ts +4 -1
  200. package/dist/features/stores/components/StoreDigitalCodesPageView.js +16 -12
  201. package/dist/features/stores/components/StoreLiveItemsListing.js +7 -0
  202. package/dist/features/stores/components/StoreLiveItemsPageView.d.ts +4 -1
  203. package/dist/features/stores/components/StoreLiveItemsPageView.js +16 -12
  204. package/dist/features/stores/components/StorePreOrdersListing.js +6 -11
  205. package/dist/features/stores/components/StorePreOrdersPageView.d.ts +4 -1
  206. package/dist/features/stores/components/StorePreOrdersPageView.js +17 -17
  207. package/dist/features/stores/components/StorePrizeDrawsPageView.d.ts +4 -8
  208. package/dist/features/stores/components/StorePrizeDrawsPageView.js +17 -22
  209. package/dist/features/stores/components/StoreProductsListing.d.ts +7 -1
  210. package/dist/features/stores/components/StoreProductsListing.js +3 -2
  211. package/dist/features/stores/components/StoreProductsPageView.d.ts +1 -1
  212. package/dist/features/stores/components/StoreProductsPageView.js +16 -21
  213. package/dist/features/stores/components/StoreReviewsListing.d.ts +4 -0
  214. package/dist/features/stores/components/StoreReviewsListing.js +7 -108
  215. package/dist/features/stores/schemas/index.d.ts +2 -2
  216. package/dist/features/tester/seed-data/coupons-tester-seed-data.js +3 -3
  217. package/dist/features/tester/seed-data/index.d.ts +1 -0
  218. package/dist/features/tester/seed-data/index.js +1 -0
  219. package/dist/features/tester/seed-data/offers-tester-seed-data.d.ts +2 -0
  220. package/dist/features/tester/seed-data/offers-tester-seed-data.js +61 -0
  221. package/dist/features/tester/seed-data/tester-checklist-seed-data.js +939 -1
  222. package/dist/index.d.ts +9 -3
  223. package/dist/index.js +11 -2
  224. package/dist/next/routing/route-map.d.ts +2 -0
  225. package/dist/next/routing/route-map.js +5 -0
  226. package/dist/react/hooks/useListingTypeFlags.d.ts +12 -19
  227. package/dist/react/hooks/useListingTypeFlags.js +4 -9
  228. package/dist/schemas/registry.d.ts +0 -12
  229. package/dist/seed/claimed-coupons-seed-data.js +3 -3
  230. package/dist/seed/coupons-seed-data.js +29 -10
  231. package/dist/seed/faq-seed-data.js +2 -2
  232. package/dist/seed/manifest.js +2 -2
  233. package/dist/seed/reviews-seed-data.js +52 -0
  234. package/dist/server-entry.d.ts +1 -0
  235. package/dist/server-entry.js +1 -0
  236. package/dist/styles.css +55 -39
  237. package/dist/tailwind-utilities.css +1 -1
  238. package/dist/ui/components/Checkbox.d.ts +10 -1
  239. package/dist/ui/components/Checkbox.js +14 -2
  240. package/dist/ui/components/Checkbox.style.css +11 -0
  241. package/dist/ui/components/FilterChipGroup.d.ts +21 -3
  242. package/dist/ui/components/FilterChipGroup.js +33 -4
  243. package/dist/ui/components/HorizontalScroller.d.ts +1 -2
  244. package/dist/ui/components/HorizontalScroller.js +9 -5
  245. package/dist/ui/components/HorizontalScroller.style.css +43 -38
  246. package/package.json +1 -1
@@ -17,7 +17,7 @@ const __P = {
17
17
  p3: "p-[var(--appkit-space-3)]",
18
18
  };
19
19
  const FILTER_KEYS = ["condition", "brand", "minPrice", "maxPrice"];
20
- export function StoreProductsListing({ storeId, initialData }) {
20
+ export function StoreProductsListing({ storeId, listingTypes = ["standard"], initialData }) {
21
21
  const table = useUrlTable({ defaults: { pageSize: "24", sort: "-createdAt" } });
22
22
  const { showToast } = useToast();
23
23
  const { requireAuth, modalOpen, modalMessage, closeModal } = useAuthGate();
@@ -53,7 +53,8 @@ export function StoreProductsListing({ storeId, initialData }) {
53
53
  page: table.getNumber("page", 1),
54
54
  perPage: table.getNumber("pageSize", 24),
55
55
  storeId: storeId || undefined,
56
- listingType: "standard",
56
+ // Pipe-joined OR-group when the tab spans several types.
57
+ listingType: listingTypes.join("|"),
57
58
  };
58
59
  const { products, totalPages, page, isLoading } = useProducts(params, { initialData });
59
60
  const commitSearch = useCallback(() => {
@@ -4,5 +4,5 @@ export interface StoreProductsPageViewProps {
4
4
  storeSlug: string;
5
5
  searchParams?: SearchParams;
6
6
  }
7
- export declare function StoreProductsPageView({ storeSlug, searchParams, }: StoreProductsPageViewProps): Promise<React.JSX.Element | null>;
7
+ export declare function StoreProductsPageView({ storeSlug, searchParams }: StoreProductsPageViewProps): Promise<React.JSX.Element | null>;
8
8
  export {};
@@ -1,29 +1,24 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- import { sieveFilter, sieveAnd, SIEVE_OP } from "@mohasinac/appkit";
3
- import { productRepository } from "../../../repositories";
4
- import { parseListingSearchParams } from "../../../utils/listing-params";
2
+ import { PRODUCT_FIELDS } from "../../../constants/field-names";
3
+ import { sortBy } from "../../../constants/sort";
4
+ import { listStoreProducts } from "../../../_internal/server/features/products/list-public";
5
5
  import { getStoreBySlug } from "./StoreDetailLayoutView";
6
6
  import { StoreProductsListing } from "./StoreProductsListing";
7
- const DEFAULT_PAGE = 1;
7
+ const LISTING_TYPES = ["standard"];
8
8
  const DEFAULT_PAGE_SIZE = 24;
9
- const DEFAULT_SORT = "-createdAt";
10
- export async function StoreProductsPageView({ storeSlug, searchParams, }) {
9
+ const DEFAULT_SORT = sortBy(PRODUCT_FIELDS.CREATED_AT);
10
+ export async function StoreProductsPageView({ storeSlug, searchParams }) {
11
11
  const store = await getStoreBySlug(storeSlug);
12
12
  const storeId = store?.id;
13
- if (!storeId) {
13
+ if (typeof storeId !== "string" || !storeId)
14
14
  return null;
15
- }
16
- const std = parseListingSearchParams(searchParams);
17
- const sorts = std.sorts ?? DEFAULT_SORT;
18
- const page = std.page ?? DEFAULT_PAGE;
19
- const pageSize = std.pageSize ?? DEFAULT_PAGE_SIZE;
20
- const result = await productRepository
21
- .list({
22
- filters: sieveAnd(sieveFilter("storeId", SIEVE_OP.EQ, storeId), sieveFilter("status", SIEVE_OP.EQ, "published"), sieveFilter("listingType", SIEVE_OP.EQ, "standard")),
23
- sorts,
24
- page,
25
- pageSize,
26
- })
27
- .catch(() => null);
28
- return (_jsx(StoreProductsListing, { storeId: storeId, initialData: result ?? undefined }));
15
+ // Shared query — see listStoreProducts. This view used to call
16
+ // productRepository.list() with an inline filter string and swallow every
17
+ // failure via a bare .catch(() => null), so a missing index rendered as an
18
+ // empty store tab with nothing logged (Root Cause #30's family).
19
+ const result = await listStoreProducts(storeId, LISTING_TYPES, searchParams ?? {}, {
20
+ pageSize: DEFAULT_PAGE_SIZE,
21
+ sorts: DEFAULT_SORT,
22
+ });
23
+ return _jsx(StoreProductsListing, { storeId: storeId, initialData: result ?? undefined });
29
24
  }
@@ -2,4 +2,8 @@ import React from "react";
2
2
  export interface StoreReviewsListingProps {
3
3
  storeSlug: string;
4
4
  }
5
+ /**
6
+ * The `/stores/[slug]/reviews` tab. Delegates to the shared `ReviewsListingPanel` —
7
+ * see the note in `ReviewsIndexListing` for why the two were merged.
8
+ */
5
9
  export declare function StoreReviewsListing({ storeSlug }: StoreReviewsListingProps): React.JSX.Element;
@@ -1,111 +1,10 @@
1
1
  "use client";
2
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { useState, useCallback, useMemo } from "react";
4
- import { useUrlTable } from "../../../react/hooks/useUrlTable";
5
- import { Div, ListingFilterDrawer, ListingToolbar, Pagination, Row, Span, Stack, Text, StickyToolbar } from "../../../ui";
6
- import { ReviewCard } from "../../reviews/components/ReviewsList";
7
- import { ReviewFilters, REVIEW_PUBLIC_SORT_OPTIONS } from "../../reviews/components/ReviewFilters";
8
- import { useStoreReviews } from "../hooks/useStores";
9
- import { TABLE_KEYS, VIEW_MODE } from "../../../constants/table-keys";
10
- import { sortBy } from "../../../constants/sort";
11
- import { REVIEW_FIELDS } from "../../../constants/field-names";
12
- const __P = {
13
- p4: "p-[var(--appkit-space-4)]",
14
- };
15
- const __O = {
16
- hidden: "overflow-hidden",
17
- };
18
- const PAGE_SIZE = 12;
19
- const DEFAULT_SORT = sortBy(REVIEW_FIELDS.CREATED_AT);
20
- const FILTER_KEYS = ["rating", TABLE_KEYS.DATE_FROM, TABLE_KEYS.DATE_TO, "hasImages"];
21
- const SORT_OPTION_LABELS = {
22
- sortNewest: "Newest First",
23
- sortOldest: "Oldest First",
24
- sortHighestRated: "Highest Rated",
25
- sortLowestRated: "Lowest Rated",
26
- };
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { ReviewsListingPanel } from "../../reviews/components/ReviewsListingPanel";
4
+ /**
5
+ * The `/stores/[slug]/reviews` tab. Delegates to the shared `ReviewsListingPanel`
6
+ * see the note in `ReviewsIndexListing` for why the two were merged.
7
+ */
27
8
  export function StoreReviewsListing({ storeSlug }) {
28
- const table = useUrlTable({ defaults: { pageSize: String(PAGE_SIZE), sort: DEFAULT_SORT } });
29
- const [searchInput, setSearchInput] = useState(table.get(TABLE_KEYS.QUERY) || "");
30
- const [filterOpen, setFilterOpen] = useState(false);
31
- const [view, setView] = useState(table.get(TABLE_KEYS.VIEW) || VIEW_MODE.GRID);
32
- const handleViewToggle = (next) => {
33
- if (next === VIEW_MODE.TABLE)
34
- return;
35
- setView(next);
36
- table.set(TABLE_KEYS.VIEW, next);
37
- };
38
- const sort = table.get(TABLE_KEYS.SORT) || DEFAULT_SORT;
39
- const currentPage = table.getNumber(TABLE_KEYS.PAGE, 1);
40
- const [pendingFilters, setPendingFilters] = useState(() => Object.fromEntries(FILTER_KEYS.map((k) => [k, table.get(k)])));
41
- const pendingTable = useMemo(() => ({
42
- get: (key) => pendingFilters[key] ?? "",
43
- getNumber: (key, fallback = 0) => {
44
- const v = pendingFilters[key];
45
- if (!v)
46
- return fallback;
47
- const n = Number(v);
48
- return isNaN(n) ? fallback : n;
49
- },
50
- set: (key, value) => setPendingFilters((p) => ({ ...p, [key]: value })),
51
- setMany: (updates) => setPendingFilters((p) => ({ ...p, ...updates })),
52
- clear: (keys) => {
53
- const ks = keys ?? FILTER_KEYS;
54
- setPendingFilters((p) => ({
55
- ...p,
56
- ...Object.fromEntries(ks.map((k) => [k, ""])),
57
- }));
58
- },
59
- setPage: (_) => { },
60
- setPageSize: (_) => { },
61
- setSort: (_) => { },
62
- buildSieveParams: () => "",
63
- buildSearchParams: () => "",
64
- params: new URLSearchParams(),
65
- }), [pendingFilters]);
66
- const openFilters = useCallback(() => {
67
- setPendingFilters(Object.fromEntries(FILTER_KEYS.map((k) => [k, table.get(k)])));
68
- setFilterOpen(true);
69
- }, [table]);
70
- const applyFilters = useCallback(() => {
71
- const updates = { page: "1" };
72
- for (const k of FILTER_KEYS)
73
- updates[k] = pendingFilters[k] ?? "";
74
- table.setMany(updates);
75
- setFilterOpen(false);
76
- }, [pendingFilters, table]);
77
- const clearFilters = useCallback(() => {
78
- setPendingFilters(Object.fromEntries(FILTER_KEYS.map((k) => [k, ""])));
79
- }, []);
80
- const resetAll = useCallback(() => {
81
- const updates = { [TABLE_KEYS.QUERY]: "", [TABLE_KEYS.SORT]: "" };
82
- for (const k of FILTER_KEYS)
83
- updates[k] = "";
84
- table.setMany(updates);
85
- setSearchInput("");
86
- }, [table]);
87
- const commitSearch = useCallback(() => {
88
- table.set(TABLE_KEYS.QUERY, searchInput.trim());
89
- }, [searchInput, table]);
90
- const ratingRaw = table.get("rating");
91
- const ratingNum = ratingRaw ? Number(ratingRaw.split("|")[0]) : undefined;
92
- const activeFilterCount = FILTER_KEYS.filter((k) => !!table.get(k)).length;
93
- const hasActiveState = !!table.get(TABLE_KEYS.QUERY) ||
94
- table.get(TABLE_KEYS.SORT) !== DEFAULT_SORT ||
95
- activeFilterCount > 0;
96
- const { reviews, averageRating, totalReviews, totalPages, isLoading } = useStoreReviews(storeSlug, {
97
- rating: ratingNum,
98
- page: currentPage,
99
- pageSize: PAGE_SIZE,
100
- sort,
101
- q: table.get(TABLE_KEYS.QUERY) || undefined,
102
- dateFrom: table.get(TABLE_KEYS.DATE_FROM) || undefined,
103
- dateTo: table.get(TABLE_KEYS.DATE_TO) || undefined,
104
- hasImages: table.get("hasImages") === "true" ? true : undefined,
105
- });
106
- const sortOptions = REVIEW_PUBLIC_SORT_OPTIONS.map((opt) => ({
107
- value: opt.value,
108
- label: SORT_OPTION_LABELS[opt.key] ?? opt.key,
109
- }));
110
- return (_jsxs(Div, { className: "min-h-screen", children: [totalReviews > 0 && (_jsxs(Row, { border: "default", align: "center", gap: "sm", className: "border-b", padding: "inline", children: [_jsx(Span, { weight: "bold", size: "2xl", color: "primary", children: averageRating.toFixed(1) }), _jsxs(Span, { size: "sm", color: "muted", children: ["/ 5 \u00B7 ", totalReviews, " reviews"] })] })), _jsx(ListingToolbar, { filterCount: activeFilterCount, onFiltersClick: openFilters, searchValue: searchInput, searchPlaceholder: "Search reviews...", onSearchChange: setSearchInput, onSearchCommit: commitSearch, sortValue: sort, sortOptions: sortOptions, onSortChange: (v) => { table.set(TABLE_KEYS.SORT, v); }, view: view, onViewChange: handleViewToggle, onResetAll: resetAll, hasActiveState: hasActiveState }), totalPages > 1 && (_jsx(StickyToolbar, { offset: "header+pagination", tone: "translucent", border: true, padding: "toolbar", children: _jsx(Row, { justify: "center", children: _jsx(Pagination, { currentPage: currentPage, totalPages: totalPages, onPageChange: (p) => table.setPage(p) }) }) })), _jsx(Div, { paddingY: "y-lg", paddingX: "x-md", children: isLoading ? (_jsx(Div, { layout: "grid", gap: "6", className: "grid-cols-1 sm:grid-cols-2 lg:grid-cols-3", children: Array.from({ length: 6 }).map((_, i) => (_jsx(Div, { className: `${__O.hidden} animate-pulse`, border: "subtle", rounded: "xl", children: _jsxs(Stack, { className: `${__P.p4}`, gap: "3", children: [_jsx(Div, { className: "h-4 w-3/4", surface: "subtle", rounded: "default" }), _jsx(Div, { className: "h-3 w-full", surface: "subtle", rounded: "default" }), _jsx(Div, { className: "h-3 w-2/3", surface: "subtle", rounded: "default" })] }) }, i))) })) : reviews.length === 0 ? (_jsx(Text, { paddingY: "3xl", color: "muted", size: "sm", align: "start", children: "No reviews found." })) : view === "list" ? (_jsx(Stack, { className: "divide-y divide-zinc-100 divide-[var(--appkit-color-border-subtle)]", border: "subtle", rounded: "xl", children: reviews.map((review) => (_jsx(ReviewCard, { review: review, context: "store" }, review.id))) })) : (_jsx(Div, { layout: "grid", gap: "6", className: "grid-cols-1 sm:grid-cols-2 lg:grid-cols-3", children: reviews.map((review) => (_jsx(ReviewCard, { review: review, context: "store" }, review.id))) })) }), _jsx(ListingFilterDrawer, { open: filterOpen, onClose: () => setFilterOpen(false), onApply: applyFilters, onClear: clearFilters, activeCount: activeFilterCount, children: _jsx(ReviewFilters, { table: pendingTable, variant: "public" }) })] }));
9
+ return (_jsx(ReviewsListingPanel, { source: { kind: "store", storeSlug }, stateMode: "url", context: "store", className: "min-h-screen" }));
111
10
  }
@@ -617,9 +617,9 @@ export declare const storeListItemSchema: z.ZodObject<{
617
617
  storeLogoURL?: string | undefined;
618
618
  storeBannerURL?: string | undefined;
619
619
  itemsSold?: number | undefined;
620
+ averageRating?: number | undefined;
620
621
  totalProducts?: number | undefined;
621
622
  totalReviews?: number | undefined;
622
- averageRating?: number | undefined;
623
623
  }, {
624
624
  status: string;
625
625
  id: string;
@@ -633,9 +633,9 @@ export declare const storeListItemSchema: z.ZodObject<{
633
633
  storeLogoURL?: string | undefined;
634
634
  storeBannerURL?: string | undefined;
635
635
  itemsSold?: number | undefined;
636
+ averageRating?: number | undefined;
636
637
  totalProducts?: number | undefined;
637
638
  totalReviews?: number | undefined;
638
- averageRating?: number | undefined;
639
639
  }>;
640
640
  export declare const storeListParamsSchema: z.ZodObject<{
641
641
  category: z.ZodOptional<z.ZodString>;
@@ -34,7 +34,7 @@ export const couponsTesterSeedData = [
34
34
  discount: { value: 10, maxDiscount: 100, minPurchase: 100 },
35
35
  usage: { totalLimit: undefined, perUserLimit: 1, currentUsage: 0 },
36
36
  validity: { startDate: daysAgo(1), endDate: daysAhead(7), isActive: true },
37
- restrictions: { firstTimeUserOnly: false, combineWithSellerCoupons: true },
37
+ restrictions: { firstTimeUserOnly: false },
38
38
  createdBy: "user-admin-letitrip",
39
39
  createdAt: daysAgo(1),
40
40
  updatedAt: daysAgo(1),
@@ -50,7 +50,7 @@ export const couponsTesterSeedData = [
50
50
  discount: { value: 50, maxDiscount: 50, minPurchase: 100 },
51
51
  usage: { totalLimit: undefined, perUserLimit: 5, currentUsage: 0 },
52
52
  validity: { startDate: daysAgo(30), endDate: daysAgo(1), isActive: true },
53
- restrictions: { firstTimeUserOnly: false, combineWithSellerCoupons: true },
53
+ restrictions: { firstTimeUserOnly: false },
54
54
  createdBy: "user-admin-letitrip",
55
55
  createdAt: daysAgo(30),
56
56
  updatedAt: daysAgo(30),
@@ -67,7 +67,7 @@ export const couponsTesterSeedData = [
67
67
  discount: { value: 5, maxDiscount: 50, minPurchase: 0 },
68
68
  usage: { totalLimit: undefined, perUserLimit: 3, currentUsage: 0 },
69
69
  validity: { startDate: daysAgo(1), endDate: daysAhead(7), isActive: true },
70
- restrictions: { firstTimeUserOnly: false, combineWithSellerCoupons: true },
70
+ restrictions: { firstTimeUserOnly: false },
71
71
  createdBy: "user-admin-letitrip",
72
72
  createdAt: daysAgo(1),
73
73
  updatedAt: daysAgo(1),
@@ -7,3 +7,4 @@ export { eventsTesterSeedData } from "./events-tester-seed-data";
7
7
  export { couponsTesterSeedData } from "./coupons-tester-seed-data";
8
8
  export { bidsTesterSeedData } from "./bids-tester-seed-data";
9
9
  export { ordersTesterSeedData } from "./orders-tester-seed-data";
10
+ export { offersTesterSeedData } from "./offers-tester-seed-data";
@@ -7,3 +7,4 @@ export { eventsTesterSeedData } from "./events-tester-seed-data";
7
7
  export { couponsTesterSeedData } from "./coupons-tester-seed-data";
8
8
  export { bidsTesterSeedData } from "./bids-tester-seed-data";
9
9
  export { ordersTesterSeedData } from "./orders-tester-seed-data";
10
+ export { offersTesterSeedData } from "./offers-tester-seed-data";
@@ -0,0 +1,2 @@
1
+ import type { OfferDocument } from "../../seller/schemas/firestore";
2
+ export declare const offersTesterSeedData: Partial<OfferDocument>[];
@@ -0,0 +1,61 @@
1
+ /*
2
+ * WHY: Shared tester sandbox — a pre-ACCEPTED offer for the tester persona.
3
+ * Needed because the offer lifecycle spans two parties: a tester can make
4
+ * an offer (buyer side) but cannot accept it, since acceptance belongs to
5
+ * the store that owns the listing (`store-beyblade-arena`, not the
6
+ * tester's own sandbox store). Without a pre-accepted fixture, the
7
+ * "checkout at the agreed price" and "offer flips to paid" cases are not
8
+ * reachable by a single tester at all.
9
+ * WHAT: Exports offersTesterSeedData — 1 Partial<OfferDocument> already in the
10
+ * `accepted` state, with a live `checkoutDeadline`, so the tester can
11
+ * drive it straight through the Offers checkout lane.
12
+ *
13
+ * Every date is Date.now()-relative (per CLAUDE.md's tester-fixture standards)
14
+ * so the 4-hour testerSandboxRefresh re-arms it instead of letting it go stale.
15
+ *
16
+ * EXPORTS:
17
+ * offersTesterSeedData — Array of 1 Partial<OfferDocument> for the seed runner
18
+ *
19
+ * @tag domain:offers,seller,tester
20
+ * @tag layer:seed
21
+ * @tag pattern:none
22
+ * @tag access:server-only
23
+ * @tag consumers:seed/manifest.ts,seed-cli.mjs
24
+ * @tag sideEffects:none
25
+ */
26
+ import { OfferStatusValues } from "../../seller/schemas/firestore";
27
+ import { testDataExpiresAt } from "./tester-ttl";
28
+ const NOW = new Date();
29
+ const hoursAgo = (n) => new Date(NOW.getTime() - n * 3600000);
30
+ const hoursFromNow = (n) => new Date(NOW.getTime() + n * 3600000);
31
+ export const offersTesterSeedData = [
32
+ {
33
+ id: "offer-tester-sandbox-accepted",
34
+ productId: "product-beyblade-burst-valkyrie",
35
+ productTitle: "Beyblade Burst Valkyrie",
36
+ productSlug: "product-beyblade-burst-valkyrie",
37
+ storeId: "store-beyblade-arena",
38
+ storeName: "Beyblade Arena",
39
+ buyerUid: "user-tester-qa",
40
+ buyerName: "QA Tester",
41
+ buyerEmail: "tester@letitrip.in",
42
+ listedPrice: 1899,
43
+ offerAmount: 1450,
44
+ // The agreed price. Checkout MUST bill this, not `listedPrice` — that
45
+ // divergence is exactly what the paired checklist case checks.
46
+ lockedPrice: 1450,
47
+ currency: "INR",
48
+ status: OfferStatusValues.ACCEPTED,
49
+ buyerNote: "Sandbox offer — already accepted so testers can drive checkout.",
50
+ sellerNote: "Accepted for QA sandbox testing.",
51
+ expiresAt: hoursFromNow(24),
52
+ acceptedAt: hoursAgo(1),
53
+ respondedAt: hoursAgo(1),
54
+ // Well inside the 48h window so the lane is live for a whole test session.
55
+ checkoutDeadline: hoursFromNow(36),
56
+ createdAt: hoursAgo(2),
57
+ updatedAt: hoursAgo(1),
58
+ isTestData: true,
59
+ testDataExpiresAt: testDataExpiresAt(),
60
+ },
61
+ ];