@mohasinac/appkit 2.7.11 → 2.7.12

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 (141) hide show
  1. package/dist/_internal/server/jobs/core/assignSpinPrize.js +8 -7
  2. package/dist/_internal/server/jobs/core/bundleStockSync.js +11 -6
  3. package/dist/_internal/server/jobs/core/countersReconcile.js +3 -2
  4. package/dist/_internal/server/jobs/core/onProductStockChange.js +12 -7
  5. package/dist/_internal/server/jobs/core/onProductWrite.js +3 -2
  6. package/dist/_internal/server/jobs/core/prizeRevealClose.js +7 -5
  7. package/dist/_internal/server/jobs/core/prizeRevealExpiry.js +11 -6
  8. package/dist/_internal/server/jobs/core/prizeRevealOpen.js +13 -7
  9. package/dist/_internal/server/jobs/core/prizeRevealReminder.js +9 -4
  10. package/dist/_internal/server/jobs/core/triggerEventRaffle.js +3 -2
  11. package/dist/_internal/shared/features/blog/schema.d.ts +4 -4
  12. package/dist/_internal/shared/features/categories/bundle-schemas.d.ts +32 -32
  13. package/dist/_internal/shared/features/events/schema.d.ts +4 -4
  14. package/dist/_internal/shared/features/products/schema.d.ts +20 -20
  15. package/dist/_internal/shared/features/promotions/schema.d.ts +2 -2
  16. package/dist/_internal/shared/features/reviews/schema.d.ts +1 -1
  17. package/dist/constants/field-names.d.ts +813 -0
  18. package/dist/constants/field-names.js +918 -0
  19. package/dist/constants/sort.d.ts +7 -0
  20. package/dist/constants/sort.js +5 -0
  21. package/dist/constants/table-keys.d.ts +48 -0
  22. package/dist/constants/table-keys.js +46 -0
  23. package/dist/features/account/components/AddressesIndexListing.js +9 -6
  24. package/dist/features/admin/components/AdminAllEventEntriesView.js +4 -1
  25. package/dist/features/admin/components/AdminBidsView.js +4 -1
  26. package/dist/features/admin/components/AdminBlogView.js +9 -2
  27. package/dist/features/admin/components/AdminBrandsView.js +9 -2
  28. package/dist/features/admin/components/AdminCarouselView.js +4 -1
  29. package/dist/features/admin/components/AdminCartsView.js +4 -1
  30. package/dist/features/admin/components/AdminCategoriesView.js +9 -2
  31. package/dist/features/admin/components/AdminContactView.js +4 -1
  32. package/dist/features/admin/components/AdminCouponsView.js +4 -1
  33. package/dist/features/admin/components/AdminFaqsView.js +5 -1
  34. package/dist/features/admin/components/AdminFeaturesView.js +5 -2
  35. package/dist/features/admin/components/AdminHistoryView.js +5 -1
  36. package/dist/features/admin/components/AdminNewsletterView.js +4 -1
  37. package/dist/features/admin/components/AdminNotificationsView.js +4 -1
  38. package/dist/features/admin/components/AdminOrdersView.js +14 -12
  39. package/dist/features/admin/components/AdminPayoutsView.js +4 -1
  40. package/dist/features/admin/components/AdminPrizeDrawsView.js +4 -1
  41. package/dist/features/admin/components/AdminProductsView.js +14 -3
  42. package/dist/features/admin/components/AdminReturnRequestsView.js +4 -1
  43. package/dist/features/admin/components/AdminReviewsView.js +4 -1
  44. package/dist/features/admin/components/AdminScammersView.js +4 -1
  45. package/dist/features/admin/components/AdminSessionsView.js +4 -1
  46. package/dist/features/admin/components/AdminStoreAddressesView.js +5 -1
  47. package/dist/features/admin/components/AdminStoresView.js +10 -3
  48. package/dist/features/admin/components/AdminSublistingCategoriesView.js +4 -1
  49. package/dist/features/admin/components/AdminSupportTicketsView.js +4 -1
  50. package/dist/features/admin/components/AdminTeamView.js +4 -1
  51. package/dist/features/admin/components/AdminUsersView.js +9 -12
  52. package/dist/features/admin/components/AdminViewCards.d.ts +12 -0
  53. package/dist/features/admin/components/AdminViewCards.js +53 -0
  54. package/dist/features/admin/components/AdminWishlistsView.js +4 -1
  55. package/dist/features/auctions/repository/bid.repository.js +1 -6
  56. package/dist/features/auctions/schemas/index.d.ts +4 -4
  57. package/dist/features/blog/actions/blog-actions.d.ts +16 -16
  58. package/dist/features/blog/components/BlogFilters.d.ts +28 -28
  59. package/dist/features/blog/components/BlogFilters.js +18 -15
  60. package/dist/features/blog/components/BlogIndexListing.js +20 -16
  61. package/dist/features/blog/schemas/index.d.ts +10 -10
  62. package/dist/features/categories/components/CategoriesIndexListing.js +25 -21
  63. package/dist/features/categories/schemas/index.d.ts +2 -2
  64. package/dist/features/events/components/AdminEventsView.js +5 -1
  65. package/dist/features/events/components/EventFilters.d.ts +24 -24
  66. package/dist/features/events/components/EventFilters.js +16 -13
  67. package/dist/features/events/components/EventStatusBadge.js +1 -0
  68. package/dist/features/events/components/EventsIndexListing.js +31 -26
  69. package/dist/features/events/components/EventsListPageView.js +13 -10
  70. package/dist/features/events/schemas/firestore.d.ts +1 -0
  71. package/dist/features/events/schemas/firestore.js +1 -0
  72. package/dist/features/events/schemas/index.d.ts +1 -1
  73. package/dist/features/events/types/index.d.ts +1 -1
  74. package/dist/features/faq/actions/faq-actions.d.ts +10 -10
  75. package/dist/features/faq/schemas/index.d.ts +4 -4
  76. package/dist/features/orders/components/OrderFilters.d.ts +20 -20
  77. package/dist/features/orders/components/OrderFilters.js +33 -30
  78. package/dist/features/orders/repository/orders.repository.js +1 -15
  79. package/dist/features/orders/schemas/index.d.ts +2 -2
  80. package/dist/features/pre-orders/components/PreOrdersIndexListing.js +35 -31
  81. package/dist/features/pre-orders/schemas/index.d.ts +3 -3
  82. package/dist/features/products/components/AuctionsIndexListing.js +34 -30
  83. package/dist/features/products/components/BidHistory.d.ts +0 -1
  84. package/dist/features/products/components/BidHistory.js +1 -1
  85. package/dist/features/products/components/PrizeDrawsIndexListing.js +44 -40
  86. package/dist/features/products/components/ProductDetailPageView.js +1 -1
  87. package/dist/features/products/components/ProductFilters.d.ts +20 -20
  88. package/dist/features/products/components/ProductFilters.js +62 -59
  89. package/dist/features/products/components/ProductsIndexListing.js +28 -24
  90. package/dist/features/products/components/ProductsIndexPageView.js +18 -10
  91. package/dist/features/products/hooks/useProducts.js +2 -0
  92. package/dist/features/products/repository/products.repository.js +2 -22
  93. package/dist/features/products/schemas/index.d.ts +28 -28
  94. package/dist/features/products/schemas/product-features.validators.d.ts +12 -12
  95. package/dist/features/products/types/index.d.ts +2 -0
  96. package/dist/features/promotions/components/CouponsIndexListing.js +21 -17
  97. package/dist/features/promotions/schemas/index.d.ts +4 -4
  98. package/dist/features/reviews/components/ReviewDetailShell.js +6 -5
  99. package/dist/features/reviews/components/ReviewFilters.d.ts +16 -16
  100. package/dist/features/reviews/components/ReviewFilters.js +10 -7
  101. package/dist/features/reviews/components/ReviewsIndexListing.js +21 -17
  102. package/dist/features/reviews/components/ReviewsList.d.ts +5 -2
  103. package/dist/features/reviews/components/ReviewsList.js +11 -5
  104. package/dist/features/reviews/schemas/firestore.d.ts +1 -0
  105. package/dist/features/reviews/schemas/index.d.ts +8 -8
  106. package/dist/features/reviews/types/index.d.ts +1 -0
  107. package/dist/features/search/schemas/index.d.ts +2 -2
  108. package/dist/features/seller/components/SellerAuctionsView.js +5 -1
  109. package/dist/features/seller/components/SellerBidsView.js +4 -1
  110. package/dist/features/seller/components/SellerCouponsView.js +4 -1
  111. package/dist/features/seller/components/SellerOffersView.js +5 -1
  112. package/dist/features/seller/components/SellerOrdersView.js +4 -1
  113. package/dist/features/seller/components/SellerPayoutsView.js +5 -1
  114. package/dist/features/seller/components/SellerPreOrdersView.js +4 -1
  115. package/dist/features/seller/components/SellerPrizeDrawsView.js +4 -1
  116. package/dist/features/seller/components/SellerProductsView.js +4 -1
  117. package/dist/features/seller/schemas/index.d.ts +10 -10
  118. package/dist/features/stores/api/route.js +10 -1
  119. package/dist/features/stores/components/StoreReviewsListing.js +1 -1
  120. package/dist/features/stores/components/StoresIndexListing.js +24 -20
  121. package/dist/features/stores/schemas/firestore.d.ts +1 -0
  122. package/dist/features/stores/schemas/index.d.ts +4 -4
  123. package/dist/index.d.ts +8 -1
  124. package/dist/index.js +12 -1
  125. package/dist/react/hooks/useUrlTable.js +2 -1
  126. package/dist/seed/bids-seed-data.js +45 -44
  127. package/dist/seed/categories-seed-data.js +41 -40
  128. package/dist/seed/coupons-seed-data.js +41 -40
  129. package/dist/seed/products-auctions-seed-data.js +54 -53
  130. package/dist/seed/products-preorders-seed-data.js +25 -24
  131. package/dist/seed/products-prize-draws-seed-data.js +24 -23
  132. package/dist/seed/products-standard-seed-data.js +294 -293
  133. package/dist/seed/reviews-seed-data.js +61 -60
  134. package/dist/seed/scammers-seed-data.js +3 -2
  135. package/dist/seed/stores-seed-data.js +9 -8
  136. package/dist/seed/support-tickets-seed-data.js +13 -12
  137. package/dist/seed/users-seed-data.js +28 -27
  138. package/dist/tailwind-utilities.css +1 -1
  139. package/dist/utils/sieve-builder.d.ts +41 -0
  140. package/dist/utils/sieve-builder.js +66 -0
  141. package/package.json +1 -1
