@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
@@ -4,19 +4,31 @@ import { Container, Div, Heading, Main, Section, Text, TextLink } from "../../..
4
4
  import { AdSlot } from "../../homepage/components/AdSlot";
5
5
  import { ProductsIndexListing } from "./ProductsIndexListing";
6
6
  import { PRODUCT_FIELDS } from "../../../constants/field-names";
7
+ import { TABLE_KEYS } from "../../../constants/table-keys";
7
8
  import { sortBy } from "../../../constants/sort";
8
9
  import { GENERIC_PRODUCT_LISTING_TYPES } from "../constants/listing-tabs";
9
- import { listPublicProducts, parsePublicProductParams, } from "../../../_internal/server/features/products/list-public";
10
+ import { listPublicProducts, parsePublicProductParams, defaultTogglesForListingTypes, } from "../../../_internal/server/features/products/list-public";
11
+ import { parseSelectedListingTypes } from "../utils/listing-type";
10
12
  const DEFAULT_PAGE_SIZE = 24;
11
13
  const DEFAULT_SORT = sortBy(PRODUCT_FIELDS.CREATED_AT);
12
14
  export async function ProductsIndexPageView({ searchParams = {} }) {
15
+ // The "Show sold" / "Show ended" defaults depend on WHICH types are in play,
16
+ // and this page now spans all nine. Both sides derive them from the same
17
+ // helper — a hardcoded `hideSoldByDefault: true` here would disagree with
18
+ // the client the moment the user ticks Auctions, and `staleTime: Infinity`
19
+ // would freeze that disagreement (Root Cause #30).
20
+ const raw = searchParams[TABLE_KEYS.LISTING_TYPE];
21
+ const selectedTypes = parseSelectedListingTypes(Array.isArray(raw) ? raw[0] : raw);
22
+ const effectiveTypes = selectedTypes.length > 0 ? selectedTypes : GENERIC_PRODUCT_LISTING_TYPES;
23
+ const { hideSoldByDefault, hideEndedByDefault } = defaultTogglesForListingTypes(effectiveTypes);
13
24
  // See ArtStickersListView — one shared filter implementation with
14
25
  // /api/products, so SSR and the client refetch agree by construction.
15
26
  const products = await listPublicProducts(parsePublicProductParams(searchParams, {
16
27
  listingTypes: GENERIC_PRODUCT_LISTING_TYPES,
17
28
  pageSize: DEFAULT_PAGE_SIZE,
18
29
  sorts: DEFAULT_SORT,
19
- hideSoldByDefault: true,
30
+ hideSoldByDefault,
31
+ hideEndedByDefault,
20
32
  }));
21
33
  return (_jsxs(Main, { children: [_jsx(Section, { border: "bottom-subtle", paddingY: "b-md", padding: "t-xl", children: _jsxs(Container, { size: "xl", children: [_jsx(Heading, { level: 1, size: "3xl", weight: "bold", color: "primary", children: "Products" }), _jsx(Text, { className: "mt-1", color: "muted", size: "sm", children: "Discover amazing products and deals" }), _jsx(Div, { className: "mt-3", children: _jsx(TextLink, { variant: "bare", href: String(ROUTES.PUBLIC.AUCTIONS), rounded: "full", paddingX: "sm", paddingY: "2xs", size: "xs", weight: "medium", layout: "inline-flex", align: "center", gap: "sm", className: "border border-primary/30 bg-primary/10 text-primary-700 dark:text-primary-400 hover:bg-primary/15 transition-colors", children: "\uD83C\uDFF7\uFE0F Looking for unique deals? Browse Auctions \u2192" }) })] }) }), _jsxs(Container, { size: "xl", padding: "x-md", children: [_jsx(AdSlot, { id: "listing-sidebar-top", className: "mb-4 mt-4" }), _jsx(ProductsIndexListing, { initialData: products }), _jsx(AdSlot, { id: "listing-sidebar-bottom", className: "mt-8" })] })] }));
22
34
  }
