@mohasinac/appkit 2.8.3 → 2.8.4

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 (171) hide show
  1. package/dist/client.d.ts +2 -0
  2. package/dist/client.js +2 -0
  3. package/dist/core/hooks/useSiteSettings.d.ts +1 -1
  4. package/dist/features/account/hooks/useAccount.d.ts +2 -2
  5. package/dist/features/account/hooks/useAddressSelector.d.ts +1 -1
  6. package/dist/features/account/hooks/useAddresses.d.ts +2 -2
  7. package/dist/features/account/hooks/useNotifications.d.ts +1 -1
  8. package/dist/features/account/hooks/useProfile.d.ts +1 -1
  9. package/dist/features/account/hooks/usePublicProfile.d.ts +2 -2
  10. package/dist/features/admin/components/AdminAllEventEntriesView.js +5 -3
  11. package/dist/features/admin/components/AdminBidsView.js +6 -4
  12. package/dist/features/admin/components/AdminBlogView.js +6 -4
  13. package/dist/features/admin/components/AdminBrandsView.js +8 -6
  14. package/dist/features/admin/components/AdminBundlesView.js +10 -8
  15. package/dist/features/admin/components/AdminCartsView.js +6 -4
  16. package/dist/features/admin/components/AdminCategoriesView.js +7 -5
  17. package/dist/features/admin/components/AdminClassifiedView.js +4 -3
  18. package/dist/features/admin/components/AdminContactView.js +6 -4
  19. package/dist/features/admin/components/AdminCouponsView.js +6 -4
  20. package/dist/features/admin/components/AdminDigitalCodesView.js +4 -3
  21. package/dist/features/admin/components/AdminFaqsView.js +5 -3
  22. package/dist/features/admin/components/AdminFeaturesView.js +5 -4
  23. package/dist/features/admin/components/AdminGroupedListingsView.js +4 -3
  24. package/dist/features/admin/components/AdminHistoryView.js +4 -3
  25. package/dist/features/admin/components/AdminLiveView.js +4 -3
  26. package/dist/features/admin/components/AdminNewsletterView.js +5 -3
  27. package/dist/features/admin/components/AdminNotificationsView.js +6 -4
  28. package/dist/features/admin/components/AdminOrdersView.js +6 -4
  29. package/dist/features/admin/components/AdminPayoutsView.js +7 -5
  30. package/dist/features/admin/components/AdminPrizeDrawsView.js +6 -4
  31. package/dist/features/admin/components/AdminProductsView.js +7 -5
  32. package/dist/features/admin/components/AdminReturnRequestsView.js +4 -3
  33. package/dist/features/admin/components/AdminReviewsView.js +8 -6
  34. package/dist/features/admin/components/AdminScammersView.js +8 -6
  35. package/dist/features/admin/components/AdminSessionsView.js +6 -4
  36. package/dist/features/admin/components/AdminStoreAddressesView.js +2 -1
  37. package/dist/features/admin/components/AdminStoresView.js +6 -4
  38. package/dist/features/admin/components/AdminSublistingCategoriesView.js +6 -5
  39. package/dist/features/admin/components/AdminSupportTicketsView.js +8 -6
  40. package/dist/features/admin/components/AdminTeamView.js +6 -4
  41. package/dist/features/admin/components/AdminUsersView.js +6 -4
  42. package/dist/features/admin/components/AdminWishlistsView.js +4 -3
  43. package/dist/features/admin/constants/filter-tabs.d.ts +1 -1
  44. package/dist/features/admin/constants/filter-tabs.js +0 -11
  45. package/dist/features/admin/hooks/useAdmin.d.ts +1 -1
  46. package/dist/features/admin/hooks/useAdminSectionsListing.d.ts +1 -1
  47. package/dist/features/admin/hooks/useChat.d.ts +1 -1
  48. package/dist/features/admin/types/index.d.ts +1 -1
  49. package/dist/features/auctions/actions/bid-actions.js +4 -2
  50. package/dist/features/auctions/components/AuctionsListView.js +7 -6
  51. package/dist/features/auctions/hooks/useAuctions.d.ts +8 -8
  52. package/dist/features/auth/hooks/useAuth.d.ts +2 -2
  53. package/dist/features/blog/actions/blog-actions.js +3 -2
  54. package/dist/features/cart/hooks/useCart.d.ts +1 -1
  55. package/dist/features/cart/hooks/useCartQuery.d.ts +1 -1
  56. package/dist/features/cart/hooks/useCheckoutReadQueries.d.ts +2 -2
  57. package/dist/features/cart/hooks/useOrder.d.ts +2 -2
  58. package/dist/features/categories/components/BrandDetailPageView.js +10 -8
  59. package/dist/features/categories/components/CategoriesIndexListing.js +1 -1
  60. package/dist/features/categories/components/CategoriesIndexPageView.js +5 -4
  61. package/dist/features/categories/components/CategoryBundlesListing.js +5 -4
  62. package/dist/features/categories/components/CategoryDetailPageView.js +12 -10
  63. package/dist/features/categories/components/CategoryFilters.d.ts +12 -12
  64. package/dist/features/categories/components/CategoryFilters.js +13 -12
  65. package/dist/features/categories/components/CategoryTree.d.ts +1 -1
  66. package/dist/features/categories/components/CategoryTree.js +1 -1
  67. package/dist/features/categories/hooks/useCategories.d.ts +3 -3
  68. package/dist/features/categories/hooks/useCategorySelector.d.ts +3 -3
  69. package/dist/features/categories/hooks/useCategoryTree.d.ts +1 -1
  70. package/dist/features/categories/schemas/firestore.d.ts +2 -2
  71. package/dist/features/checkout/actions/checkout-actions.d.ts +1 -1
  72. package/dist/features/checkout/actions/checkout-actions.js +1 -1
  73. package/dist/features/checkout/hooks/useCheckoutApi.d.ts +2 -2
  74. package/dist/features/classified/components/ClassifiedListView.js +6 -5
  75. package/dist/features/collections/hooks/useCollections.d.ts +2 -2
  76. package/dist/features/cron/jobs/auction-expiry.job.d.ts +2 -2
  77. package/dist/features/cron/jobs/auction-expiry.job.js +2 -1
  78. package/dist/features/cron/jobs/preorder-reminder.job.d.ts +1 -1
  79. package/dist/features/cron/jobs/preorder-reminder.job.js +2 -1
  80. package/dist/features/digital-codes/components/DigitalCodesListView.js +4 -3
  81. package/dist/features/events/actions/event-actions.js +6 -4
  82. package/dist/features/events/components/AdminEventEditorView.js +1 -1
  83. package/dist/features/events/components/AdminEventsView.js +7 -5
  84. package/dist/features/events/components/EventFilters.d.ts +4 -4
  85. package/dist/features/events/components/EventFilters.js +2 -2
  86. package/dist/features/events/components/EventRafflesSection.js +4 -2
  87. package/dist/features/events/hooks/useEvent.d.ts +3 -3
  88. package/dist/features/events/hooks/useEvents.d.ts +1 -1
  89. package/dist/features/faq/actions/faq-actions.js +4 -2
  90. package/dist/features/faq/components/FAQPageContent.js +2 -1
  91. package/dist/features/faq/hooks/useFAQs.d.ts +1 -1
  92. package/dist/features/faq/hooks/useFaqList.d.ts +15 -15
  93. package/dist/features/homepage/components/MarketplaceHomepageView.js +4 -2
  94. package/dist/features/homepage/hooks/useBlogArticles.d.ts +1 -1
  95. package/dist/features/homepage/hooks/useFeaturedAuctions.d.ts +1 -1
  96. package/dist/features/homepage/hooks/useFeaturedPreOrders.d.ts +1 -1
  97. package/dist/features/homepage/hooks/useFeaturedProducts.d.ts +1 -1
  98. package/dist/features/homepage/hooks/useFeaturedStores.d.ts +1 -1
  99. package/dist/features/homepage/hooks/useHeroCarousel.d.ts +1 -1
  100. package/dist/features/homepage/hooks/useHomepageEvents.d.ts +1 -1
  101. package/dist/features/homepage/hooks/useHomepageReviews.d.ts +1 -1
  102. package/dist/features/homepage/hooks/useHomepageSections.d.ts +1 -1
  103. package/dist/features/homepage/hooks/useTopBrands.d.ts +1 -1
  104. package/dist/features/homepage/hooks/useTopCategories.d.ts +1 -1
  105. package/dist/features/layout/BottomActions.js +0 -27
  106. package/dist/features/layout/BottomActionsContext.d.ts +0 -36
  107. package/dist/features/layout/BottomActionsContext.js +0 -36
  108. package/dist/features/live/components/LiveItemsListView.js +6 -5
  109. package/dist/features/loyalty/hooks/useLoyaltyBalance.d.ts +1 -1
  110. package/dist/features/orders/hooks/useOrders.d.ts +2 -2
  111. package/dist/features/payments/hooks/usePayments.d.ts +1 -1
  112. package/dist/features/pre-orders/components/PreOrdersListView.js +5 -4
  113. package/dist/features/pre-orders/hooks/usePreOrders.d.ts +2 -2
  114. package/dist/features/products/actions/product-actions.js +17 -15
  115. package/dist/features/products/columns/index.d.ts +1 -1
  116. package/dist/features/products/columns/index.js +1 -1
  117. package/dist/features/products/components/PrizeDrawCollage.js +0 -14
  118. package/dist/features/products/components/PrizeDrawsListingView.js +5 -4
  119. package/dist/features/products/components/PrizeDrawsSection.js +4 -2
  120. package/dist/features/products/constants/sieve.d.ts +2 -2
  121. package/dist/features/products/constants/sieve.js +2 -2
  122. package/dist/features/products/hooks/useProductDetail.d.ts +1 -1
  123. package/dist/features/products/hooks/useRelatedProducts.d.ts +1 -1
  124. package/dist/features/products/hooks/useRelatedProducts.js +5 -4
  125. package/dist/features/promotions/hooks/usePromotions.d.ts +2 -2
  126. package/dist/features/reviews/actions/review-actions.js +2 -1
  127. package/dist/features/reviews/components/ReviewsIndexPageView.js +7 -6
  128. package/dist/features/reviews/hooks/useReviews.d.ts +2 -2
  129. package/dist/features/scams/actions/scam-actions.js +3 -2
  130. package/dist/features/scams/components/ScamRegistryView.js +5 -4
  131. package/dist/features/search/actions/search-actions.js +7 -6
  132. package/dist/features/search/hooks/useSearch.d.ts +2 -2
  133. package/dist/features/seller/components/CouponInlineSelect.js +2 -1
  134. package/dist/features/seller/components/SellerAuctionsView.js +7 -5
  135. package/dist/features/seller/components/SellerBidsView.js +5 -3
  136. package/dist/features/seller/components/SellerBundlesView.js +7 -6
  137. package/dist/features/seller/components/SellerClassifiedView.js +6 -5
  138. package/dist/features/seller/components/SellerCouponsView.js +6 -4
  139. package/dist/features/seller/components/SellerDigitalCodesView.js +5 -4
  140. package/dist/features/seller/components/SellerGroupedListingsView.js +5 -4
  141. package/dist/features/seller/components/SellerLiveView.js +6 -5
  142. package/dist/features/seller/components/SellerOffersView.js +6 -4
  143. package/dist/features/seller/components/SellerOrdersView.js +5 -3
  144. package/dist/features/seller/components/SellerPayoutMethodsView.js +3 -2
  145. package/dist/features/seller/components/SellerPayoutsView.js +6 -4
  146. package/dist/features/seller/components/SellerPreOrdersView.js +6 -4
  147. package/dist/features/seller/components/SellerPrizeDrawsView.js +6 -4
  148. package/dist/features/seller/components/SellerProductsView.js +9 -7
  149. package/dist/features/seller/components/SellerShippingConfigsView.js +3 -2
  150. package/dist/features/seller/components/SellerStoreCategoriesView.js +4 -3
  151. package/dist/features/seller/components/SellerTemplatesView.js +4 -3
  152. package/dist/features/seller/components/SublistingInlineSelect.js +2 -1
  153. package/dist/features/seller/hooks/useSellerPayouts.d.ts +3 -3
  154. package/dist/features/seller/hooks/useSellerStore.d.ts +6 -6
  155. package/dist/features/seller/hooks/useSellerStorefront.d.ts +2 -2
  156. package/dist/features/stores/actions/store-query-actions.js +3 -2
  157. package/dist/features/stores/components/StoreAuctionsPageView.js +4 -2
  158. package/dist/features/stores/components/StoreDetailLayoutView.d.ts +1 -1
  159. package/dist/features/stores/components/StoreDetailLayoutView.js +7 -6
  160. package/dist/features/stores/components/StorePreOrdersPageView.js +4 -2
  161. package/dist/features/stores/components/StorePrizeDrawsPageView.js +4 -2
  162. package/dist/features/stores/components/StoreProductsPageView.js +2 -1
  163. package/dist/features/stores/components/StoreProductsView.js +5 -4
  164. package/dist/features/stores/components/StoresIndexListing.js +4 -3
  165. package/dist/features/stores/hooks/useStoreAddressSelector.d.ts +1 -1
  166. package/dist/features/stores/hooks/useStores.d.ts +6 -6
  167. package/dist/features/wishlist/components/WishlistView.js +4 -3
  168. package/dist/features/wishlist/hooks/useUserWishlist.d.ts +15 -15
  169. package/dist/features/wishlist/hooks/useWishlist.d.ts +1 -1
  170. package/dist/features/wishlist/hooks/useWishlistWithGuest.d.ts +1 -1
  171. package/package.json +1 -1