@@ -5,60 +5,63 @@ import { FilterFacetSection } from "../../filters/FilterFacetSection";
5
5
  import { RangeFilter } from "../../filters/RangeFilter";
6
6
  import { SwitchFilter } from "../../filters/SwitchFilter";
7
7
  import { Div } from "../../../ui";
8
+ import { TABLE_KEYS } from "../../../constants/table-keys";
9
+ import { PRODUCT_FIELDS } from "../../../constants/field-names";
10
+ import { sortBy } from "../../../constants/sort";
8
11
  export const PRODUCT_FILTER_KEYS = {
9
12
  admin: [
10
- "category",
11
- "condition",
12
- "minPrice",
13
- "maxPrice",
14
- "brand",
15
- "seller",
16
- "tags",
17
- "status",
13
+ TABLE_KEYS.CATEGORY,
14
+ TABLE_KEYS.CONDITION,
15
+ TABLE_KEYS.MIN_PRICE,
16
+ TABLE_KEYS.MAX_PRICE,
17
+ TABLE_KEYS.BRAND,
18
+ TABLE_KEYS.SELLER,
19
+ TABLE_KEYS.TAGS,
20
+ TABLE_KEYS.STATUS,
18
21
  ],
19
22
  seller: [
20
- "category",
21
- "condition",
22
- "minPrice",
23
- "maxPrice",
24
- "brand",
25
- "tags",
26
- "status",
23
+ TABLE_KEYS.CATEGORY,
24
+ TABLE_KEYS.CONDITION,
25
+ TABLE_KEYS.MIN_PRICE,
26
+ TABLE_KEYS.MAX_PRICE,
27
+ TABLE_KEYS.BRAND,
28
+ TABLE_KEYS.TAGS,
29
+ TABLE_KEYS.STATUS,
27
30
  ],
28
31
  public: [
29
- "category",
30
- "condition",
31
- "minPrice",
32
- "maxPrice",
33
- "brand",
34
- "seller",
35
- "tags",
32
+ TABLE_KEYS.CATEGORY,
33
+ TABLE_KEYS.CONDITION,
34
+ TABLE_KEYS.MIN_PRICE,
35
+ TABLE_KEYS.MAX_PRICE,
36
+ TABLE_KEYS.BRAND,
37
+ TABLE_KEYS.STORE_ID,
38
+ TABLE_KEYS.TAGS,
36
39
  ],
37
40
  };
38
41
  export const PRODUCT_ADMIN_SORT_OPTIONS = [
39
- { value: "-createdAt", label: "Newest First" },
40
- { value: "createdAt", label: "Oldest First" },
41
- { value: "-price", label: "Price: High to Low" },
42
- { value: "price", label: "Price: Low to High" },
43
- { value: "title", label: "Title A-Z" },
44
- { value: "-title", label: "Title Z-A" },
45
- { value: "-views", label: "Most Viewed" },
42
+ { value: sortBy(PRODUCT_FIELDS.CREATED_AT), label: "Newest First" },
43
+ { value: sortBy(PRODUCT_FIELDS.CREATED_AT, "ASC"), label: "Oldest First" },
44
+ { value: sortBy(PRODUCT_FIELDS.PRICE), label: "Price: High to Low" },
45
+ { value: sortBy(PRODUCT_FIELDS.PRICE, "ASC"), label: "Price: Low to High" },
46
+ { value: sortBy(PRODUCT_FIELDS.TITLE, "ASC"), label: "Title A-Z" },
47
+ { value: sortBy(PRODUCT_FIELDS.TITLE), label: "Title Z-A" },
48
+ { value: sortBy(PRODUCT_FIELDS.VIEW_COUNT), label: "Most Viewed" },
46
49
  ];
