@mohasinac/appkit 2.7.10 → 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.
- package/dist/_internal/server/jobs/core/assignSpinPrize.js +8 -7
- package/dist/_internal/server/jobs/core/bundleStockSync.js +11 -6
- package/dist/_internal/server/jobs/core/countersReconcile.js +3 -2
- package/dist/_internal/server/jobs/core/onProductStockChange.js +12 -7
- package/dist/_internal/server/jobs/core/onProductWrite.js +3 -2
- package/dist/_internal/server/jobs/core/prizeRevealClose.js +7 -5
- package/dist/_internal/server/jobs/core/prizeRevealExpiry.js +11 -6
- package/dist/_internal/server/jobs/core/prizeRevealOpen.js +13 -7
- package/dist/_internal/server/jobs/core/prizeRevealReminder.js +9 -4
- package/dist/_internal/server/jobs/core/triggerEventRaffle.js +3 -2
- package/dist/_internal/shared/features/blog/schema.d.ts +4 -4
- package/dist/_internal/shared/features/categories/bundle-schemas.d.ts +32 -32
- package/dist/_internal/shared/features/events/schema.d.ts +4 -4
- package/dist/_internal/shared/features/products/schema.d.ts +20 -20
- package/dist/_internal/shared/features/promotions/schema.d.ts +2 -2
- package/dist/_internal/shared/features/reviews/schema.d.ts +1 -1
- package/dist/configs/next.js +17 -1
- package/dist/constants/field-names.d.ts +813 -0
- package/dist/constants/field-names.js +918 -0
- package/dist/constants/sort.d.ts +7 -0
- package/dist/constants/sort.js +5 -0
- package/dist/constants/table-keys.d.ts +48 -0
- package/dist/constants/table-keys.js +46 -0
- package/dist/features/account/components/AddressesIndexListing.js +9 -6
- package/dist/features/admin/components/AdminAllEventEntriesView.js +4 -1
- package/dist/features/admin/components/AdminBidsView.js +4 -1
- package/dist/features/admin/components/AdminBlogView.js +9 -2
- package/dist/features/admin/components/AdminBrandsView.js +9 -2
- package/dist/features/admin/components/AdminCarouselView.js +4 -1
- package/dist/features/admin/components/AdminCartsView.js +4 -1
- package/dist/features/admin/components/AdminCategoriesView.js +9 -2
- package/dist/features/admin/components/AdminContactView.js +4 -1
- package/dist/features/admin/components/AdminCouponsView.js +4 -1
- package/dist/features/admin/components/AdminFaqsView.js +5 -1
- package/dist/features/admin/components/AdminFeaturesView.js +5 -2
- package/dist/features/admin/components/AdminHistoryView.js +5 -1
- package/dist/features/admin/components/AdminNewsletterView.js +4 -1
- package/dist/features/admin/components/AdminNotificationsView.js +4 -1
- package/dist/features/admin/components/AdminOrdersView.js +14 -12
- package/dist/features/admin/components/AdminPayoutsView.js +4 -1
- package/dist/features/admin/components/AdminPrizeDrawsView.js +4 -1
- package/dist/features/admin/components/AdminProductsView.js +14 -3
- package/dist/features/admin/components/AdminReturnRequestsView.js +4 -1
- package/dist/features/admin/components/AdminReviewsView.js +4 -1
- package/dist/features/admin/components/AdminScammersView.js +4 -1
- package/dist/features/admin/components/AdminSessionsView.js +4 -1
- package/dist/features/admin/components/AdminStoreAddressesView.js +5 -1
- package/dist/features/admin/components/AdminStoresView.js +10 -3
- package/dist/features/admin/components/AdminSublistingCategoriesView.js +4 -1
- package/dist/features/admin/components/AdminSupportTicketsView.js +4 -1
- package/dist/features/admin/components/AdminTeamView.js +4 -1
- package/dist/features/admin/components/AdminUsersView.js +9 -12
- package/dist/features/admin/components/AdminViewCards.d.ts +12 -0
- package/dist/features/admin/components/AdminViewCards.js +53 -0
- package/dist/features/admin/components/AdminWishlistsView.js +4 -1
- package/dist/features/auctions/repository/bid.repository.js +1 -6
- package/dist/features/auctions/schemas/index.d.ts +4 -4
- package/dist/features/blog/actions/blog-actions.d.ts +16 -16
- package/dist/features/blog/components/BlogFilters.d.ts +28 -28
- package/dist/features/blog/components/BlogFilters.js +18 -15
- package/dist/features/blog/components/BlogIndexListing.js +24 -13
- package/dist/features/blog/schemas/index.d.ts +10 -10
- package/dist/features/categories/components/CategoriesIndexListing.js +30 -19
- package/dist/features/categories/schemas/index.d.ts +2 -2
- package/dist/features/events/components/AdminEventsView.js +5 -1
- package/dist/features/events/components/EventFilters.d.ts +24 -24
- package/dist/features/events/components/EventFilters.js +16 -13
- package/dist/features/events/components/EventStatusBadge.js +1 -0
- package/dist/features/events/components/EventsIndexListing.js +36 -24
- package/dist/features/events/components/EventsListPageView.js +13 -10
- package/dist/features/events/schemas/firestore.d.ts +1 -0
- package/dist/features/events/schemas/firestore.js +1 -0
- package/dist/features/events/schemas/index.d.ts +1 -1
- package/dist/features/events/types/index.d.ts +1 -1
- package/dist/features/faq/actions/faq-actions.d.ts +10 -10
- package/dist/features/faq/schemas/index.d.ts +4 -4
- package/dist/features/layout/TitleBarLayout.js +1 -1
- package/dist/features/orders/components/OrderFilters.d.ts +20 -20
- package/dist/features/orders/components/OrderFilters.js +33 -30
- package/dist/features/orders/repository/orders.repository.js +1 -15
- package/dist/features/orders/schemas/index.d.ts +2 -2
- package/dist/features/pre-orders/components/PreOrdersIndexListing.js +44 -36
- package/dist/features/pre-orders/schemas/index.d.ts +3 -3
- package/dist/features/products/components/AuctionsIndexListing.js +63 -30
- package/dist/features/products/components/BidHistory.d.ts +0 -1
- package/dist/features/products/components/BidHistory.js +1 -1
- package/dist/features/products/components/PrizeDrawsIndexListing.js +44 -37
- package/dist/features/products/components/ProductDetailPageView.js +1 -1
- package/dist/features/products/components/ProductFilters.d.ts +20 -20
- package/dist/features/products/components/ProductFilters.js +62 -59
- package/dist/features/products/components/ProductsIndexListing.js +37 -29
- package/dist/features/products/components/ProductsIndexPageView.js +18 -10
- package/dist/features/products/hooks/useProducts.js +2 -0
- package/dist/features/products/repository/products.repository.js +2 -22
- package/dist/features/products/schemas/index.d.ts +28 -28
- package/dist/features/products/schemas/product-features.validators.d.ts +12 -12
- package/dist/features/products/types/index.d.ts +2 -0
- package/dist/features/promotions/components/CouponsIndexListing.js +21 -17
- package/dist/features/promotions/schemas/index.d.ts +4 -4
- package/dist/features/reviews/components/ReviewDetailShell.js +6 -5
- package/dist/features/reviews/components/ReviewFilters.d.ts +16 -16
- package/dist/features/reviews/components/ReviewFilters.js +10 -7
- package/dist/features/reviews/components/ReviewsIndexListing.js +25 -14
- package/dist/features/reviews/components/ReviewsList.d.ts +5 -2
- package/dist/features/reviews/components/ReviewsList.js +11 -5
- package/dist/features/reviews/schemas/firestore.d.ts +1 -0
- package/dist/features/reviews/schemas/index.d.ts +8 -8
- package/dist/features/reviews/types/index.d.ts +1 -0
- package/dist/features/search/schemas/index.d.ts +2 -2
- package/dist/features/seller/components/SellerAuctionsView.js +5 -1
- package/dist/features/seller/components/SellerBidsView.js +4 -1
- package/dist/features/seller/components/SellerCouponsView.js +4 -1
- package/dist/features/seller/components/SellerOffersView.js +5 -1
- package/dist/features/seller/components/SellerOrdersView.js +4 -1
- package/dist/features/seller/components/SellerPayoutsView.js +5 -1
- package/dist/features/seller/components/SellerPreOrdersView.js +4 -1
- package/dist/features/seller/components/SellerPrizeDrawsView.js +4 -1
- package/dist/features/seller/components/SellerProductsView.js +4 -1
- package/dist/features/seller/schemas/index.d.ts +10 -10
- package/dist/features/stores/api/route.js +10 -1
- package/dist/features/stores/components/StoreAuctionsListing.js +2 -1
- package/dist/features/stores/components/StorePreOrdersListing.js +2 -1
- package/dist/features/stores/components/StoreReviewsListing.js +1 -1
- package/dist/features/stores/components/StoresIndexListing.js +45 -27
- package/dist/features/stores/schemas/firestore.d.ts +1 -0
- package/dist/features/stores/schemas/index.d.ts +4 -4
- package/dist/index.d.ts +8 -1
- package/dist/index.js +12 -1
- package/dist/react/hooks/useUrlTable.js +2 -1
- package/dist/seed/bids-seed-data.js +45 -44
- package/dist/seed/categories-seed-data.js +41 -40
- package/dist/seed/coupons-seed-data.js +41 -40
- package/dist/seed/products-auctions-seed-data.js +54 -53
- package/dist/seed/products-preorders-seed-data.js +25 -24
- package/dist/seed/products-prize-draws-seed-data.js +24 -23
- package/dist/seed/products-standard-seed-data.js +294 -293
- package/dist/seed/reviews-seed-data.js +61 -60
- package/dist/seed/scammers-seed-data.js +3 -2
- package/dist/seed/stores-seed-data.js +9 -8
- package/dist/seed/support-tickets-seed-data.js +13 -12
- package/dist/seed/users-seed-data.js +28 -27
- package/dist/tailwind-utilities.css +1 -1
- package/dist/ui/components/ListingToolbar.d.ts +7 -4
- package/dist/ui/components/ListingToolbar.js +4 -3
- package/dist/ui/components/SiteLogo.js +1 -1
- package/dist/utils/sieve-builder.d.ts +41 -0
- package/dist/utils/sieve-builder.js +66 -0
- package/package.json +1 -1
|
@@ -4,6 +4,7 @@ import React, { useState, useCallback } from "react";
|
|
|
4
4
|
import { useActionDispatch } from "../../../react/hooks/use-action-dispatch";
|
|
5
5
|
import { X, Pencil, Trash2 } from "lucide-react";
|
|
6
6
|
import { useUrlTable } from "../../../react/hooks/useUrlTable";
|
|
7
|
+
import { useBulkSelection } from "../../../react/hooks/useBulkSelection";
|
|
7
8
|
import { Alert, FilterChipGroup, ListingToolbar, Pagination, ListingViewShell, Badge, Button } from "../../../ui";
|
|
8
9
|
import { SELLER_ENDPOINTS } from "../../../constants/api-endpoints";
|
|
9
10
|
import { SELLER_PRODUCT_STATUS_TABS } from "../../admin/constants/filter-tabs";
|
|
@@ -86,6 +87,7 @@ const PRODUCT_COLUMNS = [
|
|
|
86
87
|
];
|
|
87
88
|
export function SellerProductsView({ onDeleteProduct, children, ...props }) {
|
|
88
89
|
const hasChildren = React.Children.count(children) > 0;
|
|
90
|
+
const [view, setView] = useState("table");
|
|
89
91
|
const dispatch = useActionDispatch();
|
|
90
92
|
const table = useUrlTable({ defaults: { pageSize: String(PAGE_SIZE), sort: DEFAULT_SORT } });
|
|
91
93
|
const [searchInput, setSearchInput] = useState(table.get("q") || "");
|
|
@@ -175,6 +177,7 @@ export function SellerProductsView({ onDeleteProduct, children, ...props }) {
|
|
|
175
177
|
});
|
|
176
178
|
const currentPage = table.getNumber("page", 1);
|
|
177
179
|
const totalPages = Math.ceil(total / PAGE_SIZE);
|
|
180
|
+
const selection = useBulkSelection({ items: rows, keyExtractor: (r) => r.id });
|
|
178
181
|
if (hasChildren) {
|
|
179
182
|
return (_jsx(ListingViewShell, { portal: "seller", ...props, children: children }));
|
|
180
183
|
}
|
|
@@ -201,7 +204,7 @@ export function SellerProductsView({ onDeleteProduct, children, ...props }) {
|
|
|
201
204
|
setDeletingId(null);
|
|
202
205
|
}
|
|
203
206
|
};
|
|
204
|
-
return (_jsx(_Fragment, { children: _jsxs("div", { className: "min-h-screen", children: [_jsx(ListingToolbar, { filterCount: activeFilterCount, onFiltersClick: openFilters, searchValue: searchInput, searchPlaceholder: "Search products by name\u2026", onSearchChange: setSearchInput, onSearchCommit: commitSearch, sortValue: table.get("sort") || DEFAULT_SORT, sortOptions: SORT_OPTIONS, onSortChange: (v) => { table.set("sort", v); },
|
|
207
|
+
return (_jsx(_Fragment, { children: _jsxs("div", { className: "min-h-screen", children: [_jsx(ListingToolbar, { filterCount: activeFilterCount, onFiltersClick: openFilters, searchValue: searchInput, searchPlaceholder: "Search products by name\u2026", onSearchChange: setSearchInput, onSearchCommit: commitSearch, sortValue: table.get("sort") || DEFAULT_SORT, sortOptions: SORT_OPTIONS, onSortChange: (v) => { table.set("sort", v); }, showTableView: true, view: view, onViewChange: (v) => setView(v), onResetAll: resetAll, hasActiveState: hasActiveState }), _jsx(TypeChips, { active: listingKind, onChange: handleKindChange }), totalPages > 1 && (_jsx("div", { className: "sticky z-10 flex justify-center bg-[var(--appkit-color-surface)]/95 backdrop-blur-sm border-b border-[var(--appkit-color-border)] px-3 py-1.5", style: { top: "calc(var(--header-height, 0px) + 44px)" }, children: _jsx(Pagination, { currentPage: currentPage, totalPages: totalPages, onPageChange: (p) => table.setPage(p) }) })), _jsxs("div", { className: "py-4 px-3 sm:px-4", children: [errorMessage && (_jsx(Alert, { variant: "error", className: "mb-4", children: errorMessage })), _jsx(DataTable, { columns: PRODUCT_COLUMNS, rows: rows, isLoading: isLoading, emptyLabel: listingKind !== "all"
|
|
205
208
|
? `No ${listingKind} listings found`
|
|
206
209
|
: "No products listed yet", getRowHref: (row) => row.listingKind === "auction"
|
|
207
210
|
? String(ROUTES.STORE.AUCTIONS_EDIT(row.id))
|
|
@@ -89,8 +89,8 @@ export declare const sellerStoreSchema: z.ZodObject<{
|
|
|
89
89
|
createdAt: string;
|
|
90
90
|
updatedAt: string;
|
|
91
91
|
status: "pending" | "active" | "rejected" | "suspended";
|
|
92
|
-
isPublic: boolean;
|
|
93
92
|
storeName: string;
|
|
93
|
+
isPublic: boolean;
|
|
94
94
|
storeSlug: string;
|
|
95
95
|
ownerId: string;
|
|
96
96
|
location?: string | undefined;
|
|
@@ -102,17 +102,17 @@ export declare const sellerStoreSchema: z.ZodObject<{
|
|
|
102
102
|
} | undefined;
|
|
103
103
|
returnPolicy?: string | undefined;
|
|
104
104
|
website?: string | undefined;
|
|
105
|
+
storeDescription?: string | undefined;
|
|
106
|
+
storeLogoURL?: string | undefined;
|
|
107
|
+
storeBannerURL?: string | undefined;
|
|
108
|
+
bio?: string | undefined;
|
|
105
109
|
socialLinks?: {
|
|
106
110
|
instagram?: string | undefined;
|
|
107
111
|
facebook?: string | undefined;
|
|
108
112
|
twitter?: string | undefined;
|
|
109
113
|
linkedin?: string | undefined;
|
|
110
114
|
} | undefined;
|
|
111
|
-
storeDescription?: string | undefined;
|
|
112
115
|
storeCategory?: string | undefined;
|
|
113
|
-
storeLogoURL?: string | undefined;
|
|
114
|
-
storeBannerURL?: string | undefined;
|
|
115
|
-
bio?: string | undefined;
|
|
116
116
|
shippingPolicy?: string | undefined;
|
|
117
117
|
isVacationMode?: boolean | undefined;
|
|
118
118
|
vacationMessage?: string | undefined;
|
|
@@ -121,8 +121,8 @@ export declare const sellerStoreSchema: z.ZodObject<{
|
|
|
121
121
|
createdAt: string;
|
|
122
122
|
updatedAt: string;
|
|
123
123
|
status: "pending" | "active" | "rejected" | "suspended";
|
|
124
|
-
isPublic: boolean;
|
|
125
124
|
storeName: string;
|
|
125
|
+
isPublic: boolean;
|
|
126
126
|
storeSlug: string;
|
|
127
127
|
ownerId: string;
|
|
128
128
|
location?: string | undefined;
|
|
@@ -134,17 +134,17 @@ export declare const sellerStoreSchema: z.ZodObject<{
|
|
|
134
134
|
} | undefined;
|
|
135
135
|
returnPolicy?: string | undefined;
|
|
136
136
|
website?: string | undefined;
|
|
137
|
+
storeDescription?: string | undefined;
|
|
138
|
+
storeLogoURL?: string | undefined;
|
|
139
|
+
storeBannerURL?: string | undefined;
|
|
140
|
+
bio?: string | undefined;
|
|
137
141
|
socialLinks?: {
|
|
138
142
|
instagram?: string | undefined;
|
|
139
143
|
facebook?: string | undefined;
|
|
140
144
|
twitter?: string | undefined;
|
|
141
145
|
linkedin?: string | undefined;
|
|
142
146
|
} | undefined;
|
|
143
|
-
storeDescription?: string | undefined;
|
|
144
147
|
storeCategory?: string | undefined;
|
|
145
|
-
storeLogoURL?: string | undefined;
|
|
146
|
-
storeBannerURL?: string | undefined;
|
|
147
|
-
bio?: string | undefined;
|
|
148
148
|
shippingPolicy?: string | undefined;
|
|
149
149
|
isVacationMode?: boolean | undefined;
|
|
150
150
|
vacationMessage?: string | undefined;
|
|
@@ -22,6 +22,9 @@ const SAFE_STORE_FILTER_FIELDS = new Set([
|
|
|
22
22
|
"storeCategory",
|
|
23
23
|
"status",
|
|
24
24
|
"isPublic",
|
|
25
|
+
"isFeatured",
|
|
26
|
+
"averageRating",
|
|
27
|
+
"stats.totalProducts",
|
|
25
28
|
]);
|
|
26
29
|
function validateSieveFilters(raw, allowedFields) {
|
|
27
30
|
return raw
|
|
@@ -40,7 +43,13 @@ export async function GET(request) {
|
|
|
40
43
|
const std = parseListingParams(url);
|
|
41
44
|
const page = std.page ?? DEFAULT_PAGE;
|
|
42
45
|
const pageSize = std.pageSize ?? DEFAULT_PAGE_SIZE;
|
|
43
|
-
|
|
46
|
+
// Translate user-friendly sort names to Firestore nested field paths.
|
|
47
|
+
const rawSort = std.sorts ?? DEFAULT_SORT;
|
|
48
|
+
const sort = rawSort
|
|
49
|
+
.replace(/^-itemsSold$/, "-stats.itemsSold")
|
|
50
|
+
.replace(/^itemsSold$/, "stats.itemsSold")
|
|
51
|
+
.replace(/^-averageRating$/, "-stats.averageRating")
|
|
52
|
+
.replace(/^averageRating$/, "stats.averageRating");
|
|
44
53
|
const parts = ["status==active,isPublic==true"];
|
|
45
54
|
if (std.q)
|
|
46
55
|
parts.push(`storeName@=*${std.q}`);
|
|
@@ -127,5 +127,6 @@ export function StoreAuctionsListing({ storeId, initialData }) {
|
|
|
127
127
|
isWishlisted: (productId) => wishlistedIds.has(productId),
|
|
128
128
|
};
|
|
129
129
|
const gridClass = "grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 gap-4";
|
|
130
|
-
return (_jsxs("div", { className: "min-h-[200px]", children: [_jsx(ListingToolbar, { filterCount: activeFilterCount, onFiltersClick: openFilters, searchValue: searchInput, searchPlaceholder: "Search store auctions...", onSearchChange: setSearchInput, onSearchCommit: commitSearch, sortValue: table.get("sort") || "auctionEndDate", sortOptions: AUCTION_SORT_OPTIONS, onSortChange: (v) => { table.set("sort", v); }, view: view, onViewChange: (v) => {
|
|
130
|
+
return (_jsxs("div", { className: "min-h-[200px]", children: [_jsx(ListingToolbar, { filterCount: activeFilterCount, onFiltersClick: openFilters, searchValue: searchInput, searchPlaceholder: "Search store auctions...", onSearchChange: setSearchInput, onSearchCommit: commitSearch, sortValue: table.get("sort") || "auctionEndDate", sortOptions: AUCTION_SORT_OPTIONS, onSortChange: (v) => { table.set("sort", v); }, view: view, onViewChange: (v) => { if (v === "table")
|
|
131
|
+
return; setView(v); table.set("view", v); }, onResetAll: resetAll, hasActiveState: hasActiveState }), totalPages > 1 && (_jsx("div", { className: "sticky top-[calc(var(--header-height,0px)+44px)] z-10 flex justify-center bg-white/95 dark:bg-slate-900/95 backdrop-blur-sm border-b border-zinc-200 dark:border-slate-700 px-3 py-1.5", children: _jsx(Pagination, { currentPage: page, totalPages: totalPages, onPageChange: (p) => table.setPage(p) }) })), _jsx("div", { className: "py-6", children: isLoading ? (_jsx("div", { className: gridClass, children: Array.from({ length: 8 }).map((_, i) => (_jsxs("div", { className: "rounded-xl border border-zinc-100 dark:border-slate-700 overflow-hidden animate-pulse", children: [_jsx("div", { className: "aspect-square bg-zinc-200 dark:bg-slate-700" }), _jsxs("div", { className: "p-3 space-y-2", children: [_jsx("div", { className: "h-3 bg-zinc-200 dark:bg-slate-700 rounded w-3/4" }), _jsx("div", { className: "h-4 bg-zinc-200 dark:bg-slate-700 rounded w-1/2" }), _jsx("div", { className: "h-8 bg-zinc-200 dark:bg-slate-700 rounded" })] })] }, i))) })) : (_jsx(MarketplaceAuctionGrid, { auctions: auctions, variant: view === "list" ? "list" : "grid", gridClassName: view === "list" ? "flex flex-col gap-4" : gridClass, wishlistActions: wishlistActions, labels: { emptyTitle: "No auctions yet", emptyDescription: "This store has no active auctions." } })) }), filterOpen && (_jsxs(_Fragment, { children: [_jsx("div", { className: "fixed inset-0 z-40 bg-black/40", "aria-hidden": "true", onClick: () => setFilterOpen(false) }), _jsxs("div", { className: "fixed inset-y-0 left-0 z-50 flex w-80 flex-col bg-white dark:bg-slate-900 shadow-2xl", children: [_jsxs("div", { className: "flex items-center justify-between border-b border-zinc-200 dark:border-slate-700 px-4 py-3.5", children: [_jsxs("span", { className: "flex items-center gap-2 text-base font-semibold text-zinc-900 dark:text-zinc-100", children: [_jsx(SlidersHorizontal, { className: "h-4 w-4" }), "Filters"] }), _jsxs("div", { className: "flex items-center gap-2", children: [activeFilterCount > 0 && (_jsx("button", { type: "button", onClick: clearFilters, className: "text-xs text-zinc-500 hover:text-rose-500 dark:text-zinc-400 transition-colors", children: "Clear all" })), _jsx("button", { type: "button", onClick: () => setFilterOpen(false), "aria-label": "Close filters", className: "rounded-lg p-1.5 text-zinc-500 hover:bg-zinc-100 dark:hover:bg-slate-800 transition-colors", children: _jsx(X, { className: "h-5 w-5" }) })] })] }), _jsx("div", { className: "flex-1 overflow-y-auto px-4 py-4", children: _jsx(ProductFilters, { table: pendingTable, currencyPrefix: "\u20B9" }) }), _jsx("div", { className: "border-t border-zinc-200 dark:border-slate-700 px-4 py-3.5", children: _jsxs("button", { type: "button", onClick: applyFilters, className: "w-full rounded-lg bg-primary py-2.5 text-sm font-semibold text-white hover:bg-primary-600 transition-colors active:scale-[0.98]", children: ["Apply Filters", activeFilterCount > 0 ? ` (${activeFilterCount})` : ""] }) })] })] }))] }));
|
|
131
132
|
}
|
|
@@ -87,5 +87,6 @@ export function StorePreOrdersListing({ storeId, initialData }) {
|
|
|
87
87
|
table.setPage(1);
|
|
88
88
|
}, [searchInput, table]);
|
|
89
89
|
const gridClass = "grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5 gap-4";
|
|
90
|
-
return (_jsxs("div", { className: "min-h-[200px]", children: [_jsx(ListingToolbar, { filterCount: activeFilterCount, onFiltersClick: openFilters, searchValue: searchInput, searchPlaceholder: "Search store pre-orders...", onSearchChange: setSearchInput, onSearchCommit: commitSearch, sortValue: table.get("sort") || "-createdAt", sortOptions: PREORDER_SORT_OPTIONS, onSortChange: (v) => { table.set("sort", v); }, view: view, onViewChange: (v) => {
|
|
90
|
+
return (_jsxs("div", { className: "min-h-[200px]", children: [_jsx(ListingToolbar, { filterCount: activeFilterCount, onFiltersClick: openFilters, searchValue: searchInput, searchPlaceholder: "Search store pre-orders...", onSearchChange: setSearchInput, onSearchCommit: commitSearch, sortValue: table.get("sort") || "-createdAt", sortOptions: PREORDER_SORT_OPTIONS, onSortChange: (v) => { table.set("sort", v); }, view: view, onViewChange: (v) => { if (v === "table")
|
|
91
|
+
return; setView(v); table.set("view", v); }, onResetAll: resetAll, hasActiveState: hasActiveState }), totalPages > 1 && (_jsx("div", { className: "sticky top-[calc(var(--header-height,0px)+44px)] z-10 flex justify-center bg-white/95 dark:bg-slate-900/95 backdrop-blur-sm border-b border-zinc-200 dark:border-slate-700 px-3 py-1.5", children: _jsx(Pagination, { currentPage: page, totalPages: totalPages, onPageChange: (p) => table.setPage(p) }) })), _jsx("div", { className: "py-6", children: isLoading ? (_jsx("div", { className: gridClass, children: Array.from({ length: 8 }).map((_, i) => (_jsxs("div", { className: "rounded-xl border border-zinc-100 dark:border-slate-700 overflow-hidden animate-pulse", children: [_jsx("div", { className: "aspect-square bg-zinc-200 dark:bg-slate-700" }), _jsxs("div", { className: "p-3 space-y-2", children: [_jsx("div", { className: "h-3 bg-zinc-200 dark:bg-slate-700 rounded w-3/4" }), _jsx("div", { className: "h-3 bg-zinc-200 dark:bg-slate-700 rounded w-1/2" }), _jsx("div", { className: "h-8 bg-zinc-200 dark:bg-slate-700 rounded" })] })] }, i))) })) : preOrders.length === 0 ? (_jsx("p", { className: "py-12 text-center text-sm text-zinc-500 dark:text-zinc-400", children: "This store has no pre-orders yet." })) : view === "list" ? (_jsx("div", { className: "flex flex-col divide-y divide-zinc-100 dark:divide-zinc-800 rounded-xl border border-zinc-100 dark:border-zinc-800", children: preOrders.map((product) => (_jsx(MarketplacePreorderCard, { product: product, variant: "list", hrefBuilder: (p) => String(ROUTES.PUBLIC.PRE_ORDER_DETAIL(p.id)) }, product.id))) })) : (_jsx("div", { className: gridClass, children: preOrders.map((product) => (_jsx(MarketplacePreorderCard, { product: product, variant: "grid", hrefBuilder: (p) => String(ROUTES.PUBLIC.PRE_ORDER_DETAIL(p.id)) }, product.id))) })) }), filterOpen && (_jsxs(_Fragment, { children: [_jsx("div", { className: "fixed inset-0 z-40 bg-black/40", "aria-hidden": "true", onClick: () => setFilterOpen(false) }), _jsxs("div", { className: "fixed inset-y-0 left-0 z-50 flex w-80 flex-col bg-white dark:bg-slate-900 shadow-2xl", children: [_jsxs("div", { className: "flex items-center justify-between border-b border-zinc-200 dark:border-slate-700 px-4 py-3.5", children: [_jsxs("span", { className: "flex items-center gap-2 text-base font-semibold text-zinc-900 dark:text-zinc-100", children: [_jsx(SlidersHorizontal, { className: "h-4 w-4" }), "Filters"] }), _jsxs("div", { className: "flex items-center gap-2", children: [activeFilterCount > 0 && (_jsx("button", { type: "button", onClick: clearFilters, className: "text-xs text-zinc-500 hover:text-rose-500 dark:text-zinc-400 transition-colors", children: "Clear all" })), _jsx("button", { type: "button", onClick: () => setFilterOpen(false), "aria-label": "Close filters", className: "rounded-lg p-1.5 text-zinc-500 hover:bg-zinc-100 dark:hover:bg-slate-800 transition-colors", children: _jsx(X, { className: "h-5 w-5" }) })] })] }), _jsx("div", { className: "flex-1 overflow-y-auto px-4 py-4", children: _jsx(ProductFilters, { table: pendingTable, currencyPrefix: "\u20B9" }) }), _jsx("div", { className: "border-t border-zinc-200 dark:border-slate-700 px-4 py-3.5", children: _jsxs("button", { type: "button", onClick: applyFilters, className: "w-full rounded-lg bg-primary py-2.5 text-sm font-semibold text-white hover:bg-primary-600 transition-colors active:scale-[0.98]", children: ["Apply Filters", activeFilterCount > 0 ? ` (${activeFilterCount})` : ""] }) })] })] }))] }));
|
|
91
92
|
}
|
|
@@ -25,5 +25,5 @@ export function StoreReviewsListing({ storeSlug }) {
|
|
|
25
25
|
: "border-zinc-200 text-zinc-600 hover:bg-zinc-50 dark:border-zinc-700 dark:text-zinc-300",
|
|
26
26
|
].join(" "), children: opt.label }, opt.value))) }), isLoading ? (_jsx(Stack, { align: "center", gap: "3", className: "justify-center py-12", children: _jsx(Text, { className: "text-zinc-500", children: "Loading reviews..." }) })) : paginated.length === 0 ? (_jsxs(Stack, { align: "center", gap: "3", className: "justify-center py-24 text-center", children: [_jsx(Text, { className: "text-xl font-medium text-zinc-900 dark:text-zinc-50", children: "No reviews yet" }), _jsx(Text, { className: "text-sm text-zinc-500", children: ratingFilter > 0
|
|
27
27
|
? `No ${ratingFilter}-star reviews yet.`
|
|
28
|
-
: "Be the first to review this store by purchasing a product." })] })) : (_jsxs(_Fragment, { children: [_jsx(Grid, { cols: 3, gap: "md", children: paginated.map((review) => (_jsx(ReviewCard, { review: review }, review.id))) }), totalPages > 1 && (_jsx(Row, { className: "mt-8 justify-center", children: _jsx(Pagination, { currentPage: page, totalPages: totalPages, onPageChange: setPage }) }))] }))] }) }));
|
|
28
|
+
: "Be the first to review this store by purchasing a product." })] })) : (_jsxs(_Fragment, { children: [_jsx(Grid, { cols: 3, gap: "md", children: paginated.map((review) => (_jsx(ReviewCard, { review: review, context: "store" }, review.id))) }), totalPages > 1 && (_jsx(Row, { className: "mt-8 justify-center", children: _jsx(Pagination, { currentPage: page, totalPages: totalPages, onPageChange: setPage }) }))] }))] }) }));
|
|
29
29
|
}
|
|
@@ -4,22 +4,33 @@ import { useState, useCallback, useMemo } from "react";
|
|
|
4
4
|
import { SlidersHorizontal, X } from "lucide-react";
|
|
5
5
|
import { useUrlTable } from "../../../react/hooks/useUrlTable";
|
|
6
6
|
import { useStores } from "../hooks/useStores";
|
|
7
|
-
import {
|
|
7
|
+
import { BulkActionBar, Pagination, ListingToolbar } from "../../../ui";
|
|
8
8
|
import { ROUTES } from "../../../next";
|
|
9
9
|
import { InteractiveStoreCard } from "./InteractiveStoreCard";
|
|
10
10
|
import { StoreFilters } from "./StoreFilters";
|
|
11
11
|
import { useBulkSelection } from "../../../react/hooks/useBulkSelection";
|
|
12
|
+
import { TABLE_KEYS, VIEW_MODE } from "../../../constants/table-keys";
|
|
13
|
+
import { sortBy } from "../../../constants/sort";
|
|
14
|
+
import { STORE_FIELDS } from "../../../constants/field-names";
|
|
15
|
+
const DEFAULT_SORT = sortBy(STORE_FIELDS.CREATED_AT);
|
|
12
16
|
const STORE_SORT_OPTIONS = [
|
|
13
|
-
{ value:
|
|
14
|
-
{ value: "
|
|
17
|
+
{ value: sortBy(STORE_FIELDS.CREATED_AT), label: "Newest First" },
|
|
18
|
+
{ value: sortBy(STORE_FIELDS.STORE_NAME, "ASC"), label: "Name A–Z" },
|
|
15
19
|
{ value: "-itemsSold", label: "Most Sales" },
|
|
16
20
|
{ value: "-averageRating", label: "Top Rated" },
|
|
17
21
|
];
|
|
18
|
-
const FILTER_KEYS = [
|
|
22
|
+
const FILTER_KEYS = [TABLE_KEYS.CATEGORY, "rating", "minProductCount", "maxProductCount", TABLE_KEYS.FEATURED];
|
|
19
23
|
export function StoresIndexListing({ initialData }) {
|
|
20
|
-
const table = useUrlTable({ defaults: { pageSize: "24", sort:
|
|
21
|
-
const [searchInput, setSearchInput] = useState(table.get(
|
|
24
|
+
const table = useUrlTable({ defaults: { pageSize: "24", sort: DEFAULT_SORT } });
|
|
25
|
+
const [searchInput, setSearchInput] = useState(table.get(TABLE_KEYS.QUERY) || "");
|
|
22
26
|
const [filterOpen, setFilterOpen] = useState(false);
|
|
27
|
+
const [view, setView] = useState(table.get(TABLE_KEYS.VIEW) || VIEW_MODE.GRID);
|
|
28
|
+
const handleViewToggle = (next) => {
|
|
29
|
+
if (next === VIEW_MODE.TABLE)
|
|
30
|
+
return;
|
|
31
|
+
setView(next);
|
|
32
|
+
table.set(TABLE_KEYS.VIEW, next);
|
|
33
|
+
};
|
|
23
34
|
// Pending filter state — buffered until "Apply Filters" clicked
|
|
24
35
|
const [pendingFilters, setPendingFilters] = useState(() => Object.fromEntries(FILTER_KEYS.map((k) => [k, table.get(k)])));
|
|
25
36
|
const pendingTable = useMemo(() => ({
|
|
@@ -62,24 +73,24 @@ export function StoresIndexListing({ initialData }) {
|
|
|
62
73
|
setPendingFilters(Object.fromEntries(FILTER_KEYS.map((k) => [k, ""])));
|
|
63
74
|
}, []);
|
|
64
75
|
const resetAll = useCallback(() => {
|
|
65
|
-
const updates = {
|
|
76
|
+
const updates = { [TABLE_KEYS.QUERY]: "", [TABLE_KEYS.SORT]: "" };
|
|
66
77
|
for (const k of FILTER_KEYS)
|
|
67
78
|
updates[k] = "";
|
|
68
79
|
table.setMany(updates);
|
|
69
80
|
setSearchInput("");
|
|
70
81
|
}, [table]);
|
|
71
82
|
const activeFilterCount = FILTER_KEYS.filter((k) => !!table.get(k)).length;
|
|
72
|
-
const hasActiveState = !!table.get(
|
|
73
|
-
table.get(
|
|
83
|
+
const hasActiveState = !!table.get(TABLE_KEYS.QUERY) ||
|
|
84
|
+
table.get(TABLE_KEYS.SORT) !== DEFAULT_SORT ||
|
|
74
85
|
activeFilterCount > 0;
|
|
75
86
|
const commitSearch = useCallback(() => {
|
|
76
|
-
table.set(
|
|
87
|
+
table.set(TABLE_KEYS.QUERY, searchInput.trim());
|
|
77
88
|
}, [searchInput, table]);
|
|
78
89
|
// Build sieve filters from applied URL params
|
|
79
|
-
const ratingRaw = table.get(
|
|
90
|
+
const ratingRaw = table.get(TABLE_KEYS.RATING);
|
|
80
91
|
const minProductCount = table.get("minProductCount");
|
|
81
92
|
const maxProductCount = table.get("maxProductCount");
|
|
82
|
-
const featured = table.get(
|
|
93
|
+
const featured = table.get(TABLE_KEYS.FEATURED);
|
|
83
94
|
const filterParts = [];
|
|
84
95
|
if (ratingRaw) {
|
|
85
96
|
const ratings = ratingRaw.split("|").filter(Boolean);
|
|
@@ -93,26 +104,33 @@ export function StoresIndexListing({ initialData }) {
|
|
|
93
104
|
if (featured === "true")
|
|
94
105
|
filterParts.push("isFeatured==true");
|
|
95
106
|
const { stores, totalPages, isLoading } = useStores({
|
|
96
|
-
q: table.get(
|
|
97
|
-
page: table.getNumber(
|
|
98
|
-
pageSize: table.getNumber(
|
|
99
|
-
sort: table.get(
|
|
100
|
-
category: table.get(
|
|
107
|
+
q: table.get(TABLE_KEYS.QUERY) || undefined,
|
|
108
|
+
page: table.getNumber(TABLE_KEYS.PAGE, 1),
|
|
109
|
+
pageSize: table.getNumber(TABLE_KEYS.PAGE_SIZE, 24),
|
|
110
|
+
sort: table.get(TABLE_KEYS.SORT) || undefined,
|
|
111
|
+
category: table.get(TABLE_KEYS.CATEGORY) || undefined,
|
|
101
112
|
filters: filterParts.length > 0 ? filterParts.join(",") : undefined,
|
|
102
113
|
}, { initialData });
|
|
103
114
|
const selection = useBulkSelection({ items: stores, keyExtractor: (s) => s.id ?? s.storeSlug });
|
|
104
|
-
return (_jsxs("div", { className: "min-h-screen", children: [_jsx(ListingToolbar, { filterCount: activeFilterCount, onFiltersClick: openFilters, searchValue: searchInput, searchPlaceholder: "Search stores...", onSearchChange: setSearchInput, onSearchCommit: commitSearch, sortValue: table.get(
|
|
105
|
-
const storeKey = store.storeSlug ?? store.id;
|
|
106
|
-
return (_jsx(InteractiveStoreCard, { store: store, href: String(ROUTES.PUBLIC.STORE_DETAIL(storeKey)), selectable: selection.isSelecting, isSelected: selection.isSelected(store.id ?? store.storeSlug), onSelect: (id, sel) => { void sel; selection.toggle(id); } }, storeKey));
|
|
107
|
-
}) })) }), _jsx(BulkActionsBar, { selectedCount: selection.selectedCount, onClearSelection: selection.clearSelection, actions: [
|
|
115
|
+
return (_jsxs("div", { className: "min-h-screen", children: [_jsx(ListingToolbar, { filterCount: activeFilterCount, onFiltersClick: openFilters, searchValue: searchInput, searchPlaceholder: "Search stores...", onSearchChange: setSearchInput, onSearchCommit: commitSearch, sortValue: table.get(TABLE_KEYS.SORT) || DEFAULT_SORT, sortOptions: STORE_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: stores.length, onBulkSelectAll: selection.toggleAll, onBulkClear: selection.clearSelection }), _jsx(BulkActionBar, { selectedCount: selection.selectedCount, onClearSelection: selection.clearSelection, actions: [
|
|
108
116
|
{
|
|
109
|
-
|
|
117
|
+
id: "compare",
|
|
110
118
|
label: "Compare",
|
|
111
119
|
variant: "secondary",
|
|
112
|
-
onClick: () => {
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
120
|
+
onClick: () => { selection.clearSelection(); },
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
id: "visit",
|
|
124
|
+
label: "Visit Store",
|
|
125
|
+
variant: "primary",
|
|
126
|
+
disabled: selection.selectedCount !== 1,
|
|
127
|
+
onClick: () => { selection.clearSelection(); },
|
|
116
128
|
},
|
|
117
|
-
] }),
|
|
129
|
+
] }), totalPages > 1 && (_jsx("div", { className: "sticky top-[calc(var(--header-height,0px)+44px)] z-10 flex justify-center bg-white/95 dark:bg-slate-900/95 backdrop-blur-sm border-b border-zinc-200 dark:border-slate-700 px-3 py-1.5", children: _jsx(Pagination, { currentPage: table.getNumber("page", 1), totalPages: totalPages, onPageChange: (p) => table.setPage(p) }) })), _jsx("div", { className: "py-6", children: isLoading ? (_jsx("div", { className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6", children: Array.from({ length: 6 }).map((_, i) => (_jsxs("div", { className: "rounded-xl border border-zinc-100 dark:border-slate-700 overflow-hidden animate-pulse", children: [_jsx("div", { className: "aspect-video bg-zinc-200 dark:bg-slate-700" }), _jsxs("div", { className: "p-4 space-y-2.5", children: [_jsx("div", { className: "flex items-center gap-2", children: _jsx("div", { className: "h-10 w-10 rounded-lg bg-zinc-200 dark:bg-slate-700" }) }), _jsx("div", { className: "h-4 bg-zinc-200 dark:bg-slate-700 rounded w-2/3" }), _jsx("div", { className: "h-3 bg-zinc-200 dark:bg-slate-700 rounded w-full" }), _jsx("div", { className: "h-3 bg-zinc-200 dark:bg-slate-700 rounded w-1/2" })] })] }, i))) })) : stores.length === 0 ? (_jsx("p", { className: "py-16 text-center text-sm text-zinc-500 dark:text-zinc-400", children: "No stores found." })) : view === "list" ? (_jsx("div", { className: "flex flex-col divide-y divide-zinc-100 dark:divide-zinc-800 rounded-xl border border-zinc-100 dark:border-zinc-800", children: stores.map((store) => {
|
|
130
|
+
const storeKey = store.storeSlug ?? store.id;
|
|
131
|
+
return (_jsx(InteractiveStoreCard, { store: store, href: String(ROUTES.PUBLIC.STORE_DETAIL(storeKey)), selectable: selection.isSelecting, isSelected: selection.isSelected(store.id ?? store.storeSlug), onSelect: (id, sel) => { void sel; selection.toggle(id); } }, storeKey));
|
|
132
|
+
}) })) : (_jsx("div", { className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6", children: stores.map((store) => {
|
|
133
|
+
const storeKey = store.storeSlug ?? store.id;
|
|
134
|
+
return (_jsx(InteractiveStoreCard, { store: store, href: String(ROUTES.PUBLIC.STORE_DETAIL(storeKey)), selectable: selection.isSelecting, isSelected: selection.isSelected(store.id ?? store.storeSlug), onSelect: (id, sel) => { void sel; selection.toggle(id); } }, storeKey));
|
|
135
|
+
}) })) }), filterOpen && (_jsxs(_Fragment, { children: [_jsx("div", { className: "fixed inset-0 z-40 bg-black/40", "aria-hidden": "true", onClick: () => setFilterOpen(false) }), _jsxs("div", { className: "fixed inset-y-0 left-0 z-50 flex w-80 flex-col bg-white dark:bg-slate-900 shadow-2xl", children: [_jsxs("div", { className: "flex items-center justify-between border-b border-zinc-200 dark:border-slate-700 px-4 py-3.5", children: [_jsxs("span", { className: "flex items-center gap-2 text-base font-semibold text-zinc-900 dark:text-zinc-100", children: [_jsx(SlidersHorizontal, { className: "h-4 w-4" }), "Filters"] }), _jsxs("div", { className: "flex items-center gap-2", children: [activeFilterCount > 0 && (_jsx("button", { type: "button", onClick: clearFilters, className: "text-xs text-zinc-500 hover:text-rose-500 dark:text-zinc-400 transition-colors", children: "Clear all" })), _jsx("button", { type: "button", onClick: () => setFilterOpen(false), "aria-label": "Close filters", className: "rounded-lg p-1.5 text-zinc-500 hover:bg-zinc-100 dark:hover:bg-slate-800 transition-colors", children: _jsx(X, { className: "h-5 w-5" }) })] })] }), _jsx("div", { className: "flex-1 overflow-y-auto px-4 py-4", children: _jsx(StoreFilters, { table: pendingTable }) }), _jsx("div", { className: "border-t border-zinc-200 dark:border-slate-700 px-4 py-3.5", children: _jsxs("button", { type: "button", onClick: applyFilters, className: "w-full rounded-lg bg-primary py-2.5 text-sm font-semibold text-white hover:bg-primary-600 transition-colors active:scale-[0.98]", children: ["Apply Filters", activeFilterCount > 0 ? ` (${activeFilterCount})` : ""] }) })] })] }))] }));
|
|
118
136
|
}
|
|
@@ -34,32 +34,32 @@ export declare const storeListItemSchema: z.ZodObject<{
|
|
|
34
34
|
}, "strip", z.ZodTypeAny, {
|
|
35
35
|
id: string;
|
|
36
36
|
status: string;
|
|
37
|
-
isPublic: boolean;
|
|
38
37
|
storeName: string;
|
|
38
|
+
isPublic: boolean;
|
|
39
39
|
storeSlug: string;
|
|
40
40
|
ownerId: string;
|
|
41
41
|
createdAt?: string | undefined;
|
|
42
42
|
itemsSold?: number | undefined;
|
|
43
43
|
storeDescription?: string | undefined;
|
|
44
|
-
storeCategory?: string | undefined;
|
|
45
44
|
storeLogoURL?: string | undefined;
|
|
46
45
|
storeBannerURL?: string | undefined;
|
|
46
|
+
storeCategory?: string | undefined;
|
|
47
47
|
totalProducts?: number | undefined;
|
|
48
48
|
totalReviews?: number | undefined;
|
|
49
49
|
averageRating?: number | undefined;
|
|
50
50
|
}, {
|
|
51
51
|
id: string;
|
|
52
52
|
status: string;
|
|
53
|
-
isPublic: boolean;
|
|
54
53
|
storeName: string;
|
|
54
|
+
isPublic: boolean;
|
|
55
55
|
storeSlug: string;
|
|
56
56
|
ownerId: string;
|
|
57
57
|
createdAt?: string | undefined;
|
|
58
58
|
itemsSold?: number | undefined;
|
|
59
59
|
storeDescription?: string | undefined;
|
|
60
|
-
storeCategory?: string | undefined;
|
|
61
60
|
storeLogoURL?: string | undefined;
|
|
62
61
|
storeBannerURL?: string | undefined;
|
|
62
|
+
storeCategory?: string | undefined;
|
|
63
63
|
totalProducts?: number | undefined;
|
|
64
64
|
totalReviews?: number | undefined;
|
|
65
65
|
averageRating?: number | undefined;
|
package/dist/index.d.ts
CHANGED
|
@@ -528,7 +528,7 @@ export { storeRepository } from "./repositories/index";
|
|
|
528
528
|
export { scammerRepository } from "./repositories/index";
|
|
529
529
|
export { supportRepository, SupportRepository } from "./repositories/index";
|
|
530
530
|
export type { SupportTicketDocument, SupportTicketCreateInput, SupportTicketUpdateInput, TicketMessage, TicketCategory, TicketStatus, TicketPriority, } from "./repositories/index";
|
|
531
|
-
export { ELIGIBLE_ORDER_STATUSES_FOR_TICKET, SUPPORT_TICKET_COLLECTION, ACTIVE_TICKET_STATUSES, TicketCategoryValues, TicketStatusValues, TicketPriorityValues, } from "./features/support/schemas/firestore";
|
|
531
|
+
export { ELIGIBLE_ORDER_STATUSES_FOR_TICKET, SUPPORT_TICKET_COLLECTION, ACTIVE_TICKET_STATUSES, SUPPORT_TICKET_FIELDS, TicketCategoryValues, TicketStatusValues, TicketPriorityValues, } from "./features/support/schemas/firestore";
|
|
532
532
|
export { supportTicketsSeedData } from "./seed/index";
|
|
533
533
|
export { productFeaturesRepository } from "./repositories/index";
|
|
534
534
|
export type { ProductFeatureListFilter } from "./repositories/index";
|
|
@@ -3047,3 +3047,10 @@ export { getListingRule, getCategoryRule, pickOrderType, getSplitKey, runSyncPre
|
|
|
3047
3047
|
export type { ListingCheckoutRule, CategoryCheckoutRule, CartItemProductPair, OrderItemInput, RefundPolicy, } from "./_internal/shared/checkout/rules";
|
|
3048
3048
|
export { MEGABYTE, MAX_IMAGE_BYTES, MAX_PDF_BYTES, MAX_VIDEO_BYTES, MAX_LABEL, MAX_BYTES, ALLOWED_IMAGE_MIMES, ALLOWED_VIDEO_MIMES, ALLOWED_DOC_MIMES, ALLOWED_MIMES, ALLOWED_TYPES_LABEL, MIME_TO_EXT, PDF_MAGIC, VIDEO_CONVERSION_HINTS, classifyMime, isAllowedMime, maxBytesFor, getConversionHint, } from "./_internal/shared/media/limits";
|
|
3049
3049
|
export type { MediaKind, AllowedImageMime, AllowedVideoMime, AllowedDocMime, AllowedMime, } from "./_internal/shared/media/limits";
|
|
3050
|
+
export { PRODUCT_FIELDS, PRODUCT_STATUS_TRANSITIONS, ORDER_FIELDS, REVIEW_FIELDS, BID_FIELDS, AD_FIELDS, BLOG_FIELDS, BRAND_FIELDS, WISHLIST_FIELDS, HISTORY_FIELDS, COUPON_USAGE_FIELDS, CONVERSATION_FIELDS, CAROUSEL_FIELDS, FAQ_FIELDS, HOMEPAGE_SECTION_FIELDS, SITE_SETTINGS_FIELDS, COMMON_FIELDS, OAUTH_STATE_VALUES, SCHEMA_DEFAULTS, } from "./constants/field-names";
|
|
3051
|
+
export { SORT_DIR, sortBy } from "./constants/sort";
|
|
3052
|
+
export type { SortDirection } from "./constants/sort";
|
|
3053
|
+
export { TABLE_KEYS, VIEW_MODE } from "./constants/table-keys";
|
|
3054
|
+
export type { TableKey, ViewMode } from "./constants/table-keys";
|
|
3055
|
+
export { SIEVE_OP, SIEVE_PIPE_OPS, sieveFilter, sieveMultiEq, expandSieveParam, sieveAnd, } from "./utils/sieve-builder";
|
|
3056
|
+
export type { SieveOp } from "./utils/sieve-builder";
|
package/dist/index.js
CHANGED
|
@@ -1084,7 +1084,7 @@ export { storeRepository } from "./repositories/index";
|
|
|
1084
1084
|
export { scammerRepository } from "./repositories/index";
|
|
1085
1085
|
// supportRepository - Server-only repository for support tickets (BAN1).
|
|
1086
1086
|
export { supportRepository, SupportRepository } from "./repositories/index";
|
|
1087
|
-
export { ELIGIBLE_ORDER_STATUSES_FOR_TICKET, SUPPORT_TICKET_COLLECTION, ACTIVE_TICKET_STATUSES, TicketCategoryValues, TicketStatusValues, TicketPriorityValues, } from "./features/support/schemas/firestore";
|
|
1087
|
+
export { ELIGIBLE_ORDER_STATUSES_FOR_TICKET, SUPPORT_TICKET_COLLECTION, ACTIVE_TICKET_STATUSES, SUPPORT_TICKET_FIELDS, TicketCategoryValues, TicketStatusValues, TicketPriorityValues, } from "./features/support/schemas/firestore";
|
|
1088
1088
|
// Support tickets — seed data
|
|
1089
1089
|
export { supportTicketsSeedData } from "./seed/index";
|
|
1090
1090
|
// SB-UNI-B — sublistingCategoriesRepository + SublistingCategoryDocument deleted.
|
|
@@ -5488,3 +5488,14 @@ export { LISTING_TYPE_REGISTRY, pluginFor } from "./_internal/shared/listing-typ
|
|
|
5488
5488
|
export { getListingRule, getCategoryRule, pickOrderType, getSplitKey, runSyncPreflight, CHECKOUT_RULES, CATEGORY_CHECKOUT_RULES, CHECKOUT_MAX_ORDERS_PER_TX, PRIZE_DRAW_MAX_REVEALS_PER_ORDER, BUNDLE_MAX_QTY_PER_TX, STANDARD_MAX_QTY_PER_LINE, } from "./_internal/shared/checkout/rules";
|
|
5489
5489
|
// Media upload limits — pure constants, safe in both client and server bundles.
|
|
5490
5490
|
export { MEGABYTE, MAX_IMAGE_BYTES, MAX_PDF_BYTES, MAX_VIDEO_BYTES, MAX_LABEL, MAX_BYTES, ALLOWED_IMAGE_MIMES, ALLOWED_VIDEO_MIMES, ALLOWED_DOC_MIMES, ALLOWED_MIMES, ALLOWED_TYPES_LABEL, MIME_TO_EXT, PDF_MAGIC, VIDEO_CONVERSION_HINTS, classifyMime, isAllowedMime, maxBytesFor, getConversionHint, } from "./_internal/shared/media/limits";
|
|
5491
|
+
// ── Field name constants — canonical source of truth for all Firestore field names ──
|
|
5492
|
+
// NOTE: STORE_FIELDS, CATEGORY_FIELDS, EVENT_FIELDS, EVENT_ENTRY_FIELDS, PAYOUT_FIELDS,
|
|
5493
|
+
// COUPON_FIELDS, CART_FIELDS, USER_FIELDS, ADDRESS_FIELDS, NOTIFICATION_FIELDS,
|
|
5494
|
+
// SESSION_FIELDS, SCAMMER_FIELDS are already exported from feature barrels above.
|
|
5495
|
+
export { PRODUCT_FIELDS, PRODUCT_STATUS_TRANSITIONS, ORDER_FIELDS, REVIEW_FIELDS, BID_FIELDS, AD_FIELDS, BLOG_FIELDS, BRAND_FIELDS, WISHLIST_FIELDS, HISTORY_FIELDS, COUPON_USAGE_FIELDS, CONVERSATION_FIELDS, CAROUSEL_FIELDS, FAQ_FIELDS, HOMEPAGE_SECTION_FIELDS, SITE_SETTINGS_FIELDS, COMMON_FIELDS, OAUTH_STATE_VALUES, SCHEMA_DEFAULTS, } from "./constants/field-names";
|
|
5496
|
+
// ── Sort helpers ──────────────────────────────────────────────────────────────
|
|
5497
|
+
export { SORT_DIR, sortBy } from "./constants/sort";
|
|
5498
|
+
// ── URL table keys + view mode ────────────────────────────────────────────────
|
|
5499
|
+
export { TABLE_KEYS, VIEW_MODE } from "./constants/table-keys";
|
|
5500
|
+
// ── Sieve query builder ───────────────────────────────────────────────────────
|
|
5501
|
+
export { SIEVE_OP, SIEVE_PIPE_OPS, sieveFilter, sieveMultiEq, expandSieveParam, sieveAnd, } from "./utils/sieve-builder";
|
|
@@ -34,7 +34,8 @@
|
|
|
34
34
|
*/
|
|
35
35
|
import { useRouter, usePathname, useSearchParams } from "next/navigation";
|
|
36
36
|
import { useCallback, useRef } from "react";
|
|
37
|
-
|
|
37
|
+
import { TABLE_KEYS } from "../../constants/table-keys";
|
|
38
|
+
const NON_RESETTING_KEYS = [TABLE_KEYS.PAGE, TABLE_KEYS.PAGE_SIZE, TABLE_KEYS.VIEW];
|
|
38
39
|
export function useUrlTable(options) {
|
|
39
40
|
// Always call native hooks unconditionally (React rules).
|
|
40
41
|
const nativeRouter = useRouter();
|