@@ -1,7 +1,7 @@
1
1
  import type { CollectionItem, CollectionListItem } from "../types";
2
2
  export declare function useCollections(opts?: {
3
3
  endpoint?: string;
4
- }): import("@tanstack/react-query").UseQueryResult<NoInfer<CollectionListItem[]>, Error>;
4
+ }): import("@tanstack/react-query").UseQueryResult<CollectionListItem[], Error>;
5
5
  export declare function useCollection(slug: string | undefined, opts?: {
6
6
  endpoint?: string;
7
- }): import("@tanstack/react-query").UseQueryResult<NoInfer<CollectionItem | null>, Error>;
7
+ }): import("@tanstack/react-query").UseQueryResult<CollectionItem | null, Error>;
@@ -3,7 +3,7 @@ import type { IRepository } from "../../../contracts";
3
3
  * Built-in job: Close live auctions whose `endTime` has passed.
4
4
  *
5
5
  * Run interval: every 5 minutes (recommended).
6
- * Requires an `IRepository<AuctionDocument>` injected at registration time.
6
+ * Requires an sieveFilter("IRepository", SIEVE_OP.LT, "AuctionDocument>") injected at registration time.
7
7
  *
8
8
  * @example
9
9
  * ```ts
@@ -23,5 +23,5 @@ interface AuctionDocument {
23
23
  highestBidAmount?: number;
24
24
  closedAt?: string;
25
25
  }
26
- export declare function createAuctionExpiryJob(auctionRepo: IRepository<AuctionDocument>): import("..").CronJobDefinition;
26
+ export declare function createAuctionExpiryJob(auctionRepo: IRepository<AuctionDocument>): import("@mohasinac/appkit").CronJobDefinition;
27
27
  export {};
@@ -1,3 +1,4 @@
1
+ import { sieveFilter, sieveAnd, SIEVE_OP } from "@mohasinac/appkit";
1
2
  import { createCronJob } from "../registry";
2
3
  export function createAuctionExpiryJob(auctionRepo) {
3
4
  return createCronJob({
@@ -9,7 +10,7 @@ export function createAuctionExpiryJob(auctionRepo) {
9
10
  timeoutSeconds: 60,
10
11
  }, async (ctx) => {
11
12
  const result = await auctionRepo.findAll({
12
- filters: `status==live,endTime<=${ctx.scheduleTime}`,
13
+ filters: sieveAnd(sieveFilter("status", SIEVE_OP.EQ, "live"), sieveFilter("endTime", SIEVE_OP.LTE, ctx.scheduleTime)),
13
14
  perPage: 500,
14
15
  });
15
16
  let processed = 0;
@@ -10,5 +10,5 @@ interface PreOrderDocument {
10
10
  status: string;
11
11
  expectedShippingDate?: string;
12
12
  }
13
- export declare function createPreOrderReminderJob(preOrderRepo: IRepository<PreOrderDocument>): import("..").CronJobDefinition;
13
+ export declare function createPreOrderReminderJob(preOrderRepo: IRepository<PreOrderDocument>): import("@mohasinac/appkit").CronJobDefinition;
14
14
  export {};
@@ -1,3 +1,4 @@
1
+ import { sieveFilter, sieveAnd, SIEVE_OP } from "@mohasinac/appkit";
1
2
  import { createCronJob } from "../registry";
2
3
  export function createPreOrderReminderJob(preOrderRepo) {
3
4
  const sevenDaysFromNow = () => {
@@ -15,7 +16,7 @@ export function createPreOrderReminderJob(preOrderRepo) {
15
16
  }, async () => {
16
17
  const cutoff = sevenDaysFromNow();
17
18
  const result = await preOrderRepo.findAll({
18
- filters: `status==confirmed,expectedShippingDate<=${cutoff}`,
19
+ filters: sieveAnd(sieveFilter("status", SIEVE_OP.EQ, "confirmed"), sieveFilter("expectedShippingDate", SIEVE_OP.LTE, cutoff)),
19
20
  perPage: 500,
20
21
  });
21
22
  let processed = 0;
@@ -1,4 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { sieveFilter, SIEVE_OP } from "@mohasinac/appkit";
2
3
  import { productRepository } from "../../../repositories";
3
4
  import { Container, Heading, Main, Section } from "../../../ui";
4
5
  import { AdSlot } from "../../homepage/components/AdSlot";
@@ -16,12 +17,12 @@ function buildDigitalCodeFilters(params) {
16
17
  const minPrice = sp(params, "minPrice");
17
18
  const maxPrice = sp(params, "maxPrice");
18
19
  if (minPrice)
19
- parts.push(`price>=${minPrice}`);
20
+ parts.push(sieveFilter("price", SIEVE_OP.GTE, minPrice));
20
21
  if (maxPrice)
21
- parts.push(`price<=${maxPrice}`);
22
+ parts.push(sieveFilter("price", SIEVE_OP.LTE, maxPrice));
22
23
  const deliveryMethod = sp(params, "deliveryMethod");
23
24
  if (deliveryMethod)
24
- parts.push(`digitalCodeDelivery==${deliveryMethod}`);
25
+ parts.push(sieveFilter("digitalCodeDelivery", SIEVE_OP.EQ, deliveryMethod));
25
26
  return parts.join(",");
26
27
  }
27
28
  export async function DigitalCodesListView({ searchParams = {} }) {
@@ -4,6 +4,8 @@
4
4
  * Business logic for event CRUD, status changes, entries, and public access.
5
5
  * Auth, rate-limiting, and input validation are handled by the calling server action.
6
6
  */
7
+ import { sieveFilter, SIEVE_OP } from "@mohasinac/appkit";
8
+ import { sortBy } from "@mohasinac/appkit";
7
9
  import { serverLogger } from "../../../monitoring";
8
10
  import { eventRepository } from "../repository/events.repository";
9
11
  import { eventEntryRepository } from "../repository/event-entry.repository";
@@ -108,13 +110,13 @@ export async function listPublicEvents(params) {
108
110
  if (!filters) {
109
111
  const parts = [];
110
112
  if (sp.has("status"))
111
- parts.push(`status==${sp.get("status")}`);
113
+ parts.push(sieveFilter("status", SIEVE_OP.EQ, sp.get("status")));
112
114
  if (sp.has("type"))
113
- parts.push(`type==${sp.get("type")}`);
115
+ parts.push(sieveFilter("type", SIEVE_OP.EQ, sp.get("type")));
114
116
  if (sp.has("types")) {
115
117
  const types = sp.get("types").split(",");
116
118
  if (types.length === 1)
117
- parts.push(`type==${types[0]}`);
119
+ parts.push(sieveFilter("type", SIEVE_OP.EQ, types[0]));
118
120
  }
119
121
  if (parts.length)
120
122
  filters = parts.join(",");
@@ -157,7 +159,7 @@ export async function adminGetEventById(id) {
157
159
  }
158
160
  export async function adminGetEventEntries(eventId, params) {
159
161
  const result = await eventEntryRepository.listForEvent(eventId, {
160
- sorts: "-createdAt",
162
+ sorts: sortBy("createdAt", "DESC"),
161
163
  page: params?.page ?? 1,
162
164
  pageSize: params?.pageSize ?? 50,
163
165
  });
@@ -52,7 +52,7 @@ const FORM_FIELD_TYPE_OPTIONS = [
52
52
  { label: "Checkbox", value: "checkbox" },
53
53
  { label: "Radio", value: "radio" },
54
54
  { label: "Date", value: "date" },
55
- { label: "Rating (1–5)", value: "rating" },
55
+ { label: "Rating (1–5)", value: "rating" }, // audit-sieve-views-ok — form field type, not sort key
56
56
  { label: "File upload", value: "file" },
57
57
  ];
58
58
  const FIELD_TYPES_WITH_OPTIONS = ["select", "multiselect", "radio", "checkbox"];
@@ -1,5 +1,7 @@
1
1
  "use client";
2
2
  import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { sieveFilter, SIEVE_OP } from "@mohasinac/appkit";
4
+ import { sortBy } from "@mohasinac/appkit";
3
5
  import React from "react";
4
6
  import { FilterChipGroup, ListingLayout } from "../../../ui";
5
7
  import { ADMIN_ENDPOINTS } from "../../../constants/api-endpoints";
@@ -29,13 +31,13 @@ export function AdminEventsView({ children, ...props }) {
29
31
  searchPlaceholder: "Search events by title or type",
30
32
  emptyLabel: "No events found",
31
33
  filterKeys: ["status", "type"],
32
- defaultSort: "-startsAt",
34
+ defaultSort: sortBy("startsAt", "DESC"),
33
35
  queryKey: ["admin", "events", "listing"],
34
36
  endpoint: ADMIN_ENDPOINTS.EVENTS,
35
37
  sortOptions: [
36
- { value: "-startsAt", label: "Starting soonest" },
38
+ { value: sortBy("startsAt", "DESC"), label: "Starting soonest" },
37
39
  { value: "startsAt", label: "Starting latest" },
38
- { value: "-createdAt", label: "Newest" },
40
+ { value: sortBy("createdAt", "DESC"), label: "Newest" },
39
41
  { value: "title", label: "Title A–Z" },
40
42
  ],
41
43
  mapRows: (response) => toRecordArray(response.items).map((item, index) => ({
@@ -51,9 +53,9 @@ export function AdminEventsView({ children, ...props }) {
51
53
  buildFilters: (state) => {
52
54
  const parts = [];
53
55
  if (state.status && state.status !== "All")
54
- parts.push(`status==${state.status}`);
56
+ parts.push(sieveFilter("status", SIEVE_OP.EQ, state.status));
55
57
  if (state.type && state.type !== "All")
56
- parts.push(`type==${state.type}`);
58
+ parts.push(sieveFilter("type", SIEVE_OP.EQ, state.type));
57
59
  return parts.join(",") || undefined;
58
60
  },
59
61
  primaryAction: {
@@ -24,7 +24,7 @@ export declare const EVENT_ADMIN_SORT_OPTIONS: readonly [{
24
24
  readonly value: string;
25
25
  readonly label: "Ends Soonest";
26
26
  }, {
27
- readonly value: "-stats.totalEntries";
27
+ readonly value: string;
28
28
  readonly label: "Most Entries";
29
29
  }, {
30
30
  readonly value: string;
@@ -49,7 +49,7 @@ export declare const EVENT_SELLER_SORT_OPTIONS: readonly [{
49
49
  readonly value: string;
50
50
  readonly label: "Ends Soonest";
51
51
  }, {
52
- readonly value: "-stats.totalEntries";
52
+ readonly value: string;
53
53
  readonly label: "Most Entries";
54
54
  }, {
55
55
  readonly value: string;
@@ -68,7 +68,7 @@ export declare const EVENT_PUBLIC_SORT_OPTIONS: readonly [{
68
68
  readonly value: string;
69
69
  readonly label: "Title Z–A";
70
70
  }, {
71
- readonly value: "-stats.totalEntries";
71
+ readonly value: string;
72
72
  readonly label: "Most Entries";
73
73
  }];
74
74
  export declare const EVENT_SORT_OPTIONS: readonly [{
@@ -90,7 +90,7 @@ export declare const EVENT_SORT_OPTIONS: readonly [{
90
90
  readonly value: string;
91
91
  readonly label: "Ends Soonest";
92
92
  }, {
93
- readonly value: "-stats.totalEntries";
93
+ readonly value: string;
94
94
  readonly label: "Most Entries";
95
95
  }, {
96
96
  readonly value: string;
@@ -20,7 +20,7 @@ export const EVENT_ADMIN_SORT_OPTIONS = [
20
20
  { value: sortBy(EVENT_FIELDS.STARTS_AT, "ASC"), label: "Starts Soonest" },
21
21
  { value: sortBy(EVENT_FIELDS.ENDS_AT), label: "Ends Latest" },
22
22
  { value: sortBy(EVENT_FIELDS.ENDS_AT, "ASC"), label: "Ends Soonest" },
23
- { value: "-stats.totalEntries", label: "Most Entries" },
23
+ { value: sortBy("stats.totalEntries", "DESC"), label: "Most Entries" },
24
24
  { value: sortBy(EVENT_FIELDS.CREATED_AT), label: "Newest First" },
25
25
  ];
26
26
  export const EVENT_SELLER_SORT_OPTIONS = EVENT_ADMIN_SORT_OPTIONS;
@@ -29,7 +29,7 @@ export const EVENT_PUBLIC_SORT_OPTIONS = [
29
29
  { value: sortBy(EVENT_FIELDS.STARTS_AT), label: "Starts Latest" },
30
30
  { value: sortBy(EVENT_FIELDS.TITLE, "ASC"), label: "Title A–Z" },
31
31
  { value: sortBy(EVENT_FIELDS.TITLE), label: "Title Z–A" },
32
- { value: "-stats.totalEntries", label: "Most Entries" },
32
+ { value: sortBy("stats.totalEntries", "DESC"), label: "Most Entries" },
33
33
  ];
34
34
  // Backward-compatible alias.
35
35
  export const EVENT_SORT_OPTIONS = EVENT_ADMIN_SORT_OPTIONS;
@@ -1,4 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { sieveFilter, sieveAnd, SIEVE_OP } from "@mohasinac/appkit";
3
+ import { sortBy } from "@mohasinac/appkit";
2
4
  import Link from "next/link";
3
5
  import { Container, Div, Heading, Section, Stack, Text, } from "../../../ui";
4
6
  import { ROUTES } from "../../../next";
@@ -15,8 +17,8 @@ export async function EventRafflesSection({ config, }) {
15
17
  let events = [];
16
18
  try {
17
19
  const result = await eventRepository.list({
18
- filters: "hasRaffle==true,status==active",
19
- sorts: "-startsAt",
20
+ filters: sieveAnd(sieveFilter("hasRaffle", SIEVE_OP.EQ, "true"), sieveFilter("status", SIEVE_OP.EQ, "active")),
21
+ sorts: sortBy("startsAt", "DESC"),
20
22
  pageSize: limit,
21
23
  });
22
24
  events = (result.items ?? []);
@@ -16,7 +16,7 @@ export declare function useEvent<T extends EventItem = EventItem>(id: string, op
16
16
  event: T | null;
17
17
  isLoading: boolean;
18
18
  error: string | null;
19
- refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<NoInfer<EventItem | null>, Error>>;
19
+ refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<EventItem | null, Error>>;
20
20
  };
21
21
  export declare function useEventEntries(eventId: string, params?: {
22
22
  page?: number;
@@ -30,13 +30,13 @@ export declare function useEventEntries(eventId: string, params?: {
30
30
  total: number;
31
31
  isLoading: boolean;
32
32
  error: string | null;
33
- refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<NoInfer<EventEntryListResponse>, Error>>;
33
+ refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<EventEntryListResponse, Error>>;
34
34
  };
35
35
  export declare function useEventLeaderboard(eventId: string, limit?: number, opts?: {
36
36
  enabled?: boolean;
37
37
  endpoint?: string;
38
38
  }): {
39
- leaderboard: NoInfer<LeaderboardEntry[]>;
39
+ leaderboard: LeaderboardEntry[];
40
40
  isLoading: boolean;
41
41
  error: string | null;
42
42
  };
@@ -23,6 +23,6 @@ export declare function useEvents<T extends EventItem = EventItem>(params?: Even
23
23
  hasMore: boolean;
24
24
  isLoading: boolean;
25
25
  error: string | null;
26
- refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<NoInfer<EventListResponse>, Error>>;
26
+ refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<EventListResponse, Error>>;
27
27
  };
28
28
  export {};
@@ -1,5 +1,7 @@
1
+ import { sieveFilter, SIEVE_OP } from "@mohasinac/appkit";
1
2
  import { z } from "zod";
2
3
  import { serverLogger } from "../../../monitoring";
4
+ import { sortBy } from "../../../constants/sort";
3
5
  import { faqsRepository } from "../repository/faqs.repository";
4
6
  // --- Schemas --------------------------------------------------------------
5
7
  const faqBaseSchema = z.object({
@@ -89,10 +91,10 @@ export async function listFaqs(params) {
89
91
  export async function listPublicFaqs(category, limit = 20) {
90
92
  const filters = ["isActive==true"];
91
93
  if (category)
92
- filters.push(`category==${category}`);
94
+ filters.push(sieveFilter("category", SIEVE_OP.EQ, category));
93
95
  const result = await faqsRepository.list({
94
96
  filters: filters.join(","),
95
- sorts: "-priority,order",
97
+ sorts: [sortBy("priority", "DESC"), sortBy("order", "ASC")].join(","),
96
98
  page: 1,
97
99
  pageSize: limit,
98
100
  });
@@ -1,6 +1,7 @@
1
1
  "use client";
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { Div, Heading, Input, SlottedListingView, Text } from "../../../ui";
4
+ import { sortBy } from "../../../constants/sort";
4
5
  import { FAQCategorySidebar } from "./FAQCategorySidebar";
5
6
  import { FAQSortDropdown } from "./FAQSortDropdown";
6
7
  import { FAQAccordion } from "./FAQAccordion";
@@ -22,7 +23,7 @@ export function FAQPageContent({ initialCategory = "all", categories, routeHelpe
22
23
  });
23
24
  const { faqs: allMatchingFaqs } = useFaqList({
24
25
  search: searchValue.trim() || undefined,
25
- sorts: "-priority,order",
26
+ sorts: [sortBy("priority", "DESC"), sortBy("order", "ASC")].join(","),
26
27
  page: 1,
27
28
  pageSize: 200,
28
29
  });
@@ -15,7 +15,7 @@ export declare function useFAQ(id: string, opts?: {
15
15
  enabled?: boolean;
16
16
  endpoint?: string;
17
17
  }): {
18
- faq: NoInfer<FAQ> | undefined;
18
+ faq: FAQ | undefined;
19
19
  isLoading: boolean;
20
20
  error: Error | null;
21
21
  };
@@ -14,7 +14,7 @@ export declare function useFaqList(options?: UseFaqListOptions): {
14
14
  faqs: import("..").FAQ[];
15
15
  total: number;
16
16
  categories: readonly string[];
17
- data: NoInfer<FAQListResponse>;
17
+ data: FAQListResponse;
18
18
  error: Error;
19
19
  isError: true;
20
20
  isPending: false;
@@ -37,14 +37,14 @@ export declare function useFaqList(options?: UseFaqListOptions): {
37
37
  isRefetching: boolean;
38
38
  isStale: boolean;
39
39
  isEnabled: boolean;
40
- refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<NoInfer<FAQListResponse>, Error>>;
40
+ refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<FAQListResponse, Error>>;
41
41
  fetchStatus: import("@tanstack/query-core").FetchStatus;
42
- promise: Promise<NoInfer<FAQListResponse>>;
42
+ promise: Promise<FAQListResponse>;
43
43
  } | {
44
44
  faqs: import("..").FAQ[];
45
45
  total: number;
46
46
  categories: readonly string[];
47
- data: NoInfer<FAQListResponse>;
47
+ data: FAQListResponse;
48
48
  error: null;
49
49
  isError: false;
50
50
  isPending: false;
@@ -67,9 +67,9 @@ export declare function useFaqList(options?: UseFaqListOptions): {
67
67
  isRefetching: boolean;
68
68
  isStale: boolean;
69
69
  isEnabled: boolean;
70
- refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<NoInfer<FAQListResponse>, Error>>;
70
+ refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<FAQListResponse, Error>>;
71
71
  fetchStatus: import("@tanstack/query-core").FetchStatus;
72
- promise: Promise<NoInfer<FAQListResponse>>;
72
+ promise: Promise<FAQListResponse>;
73
73
  } | {
74
74
  faqs: import("..").FAQ[];
75
75
  total: number;
@@ -97,9 +97,9 @@ export declare function useFaqList(options?: UseFaqListOptions): {
97
97
  isRefetching: boolean;
98
98
  isStale: boolean;
99
99
  isEnabled: boolean;
100
- refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<NoInfer<FAQListResponse>, Error>>;
100
+ refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<FAQListResponse, Error>>;
101
101
  fetchStatus: import("@tanstack/query-core").FetchStatus;
102
- promise: Promise<NoInfer<FAQListResponse>>;
102
+ promise: Promise<FAQListResponse>;
103
103
  } | {
104
104
  faqs: import("..").FAQ[];
105
105
  total: number;
@@ -127,9 +127,9 @@ export declare function useFaqList(options?: UseFaqListOptions): {
127
127
  isRefetching: boolean;
128
128
  isStale: boolean;
129
129
  isEnabled: boolean;
130
- refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<NoInfer<FAQListResponse>, Error>>;
130
+ refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<FAQListResponse, Error>>;
131
131
  fetchStatus: import("@tanstack/query-core").FetchStatus;
132
- promise: Promise<NoInfer<FAQListResponse>>;
132
+ promise: Promise<FAQListResponse>;
133
133
  } | {
134
134
  faqs: import("..").FAQ[];
135
135
  total: number;
@@ -157,14 +157,14 @@ export declare function useFaqList(options?: UseFaqListOptions): {
157
157
  isRefetching: boolean;
158
158
  isStale: boolean;
159
159
  isEnabled: boolean;
160
- refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<NoInfer<FAQListResponse>, Error>>;
160
+ refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<FAQListResponse, Error>>;
161
161
  fetchStatus: import("@tanstack/query-core").FetchStatus;
162
- promise: Promise<NoInfer<FAQListResponse>>;
162
+ promise: Promise<FAQListResponse>;
163
163
  } | {
164
164
  faqs: import("..").FAQ[];
165
165
  total: number;
166
166
  categories: readonly string[];
167
- data: NoInfer<FAQListResponse>;
167
+ data: FAQListResponse;
168
168
  isError: false;
169
169
  error: null;
170
170
  isPending: false;
@@ -187,8 +187,8 @@ export declare function useFaqList(options?: UseFaqListOptions): {
187
187
  isRefetching: boolean;
188
188
  isStale: boolean;
189
189
  isEnabled: boolean;
190
- refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<NoInfer<FAQListResponse>, Error>>;
190
+ refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<FAQListResponse, Error>>;
191
191
  fetchStatus: import("@tanstack/query-core").FetchStatus;
192
- promise: Promise<NoInfer<FAQListResponse>>;
192
+ promise: Promise<FAQListResponse>;
193
193
  };
194
194
  export {};
@@ -1,4 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { sieveFilter, SIEVE_OP } from "@mohasinac/appkit";
3
+ import { sortBy } from "@mohasinac/appkit";
2
4
  import { Main } from "../../../ui";
3
5
  import { carouselRepository, faqsRepository, siteSettingsRepository } from "../../../repositories";
4
6
  import { fetchLiveStats } from "../lib/live-stats";
@@ -78,9 +80,9 @@ export async function MarketplaceHomepageView({ adSlots, newsletterFormSlot, onB
78
80
  activeTypes.has("categories") ? listTopLevelCategories(12).catch(() => null) : null,
79
81
  activeTypes.has("brands") ? listBrandCategories(12).catch(() => null) : null,
80
82
  activeTypes.has("featured-bundles") ? listFeaturedBundles(8).catch(() => null) : null,
81
- activeTypes.has("stores") ? listStores({ pageSize: 8, sorts: "-averageRating" }).catch(() => null) : null,
83
+ activeTypes.has("stores") ? listStores({ pageSize: 8, sorts: sortBy("averageRating", "DESC") }).catch(() => null) : null,
82
84
  activeTypes.has("blog-articles") ? getFeaturedBlogPosts(6).catch(() => null) : null,
83
- activeTypes.has("events") ? listPublicEvents({ filters: "status==active", pageSize: 6 }).catch(() => null) : null,
85
+ activeTypes.has("events") ? listPublicEvents({ filters: sieveFilter("status", SIEVE_OP.EQ, "active"), pageSize: 6 }).catch(() => null) : null,
84
86
  ]);
85
87
  // ProductDocument / BlogDocument / EventDocument have Date fields and extra Firestore-only
86
88
  // fields absent from the corresponding *Item types. The casts below are safe: section
@@ -10,4 +10,4 @@ export interface BlogListResult {
10
10
  export declare function useBlogArticles(options?: {
11
11
  endpoint?: string;
12
12
  initialPosts?: BlogListResult["posts"];
13
- }): import("@tanstack/react-query").UseQueryResult<NoInfer<BlogListResult>, Error>;
13
+ }): import("@tanstack/react-query").UseQueryResult<BlogListResult, Error>;
@@ -2,4 +2,4 @@ import type { ProductItem } from "@mohasinac/appkit/features/products";
2
2
  export declare function useFeaturedAuctions(options?: {
3
3
  filterByBrand?: string;
4
4
  initialData?: ProductItem[];
5
- }): import("@tanstack/react-query").UseQueryResult<NoInfer<ProductItem[]>, Error>;
5
+ }): import("@tanstack/react-query").UseQueryResult<ProductItem[], Error>;
@@ -2,4 +2,4 @@ import type { ProductItem } from "@mohasinac/appkit/features/products";
2
2
  export declare function useFeaturedPreOrders(options?: {
3
3
  filterByBrand?: string;
4
4
  initialData?: ProductItem[];
5
- }): import("@tanstack/react-query").UseQueryResult<NoInfer<ProductItem[]>, Error>;
5
+ }): import("@tanstack/react-query").UseQueryResult<ProductItem[], Error>;
@@ -2,4 +2,4 @@ import type { ProductListResponse } from "../../products/types";
2
2
  export declare function useFeaturedProducts(options?: {
3
3
  initialData?: ProductListResponse;
4
4
  filterByBrand?: string;
5
- }): import("@tanstack/react-query").UseQueryResult<NoInfer<ProductListResponse>, Error>;
5
+ }): import("@tanstack/react-query").UseQueryResult<ProductListResponse, Error>;
@@ -1,4 +1,4 @@
1
1
  import type { StoreListItem } from "../../stores/types";
2
2
  export declare function useFeaturedStores(limit?: number, options?: {
3
3
  initialData?: StoreListItem[];
4
- }): import("@tanstack/react-query").UseQueryResult<NoInfer<StoreListItem[]>, Error>;
4
+ }): import("@tanstack/react-query").UseQueryResult<StoreListItem[], Error>;
@@ -6,4 +6,4 @@ import type { CarouselSlide } from "../types/index";
6
6
  */
7
7
  export declare function useHeroCarousel(options?: {
8
8
  initialData?: CarouselSlide[];
9
- }): import("@tanstack/react-query").UseQueryResult<NoInfer<CarouselSlide[]>, Error>;
9
+ }): import("@tanstack/react-query").UseQueryResult<CarouselSlide[], Error>;
@@ -5,4 +5,4 @@ export interface HomepageEventsListResponse {
5
5
  }
6
6
  export declare function useHomepageEvents(limit?: number, options?: {
7
7
  initialData?: EventItem[];
8
- }): import("@tanstack/react-query").UseQueryResult<NoInfer<EventItem[]>, Error>;
8
+ }): import("@tanstack/react-query").UseQueryResult<EventItem[], Error>;
@@ -4,4 +4,4 @@ export interface UseHomepageReviewsOptions {
4
4
  initialData?: Review[];
5
5
  staleTime?: number;
6
6
  }
7
- export declare function useHomepageReviews(options?: UseHomepageReviewsOptions): import("@tanstack/react-query").UseQueryResult<NoInfer<Review[]>, Error>;
7
+ export declare function useHomepageReviews(options?: UseHomepageReviewsOptions): import("@tanstack/react-query").UseQueryResult<Review[], Error>;
@@ -1,2 +1,2 @@
1
1
  import type { HomepageSectionDocument } from "../schemas";
2
- export declare function useHomepageSections(params?: string): import("@tanstack/react-query").UseQueryResult<NoInfer<HomepageSectionDocument[]>, Error>;
2
+ export declare function useHomepageSections(params?: string): import("@tanstack/react-query").UseQueryResult<HomepageSectionDocument[], Error>;
@@ -1,4 +1,4 @@
1
1
  import type { CategoryItem } from "../../categories/types";
2
2
  export declare function useTopBrands(limit?: number, options?: {
3
3
  initialData?: CategoryItem[];
4
- }): import("@tanstack/react-query").UseQueryResult<NoInfer<CategoryItem[]>, Error>;
4
+ }): import("@tanstack/react-query").UseQueryResult<CategoryItem[], Error>;
@@ -1,4 +1,4 @@
1
1
  import type { CategoryItem } from "../../categories/types";
2
2
  export declare function useTopCategories(limit?: number, options?: {
3
3
  initialData?: CategoryItem[];
4
- }): import("@tanstack/react-query").UseQueryResult<NoInfer<CategoryItem[]>, Error>;
4
+ }): import("@tanstack/react-query").UseQueryResult<CategoryItem[], Error>;
@@ -1,32 +1,5 @@
1
1
  "use client";
2
2
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
- /**
4
- * BottomActions Component
5
- *
6
- * A fixed-bottom mobile action bar rendered **above** BottomNavbar (bottom-14).
7
- * Reads from `BottomActionsContext` — features register their actions via the
8
- * `useBottomActions` hook; this component just renders whatever is registered.
9
- *
10
- * Two modes:
11
- * - **Page mode** — shows registered page-level actions inline (Add to Cart,
12
- * Buy Now, Place Bid, Proceed to Checkout, etc.) with an optional info label.
13
- * - **Bulk mode** — activates when `bulk.selectedCount > 0`; shows:
14
- * • Selection count pill on the left (tap to deselect all)
15
- * • An upward-opening type-picker dropdown (middle, flex-1) — tap to
16
- * choose WHICH action to run; the chosen label is always visible.
17
- * • An "Apply" submit button on the right — executes the selected action,
18
- * styled with the selected action's variant (danger = red, etc.).
19
- *
20
- * Layout rules:
21
- * - Hidden on lg+ screens (`lg:hidden`) — desktop shows inline action panels.
22
- * - The bar slides up with a 300 ms ease-out transition; `pointer-events-none`
23
- * while off-screen.
24
- *
25
- * @component
26
- * @example
27
- * // Automatically rendered by LayoutClient — no manual usage required.
28
- * // Features use `useBottomActions` to register their actions.
29
- */
30
3
  import { useState, useRef, useEffect } from "react";
31
4
  import { X, ChevronUp, ChevronDown, Check } from "lucide-react";
32
5
  import { useBottomActionsContext } from "./BottomActionsContext";
@@ -1,39 +1,3 @@
1
- /**
2
- * BottomActionsContext
3
- *
4
- * Provides a context for registering page-level mobile action bars.
5
- * Features call `useBottomActions` to push actions; the `<BottomActions>`
6
- * layout component reads this context and renders the bar above BottomNavbar.
7
- *
8
- * Supports two modes:
9
- * - Page mode: primary page actions (Add to Cart, Buy Now, Place Bid, etc.)
10
- * - Bulk mode: activated when `bulk.selectedCount > 0` — shows selection
11
- * count + custom bulk action buttons (Delete, Archive, Export, etc.)
12
- *
13
- * @example — product detail page
14
- * ```tsx
15
- * useBottomActions({
16
- * actions: [
17
- * { id: "wishlist", icon: <Heart className="w-4 h-4" />, label: t("wishlist"), variant: "ghost", grow: false, onClick: handleWishlist },
18
- * { id: "cart", label: t("addToCart"), variant: "outline", onClick: handleAddToCart },
19
- * { id: "buy", label: t("buyNow"), variant: "primary", onClick: handleBuyNow },
20
- * ],
21
- * });
22
- * ```
23
- *
24
- * @example — admin listing with bulk select
25
- * ```tsx
26
- * useBottomActions({
27
- * bulk: {
28
- * selectedCount: selectedIds.length,
29
- * onClearSelection: () => setSelectedIds([]),
30
- * actions: [
31
- * { id: "delete", label: t("bulkDelete", { count: selectedIds.length }), variant: "danger", onClick: handleBulkDelete },
32
- * ],
33
- * },
34
- * });
35
- * ```
36
- */
37
1
  import React from "react";
38
2
  import type { ButtonProps } from "../../ui";
39
3
  export interface BottomAction {