47
50
  export const PRODUCT_SELLER_SORT_OPTIONS = [
48
- { value: "-createdAt", label: "Newest First" },
49
- { value: "createdAt", label: "Oldest First" },
50
- { value: "-price", label: "Price: High to Low" },
51
- { value: "price", label: "Price: Low to High" },
52
- { value: "title", label: "Title A-Z" },
51
+ { value: sortBy(PRODUCT_FIELDS.CREATED_AT), label: "Newest First" },
52
+ { value: sortBy(PRODUCT_FIELDS.CREATED_AT, "ASC"), label: "Oldest First" },
53
+ { value: sortBy(PRODUCT_FIELDS.PRICE), label: "Price: High to Low" },
54
+ { value: sortBy(PRODUCT_FIELDS.PRICE, "ASC"), label: "Price: Low to High" },
55
+ { value: sortBy(PRODUCT_FIELDS.TITLE, "ASC"), label: "Title A-Z" },
53
56
  ];
54
57
  export const PRODUCT_PUBLIC_SORT_OPTIONS = [
55
- { value: "-createdAt", label: "Newest First" },
56
- { value: "createdAt", label: "Oldest First" },
57
- { value: "-price", label: "Price: High to Low" },
58
- { value: "price", label: "Price: Low to High" },
59
- { value: "title", label: "Title A–Z" },
60
- { value: "-title", label: "Title Z–A" },
61
- { value: "-views", label: "Most Viewed" },
58
+ { value: sortBy(PRODUCT_FIELDS.CREATED_AT), label: "Newest First" },
59
+ { value: sortBy(PRODUCT_FIELDS.CREATED_AT, "ASC"), label: "Oldest First" },
60
+ { value: sortBy(PRODUCT_FIELDS.PRICE), label: "Price: High to Low" },
61
+ { value: sortBy(PRODUCT_FIELDS.PRICE, "ASC"), label: "Price: Low to High" },
62
+ { value: sortBy(PRODUCT_FIELDS.TITLE, "ASC"), label: "Title A–Z" },
63
+ { value: sortBy(PRODUCT_FIELDS.TITLE), label: "Title Z–A" },
64
+ { value: sortBy(PRODUCT_FIELDS.VIEW_COUNT), label: "Most Viewed" },
62
65
  ];