@@ -0,0 +1,31 @@
1
+ import type { JsonArray } from "../../../schemas/types";
2
+ import type { ListingType } from "../types";
3
+ import type { ListingViewConfig } from "../../admin/components/DataListingView";
4
+ export interface ListingTypeListingRow {
5
+ id: string;
6
+ primary: string;
7
+ secondary: string;
8
+ status: string;
9
+ updatedAt: string;
10
+ image?: string;
11
+ }
12
+ interface ListingTypeListingResponse {
13
+ items?: JsonArray;
14
+ total?: number;
15
+ }
16
+ export interface BuildListingTypeListingOptions {
17
+ /** Override the page heading; defaults to the type's registered plural label. */
18
+ title?: string;
19
+ searchPlaceholder?: string;
20
+ emptyLabel?: string;
21
+ }
22
+ /**
23
+ * Admin browse config for one listing type.
24
+ *
25
+ * `status` is a real filter here (unlike the five hand-written copies, which
26
+ * offered none) because an admin's main reason to open a per-type list is to
27
+ * find the drafts and in-review items — exactly the rows a status filter
28
+ * surfaces.
29
+ */
30
+ export declare function buildListingTypeListingConfig(type: ListingType, opts?: BuildListingTypeListingOptions): ListingViewConfig<ListingTypeListingResponse, ListingTypeListingRow>;
31
+ export {};
@@ -0,0 +1,74 @@
1
+ /*
2
+ * WHY: Five admin views (Art, Stickers, Classified, Digital Codes, Live Items)
3
+ * were five copies of ONE config that differed only by listing type,
4
+ * title and placeholder text. Five copies is well past the Duplication
5
+ * Framework's Rule of Three, and it showed: every one carried
6
+ * `filterKeys: []` (no filter drawer at all despite filterable data) and
7
+ * its own hand-written three-option sort array, so a fix to any of it had
8
+ * to be applied five times and never was.
9
+ *
10
+ * WHAT: `buildListingTypeListingConfig(type, opts)` — one config, driven by
11
+ * the listing-type plugin registry. Title, sort set and per-type facet
12
+ * keys all come from `pluginFor(type)`, so a new listing type gets a
13
+ * working admin browse page with no new file.
14
+ *
15
+ * EXPORTS: ListingTypeListingRow, BuildListingTypeListingOptions,
16
+ * buildListingTypeListingConfig
17
+ *
18
+ * @tag domain:products
19
+ * @tag layer:config
20
+ * @tag pattern:factory
21
+ * @tag access:client
22
+ * @tag consumers:AdminArtView,AdminStickersView,AdminClassifiedView,AdminDigitalCodesView,AdminLiveView
23
+ * @tag sideEffects:none
24
+ */
25
+ import { SIEVE_OP, sieveAnd, sieveFilter } from "../../../utils/sieve-builder";
26
+ import { sortBy } from "../../../constants/sort";
27
+ import { PRODUCT_FIELDS } from "../../../constants/field-names";
28
+ import { ADMIN_ENDPOINTS } from "../../../constants/api-endpoints";
29
+ import { ROUTES } from "../../../next/routing/route-map";
30
+ import { pluginFor } from "../../../_internal/shared/listing-types/_registry";
31
+ import { toRecordArray, toRelativeDate, toCurrency, toStringValue, } from "../../admin/hooks/useAdminListingData";
32
+ /**
33
+ * Admin browse config for one listing type.
34
+ *
35
+ * `status` is a real filter here (unlike the five hand-written copies, which
36
+ * offered none) because an admin's main reason to open a per-type list is to
37
+ * find the drafts and in-review items — exactly the rows a status filter
38
+ * surfaces.
39
+ */
40
+ export function buildListingTypeListingConfig(type, opts = {}) {
41
+ const plugin = pluginFor(type);
42
+ const label = opts.title ?? plugin.pluralLabel;
43
+ return {
44
+ portal: "admin",
45
+ title: label,
46
+ searchPlaceholder: opts.searchPlaceholder ?? `Search ${label.toLowerCase()} by name or seller`,
47
+ emptyLabel: opts.emptyLabel ?? `No ${label.toLowerCase()} listings`,
48
+ filterKeys: ["status"],
49
+ defaultSort: sortBy(PRODUCT_FIELDS.CREATED_AT),
50
+ // Keyed on the canonical type so two types can never share a cache entry.
51
+ queryKey: ["admin", "listing-type", type],
52
+ endpoint: ADMIN_ENDPOINTS.PRODUCTS,
53
+ // The type's own sort set, not a copy-pasted three-option array.
54
+ sortOptions: [...plugin.sortOptions],
55
+ mapRows: (response) => toRecordArray(response.items).map((item, index) => ({
56
+ id: toStringValue(item.id, `${type}-${index}`),
57
+ primary: toStringValue(item.title ?? item.productTitle, "Untitled listing"),
58
+ secondary: [
59
+ toStringValue(item.sellerName, "Unknown seller"),
60
+ toCurrency(item.price),
61
+ ].join(" · "),
62
+ status: toStringValue(item.status, "draft"),
63
+ updatedAt: toRelativeDate(item.updatedAt ?? item.createdAt),
64
+ image: toStringValue(item.mainImage, "") || undefined,
65
+ })),
66
+ getTotal: (response, mappedRows) => typeof response.total === "number" ? response.total : mappedRows.length,
67
+ buildFilters: (state) => sieveAnd(sieveFilter(PRODUCT_FIELDS.LISTING_TYPE, SIEVE_OP.EQ, type), state.status && state.status !== "All"
68
+ ? sieveFilter(PRODUCT_FIELDS.STATUS, SIEVE_OP.EQ, state.status)
69
+ : "") || undefined,
70
+ // These are products filtered by listingType — reuse the real admin
71
+ // product editor rather than leaving rows non-navigable.
72
+ rowHrefTemplate: String(ROUTES.ADMIN.PRODUCTS_EDIT("{id}")),
73
+ };
74
+ }
@@ -6,16 +6,20 @@
6
6
  * filter on the `products` collection or to a separate collection