63
66
  export function getProductFilterKeys(variant) {
64
67
  return PRODUCT_FILTER_KEYS[variant];
@@ -79,31 +82,31 @@ export function ProductFilters({ table, categoryOptions = [], brandOptions = [],
79
82
  const resolvedStoreOptions = storeOptions.length > 0 ? storeOptions : (sellerOptions ?? []);
80
83
  const t = useTranslations("filters");
81
84
  const conditionOptions = [
82
- { value: "new", label: t("conditionNew") },
83
- { value: "used", label: t("conditionUsed") },
84
- { value: "refurbished", label: t("conditionRefurbished") },
85
- { value: "broken", label: t("conditionBroken") },
85
+ { value: PRODUCT_FIELDS.CONDITION_VALUES.NEW, label: t("conditionNew") },
86
+ { value: PRODUCT_FIELDS.CONDITION_VALUES.USED, label: t("conditionUsed") },
87
+ { value: PRODUCT_FIELDS.CONDITION_VALUES.REFURBISHED, label: t("conditionRefurbished") },
88
+ { value: PRODUCT_FIELDS.CONDITION_VALUES.BROKEN, label: t("conditionBroken") },
86
89
  ];
87
90
  const defaultStatusOptions = [
88
- { value: "published", label: t("statusPublished") },
89
- { value: "draft", label: t("statusDraft") },
90
- { value: "archived", label: t("statusArchived") },
91
+ { value: PRODUCT_FIELDS.STATUS_VALUES.PUBLISHED, label: t("statusPublished") },
92
+ { value: PRODUCT_FIELDS.STATUS_VALUES.DRAFT, label: t("statusDraft") },
93
+ { value: PRODUCT_FIELDS.STATUS_VALUES.OUT_OF_STOCK, label: t("statusOutOfStock") },
91
94
  ];
92
- const selectedCategories = table.get("category")
93
- ? table.get("category").split("|").filter(Boolean)
95
+ const selectedCategories = table.get(TABLE_KEYS.CATEGORY)
96
+ ? table.get(TABLE_KEYS.CATEGORY).split("|").filter(Boolean)
94
97
  : [];
95
- const selectedBrands = table.get("brand") ? [table.get("brand")] : [];
96
- const selectedSellers = table.get("storeId") ? [table.get("storeId")] : [];
97
- const selectedConditions = table.get("condition")
98
- ? table.get("condition").split("|").filter(Boolean)
98
+ const selectedBrands = table.get(TABLE_KEYS.BRAND) ? [table.get(TABLE_KEYS.BRAND)] : [];
99
+ const selectedSellers = table.get(TABLE_KEYS.STORE_ID) ? [table.get(TABLE_KEYS.STORE_ID)] : [];
100
+ const selectedConditions = table.get(TABLE_KEYS.CONDITION)
101
+ ? table.get(TABLE_KEYS.CONDITION).split("|").filter(Boolean)
99
102
  : [];
100
- const selectedTags = table.get("tags")
101
- ? table.get("tags").split("|").filter(Boolean)
103
+ const selectedTags = table.get(TABLE_KEYS.TAGS)
104
+ ? table.get(TABLE_KEYS.TAGS).split("|").filter(Boolean)
102
105
  : [];
103
- const selectedStatuses = table.get("status")
104
- ? table.get("status").split("|").filter(Boolean)
106
+ const selectedStatuses = table.get(TABLE_KEYS.STATUS)
107
+ ? table.get(TABLE_KEYS.STATUS).split("|").filter(Boolean)
105
108
  : [];
106
109
  const resolvedVariant = variant ?? (showStatus ? "admin" : "public");
107
110
  const shouldShowStatus = resolvedVariant !== "public" || showStatus;
108
- return (_jsxs(Div, { children: [categoryOptions.length > 0 && (_jsx(FilterFacetSection, { title: t("category"), options: categoryOptions, selected: selectedCategories, onChange: (vals) => table.set("category", vals.join("|")), searchable: true, defaultCollapsed: categoryOptions.length > 6 })), _jsx(FilterFacetSection, { title: t("condition"), options: conditionOptions, selected: selectedConditions, onChange: (vals) => table.set("condition", vals.join("|")), searchable: false, defaultCollapsed: false }), _jsx(RangeFilter, { title: t("priceRange"), minValue: table.get("minPrice"), maxValue: table.get("maxPrice"), onMinChange: (v) => table.set("minPrice", v), onMaxChange: (v) => table.set("maxPrice", v), prefix: currencyPrefix, showSlider: true, minBound: 0, maxBound: 500000, step: 500, minPlaceholder: t("minPrice"), maxPlaceholder: t("maxPrice"), defaultCollapsed: false }), brandOptions.length > 0 && (_jsx(FilterFacetSection, { title: t("brand"), options: brandOptions, selected: selectedBrands, onChange: (vals) => table.set("brand", vals[0] ?? ""), searchable: brandOptions.length > 4, defaultCollapsed: brandOptions.length > 6 })), resolvedStoreOptions.length > 0 && (_jsx(FilterFacetSection, { title: t("store"), options: resolvedStoreOptions, selected: selectedSellers, onChange: (vals) => table.set("storeId", vals[0] ?? ""), searchable: resolvedStoreOptions.length > 4, defaultCollapsed: resolvedStoreOptions.length > 6 })), showShipping && (_jsx(SwitchFilter, { title: t("shipping"), label: t("freeShippingOnly"), checked: table.get("freeShipping") === "true", onChange: (v) => table.set("freeShipping", v ? "true" : ""), defaultCollapsed: false })), tagOptions.length > 0 && (_jsx(FilterFacetSection, { title: t("tags"), options: tagOptions, selected: selectedTags, onChange: (vals) => table.set("tags", vals.join("|")), searchable: tagOptions.length > 4, defaultCollapsed: tagOptions.length > 6 })), shouldShowStatus && (_jsx(FilterFacetSection, { title: t("status"), options: statusOptions ?? defaultStatusOptions, selected: selectedStatuses, onChange: (vals) => table.set("status", vals.join("|")), searchable: false, defaultCollapsed: false }))] }));
111
+ return (_jsxs(Div, { children: [categoryOptions.length > 0 && (_jsx(FilterFacetSection, { title: t("category"), options: categoryOptions, selected: selectedCategories, onChange: (vals) => table.set(TABLE_KEYS.CATEGORY, vals.join("|")), searchable: true, defaultCollapsed: categoryOptions.length > 6 })), _jsx(FilterFacetSection, { title: t("condition"), options: conditionOptions, selected: selectedConditions, onChange: (vals) => table.set(TABLE_KEYS.CONDITION, vals.join("|")), searchable: false, defaultCollapsed: false }), _jsx(RangeFilter, { title: t("priceRange"), minValue: table.get(TABLE_KEYS.MIN_PRICE), maxValue: table.get(TABLE_KEYS.MAX_PRICE), onMinChange: (v) => table.set(TABLE_KEYS.MIN_PRICE, v), onMaxChange: (v) => table.set(TABLE_KEYS.MAX_PRICE, v), prefix: currencyPrefix, showSlider: true, minBound: 0, maxBound: 500000, step: 500, minPlaceholder: t("minPrice"), maxPlaceholder: t("maxPrice"), defaultCollapsed: false }), brandOptions.length > 0 && (_jsx(FilterFacetSection, { title: t("brand"), options: brandOptions, selected: selectedBrands, onChange: (vals) => table.set(TABLE_KEYS.BRAND, vals[0] ?? ""), searchable: brandOptions.length > 4, defaultCollapsed: brandOptions.length > 6 })), resolvedStoreOptions.length > 0 && (_jsx(FilterFacetSection, { title: t("store"), options: resolvedStoreOptions, selected: selectedSellers, onChange: (vals) => table.set(TABLE_KEYS.STORE_ID, vals[0] ?? ""), searchable: resolvedStoreOptions.length > 4, defaultCollapsed: resolvedStoreOptions.length > 6 })), showShipping && (_jsx(SwitchFilter, { title: t("shipping"), label: t("freeShippingOnly"), checked: table.get(TABLE_KEYS.FREE_SHIPPING) === "true", onChange: (v) => table.set(TABLE_KEYS.FREE_SHIPPING, v ? "true" : ""), defaultCollapsed: false })), tagOptions.length > 0 && (_jsx(FilterFacetSection, { title: t("tags"), options: tagOptions, selected: selectedTags, onChange: (vals) => table.set(TABLE_KEYS.TAGS, vals.join("|")), searchable: tagOptions.length > 4, defaultCollapsed: tagOptions.length > 6 })), shouldShowStatus && (_jsx(FilterFacetSection, { title: t("status"), options: statusOptions ?? defaultStatusOptions, selected: selectedStatuses, onChange: (vals) => table.set(TABLE_KEYS.STATUS, vals.join("|")), searchable: false, defaultCollapsed: false }))] }));
109
112
  }
@@ -15,16 +15,20 @@ import { useGuestWishlist } from "../../wishlist/hooks/useGuestWishlist";
15
15
  import { pushCartOp, pushWishlistOp } from "../../cart/utils/pending-ops";
16
16
  import { useBulkSelection } from "../../../react/hooks/useBulkSelection";
17
17
  import { useCategoryTree, categoriesToFacetOptions } from "../../categories/hooks/useCategoryTree";
18
- const FILTER_KEYS = ["category", "condition", "minPrice", "maxPrice", "brand", "storeId", "freeShipping", "tags"];
18
+ import { TABLE_KEYS, VIEW_MODE } from "../../../constants/table-keys";
19
+ import { sortBy } from "../../../constants/sort";
20
+ import { PRODUCT_FIELDS } from "../../../constants/field-names";
21
+ const DEFAULT_SORT = sortBy(PRODUCT_FIELDS.CREATED_AT);
22
+ const FILTER_KEYS = [TABLE_KEYS.CATEGORY, TABLE_KEYS.CONDITION, TABLE_KEYS.MIN_PRICE, TABLE_KEYS.MAX_PRICE, TABLE_KEYS.BRAND, TABLE_KEYS.STORE_ID, TABLE_KEYS.FREE_SHIPPING, TABLE_KEYS.TAGS];
19
23
  export function ProductsIndexListing({ initialData }) {
20
24
  const router = useRouter();
21
- const table = useUrlTable({ defaults: { pageSize: "24", sort: "-createdAt" } });
25
+ const table = useUrlTable({ defaults: { pageSize: "24", sort: DEFAULT_SORT } });
22
26
  const { showToast } = useToast();
23
- const [searchInput, setSearchInput] = useState(table.get("q") || "");
27
+ const [searchInput, setSearchInput] = useState(table.get(TABLE_KEYS.QUERY) || "");
24
28
  const [filterOpen, setFilterOpen] = useState(false);
25
29
  const [compareIds, setCompareIds] = useState([]);
26
- const showSold = table.get("showSold") === "true";
27
- const [view, setView] = useState(table.get("view") || "grid");
30
+ const showSold = table.get(TABLE_KEYS.SHOW_SOLD) === "true";
31
+ const [view, setView] = useState(table.get(TABLE_KEYS.VIEW) || VIEW_MODE.GRID);
28
32
  // Pending filter state — buffered until "Apply Filters" clicked
29
33
  const [pendingFilters, setPendingFilters] = useState(() => Object.fromEntries(FILTER_KEYS.map((k) => [k, table.get(k)])));
30
34
  const pendingTable = useMemo(() => ({
@@ -68,16 +72,16 @@ export function ProductsIndexListing({ initialData }) {
68
72
  setPendingFilters(Object.fromEntries(FILTER_KEYS.map((k) => [k, ""])));
69
73
  }, []);
70
74
  const resetAll = useCallback(() => {
71
- const updates = { q: "", sort: "", showSold: "" };
75
+ const updates = { [TABLE_KEYS.QUERY]: "", [TABLE_KEYS.SORT]: "", [TABLE_KEYS.SHOW_SOLD]: "" };
72
76
  for (const k of FILTER_KEYS)
73
77
  updates[k] = "";
74
78
  table.setMany(updates);
75
79
  setSearchInput("");
76
80
  }, [table]);
77
81
  const activeFilterCount = FILTER_KEYS.filter((k) => !!table.get(k)).length;
78
- const hasActiveState = !!table.get("q") ||
79
- table.get("showSold") === "true" ||
80
- table.get("sort") !== "-createdAt" ||
82
+ const hasActiveState = !!table.get(TABLE_KEYS.QUERY) ||
83
+ table.get(TABLE_KEYS.SHOW_SOLD) === "true" ||
84
+ table.get(TABLE_KEYS.SORT) !== DEFAULT_SORT ||
81
85
  activeFilterCount > 0;
82
86
  const localCart = useGuestCart();
83
87
  const localWishlist = useGuestWishlist();
@@ -85,17 +89,17 @@ export function ProductsIndexListing({ initialData }) {
85
89
  const { categories } = useCategoryTree();
86
90
  const categoryOptions = categoriesToFacetOptions(categories);
87
91
  const params = {
88
- q: table.get("q") || undefined,
89
- category: table.get("category") || undefined,
90
- minPrice: table.get("minPrice") ? Number(table.get("minPrice")) : undefined,
91
- maxPrice: table.get("maxPrice") ? Number(table.get("maxPrice")) : undefined,
92
- condition: table.get("condition") || undefined,
93
- brand: table.get("brand") || undefined,
94
- storeId: table.get("storeId") || undefined,
95
- freeShipping: table.get("freeShipping") === "true" ? true : undefined,
96
- sort: table.get("sort") || "-createdAt",
97
- page: table.getNumber("page", 1),
98
- perPage: table.getNumber("pageSize", 24),
92
+ q: table.get(TABLE_KEYS.QUERY) || undefined,
93
+ category: table.get(TABLE_KEYS.CATEGORY) || undefined,
94
+ minPrice: table.get(TABLE_KEYS.MIN_PRICE) ? Number(table.get(TABLE_KEYS.MIN_PRICE)) : undefined,
95
+ maxPrice: table.get(TABLE_KEYS.MAX_PRICE) ? Number(table.get(TABLE_KEYS.MAX_PRICE)) : undefined,
96
+ condition: table.get(TABLE_KEYS.CONDITION) || undefined,
97
+ brand: table.get(TABLE_KEYS.BRAND) || undefined,
98
+ storeId: table.get(TABLE_KEYS.STORE_ID) || undefined,
99
+ freeShipping: table.get(TABLE_KEYS.FREE_SHIPPING) === "true" ? true : undefined,
100
+ sort: table.get(TABLE_KEYS.SORT) || DEFAULT_SORT,
101
+ page: table.getNumber(TABLE_KEYS.PAGE, 1),
102
+ perPage: table.getNumber(TABLE_KEYS.PAGE_SIZE, 24),
99
103
  listingType: "standard",
100
104
  // Hide sold-out items by default. Uses stockQuantity>0 (always-present field)
101
105
  // instead of status=="published" because sellers don't actively transition status.
@@ -104,17 +108,17 @@ export function ProductsIndexListing({ initialData }) {
104
108
  const { products, totalPages, page, isLoading } = useProducts(params, { initialData });
105
109
  const selection = useBulkSelection({ items: products, keyExtractor: (p) => p.id });
106
110
  const commitSearch = useCallback(() => {
107
- table.set("q", searchInput.trim());
111
+ table.set(TABLE_KEYS.QUERY, searchInput.trim());
108
112
  }, [searchInput, table]);
109
113
  const handleSearchKeyDown = (e) => {
110
114
  if (e.key === "Enter")
111
115
  commitSearch();
112
116
  };
113
117
  const handleViewToggle = (next) => {
114
- if (next === "table")
118
+ if (next === VIEW_MODE.TABLE)
115
119
  return;
116
120
  setView(next);
117
- table.set("view", next);
121
+ table.set(TABLE_KEYS.VIEW, next);
118
122
  };
119
123
  const handleWishlistToggle = useCallback((productId) => {
120
124
  const isWishlisted = wishlistedIds.has(productId);
@@ -147,7 +151,7 @@ export function ProductsIndexListing({ initialData }) {
147
151
  pushCartOp({ op: "add", productId: product.id, quantity: 1, productTitle: product.title, productImage: product.mainImage, price: product.price });
148
152
  router.push(String(ROUTES.USER.CART));
149
153
  }, [localCart, router]);
150
- return (_jsxs("div", { className: "min-h-screen", children: [_jsx(ListingToolbar, { filterCount: activeFilterCount, onFiltersClick: openFilters, searchValue: searchInput, searchPlaceholder: "Search products...", onSearchChange: setSearchInput, onSearchCommit: commitSearch, onSearchKeyDown: handleSearchKeyDown, sortValue: table.get("sort") || "-createdAt", sortOptions: PRODUCT_PUBLIC_SORT_OPTIONS, onSortChange: (v) => { table.set("sort", v); }, view: view, onViewChange: handleViewToggle, onResetAll: resetAll, hasActiveState: hasActiveState, bulkMode: selection.isSelecting, bulkSelectedCount: selection.selectedCount, bulkTotalCount: products.length, onBulkSelectAll: selection.toggleAll, onBulkClear: selection.clearSelection, extra: _jsxs("label", { className: "flex items-center gap-1.5 cursor-pointer select-none shrink-0", children: [_jsx("span", { className: "hidden sm:inline text-xs text-zinc-600 dark:text-zinc-300 whitespace-nowrap", children: "Show sold" }), _jsx("button", { type: "button", role: "switch", "aria-checked": showSold, onClick: () => table.set("showSold", showSold ? "" : "true"), className: `relative inline-flex h-5 w-9 flex-shrink-0 items-center rounded-full transition-colors duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-1 ${showSold ? "bg-primary" : "bg-zinc-300 dark:bg-slate-600"}`, children: _jsx("span", { className: `inline-block h-3.5 w-3.5 transform rounded-full bg-white shadow-sm transition-transform duration-200 ${showSold ? "translate-x-[19px]" : "translate-x-[3px]"}` }) })] }) }), _jsx(BulkActionBar, { selectedCount: selection.selectedCount, onClearSelection: selection.clearSelection, actions: [
154
+ return (_jsxs("div", { className: "min-h-screen", children: [_jsx(ListingToolbar, { filterCount: activeFilterCount, onFiltersClick: openFilters, searchValue: searchInput, searchPlaceholder: "Search products...", onSearchChange: setSearchInput, onSearchCommit: commitSearch, onSearchKeyDown: handleSearchKeyDown, sortValue: table.get(TABLE_KEYS.SORT) || DEFAULT_SORT, sortOptions: PRODUCT_PUBLIC_SORT_OPTIONS, onSortChange: (v) => { table.set(TABLE_KEYS.SORT, v); }, view: view, onViewChange: handleViewToggle, onResetAll: resetAll, hasActiveState: hasActiveState, bulkMode: selection.isSelecting, bulkSelectedCount: selection.selectedCount, bulkTotalCount: products.length, onBulkSelectAll: selection.toggleAll, onBulkClear: selection.clearSelection, extra: _jsxs("label", { className: "flex items-center gap-1.5 cursor-pointer select-none shrink-0", children: [_jsx("span", { className: "hidden sm:inline text-xs text-zinc-600 dark:text-zinc-300 whitespace-nowrap", children: "Show sold" }), _jsx("button", { type: "button", role: "switch", "aria-checked": showSold, onClick: () => table.set(TABLE_KEYS.SHOW_SOLD, showSold ? "" : "true"), className: `relative inline-flex h-5 w-9 flex-shrink-0 items-center rounded-full transition-colors duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-1 ${showSold ? "bg-primary" : "bg-zinc-300 dark:bg-slate-600"}`, children: _jsx("span", { className: `inline-block h-3.5 w-3.5 transform rounded-full bg-white shadow-sm transition-transform duration-200 ${showSold ? "translate-x-[19px]" : "translate-x-[3px]"}` }) })] }) }), _jsx(BulkActionBar, { selectedCount: selection.selectedCount, onClearSelection: selection.clearSelection, actions: [
151
155
  {
152
156
  id: ACTION_ID.ADD_TO_CART,
153
157
  label: ACTION_META[ACTION_ID.ADD_TO_CART].label,
@@ -5,36 +5,44 @@ import { Container, Heading, Main, Section } from "../../../ui";
5
5
  import { AdSlot } from "../../homepage/components/AdSlot";
6
6
  import { parseListingSearchParams } from "../../../utils/listing-params";
7
7
  import { ProductsIndexListing } from "./ProductsIndexListing";
8
+ import { PRODUCT_FIELDS } from "../../../constants/field-names";
9
+ import { sieveFilter, sieveMultiEq, sieveAnd, SIEVE_OP } from "../../../utils/sieve-builder";
10
+ import { sortBy } from "../../../constants/sort";
8
11
  const DEFAULT_PAGE = 1;
9
12
  const DEFAULT_PAGE_SIZE = 24;
10
- const DEFAULT_SORT = "-createdAt";
13
+ const DEFAULT_SORT = sortBy(PRODUCT_FIELDS.CREATED_AT);
11
14
  function sp(params, key) {
12
15
  const v = params[key];
13
16
  return Array.isArray(v) ? v[0] ?? "" : v ?? "";
14
17
  }
15
18
  function buildProductFilters(params) {
16
- const parts = ["status==published", "listingType==standard"];
19
+ const parts = [
20
+ sieveFilter(PRODUCT_FIELDS.STATUS, SIEVE_OP.EQ, PRODUCT_FIELDS.STATUS_VALUES.PUBLISHED),
21
+ sieveFilter(PRODUCT_FIELDS.LISTING_TYPE, SIEVE_OP.EQ, "standard"),
22
+ ];
17
23
  const condition = sp(params, "condition");
18
24
  if (condition) {
19
25
  const values = condition.split("|").filter(Boolean);
20
26
  if (values.length === 1)
21
- parts.push(`condition==${values[0]}`);
27
+ parts.push(sieveFilter(PRODUCT_FIELDS.CONDITION, SIEVE_OP.EQ, values[0]));
28
+ // BUG FIX: pipe is invalid for ==; expand to multiple AND clauses
22
29
  else if (values.length > 1)
23
- parts.push(`condition==${values.join("|")}`);
30
+ parts.push(sieveMultiEq(PRODUCT_FIELDS.CONDITION, values));
24
31
  }
25
32
  const minPrice = sp(params, "minPrice");
26
33
  const maxPrice = sp(params, "maxPrice");
27
34
  if (minPrice)
28
- parts.push(`price>=${minPrice}`);
35
+ parts.push(sieveFilter(PRODUCT_FIELDS.PRICE, SIEVE_OP.GTE, minPrice));
29
36
  if (maxPrice)
30
- parts.push(`price<=${maxPrice}`);
37
+ parts.push(sieveFilter(PRODUCT_FIELDS.PRICE, SIEVE_OP.LTE, maxPrice));
31
38
  const storeId = sp(params, "seller");
32
39
  if (storeId)
33
- parts.push(`storeId==${storeId}`);
40
+ parts.push(sieveFilter(PRODUCT_FIELDS.STORE_ID, SIEVE_OP.EQ, storeId));
34
41
  const freeShipping = sp(params, "freeShipping");
35
- if (freeShipping === "true")
36
- parts.push("freeShipping==true");
37
- return parts.join(",");
42
+ if (freeShipping === "true") {
43
+ parts.push(sieveFilter(PRODUCT_FIELDS.SHIPPING_PAID_BY, SIEVE_OP.EQ, PRODUCT_FIELDS.SHIPPING_PAID_BY_VALUES.SELLER));
44
+ }
45
+ return sieveAnd(...parts);
38
46
  }
39
47
  export async function ProductsIndexPageView({ searchParams = {} }) {
40
48
  const std = parseListingSearchParams(searchParams);
@@ -46,6 +46,8 @@ export function useProducts(params = {}, opts) {
46
46
  sp.set("dateTo", params.dateTo);
47
47
  if (params.preOrderProductionStatus)
48
48
  sp.set("preOrderProductionStatus", params.preOrderProductionStatus);
49
+ if (params.prizeRevealStatus)
50
+ sp.set("prizeRevealStatus", params.prizeRevealStatus);
49
51
  if (params.brand)
50
52
  sp.set("brand", params.brand);
51
53
  if (params.freeShipping !== undefined)
@@ -4,33 +4,13 @@ import { BaseRepository, prepareForFirestore, } from "../../../providers/db-fire
4
4
  import { cacheManager } from "../../../core";
5
5
  import { generateUniqueId, slugify } from "../../../utils";
6
6
  import { PRODUCT_COLLECTION, ProductStatusValues, } from "../schemas";
7
- const PRODUCT_FIELDS = {
8
- STORE_ID: "storeId",
9
- STATUS: "status",
10
- FEATURED: "featured",
11
- CATEGORY: "category",
12
- SLUG: "slug",
13
- // SB1-G (S3 2026-05-13) — canonical discriminator. Legacy `isAuction` /
14
- // `isPreOrder` boolean fields were removed in this session.
15
- LISTING_TYPE: "listingType",
16
- PRE_ORDER_DELIVERY_DATE: "preOrderDeliveryDate",
17
- IS_PROMOTED: "isPromoted",
18
- AUCTION_END_DATE: "auctionEndDate",
19
- AVAILABLE_QUANTITY: "availableQuantity",
20
- VIEW_COUNT: "viewCount",
21
- };
7
+ import { PRODUCT_FIELDS } from "../../../constants/field-names";
22
8
  /**
23
9
  * Canonical listing-kind tokens used in `listingType`. Note: the public Sieve
24
10
  * alias accepts the legacy "preorder" / "product" spelling; we normalise to
25
11
  * the Firestore-stored value here.
26
12
  */
27
- const LISTING_TYPE_VALUES = {
28
- AUCTION: "auction",
29
- PRE_ORDER: "pre-order",
30
- STANDARD: "standard",
31
- PRIZE_DRAW: "prize-draw",
32
- BUNDLE: "bundle",
33
- };
13
+ const LISTING_TYPE_VALUES = PRODUCT_FIELDS.LISTING_TYPE_VALUES;
34
14
  // Reused Sieve clauses for FILTER_ALIASES. SB1-G replaced the boolean-combo
35
15
  // clauses with single-field `listingType==X` clauses now that every doc
36
16
  // carries the discriminator.
@@ -117,8 +117,8 @@ export declare const productItemSchema: z.ZodObject<{
117
117
  isWon: z.ZodBoolean;
118
118
  }, "strip", z.ZodTypeAny, {
119
119
  title: string;
120
- images: string[];
121
120
  condition: string;
121
+ images: string[];
122
122
  itemNumber: number;
123
123
  isWon: boolean;
124
124
  video?: {
@@ -129,8 +129,8 @@ export declare const productItemSchema: z.ZodObject<{
129
129
  estimatedValue?: number | undefined;
130
130
  }, {
131
131
  title: string;
132
- images: string[];
133
132
  condition: string;
133
+ images: string[];
134
134
  itemNumber: number;
135
135
  isWon: boolean;
136
136
  video?: {
@@ -305,19 +305,24 @@ export declare const productItemSchema: z.ZodObject<{
305
305
  youtubeId?: string | undefined;
306
306
  }[] | undefined;
307
307
  category?: string | undefined;
308
- images?: string[] | undefined;
308
+ brand?: string | undefined;
309
+ condition?: "new" | "used" | "refurbished" | "broken" | "like_new" | "good" | "fair" | "poor" | undefined;
310
+ tags?: string[] | undefined;
311
+ featured?: boolean | undefined;
312
+ listingType?: "auction" | "standard" | "pre-order" | "prize-draw" | "bundle" | undefined;
313
+ inStock?: boolean | undefined;
309
314
  rating?: number | undefined;
315
+ preOrderProductionStatus?: "upcoming" | "in_production" | "ready_to_ship" | undefined;
316
+ prizeRevealStatus?: "pending" | "closed" | "open" | undefined;
317
+ categorySlug?: string | undefined;
318
+ images?: string[] | undefined;
310
319
  description?: string | undefined;
311
- listingType?: "auction" | "standard" | "pre-order" | "prize-draw" | "bundle" | undefined;
312
- featured?: boolean | undefined;
313
320
  isPromoted?: boolean | undefined;
314
321
  slug?: string | undefined;
315
322
  subcategory?: string | undefined;
316
- brand?: string | undefined;
317
323
  stockQuantity?: number | undefined;
318
324
  availableQuantity?: number | undefined;
319
325
  mainImage?: string | undefined;
320
- tags?: string[] | undefined;
321
326
  specifications?: {
322
327
  value: string;
323
328
  name: string;
@@ -326,7 +331,6 @@ export declare const productItemSchema: z.ZodObject<{
326
331
  features?: string[] | undefined;
327
332
  shippingInfo?: string | undefined;
328
333
  returnPolicy?: string | undefined;
329
- condition?: "new" | "used" | "refurbished" | "broken" | "like_new" | "good" | "fair" | "poor" | undefined;
330
334
  insurance?: boolean | undefined;
331
335
  insuranceCost?: number | undefined;
332
336
  shippingPaidBy?: "seller" | "buyer" | undefined;
@@ -345,7 +349,6 @@ export declare const productItemSchema: z.ZodObject<{
345
349
  preOrderDepositAmount?: number | undefined;
346
350
  preOrderMaxQuantity?: number | undefined;
347
351
  preOrderCurrentCount?: number | undefined;
348
- preOrderProductionStatus?: "upcoming" | "in_production" | "ready_to_ship" | undefined;
349
352
  preOrderCancellable?: boolean | undefined;
350
353
  pickupAddressId?: string | undefined;
351
354
  viewCount?: number | undefined;
@@ -381,8 +384,8 @@ export declare const productItemSchema: z.ZodObject<{
381
384
  partOfBundleTitles?: string[] | undefined;
382
385
  prizeDrawItems?: {
383
386
  title: string;
384
- images: string[];
385
387
  condition: string;
388
+ images: string[];
386
389
  itemNumber: number;
387
390
  isWon: boolean;
388
391
  video?: {
@@ -397,13 +400,10 @@ export declare const productItemSchema: z.ZodObject<{
397
400
  prizeCurrentEntries?: number | undefined;
398
401
  prizeRevealWindowStart?: string | Date | undefined;
399
402
  prizeRevealWindowEnd?: string | Date | undefined;
400
- prizeRevealStatus?: "pending" | "closed" | "open" | undefined;
401
403
  prizeRevealDeadlineDays?: number | undefined;
402
404
  prizeGithubFileUrl?: string | undefined;
403
405
  originalPrice?: number | undefined;
404
- categorySlug?: string | undefined;
405
406
  sellerAvatar?: string | undefined;
406
- inStock?: boolean | undefined;
407
407
  stockCount?: number | undefined;
408
408
  attributes?: Record<string, string> | undefined;
409
409
  seo?: {
@@ -434,19 +434,24 @@ export declare const productItemSchema: z.ZodObject<{
434
434
  youtubeId?: string | undefined;
435
435
  }[] | undefined;
436
436
  category?: string | undefined;
437
- images?: string[] | undefined;
437
+ brand?: string | undefined;
438
+ condition?: "new" | "used" | "refurbished" | "broken" | "like_new" | "good" | "fair" | "poor" | undefined;
439
+ tags?: string[] | undefined;
440
+ featured?: boolean | undefined;
441
+ listingType?: "auction" | "standard" | "pre-order" | "prize-draw" | "bundle" | undefined;
442
+ inStock?: boolean | undefined;
438
443
  rating?: number | undefined;
444
+ preOrderProductionStatus?: "upcoming" | "in_production" | "ready_to_ship" | undefined;
445
+ prizeRevealStatus?: "pending" | "closed" | "open" | undefined;
446
+ categorySlug?: string | undefined;
447
+ images?: string[] | undefined;
439
448
  description?: string | undefined;
440
- listingType?: "auction" | "standard" | "pre-order" | "prize-draw" | "bundle" | undefined;
441
- featured?: boolean | undefined;
442
449
  isPromoted?: boolean | undefined;
443
450
  slug?: string | undefined;
444
451
  subcategory?: string | undefined;
445
- brand?: string | undefined;
446
452
  stockQuantity?: number | undefined;
447
453
  availableQuantity?: number | undefined;
448
454
  mainImage?: string | undefined;
449
- tags?: string[] | undefined;
450
455
  specifications?: {
451
456
  value: string;
452
457
  name: string;
@@ -455,7 +460,6 @@ export declare const productItemSchema: z.ZodObject<{
455
460
  features?: string[] | undefined;
456
461
  shippingInfo?: string | undefined;
457
462
  returnPolicy?: string | undefined;
458
- condition?: "new" | "used" | "refurbished" | "broken" | "like_new" | "good" | "fair" | "poor" | undefined;
459
463
  insurance?: boolean | undefined;
460
464
  insuranceCost?: number | undefined;
461
465
  shippingPaidBy?: "seller" | "buyer" | undefined;
@@ -474,7 +478,6 @@ export declare const productItemSchema: z.ZodObject<{
474
478
  preOrderDepositAmount?: number | undefined;
475
479
  preOrderMaxQuantity?: number | undefined;
476
480
  preOrderCurrentCount?: number | undefined;
477
- preOrderProductionStatus?: "upcoming" | "in_production" | "ready_to_ship" | undefined;
478
481
  preOrderCancellable?: boolean | undefined;
479
482
  pickupAddressId?: string | undefined;
480
483
  viewCount?: number | undefined;
@@ -510,8 +513,8 @@ export declare const productItemSchema: z.ZodObject<{
510
513
  partOfBundleTitles?: string[] | undefined;
511
514
  prizeDrawItems?: {
512
515
  title: string;
513
- images: string[];
514
516
  condition: string;
517
+ images: string[];
515
518
  itemNumber: number;
516
519
  isWon: boolean;
517
520
  video?: {
@@ -526,13 +529,10 @@ export declare const productItemSchema: z.ZodObject<{
526
529
  prizeCurrentEntries?: number | undefined;
527
530
  prizeRevealWindowStart?: string | Date | undefined;
528
531
  prizeRevealWindowEnd?: string | Date | undefined;
529
- prizeRevealStatus?: "pending" | "closed" | "open" | undefined;
530
532
  prizeRevealDeadlineDays?: number | undefined;
531
533
  prizeGithubFileUrl?: string | undefined;
532
534
  originalPrice?: number | undefined;
533
- categorySlug?: string | undefined;
534
535
  sellerAvatar?: string | undefined;
535
- inStock?: boolean | undefined;
536
536
  stockCount?: number | undefined;
537
537
  attributes?: Record<string, string> | undefined;
538
538
  seo?: {
@@ -567,9 +567,9 @@ export declare const productListParamsSchema: z.ZodObject<{
567
567
  category?: string | undefined;
568
568
  minPrice?: number | undefined;
569
569
  maxPrice?: number | undefined;
570
- listingType?: "auction" | "standard" | "pre-order" | "prize-draw" | "bundle" | undefined;
571
- featured?: boolean | undefined;
572
570
  condition?: "new" | "used" | "refurbished" | "broken" | "like_new" | "good" | "fair" | "poor" | undefined;
571
+ featured?: boolean | undefined;
572
+ listingType?: "auction" | "standard" | "pre-order" | "prize-draw" | "bundle" | undefined;
573
573
  inStock?: boolean | undefined;
574
574
  }, {
575
575
  sort?: string | undefined;
@@ -581,8 +581,8 @@ export declare const productListParamsSchema: z.ZodObject<{
581
581
  category?: string | undefined;
582
582
  minPrice?: number | undefined;
583
583
  maxPrice?: number | undefined;
584
- listingType?: "auction" | "standard" | "pre-order" | "prize-draw" | "bundle" | undefined;
585
- featured?: boolean | undefined;
586
584
  condition?: "new" | "used" | "refurbished" | "broken" | "like_new" | "good" | "fair" | "poor" | undefined;
585
+ featured?: boolean | undefined;
586
+ listingType?: "auction" | "standard" | "pre-order" | "prize-draw" | "bundle" | undefined;
587
587
  inStock?: boolean | undefined;
588
588
  }>;
@@ -26,9 +26,9 @@ export declare const productFeatureAdminCreateSchema: z.ZodObject<{
26
26
  scope: "store" | "platform";
27
27
  icon: string;
28
28
  isActive: boolean;
29
- category: "seller" | "auction" | "preorder" | "shipping" | "custom" | "condition" | "platform";
30
- productTypes: ("all" | "product" | "auction" | "preorder")[];
29
+ category: "seller" | "auction" | "preorder" | "condition" | "shipping" | "custom" | "platform";
31
30
  displayOrder: number;
31
+ productTypes: ("all" | "product" | "auction" | "preorder")[];
32
32
  storeId?: string | undefined;
33
33
  description?: string | undefined;
34
34
  iconColor?: string | undefined;
@@ -37,9 +37,9 @@ export declare const productFeatureAdminCreateSchema: z.ZodObject<{
37
37
  scope: "store" | "platform";
38
38
  icon: string;
39
39
  isActive: boolean;
40
- category: "seller" | "auction" | "preorder" | "shipping" | "custom" | "condition" | "platform";
41
- productTypes: ("all" | "product" | "auction" | "preorder")[];
40
+ category: "seller" | "auction" | "preorder" | "condition" | "shipping" | "custom" | "platform";
42
41
  displayOrder: number;
42
+ productTypes: ("all" | "product" | "auction" | "preorder")[];
43
43
  storeId?: string | undefined;
44
44
  description?: string | undefined;
45
45
  iconColor?: string | undefined;
@@ -58,18 +58,18 @@ export declare const productFeatureStoreCreateSchema: z.ZodObject<{
58
58
  label: string;
59
59
  icon: string;
60
60
  isActive: boolean;
61
- category: "seller" | "auction" | "preorder" | "shipping" | "custom" | "condition" | "platform";
62
- productTypes: ("all" | "product" | "auction" | "preorder")[];
61
+ category: "seller" | "auction" | "preorder" | "condition" | "shipping" | "custom" | "platform";
63
62
  displayOrder: number;
63
+ productTypes: ("all" | "product" | "auction" | "preorder")[];
64
64
  description?: string | undefined;
65
65
  iconColor?: string | undefined;
66
66
  }, {
67
67
  label: string;
68
68
  icon: string;
69
69
  isActive: boolean;
70
- category: "seller" | "auction" | "preorder" | "shipping" | "custom" | "condition" | "platform";
71
- productTypes: ("all" | "product" | "auction" | "preorder")[];
70
+ category: "seller" | "auction" | "preorder" | "condition" | "shipping" | "custom" | "platform";
72
71
  displayOrder: number;
72
+ productTypes: ("all" | "product" | "auction" | "preorder")[];
73
73
  description?: string | undefined;
74
74
  iconColor?: string | undefined;
75
75
  }>;
@@ -87,20 +87,20 @@ export declare const productFeatureUpdateSchema: z.ZodObject<{
87
87
  label?: string | undefined;
88
88
  icon?: string | undefined;
89
89
  isActive?: boolean | undefined;
90
- category?: "seller" | "auction" | "preorder" | "shipping" | "custom" | "condition" | "platform" | undefined;
90
+ category?: "seller" | "auction" | "preorder" | "condition" | "shipping" | "custom" | "platform" | undefined;
91
91
  description?: string | undefined;
92
92
  iconColor?: string | undefined;
93
- productTypes?: ("all" | "product" | "auction" | "preorder")[] | undefined;
94
93
  displayOrder?: number | undefined;
94
+ productTypes?: ("all" | "product" | "auction" | "preorder")[] | undefined;
95
95
  }, {
96
96
  label?: string | undefined;
97
97
  icon?: string | undefined;
98
98
  isActive?: boolean | undefined;
99
- category?: "seller" | "auction" | "preorder" | "shipping" | "custom" | "condition" | "platform" | undefined;
99
+ category?: "seller" | "auction" | "preorder" | "condition" | "shipping" | "custom" | "platform" | undefined;
100
100
  description?: string | undefined;
101
101
  iconColor?: string | undefined;
102
- productTypes?: ("all" | "product" | "auction" | "preorder")[] | undefined;
103
102
  displayOrder?: number | undefined;
103
+ productTypes?: ("all" | "product" | "auction" | "preorder")[] | undefined;
104
104
  }>;
105
105
  export type ProductFeatureAdminCreatePayload = z.infer<typeof productFeatureAdminCreateSchema>;
106
106
  export type ProductFeatureStoreCreatePayload = z.infer<typeof productFeatureStoreCreateSchema>;