7
7
  * (currently only `bundles`).
8
8
  *
9
- * Add new tab variants here never inline the tab list inside the view.
9
+ * DERIVED, NOT HAND-WRITTEN (2026-08-21). Every array below is built from
10
+ * `ALL_LISTING_TYPES` + the listing-type plugin registry, so a new listing
11
+ * type appears on every tab bar automatically. They used to be nine separate
12
+ * hand-maintained literals and had drifted badly: `/products` offered only 4
13
+ * of 9 types (missing auctions, pre-orders, prize draws, art, stickers — the
14
+ * bug that started this sweep), the admin type chips used display LABELS as
15
+ * Sieve filter ids, and several arrays still listed `bundle`, which stopped
16
+ * being a listingType in SB-UNI-D. `scripts/audit-listing-type-tab-coverage.mjs`
17
+ * blocks any regression.
18
+ *
19
+ * To add a tab that ISN'T a listing type (bundles, stores), append it to the
20
+ * relevant array explicitly — those are genuinely different collections.
10
21
  */
11
22
  import type { ListingType } from "../types";
12
- /**
13
- * The consolidated generic `/products` browse tab covers these 4 listing
14
- * types (auctions/pre-orders/bundles/prize-draws/art+stickers each have
15
- * their own dedicated public page). Shared between the server-rendered
16
- * page view and the client listing component so they can't drift apart.
17
- */
18
- export declare const GENERIC_PRODUCT_LISTING_TYPES: readonly ["standard", "classified", "digital-code", "live"];
19
23
  export interface ListingTab {
20
24
  id: string;
21
25
  label: string;
@@ -28,197 +32,38 @@ export interface ListingTab {
28
32
  /** Set when the tab queries a non-product entity (e.g. `stores`). */
29
33
  entity?: "stores";
30
34
  }
35
+ /**
36
+ * The generic `/products` browse page spans EVERY listing type (2026-08-21).
37
+ *
38
+ * It used to span only `standard|classified|digital-code|live` on the theory
39
+ * that auctions/pre-orders/prize-draws/art each had a dedicated page — but
40
+ * that made five of nine types unreachable from the main catalogue, broke
41
+ * seven legacy `/search/.../tab/<type>` permanent redirects that all point at
42
+ * `/products`, and made the cross-type Compare + bulk-cart features (which
43
+ * only exist on this page) unusable for those types. The dedicated pages
44
+ * remain, and `/products` links to them when a single time-boxed type is
45
+ * selected.
46
+ */
47
+ export declare const GENERIC_PRODUCT_LISTING_TYPES: readonly ListingType[];
48
+ /** The listing types the combined `/art` page spans. */
49
+ export declare const ART_STICKERS_LISTING_TYPES: readonly ListingType[];
31
50
  /** Tabs shown on `/categories/[slug]` and `/brands/[slug]` detail pages. */
32
- export declare const CATEGORY_PAGE_TABS: readonly [{
33
- readonly id: "products";
34
- readonly label: "Products";
35
- readonly listingType: "standard";
36
- }, {
37
- readonly id: "auctions";
38
- readonly label: "Auctions";
39
- readonly listingType: "auction";
40
- }, {
41
- readonly id: "pre-orders";
42
- readonly label: "Pre-Orders";
43
- readonly listingType: "pre-order";
44
- }, {
45
- readonly id: "prize-draws";
46
- readonly label: "Prize Draws";
47
- readonly listingType: "prize-draw";
48
- }, {
49
- readonly id: "bundles";
50
- readonly label: "Bundles";
51
- readonly collection: "bundles";
52
- }, {
53
- readonly id: "classifieds";
54
- readonly label: "Classifieds";
55
- readonly listingType: "classified";
56
- }, {
57
- readonly id: "digital-codes";
58
- readonly label: "Digital Codes";
59
- readonly listingType: "digital-code";
60
- }, {
61
- readonly id: "live";
62
- readonly label: "Live Items";
63
- readonly listingType: "live";
64
- }, {
65
- readonly id: "art";
66
- readonly label: "Art & Stickers";
67
- readonly listingType: "art|stickers";
68
- }, {
69
- readonly id: "stores";
70
- readonly label: "Stores";
71
- readonly entity: "stores";
72
- }];
73
- export type CategoryTabId = (typeof CATEGORY_PAGE_TABS)[number]["id"];
51
+ export declare const CATEGORY_PAGE_TABS: readonly ListingTab[];
52
+ export type CategoryTabId = string;
74
53
  /** Tabs shown on the public `/stores/[slug]` nav bar. */
75
- export declare const STORE_PAGE_TABS: readonly [{
76
- readonly id: "products";
77
- readonly label: "Products";
78
- readonly listingType: "standard";
79
- }, {
80
- readonly id: "auctions";
81
- readonly label: "Auctions";
82
- readonly listingType: "auction";
83
- }, {
84
- readonly id: "pre-orders";
85
- readonly label: "Pre-Orders";
86
- readonly listingType: "pre-order";
87
- }, {
88
- readonly id: "prize-draws";
89
- readonly label: "Prize Draws";
90
- readonly listingType: "prize-draw";
91
- }, {
92
- readonly id: "bundles";
93
- readonly label: "Bundles";
94
- readonly collection: "bundles";
95
- }, {
96
- readonly id: "classifieds";
97
- readonly label: "Classifieds";
98
- readonly listingType: "classified";
99
- }, {
100
- readonly id: "digital-codes";
101
- readonly label: "Digital Codes";
102
- readonly listingType: "digital-code";
103
- }, {
104
- readonly id: "live";
105
- readonly label: "Live Items";
106
- readonly listingType: "live";
107
- }, {
108
- readonly id: "art";
109
- readonly label: "Art & Stickers";
110
- readonly listingType: "art|stickers";
111
- }];
112
- export type StoreTabId = (typeof STORE_PAGE_TABS)[number]["id"];
54
+ export declare const STORE_PAGE_TABS: readonly ListingTab[];
55
+ export type StoreTabId = string;
113
56
  /** Tabs shown on the seller-dashboard listings view + admin products list. */
114
- export declare const SELLER_LISTING_TABS: readonly [{
115
- readonly id: "all";
116
- readonly label: "All";
117
- }, {
118
- readonly id: "products";
119
- readonly label: "Products";
120
- readonly listingType: "standard";
121
- }, {
122
- readonly id: "auctions";
123
- readonly label: "Auctions";
124
- readonly listingType: "auction";
125
- }, {
126
- readonly id: "pre-orders";
127
- readonly label: "Pre-Orders";
128
- readonly listingType: "pre-order";
129
- }, {
130
- readonly id: "prize-draws";
131
- readonly label: "Prize Draws";
132
- readonly listingType: "prize-draw";
133
- }, {
134
- readonly id: "classifieds";
135
- readonly label: "Classifieds";
136
- readonly listingType: "classified";
137
- }, {
138
- readonly id: "digital-codes";
139
- readonly label: "Digital Codes";
140
- readonly listingType: "digital-code";
141
- }, {
142
- readonly id: "live";
143
- readonly label: "Live Items";
144
- readonly listingType: "live";
145
- }, {
146
- readonly id: "art";
147
- readonly label: "Art";
148
- readonly listingType: "art";
149
- }, {
150
- readonly id: "stickers";
151
- readonly label: "Stickers";
152
- readonly listingType: "stickers";
153
- }];
154
- export type SellerListingTabId = (typeof SELLER_LISTING_TABS)[number]["id"];
155
- /** Tabs shown on `/search` results. */
156
- export declare const SEARCH_RESULT_TABS: readonly [{
157
- readonly id: "all";
158
- readonly label: "All";
159
- }, {
160
- readonly id: "products";
161
- readonly label: "Products";
162
- readonly listingType: "standard";
163
- }, {
164
- readonly id: "auctions";
165
- readonly label: "Auctions";
166
- readonly listingType: "auction";
167
- }, {
168
- readonly id: "pre-orders";
169
- readonly label: "Pre-Orders";
170
- readonly listingType: "pre-order";
171
- }, {
172
- readonly id: "prize-draws";
173
- readonly label: "Prize Draws";
174
- readonly listingType: "prize-draw";
175
- }, {
176
- readonly id: "bundles";
177
- readonly label: "Bundles";
178
- readonly collection: "bundles";
179
- }, {
180
- readonly id: "classifieds";
181
- readonly label: "Classifieds";
182
- readonly listingType: "classified";
183
- }, {
184
- readonly id: "digital-codes";
185
- readonly label: "Digital Codes";
186
- readonly listingType: "digital-code";
187
- }, {
188
- readonly id: "live";
189
- readonly label: "Live Items";
190
- readonly listingType: "live";
191
- }, {
192
- readonly id: "art";
193
- readonly label: "Art & Stickers";
194
- readonly listingType: "art|stickers";
195
- }];
196
- export type SearchTabId = (typeof SEARCH_RESULT_TABS)[number]["id"];
197
- /** In-page type-filter chips on the generic `/products` browse page. */
198
- export declare const PRODUCT_TYPE_FILTER_TABS: readonly [{
199
- readonly id: "All";
200
- readonly label: "All";
201
- }, {
202
- readonly id: "standard";
203
- readonly label: "Standard";
204
- }, {
205
- readonly id: "classified";
206
- readonly label: "Classified";
207
- }, {
208
- readonly id: "digital-code";
209
- readonly label: "Digital Codes";
210
- }, {
211
- readonly id: "live";
212
- readonly label: "Live Items";
213
- }];
57
+ export declare const SELLER_LISTING_TABS: readonly ListingTab[];
58
+ export type SellerListingTabId = string;
59
+ /**
60
+ * In-page type-filter chips on the generic `/products` browse page.
61
+ *
62
+ * Multi-select (checkbox semantics) — no "All" sentinel chip, because "none
63
+ * checked" already means "every type". A sentinel would be a second way to
64
+ * express the same state and would have to be cleared whenever a real chip
65
+ * was ticked.
66
+ */
67
+ export declare const PRODUCT_TYPE_FILTER_TABS: readonly ListingTab[];
214
68
  /** In-page type-filter chips on the combined `/art` (Art & Stickers) page. */
215
- export declare const ART_STICKERS_TYPE_FILTER_TABS: readonly [{
216
- readonly id: "All";
217
- readonly label: "All";
218
- }, {
219
- readonly id: "art";
220
- readonly label: "Art";
221
- }, {
222
- readonly id: "stickers";
223
- readonly label: "Stickers";
224
- }];
69
+ export declare const ART_STICKERS_TYPE_FILTER_TABS: readonly ListingTab[];
@@ -6,78 +6,91 @@
6
6
  * filter on the `products` collection or to a separate collection
7
7
  * (currently only `bundles`).
8
8
  *
9
- * Add new tab variants here never inline the tab list inside the view.
9
+ * DERIVED, NOT HAND-WRITTEN (2026-08-21). Every array below is built from
10
+ * `ALL_LISTING_TYPES` + the listing-type plugin registry, so a new listing
11
+ * type appears on every tab bar automatically. They used to be nine separate
12
+ * hand-maintained literals and had drifted badly: `/products` offered only 4
13
+ * of 9 types (missing auctions, pre-orders, prize draws, art, stickers — the
14
+ * bug that started this sweep), the admin type chips used display LABELS as
15
+ * Sieve filter ids, and several arrays still listed `bundle`, which stopped
16
+ * being a listingType in SB-UNI-D. `scripts/audit-listing-type-tab-coverage.mjs`
17
+ * blocks any regression.
18
+ *
19
+ * To add a tab that ISN'T a listing type (bundles, stores), append it to the
20
+ * relevant array explicitly — those are genuinely different collections.
21
+ */
22
+ import { ALL_LISTING_TYPES } from "../../../_internal/shared/listing-types/feature-flags";
23
+ import { pluginFor } from "../../../_internal/shared/listing-types/_registry";
24
+ /**
25
+ * The generic `/products` browse page spans EVERY listing type (2026-08-21).
26
+ *
27
+ * It used to span only `standard|classified|digital-code|live` on the theory
28
+ * that auctions/pre-orders/prize-draws/art each had a dedicated page — but
29
+ * that made five of nine types unreachable from the main catalogue, broke
30
+ * seven legacy `/search/.../tab/<type>` permanent redirects that all point at
31
+ * `/products`, and made the cross-type Compare + bulk-cart features (which
32
+ * only exist on this page) unusable for those types. The dedicated pages
33
+ * remain, and `/products` links to them when a single time-boxed type is
34
+ * selected.
35
+ */
36
+ export const GENERIC_PRODUCT_LISTING_TYPES = ALL_LISTING_TYPES;
37
+ /** The listing types the combined `/art` page spans. */
38
+ export const ART_STICKERS_LISTING_TYPES = ["art", "stickers"];
39
+ /**
40
+ * A FILTER chip — `id` is the canonical `listingType`, because it is passed
41
+ * straight into `sieveFilter("listingType", EQ, id)`. Never a display label.
42
+ */
43
+ function chipTab(type) {
44
+ return { id: type, label: pluginFor(type).chipLabel, listingType: type };
45
+ }
46
+ /**
47
+ * A ROUTE-BACKED tab — `id` is the plugin's `tabSlug`, because it doubles as
48
+ * the URL segment (`/stores/{slug}/pre-orders`) and is live in bookmarks.
49
+ * The canonical type still rides along in `listingType` for the query.
10
50
  */
51
+ function pluralTab(type) {
52
+ const plugin = pluginFor(type);
53
+ return { id: plugin.tabSlug, label: plugin.pluralLabel, listingType: type };
54
+ }
11
55
  /**
12
- * The consolidated generic `/products` browse tab covers these 4 listing
13
- * types (auctions/pre-orders/bundles/prize-draws/art+stickers each have
14
- * their own dedicated public page). Shared between the server-rendered
15
- * page view and the client listing component so they can't drift apart.
56
+ * Art and stickers share the combined `/art` browse page, so category/brand/
57
+ * store tab bars show them as ONE tab backed by a two-value OR-group. Derived
58
+ * from both plugins rather than a hardcoded `"art|stickers"` string so the
59
+ * pipe-group can't drift from the registry.
16
60
  */
17
- export const GENERIC_PRODUCT_LISTING_TYPES = ["standard", "classified", "digital-code", "live"];
61
+ const ART_STICKERS_COMBINED_TAB = {
62
+ id: pluginFor("art").tabSlug,
63
+ label: `${pluginFor("art").pluralLabel} & ${pluginFor("stickers").pluralLabel}`,
64
+ listingType: ART_STICKERS_LISTING_TYPES.join("|"),
65
+ };
66
+ /** Listing types that get their own tab on a combined surface (art+stickers merge into one). */
67
+ const SEPARATELY_TABBED_TYPES = ALL_LISTING_TYPES.filter((t) => t !== "art" && t !== "stickers");
18
68
  /** Tabs shown on `/categories/[slug]` and `/brands/[slug]` detail pages. */
19
69
  export const CATEGORY_PAGE_TABS = [
20
- { id: "products", label: "Products", listingType: "standard" },
21
- { id: "auctions", label: "Auctions", listingType: "auction" },
22
- { id: "pre-orders", label: "Pre-Orders", listingType: "pre-order" },
23
- { id: "prize-draws", label: "Prize Draws", listingType: "prize-draw" },
70
+ ...SEPARATELY_TABBED_TYPES.map(pluralTab),
24
71
  { id: "bundles", label: "Bundles", collection: "bundles" },
25
- { id: "classifieds", label: "Classifieds", listingType: "classified" },
26
- { id: "digital-codes", label: "Digital Codes", listingType: "digital-code" },
27
- { id: "live", label: "Live Items", listingType: "live" },
28
- // Combined — one public browse page (`/art`) spans both listing types.
29
- { id: "art", label: "Art & Stickers", listingType: "art|stickers" },
72
+ ART_STICKERS_COMBINED_TAB,
30
73
  { id: "stores", label: "Stores", entity: "stores" },
31
74
  ];
32
75
  /** Tabs shown on the public `/stores/[slug]` nav bar. */
33
76
  export const STORE_PAGE_TABS = [
34
- { id: "products", label: "Products", listingType: "standard" },
35
- { id: "auctions", label: "Auctions", listingType: "auction" },
36
- { id: "pre-orders", label: "Pre-Orders", listingType: "pre-order" },
37
- { id: "prize-draws", label: "Prize Draws", listingType: "prize-draw" },
77
+ ...SEPARATELY_TABBED_TYPES.map(pluralTab),
38
78
  { id: "bundles", label: "Bundles", collection: "bundles" },
39
- { id: "classifieds", label: "Classifieds", listingType: "classified" },
40
- { id: "digital-codes", label: "Digital Codes", listingType: "digital-code" },
41
- { id: "live", label: "Live Items", listingType: "live" },
42
- { id: "art", label: "Art & Stickers", listingType: "art|stickers" },
79
+ ART_STICKERS_COMBINED_TAB,
43
80
  ];
44
81
  /** Tabs shown on the seller-dashboard listings view + admin products list. */
45
82
  export const SELLER_LISTING_TABS = [
46
83
  { id: "all", label: "All" },
47
- { id: "products", label: "Products", listingType: "standard" },
48
- { id: "auctions", label: "Auctions", listingType: "auction" },
49
- { id: "pre-orders", label: "Pre-Orders", listingType: "pre-order" },
50
- { id: "prize-draws", label: "Prize Draws", listingType: "prize-draw" },
51
- { id: "classifieds", label: "Classifieds", listingType: "classified" },
52
- { id: "digital-codes", label: "Digital Codes", listingType: "digital-code" },
53
- { id: "live", label: "Live Items", listingType: "live" },
54
- { id: "art", label: "Art", listingType: "art" },
55
- { id: "stickers", label: "Stickers", listingType: "stickers" },
56
- ];
57
- /** Tabs shown on `/search` results. */
58
- export const SEARCH_RESULT_TABS = [
59
- { id: "all", label: "All" },
60
- { id: "products", label: "Products", listingType: "standard" },
61
- { id: "auctions", label: "Auctions", listingType: "auction" },
62
- { id: "pre-orders", label: "Pre-Orders", listingType: "pre-order" },
63
- { id: "prize-draws", label: "Prize Draws", listingType: "prize-draw" },
64
- { id: "bundles", label: "Bundles", collection: "bundles" },
65
- { id: "classifieds", label: "Classifieds", listingType: "classified" },
66
- { id: "digital-codes", label: "Digital Codes", listingType: "digital-code" },
67
- { id: "live", label: "Live Items", listingType: "live" },
68
- { id: "art", label: "Art & Stickers", listingType: "art|stickers" },
69
- ];
70
- /** In-page type-filter chips on the generic `/products` browse page. */
71
- export const PRODUCT_TYPE_FILTER_TABS = [
72
- { id: "All", label: "All" },
73
- { id: "standard", label: "Standard" },
74
- { id: "classified", label: "Classified" },
75
- { id: "digital-code", label: "Digital Codes" },
76
- { id: "live", label: "Live Items" },
84
+ ...ALL_LISTING_TYPES.map(pluralTab),
77
85
  ];
86
+ /**
87
+ * In-page type-filter chips on the generic `/products` browse page.
88
+ *
89
+ * Multi-select (checkbox semantics) — no "All" sentinel chip, because "none
90
+ * checked" already means "every type". A sentinel would be a second way to
91
+ * express the same state and would have to be cleared whenever a real chip
92
+ * was ticked.
93
+ */
94
+ export const PRODUCT_TYPE_FILTER_TABS = ALL_LISTING_TYPES.map(chipTab);
78
95
  /** In-page type-filter chips on the combined `/art` (Art & Stickers) page. */
79
- export const ART_STICKERS_TYPE_FILTER_TABS = [
80
- { id: "All", label: "All" },
81
- { id: "art", label: "Art" },
82
- { id: "stickers", label: "Stickers" },
83
- ];
96
+ export const ART_STICKERS_TYPE_FILTER_TABS = ART_STICKERS_LISTING_TYPES.map(chipTab);
@@ -141,6 +141,90 @@ export declare const PREORDER_SORT_OPTIONS: readonly [{
141
141
  readonly value: string;
142
142
  readonly label: "Lowest Deposit First";
143
143
  }];
144
+ /**
145
+ * Public pre-order browse subset. Drops "Lowest Deposit First" — deposit
146
+ * amount is a seller-side pricing lever buyers don't shop by — but keeps
147
+ * both delivery-date directions, which are the primary browse intent.
148
+ */
149
+ export declare const PREORDER_PUBLIC_SORT_OPTIONS: readonly [{
150
+ readonly value: string;
151
+ readonly label: "Earliest Delivery";
152
+ }, {
153
+ readonly value: string;
154
+ readonly label: "Latest Delivery";
155
+ }, {
156
+ readonly value: string;
157
+ readonly label: "Newest First";
158
+ } | {
159
+ readonly value: string;
160
+ readonly label: "Oldest First";
161
+ } | {
162
+ readonly value: string;
163
+ readonly label: "Price: Low to High";
164
+ } | {
165
+ readonly value: string;
166
+ readonly label: "Price: High to Low";
167
+ } | {
168
+ readonly value: string;
169
+ readonly label: "Fewest Slots Left";
170
+ } | {
171
+ readonly value: string;
172
+ readonly label: "Lowest Deposit First";
173
+ }, {
174
+ readonly value: string;
175
+ readonly label: "Newest First";
176
+ } | {
177
+ readonly value: string;
178
+ readonly label: "Oldest First";
179
+ } | {
180
+ readonly value: string;
181
+ readonly label: "Price: Low to High";
182
+ } | {
183
+ readonly value: string;
184
+ readonly label: "Price: High to Low";
185
+ } | {
186
+ readonly value: string;
187
+ readonly label: "Fewest Slots Left";
188
+ } | {
189
+ readonly value: string;
190
+ readonly label: "Lowest Deposit First";
191
+ }, {
192
+ readonly value: string;
193
+ readonly label: "Newest First";
194
+ } | {
195
+ readonly value: string;
196
+ readonly label: "Oldest First";
197
+ } | {
198
+ readonly value: string;
199
+ readonly label: "Price: Low to High";
200
+ } | {
201
+ readonly value: string;
202
+ readonly label: "Price: High to Low";
203
+ } | {
204
+ readonly value: string;
205
+ readonly label: "Fewest Slots Left";
206
+ } | {
207
+ readonly value: string;
208
+ readonly label: "Lowest Deposit First";
209
+ }, {
210
+ readonly value: string;
211
+ readonly label: "Newest First";
212
+ } | {
213
+ readonly value: string;
214
+ readonly label: "Oldest First";
215
+ } | {
216
+ readonly value: string;
217
+ readonly label: "Price: Low to High";
218
+ } | {
219
+ readonly value: string;
220
+ readonly label: "Price: High to Low";
221
+ } | {
222
+ readonly value: string;
223
+ readonly label: "Fewest Slots Left";
224
+ } | {
225
+ readonly value: string;
226
+ readonly label: "Lowest Deposit First";
227
+ }];
144
228
  export declare const BUNDLE_SORT_OPTIONS: readonly [...({
145
229
  readonly value: string;
146
230
  readonly label: "Newest First";
@@ -173,4 +257,23 @@ export declare const PRIZE_DRAW_SORT_OPTIONS: readonly [{
173
257
  readonly value: string;
174
258
  readonly label: "Entry: High to Low";
175
259
  }];
176
- export declare const SORT_OPTIONS_BY_LISTING_TYPE: Record<string, readonly SortOption[]>;
260
+ /** Public prize-draw browse subset every option is buyer-meaningful. */
261
+ export declare const PRIZE_DRAW_PUBLIC_SORT_OPTIONS: readonly [{
262
+ readonly value: string;
263
+ readonly label: "Newest First";
264
+ }, {
265
+ readonly value: string;
266
+ readonly label: "Oldest First";
267
+ }, {
268
+ readonly value: string;
269
+ readonly label: "Reveal: Soonest";
270
+ }, {
271
+ readonly value: string;
272
+ readonly label: "Reveal: Furthest";
273
+ }, {
274
+ readonly value: string;
275
+ readonly label: "Entry: Low to High";
276
+ }, {
277
+ readonly value: string;
278
+ readonly label: "Entry: High to Low";
279
+ }];