@mohasinac/appkit 2.8.3 → 2.8.5
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/client/features/layout/SidebarCollapseToggle.js +2 -0
- package/dist/_internal/shared/listing-types/action-tracker.js +0 -2
- package/dist/client.d.ts +2 -0
- package/dist/client.js +2 -0
- package/dist/core/hooks/useSiteSettings.d.ts +1 -1
- package/dist/core/unit-of-work.js +0 -1
- package/dist/features/account/components/NotificationBell.js +1 -0
- package/dist/features/account/components/UserOffersPanel.js +1 -0
- package/dist/features/account/components/UserSidebar.js +3 -1
- package/dist/features/account/hooks/useAccount.d.ts +2 -2
- package/dist/features/account/hooks/useAddressSelector.d.ts +1 -1
- package/dist/features/account/hooks/useAddresses.d.ts +2 -2
- package/dist/features/account/hooks/useNotifications.d.ts +1 -1
- package/dist/features/account/hooks/useProfile.d.ts +1 -1
- package/dist/features/account/hooks/usePublicProfile.d.ts +2 -2
- package/dist/features/admin/components/AdminAllEventEntriesView.js +5 -3
- package/dist/features/admin/components/AdminBidsView.js +6 -4
- package/dist/features/admin/components/AdminBlogView.js +6 -4
- package/dist/features/admin/components/AdminBrandsView.js +8 -6
- package/dist/features/admin/components/AdminBundlesView.js +10 -8
- package/dist/features/admin/components/AdminCarouselEditorView.js +3 -1
- package/dist/features/admin/components/AdminCartsView.js +6 -4
- package/dist/features/admin/components/AdminCategoriesView.js +7 -5
- package/dist/features/admin/components/AdminClassifiedView.js +4 -3
- package/dist/features/admin/components/AdminContactView.js +6 -4
- package/dist/features/admin/components/AdminCouponsView.js +6 -4
- package/dist/features/admin/components/AdminDigitalCodesView.js +4 -3
- package/dist/features/admin/components/AdminFaqsView.js +5 -3
- package/dist/features/admin/components/AdminFeaturesView.js +5 -4
- package/dist/features/admin/components/AdminGroupedListingsView.js +4 -3
- package/dist/features/admin/components/AdminHistoryView.js +4 -3
- package/dist/features/admin/components/AdminLiveView.js +4 -3
- package/dist/features/admin/components/AdminNewsletterView.js +5 -3
- package/dist/features/admin/components/AdminNotificationsView.js +6 -4
- package/dist/features/admin/components/AdminOrdersView.js +6 -4
- package/dist/features/admin/components/AdminPayoutsView.js +7 -5
- package/dist/features/admin/components/AdminPrizeDrawsView.js +6 -4
- package/dist/features/admin/components/AdminProductsView.js +7 -5
- package/dist/features/admin/components/AdminReturnRequestsView.js +4 -3
- package/dist/features/admin/components/AdminReviewsView.js +8 -6
- package/dist/features/admin/components/AdminScammersView.js +8 -6
- package/dist/features/admin/components/AdminSessionsView.js +6 -4
- package/dist/features/admin/components/AdminSidebar.js +3 -1
- package/dist/features/admin/components/AdminSiteSettingsView.js +3 -1
- package/dist/features/admin/components/AdminStoreAddressesView.js +2 -1
- package/dist/features/admin/components/AdminStoresView.js +6 -4
- package/dist/features/admin/components/AdminSublistingCategoriesView.js +6 -5
- package/dist/features/admin/components/AdminSupportTicketDetailView.js +0 -3
- package/dist/features/admin/components/AdminSupportTicketsView.js +8 -6
- package/dist/features/admin/components/AdminTeamView.js +6 -4
- package/dist/features/admin/components/AdminUsersView.js +6 -4
- package/dist/features/admin/components/AdminWishlistsView.js +4 -3
- package/dist/features/admin/components/DashboardStats.js +5 -1
- package/dist/features/admin/components/analytics/AdminAnalyticsCharts.js +3 -1
- package/dist/features/admin/components/analytics/AdminStatCard.js +5 -1
- package/dist/features/admin/constants/filter-tabs.d.ts +1 -1
- package/dist/features/admin/constants/filter-tabs.js +0 -11
- package/dist/features/admin/hooks/useAdmin.d.ts +1 -1
- package/dist/features/admin/hooks/useAdminSectionsListing.d.ts +1 -1
- package/dist/features/admin/hooks/useChat.d.ts +1 -1
- package/dist/features/admin/hooks/useChat.js +1 -0
- package/dist/features/admin/types/index.d.ts +1 -1
- package/dist/features/auctions/actions/bid-actions.js +4 -2
- package/dist/features/auctions/components/AuctionBidsTable.js +5 -1
- package/dist/features/auctions/components/AuctionsListView.js +7 -6
- package/dist/features/auctions/hooks/useAuctions.d.ts +8 -8
- package/dist/features/auth/hooks/useAuth.d.ts +2 -2
- package/dist/features/auth/hooks/useAuth.js +1 -0
- package/dist/features/blog/actions/blog-actions.js +3 -2
- package/dist/features/blog/components/BlogFeaturedCard.js +3 -1
- package/dist/features/blog/components/BlogListView.js +5 -1
- package/dist/features/blog/components/BlogPostView.js +3 -1
- package/dist/features/cart/components/CartDrawer.js +3 -1
- package/dist/features/cart/hooks/useCart.d.ts +1 -1
- package/dist/features/cart/hooks/useCartQuery.d.ts +1 -1
- package/dist/features/cart/hooks/useCheckoutReadQueries.d.ts +2 -2
- package/dist/features/cart/hooks/useOrder.d.ts +2 -2
- package/dist/features/categories/components/BrandDetailPageView.js +15 -9
- package/dist/features/categories/components/CategoriesIndexListing.js +1 -1
- package/dist/features/categories/components/CategoriesIndexPageView.js +5 -4
- package/dist/features/categories/components/CategoryBundlesListing.js +5 -4
- package/dist/features/categories/components/CategoryDetailPageView.js +15 -11
- package/dist/features/categories/components/CategoryFilters.d.ts +12 -12
- package/dist/features/categories/components/CategoryFilters.js +13 -12
- package/dist/features/categories/components/CategoryGrid.js +5 -1
- package/dist/features/categories/components/CategoryTableColumns.js +6 -2
- package/dist/features/categories/components/CategoryTree.d.ts +1 -1
- package/dist/features/categories/components/CategoryTree.js +4 -2
- package/dist/features/categories/components/ConcernCard.js +3 -1
- package/dist/features/categories/hooks/useCategories.d.ts +3 -3
- package/dist/features/categories/hooks/useCategorySelector.d.ts +3 -3
- package/dist/features/categories/hooks/useCategoryTree.d.ts +1 -1
- package/dist/features/categories/schemas/firestore.d.ts +2 -2
- package/dist/features/checkout/actions/checkout-actions.d.ts +1 -1
- package/dist/features/checkout/actions/checkout-actions.js +1 -1
- package/dist/features/checkout/hooks/useCheckoutApi.d.ts +2 -2
- package/dist/features/classified/components/ClassifiedListView.js +6 -5
- package/dist/features/collections/components/CollectionCard.js +3 -1
- package/dist/features/collections/hooks/useCollections.d.ts +2 -2
- package/dist/features/cron/jobs/auction-expiry.job.d.ts +2 -2
- package/dist/features/cron/jobs/auction-expiry.job.js +2 -1
- package/dist/features/cron/jobs/preorder-reminder.job.d.ts +1 -1
- package/dist/features/cron/jobs/preorder-reminder.job.js +2 -1
- package/dist/features/digital-codes/components/DigitalCodesListView.js +4 -3
- package/dist/features/events/actions/event-actions.js +6 -4
- package/dist/features/events/components/AdminEventEditorView.js +1 -1
- package/dist/features/events/components/AdminEventsView.js +7 -5
- package/dist/features/events/components/EventCard.js +3 -1
- package/dist/features/events/components/EventFilters.d.ts +4 -4
- package/dist/features/events/components/EventFilters.js +2 -2
- package/dist/features/events/components/EventRafflesSection.js +4 -2
- package/dist/features/events/hooks/useEvent.d.ts +3 -3
- package/dist/features/events/hooks/useEvents.d.ts +1 -1
- package/dist/features/faq/actions/faq-actions.js +4 -2
- package/dist/features/faq/components/FAQPageContent.js +2 -1
- package/dist/features/faq/hooks/useFAQs.d.ts +1 -1
- package/dist/features/faq/hooks/useFaqList.d.ts +15 -15
- package/dist/features/forms/Slider.js +3 -1
- package/dist/features/history/hooks/useHistory.js +1 -0
- package/dist/features/homepage/components/AdSlot.js +6 -2
- package/dist/features/homepage/components/AdvertisementBanner.js +3 -1
- package/dist/features/homepage/components/BeforeAfterCard.js +5 -1
- package/dist/features/homepage/components/CustomCardsSection.js +5 -1
- package/dist/features/homepage/components/HowItWorksSection.js +3 -1
- package/dist/features/homepage/components/MarketplaceHomepageView.js +4 -2
- package/dist/features/homepage/components/NewsletterBanner.js +6 -2
- package/dist/features/homepage/components/SecurityHighlightsSection.js +3 -1
- package/dist/features/homepage/components/StatsCounterSection.js +3 -1
- package/dist/features/homepage/components/TrustFeaturesSection.js +3 -1
- package/dist/features/homepage/hooks/useBlogArticles.d.ts +1 -1
- package/dist/features/homepage/hooks/useFeaturedAuctions.d.ts +1 -1
- package/dist/features/homepage/hooks/useFeaturedPreOrders.d.ts +1 -1
- package/dist/features/homepage/hooks/useFeaturedProducts.d.ts +1 -1
- package/dist/features/homepage/hooks/useFeaturedStores.d.ts +1 -1
- package/dist/features/homepage/hooks/useHeroCarousel.d.ts +1 -1
- package/dist/features/homepage/hooks/useHomepageEvents.d.ts +1 -1
- package/dist/features/homepage/hooks/useHomepageReviews.d.ts +1 -1
- package/dist/features/homepage/hooks/useHomepageSections.d.ts +1 -1
- package/dist/features/homepage/hooks/useTopBrands.d.ts +1 -1
- package/dist/features/homepage/hooks/useTopCategories.d.ts +1 -1
- package/dist/features/layout/AppLayoutShell.js +3 -1
- package/dist/features/layout/BottomActions.js +0 -27
- package/dist/features/layout/BottomActionsContext.d.ts +0 -36
- package/dist/features/layout/BottomActionsContext.js +1 -39
- package/dist/features/layout/BottomNavbar.js +1 -1
- package/dist/features/live/components/LiveItemsListView.js +6 -5
- package/dist/features/loyalty/hooks/useLoyaltyBalance.d.ts +1 -1
- package/dist/features/media/MediaLightbox.js +9 -3
- package/dist/features/media/modals/ImageEditor.js +6 -2
- package/dist/features/media/upload/MediaUploadField.js +1 -1
- package/dist/features/messages/hooks/useConversation.js +2 -0
- package/dist/features/messages/hooks/useConversations.js +1 -0
- package/dist/features/orders/components/OrdersList.js +3 -1
- package/dist/features/orders/hooks/useOrders.d.ts +2 -2
- package/dist/features/payments/hooks/usePayments.d.ts +1 -1
- package/dist/features/pre-orders/components/PreOrderDetailPageView.js +1 -1
- package/dist/features/pre-orders/components/PreOrdersListView.js +5 -4
- package/dist/features/pre-orders/hooks/usePreOrders.d.ts +2 -2
- package/dist/features/products/actions/product-actions.js +17 -15
- package/dist/features/products/columns/index.d.ts +1 -1
- package/dist/features/products/columns/index.js +1 -1
- package/dist/features/products/components/CompareOverlay.js +5 -1
- package/dist/features/products/components/FeatureBadge.js +3 -1
- package/dist/features/products/components/MarketplacePrizeDrawCard.js +1 -1
- package/dist/features/products/components/PrizeDrawCollage.js +0 -14
- package/dist/features/products/components/PrizeDrawsListingView.js +5 -4
- package/dist/features/products/components/PrizeDrawsSection.js +4 -2
- package/dist/features/products/components/ProductGrid.js +3 -1
- package/dist/features/products/constants/sieve.d.ts +2 -2
- package/dist/features/products/constants/sieve.js +2 -2
- package/dist/features/products/hooks/useProductDetail.d.ts +1 -1
- package/dist/features/products/hooks/useRelatedProducts.d.ts +1 -1
- package/dist/features/products/hooks/useRelatedProducts.js +5 -4
- package/dist/features/promotions/hooks/usePromotions.d.ts +2 -2
- package/dist/features/reviews/actions/review-actions.js +2 -1
- package/dist/features/reviews/components/ReviewDetailShell.js +8 -2
- package/dist/features/reviews/components/ReviewModal.js +5 -1
- package/dist/features/reviews/components/ReviewSummary.js +3 -1
- package/dist/features/reviews/components/ReviewsIndexPageView.js +7 -6
- package/dist/features/reviews/components/ReviewsList.js +5 -1
- package/dist/features/reviews/hooks/useReviews.d.ts +2 -2
- package/dist/features/scams/actions/scam-actions.js +3 -2
- package/dist/features/scams/components/ScamRegistryView.js +5 -4
- package/dist/features/search/actions/search-actions.js +7 -6
- package/dist/features/search/components/Search.js +3 -1
- package/dist/features/search/hooks/useSearch.d.ts +2 -2
- package/dist/features/seller/components/CouponInlineSelect.js +2 -1
- package/dist/features/seller/components/PhysicalLocationModal.js +1 -1
- package/dist/features/seller/components/SellerAddressesView.js +2 -1
- package/dist/features/seller/components/SellerAuctionsView.js +7 -5
- package/dist/features/seller/components/SellerBidsView.js +8 -4
- package/dist/features/seller/components/SellerBundlesView.js +7 -6
- package/dist/features/seller/components/SellerClassifiedView.js +6 -5
- package/dist/features/seller/components/SellerCouponEditorView.js +3 -1
- package/dist/features/seller/components/SellerCouponsView.js +6 -4
- package/dist/features/seller/components/SellerDigitalCodesView.js +5 -4
- package/dist/features/seller/components/SellerGroupedListingsView.js +5 -4
- package/dist/features/seller/components/SellerLiveView.js +6 -5
- package/dist/features/seller/components/SellerOffersPanel.js +1 -0
- package/dist/features/seller/components/SellerOffersView.js +6 -4
- package/dist/features/seller/components/SellerOrdersView.js +5 -3
- package/dist/features/seller/components/SellerPayoutMethodsView.js +4 -2
- package/dist/features/seller/components/SellerPayoutsView.js +6 -4
- package/dist/features/seller/components/SellerPreOrdersView.js +6 -4
- package/dist/features/seller/components/SellerPrizeDrawsView.js +6 -4
- package/dist/features/seller/components/SellerProductsView.js +14 -8
- package/dist/features/seller/components/SellerReviewsView.js +1 -0
- package/dist/features/seller/components/SellerShippingConfigsView.js +4 -2
- package/dist/features/seller/components/SellerSidebar.js +12 -4
- package/dist/features/seller/components/SellerStoreCategoriesView.js +5 -3
- package/dist/features/seller/components/SellerTemplatesView.js +5 -3
- package/dist/features/seller/components/SublistingInlineSelect.js +2 -1
- package/dist/features/seller/hooks/useSellerPayouts.d.ts +3 -3
- package/dist/features/seller/hooks/useSellerStore.d.ts +6 -6
- package/dist/features/seller/hooks/useSellerStorefront.d.ts +2 -2
- package/dist/features/shell/FormShell.js +10 -2
- package/dist/features/shell/QuickFormDrawer.js +5 -2
- package/dist/features/stores/actions/store-query-actions.js +3 -2
- package/dist/features/stores/components/StoreAuctionsPageView.js +4 -2
- package/dist/features/stores/components/StoreDetailLayoutView.d.ts +1 -1
- package/dist/features/stores/components/StoreDetailLayoutView.js +7 -6
- package/dist/features/stores/components/StoreHeader.js +5 -1
- package/dist/features/stores/components/StorePreOrdersPageView.js +4 -2
- package/dist/features/stores/components/StorePrizeDrawsPageView.js +4 -2
- package/dist/features/stores/components/StoreProductsPageView.js +2 -1
- package/dist/features/stores/components/StoreProductsView.js +5 -4
- package/dist/features/stores/components/StoresIndexListing.js +4 -3
- package/dist/features/stores/hooks/useStoreAddressSelector.d.ts +1 -1
- package/dist/features/stores/hooks/useStores.d.ts +6 -6
- package/dist/features/wishlist/components/WishlistPage.js +3 -1
- package/dist/features/wishlist/components/WishlistView.js +4 -3
- package/dist/features/wishlist/hooks/useUserWishlist.d.ts +15 -15
- package/dist/features/wishlist/hooks/useWishlist.d.ts +1 -1
- package/dist/features/wishlist/hooks/useWishlistWithGuest.d.ts +1 -1
- package/dist/providers/db-firebase/admin.js +0 -1
- package/dist/ui/DataTable.js +6 -2
- package/dist/ui/components/AvatarDisplay.js +3 -1
- package/dist/ui/components/BackgroundRenderer.js +4 -2
- package/dist/ui/components/Card.js +6 -2
- package/dist/ui/components/ImageGallery.js +3 -1
- package/dist/ui/components/ImageLightbox.js +3 -1
- package/dist/ui/components/PasswordStrengthIndicator.js +3 -1
- package/dist/ui/components/Progress.js +6 -2
- package/dist/ui/components/RowActionMenu.js +3 -1
- package/dist/ui/components/SiteLogo.js +7 -1
- package/dist/ui/components/Skeleton.js +3 -1
- package/dist/ui/components/Slider.js +3 -1
- package/dist/ui/components/TabStrip.js +3 -1
- package/package.json +1 -1
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* Pure business functions — auth, rate-limiting, and Next.js specifics
|
|
5
5
|
* are handled by the calling server action in the consumer.
|
|
6
6
|
*/
|
|
7
|
+
import { sieveFilter, SIEVE_OP } from "@mohasinac/appkit";
|
|
7
8
|
import { productRepository } from "../../products/repository/products.repository";
|
|
8
9
|
import { serverLogger } from "../../../monitoring";
|
|
9
10
|
/**
|
|
@@ -14,18 +15,18 @@ export async function searchProducts(query = {}) {
|
|
|
14
15
|
const { q = "", category, subcategory, minPrice = 0, maxPrice = 0, condition, listingType, sort = "-createdAt", page = 1, pageSize = 20, } = query;
|
|
15
16
|
const filterParts = ["status==published"];
|
|
16
17
|
if (category)
|
|
17
|
-
filterParts.push(
|
|
18
|
+
filterParts.push(sieveFilter("category", SIEVE_OP.EQ, category));
|
|
18
19
|
if (subcategory)
|
|
19
|
-
filterParts.push(
|
|
20
|
+
filterParts.push(sieveFilter("subcategory", SIEVE_OP.EQ, subcategory));
|
|
20
21
|
if (minPrice > 0)
|
|
21
|
-
filterParts.push(
|
|
22
|
+
filterParts.push(sieveFilter("price", SIEVE_OP.GTE, minPrice));
|
|
22
23
|
if (maxPrice > 0 && maxPrice >= minPrice)
|
|
23
|
-
filterParts.push(
|
|
24
|
+
filterParts.push(sieveFilter("price", SIEVE_OP.LTE, maxPrice));
|
|
24
25
|
if (condition)
|
|
25
|
-
filterParts.push(
|
|
26
|
+
filterParts.push(sieveFilter("condition", SIEVE_OP.EQ, condition));
|
|
26
27
|
// SB1-G Phase 4 — canonical listingType discriminator.
|
|
27
28
|
if (listingType)
|
|
28
|
-
filterParts.push(
|
|
29
|
+
filterParts.push(sieveFilter("listingType", SIEVE_OP.EQ, listingType));
|
|
29
30
|
if (q.trim())
|
|
30
31
|
filterParts.push(`title_=${q.trim()}`);
|
|
31
32
|
const sieveResult = await productRepository.list({
|
|
@@ -205,7 +205,9 @@ export function Search({ isOpen, onClose, onSearch, onOpen, value, onChange, pla
|
|
|
205
205
|
if (inlineBlurRef.current)
|
|
206
206
|
clearTimeout(inlineBlurRef.current);
|
|
207
207
|
inlineBlurRef.current = setTimeout(() => setIsInlineOpen(false), 120);
|
|
208
|
-
}, placeholder: placeholder ?? labels.placeholder, className: "w-full rounded-lg border border-zinc-300 bg-white pl-9 text-zinc-900 placeholder:text-zinc-400 focus:border-primary focus:ring-2 focus:ring-primary/20 dark:border-slate-700 dark:bg-slate-900 dark:text-white dark:placeholder:text-slate-500" }), query && (_jsx(Button, { type: "button", variant: "ghost", onClick: handleClear, className: "absolute right-3 p-0.5 rounded-full text-zinc-400 hover:text-zinc-600 dark:hover:text-zinc-200 transition-colors", "aria-label": labels.clearAriaLabel, children: _jsx("svg", { className: "w-4 h-4", "aria-hidden": "true", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) }) }))] }), resourceTypes && resourceTypes.length > 0 && (_jsx("select", { value: selectedType, onChange: (e) => handleTypeChange(e.target.value), "aria-label": labels.resourceTypeLabel ?? "Search in", className: "flex-shrink-0 rounded-lg border border-zinc-300 bg-white px-2 py-2 text-sm text-zinc-700 focus:border-primary focus:outline-none focus:ring-2 focus:ring-primary/20 dark:border-slate-700 dark:bg-slate-900 dark:text-zinc-300 cursor-pointer", children: resourceTypes.map((opt) => (_jsx("option", { value: opt.value, children: opt.label }, opt.value))) })), deferred && (_jsx(Button, { type: "button", variant: "primary", onClick: handleDeferredSubmit, "aria-label": labels.ariaLabel, className: "flex-shrink-0 px-3 py-2 rounded-lg", children: _jsx("svg", { className: "w-4 h-4", "aria-hidden": "true", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: SVG_PATH_SEARCH }) }) })), isInlineOpen && (filteredQuickLinks.length > 0 || query) && (_jsxs("div", { className: "absolute top-full left-0 right-0 mt-2 rounded-xl overflow-hidden border border-zinc-200 bg-white shadow-lg dark:border-slate-700 dark:bg-slate-900",
|
|
208
|
+
}, placeholder: placeholder ?? labels.placeholder, className: "w-full rounded-lg border border-zinc-300 bg-white pl-9 text-zinc-900 placeholder:text-zinc-400 focus:border-primary focus:ring-2 focus:ring-primary/20 dark:border-slate-700 dark:bg-slate-900 dark:text-white dark:placeholder:text-slate-500" }), query && (_jsx(Button, { type: "button", variant: "ghost", onClick: handleClear, className: "absolute right-3 p-0.5 rounded-full text-zinc-400 hover:text-zinc-600 dark:hover:text-zinc-200 transition-colors", "aria-label": labels.clearAriaLabel, children: _jsx("svg", { className: "w-4 h-4", "aria-hidden": "true", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) }) }))] }), resourceTypes && resourceTypes.length > 0 && (_jsx("select", { value: selectedType, onChange: (e) => handleTypeChange(e.target.value), "aria-label": labels.resourceTypeLabel ?? "Search in", className: "flex-shrink-0 rounded-lg border border-zinc-300 bg-white px-2 py-2 text-sm text-zinc-700 focus:border-primary focus:outline-none focus:ring-2 focus:ring-primary/20 dark:border-slate-700 dark:bg-slate-900 dark:text-zinc-300 cursor-pointer", children: resourceTypes.map((opt) => (_jsx("option", { value: opt.value, children: opt.label }, opt.value))) })), deferred && (_jsx(Button, { type: "button", variant: "primary", onClick: handleDeferredSubmit, "aria-label": labels.ariaLabel, className: "flex-shrink-0 px-3 py-2 rounded-lg", children: _jsx("svg", { className: "w-4 h-4", "aria-hidden": "true", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: SVG_PATH_SEARCH }) }) })), isInlineOpen && (filteredQuickLinks.length > 0 || query) && (_jsxs("div", { className: "absolute top-full left-0 right-0 mt-2 rounded-xl overflow-hidden border border-zinc-200 bg-white shadow-lg dark:border-slate-700 dark:bg-slate-900",
|
|
209
|
+
// audit-inline-style-ok: z-index token
|
|
210
|
+
style: { zIndex: "var(--appkit-z-dropdown)" }, onMouseDown: (event) => event.preventDefault(), children: [filteredQuickLinks.length > 0 && (_jsx(Ul, { children: filteredQuickLinks.map((link, index) => renderInlineQuickLink(link, index)) })), query && suggestionsLoading && (_jsx(Div, { className: "px-4 py-3", children: _jsx(Text, { variant: "secondary", size: "sm", children: labels.searching }) })), query &&
|
|
209
211
|
suggestions.slice(0, 5).map((suggestion, suggestionIndex) => {
|
|
210
212
|
const itemIndex = inlineQuickLinkItems.length + suggestionIndex;
|
|
211
213
|
const isActive = activeIndex === itemIndex;
|
|
@@ -11,11 +11,11 @@ interface UseSearchOptions {
|
|
|
11
11
|
* `options.initialCategories` — server-prefetched category list for filter facets.
|
|
12
12
|
*/
|
|
13
13
|
export declare function useSearch(searchParams: string, options?: UseSearchOptions): {
|
|
14
|
-
results:
|
|
14
|
+
results: SearchResponse | null;
|
|
15
15
|
items: import("..").SearchProductItem[];
|
|
16
16
|
total: number;
|
|
17
17
|
totalPages: number;
|
|
18
18
|
isLoading: boolean;
|
|
19
|
-
categories:
|
|
19
|
+
categories: SearchCategoryOption[];
|
|
20
20
|
};
|
|
21
21
|
export {};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import { sortBy } from "@mohasinac/appkit";
|
|
3
4
|
import React from "react";
|
|
4
5
|
import { PaginatedSelect } from "../../../ui/components/PaginatedSelect";
|
|
5
6
|
import { apiClient } from "../../../http";
|
|
@@ -10,7 +11,7 @@ function makeLoader(scope) {
|
|
|
10
11
|
const params = new URLSearchParams({
|
|
11
12
|
page: String(page),
|
|
12
13
|
pageSize: "25",
|
|
13
|
-
sorts: "
|
|
14
|
+
sorts: sortBy("createdAt", "DESC"),
|
|
14
15
|
});
|
|
15
16
|
if (query.trim())
|
|
16
17
|
params.set("q", query.trim());
|
|
@@ -27,5 +27,5 @@ export function PhysicalLocationModal({ count, onSave, onClose }) {
|
|
|
27
27
|
setSaving(false);
|
|
28
28
|
}
|
|
29
29
|
};
|
|
30
|
-
return (
|
|
30
|
+
return (_jsxs(Modal, { isOpen: true, onClose: onClose, title: `Set Location — ${count} item${count !== 1 ? "s" : ""}`, size: "sm", actions: _jsxs(Row, { gap: "sm", justify: "end", children: [_jsx(Button, { variant: "ghost", onClick: onClose, disabled: saving, children: "Cancel" }), _jsx(Button, { variant: "primary", onClick: handleSave, disabled: saving, children: saving ? "Saving..." : "Save" })] }), children: ["// audit-inline-style-ok: dynamic CSS", _jsxs(Div, { style: { display: "flex", flexDirection: "column", gap: "12px" }, children: [_jsx(Text, { variant: "muted", children: "Assign a physical storage location to the selected items. All fields are optional." }), _jsx(Input, { label: "Zone (e.g. A, B, Storage-1)", value: zone, onChange: e => setZone(e.target.value), placeholder: "A" }), _jsx(Input, { label: "Shelf (e.g. 3, Top, Middle)", value: shelf, onChange: e => setShelf(e.target.value), placeholder: "3" }), _jsx(Input, { label: "Bin (e.g. Blue, Box-12)", value: bin, onChange: e => setBin(e.target.value), placeholder: "Blue" }), error && _jsx(Text, { variant: "error", children: error })] })] }));
|
|
31
31
|
}
|
|
@@ -64,6 +64,7 @@ export function SellerAddressesView({ apiBase = SELLER_ENDPOINTS.STORE_ADDRESSES
|
|
|
64
64
|
const [saveError, setSaveError] = useState(null);
|
|
65
65
|
const [deleteTargetAddr, setDeleteTargetAddr] = useState(null);
|
|
66
66
|
const load = useCallback(async () => {
|
|
67
|
+
// toast-intentionally-silent — error rendered inline via setErrorMessage()
|
|
67
68
|
setIsLoading(true);
|
|
68
69
|
setErrorMessage(null);
|
|
69
70
|
try {
|
|
@@ -139,5 +140,5 @@ export function SellerAddressesView({ apiBase = SELLER_ENDPOINTS.STORE_ADDRESSES
|
|
|
139
140
|
const handleDelete = (addr) => setDeleteTargetAddr(addr);
|
|
140
141
|
const set = (key, value) => setDraft((p) => ({ ...p, [key]: value }));
|
|
141
142
|
const handleTextField = (key) => (e) => set(key, e.target.value);
|
|
142
|
-
return (_jsxs(Div, { className: "min-h-screen", children: [_jsxs(Row, { justify: "between", className: "sticky z-10 bg-white/95 dark:bg-slate-900/95 backdrop-blur-sm border-b border-zinc-200 dark:border-slate-700 px-4 py-3", style: { top: "var(--header-height, 0px)" }, children: [_jsxs(Stack, { gap: "none", children: [_jsx(Heading, { level: 2, className: "text-base font-semibold text-zinc-900 dark:text-zinc-100", children: "Pickup Addresses" }), _jsx(Text, { size: "xs", color: "muted", className: "mt-0.5", children: "Manage your store's pickup and return locations" })] }), _jsxs(Button, { size: "sm", onClick: openAdd, className: "flex items-center gap-1.5", children: [_jsx(Plus, { className: "h-4 w-4" }), _jsx(Span, { children: "Add Address" })] })] }), _jsxs(Div, { className: "py-6 px-4 sm:px-6 max-w-2xl", children: [errorMessage && (_jsx(Div, { className: "mb-4 rounded-xl border border-error/20 bg-error-surface px-4 py-3 text-sm text-error", children: errorMessage })), isLoading ? (_jsx(Row, { justify: "center", className: "py-16", children: _jsx(Div, { className: "h-6 w-6 animate-spin rounded-full border-2 border-[var(--appkit-color-primary)] border-t-transparent" }) })) : addresses.length === 0 ? (_jsxs(Div, { className: "rounded-xl border-2 border-dashed border-zinc-200 dark:border-slate-700 py-16 flex flex-col items-center gap-3", children: [_jsx(MapPin, { className: "h-8 w-8 text-zinc-300 dark:text-slate-600" }), _jsx(Text, { className: "text-sm text-zinc-500 dark:text-zinc-400", children: "No pickup addresses yet" }), _jsx(Button, { size: "sm", variant: "outline", onClick: openAdd, children: "Add your first address" })] })) : (_jsxs(_Fragment, { children: [_jsxs(Row, { justify: "end", className: "mb-2", children: [_jsx(Button, { size: "sm", variant: listView === "table" ? "primary" : "ghost", onClick: () => setListView("table"), children: "Table" }), _jsx(Button, { size: "sm", variant: listView === "cards" ? "primary" : "ghost", onClick: () => setListView("cards"), children: "Cards" })] }), listView === "cards" ? (_jsx(Grid, { gap: "sm", children: addresses.map((addr) => (_jsx(Div, { className: deletingId === addr.id ? "opacity-50 pointer-events-none" : "", children: _jsx(AddressCard, { address: addr, onEdit: () => openEdit(addr), onDelete: () => handleDelete(addr) }) }, addr.id))) })) : (_jsx(Div, { className: `${__O.xAuto} rounded-lg border border-zinc-200 dark:border-slate-700`, children: _jsxs(Table, { className: "w-full text-sm", children: [_jsx(Thead, { className: "bg-zinc-50 dark:bg-slate-800", children: _jsxs(Tr, { children: [_jsx(Th, { className: "text-left px-3 py-2 font-semibold", children: "Label" }), _jsx(Th, { className: "text-left px-3 py-2 font-semibold", children: "Name" }), _jsx(Th, { className: "text-left px-3 py-2 font-semibold", children: "City" }), _jsx(Th, { className: "text-left px-3 py-2 font-semibold", children: "Phone" }), _jsx(Th, { className: "text-right px-3 py-2 font-semibold", children: "Actions" })] }) }), _jsx(Tbody, { children: addresses.map((addr) => (_jsxs(Tr, { className: `border-t border-zinc-100 dark:border-slate-700 ${deletingId === addr.id ? "opacity-50" : ""}`, children: [_jsx(Td, { className: "px-3 py-2", children: addr.label }), _jsx(Td, { className: "px-3 py-2", children: addr.fullName }), _jsxs(Td, { className: "px-3 py-2", children: [addr.city, ", ", addr.state] }), _jsx(Td, { className: "px-3 py-2 tabular-nums", children: addr.phone }), _jsx(Td, { className: "px-3 py-2 text-right", children: _jsxs(Row, { justify: "end", className: "gap-1", children: [_jsx(Button, { size: "sm", variant: "ghost", onClick: () => openEdit(addr), children: ROW_ACTION_META[ROW_ACTION_ID.EDIT].label }), _jsx(Button, { size: "sm", variant: "ghost", onClick: () => handleDelete(addr), children: ROW_ACTION_META[ROW_ACTION_ID.DELETE].label })] }) })] }, addr.id))) })] }) }))] }))] }), _jsx(SideDrawer, { isOpen: drawerOpen, onClose: closeDrawer, title: editingId ? "Edit Address" : "Add Address", footer: _jsxs(Row, { gap: "xs", children: [_jsx(Button, { variant: "outline", onClick: closeDrawer, className: "flex-1", children: "Cancel" }), _jsx(Button, { onClick: handleSave, disabled: saving, className: "flex-1", children: saving ? "Saving…" : editingId ? "Save Changes" : "Add Address" })] }), children: _jsxs(Stack, { gap: "md", className: "py-1", children: [saveError && (_jsx(Div, { className: "rounded-lg border border-error/20 bg-error-surface px-3 py-2 text-sm text-error", children: saveError })), _jsx(Field, { label: "Label *", hint: "e.g. Warehouse, Shop, Home", children: _jsx("input", { type: "text", value: draft.label, onChange: handleTextField("label"), placeholder: "Warehouse", maxLength: 60, className: INPUT_CLS }) }), _jsxs(Grid, { cols: 2, gap: "sm", children: [_jsx(Field, { label: "Full Name *", children: _jsx("input", { type: "text", value: draft.fullName, onChange: handleTextField("fullName"), placeholder: "Ravi Kumar", maxLength: 100, className: INPUT_CLS }) }), _jsx(Field, { label: "Phone *", children: _jsx("input", { type: "tel", value: draft.phone, onChange: handleTextField("phone"), placeholder: "+91 98765 43210", maxLength: 20, className: INPUT_CLS }) })] }), _jsx(Field, { label: "Address Line 1 *", children: _jsx("input", { type: "text", value: draft.addressLine1, onChange: handleTextField("addressLine1"), placeholder: "Shop 12, Main Market", maxLength: 200, className: INPUT_CLS }) }), _jsx(Field, { label: "Address Line 2", children: _jsx("input", { type: "text", value: draft.addressLine2, onChange: handleTextField("addressLine2"), placeholder: "Building / Floor (optional)", maxLength: 200, className: INPUT_CLS }) }), _jsx(Field, { label: "Landmark", children: _jsx("input", { type: "text", value: draft.landmark, onChange: handleTextField("landmark"), placeholder: "Near metro station (optional)", maxLength: 100, className: INPUT_CLS }) }), _jsxs(Grid, { cols: 2, gap: "sm", children: [_jsx(Field, { label: "City *", children: _jsx("input", { type: "text", value: draft.city, onChange: handleTextField("city"), placeholder: "Mumbai", maxLength: 100, className: INPUT_CLS }) }), _jsx(Field, { label: "State *", children: _jsx("input", { type: "text", value: draft.state, onChange: handleTextField("state"), placeholder: "Maharashtra", maxLength: 100, className: INPUT_CLS }) })] }), _jsxs(Grid, { cols: 2, gap: "sm", children: [_jsx(Field, { label: "Postal Code *", children: _jsx("input", { type: "text", value: draft.postalCode, onChange: handleTextField("postalCode"), placeholder: "400001", maxLength: 10, className: INPUT_CLS }) }), _jsx(Field, { label: "Country *", children: _jsx("input", { type: "text", value: draft.country, onChange: handleTextField("country"), placeholder: "India", maxLength: 60, className: INPUT_CLS }) })] }), _jsxs("label", { className: "flex items-center gap-3 cursor-pointer", children: [_jsx("input", { type: "checkbox", checked: draft.isDefault, onChange: (e) => set("isDefault", e.target.checked), className: "h-4 w-4 rounded border-zinc-300 dark:border-slate-600 text-[var(--appkit-color-primary)] focus:ring-[var(--appkit-color-primary)]" }), _jsx(Span, { size: "sm", className: "text-zinc-700 dark:text-zinc-300", children: "Set as default pickup address" })] })] }) }), deleteTargetAddr && (_jsx(ConfirmDeleteModal, { isOpen: true, title: "Delete Address", message: `Delete address "${deleteTargetAddr.label}"? This cannot be undone.`, onConfirm: () => { deleteById(deleteTargetAddr.id); setDeleteTargetAddr(null); }, onClose: () => setDeleteTargetAddr(null), isDeleting: deletingId === deleteTargetAddr.id }))] }));
|
|
143
|
+
return (_jsxs(Div, { className: "min-h-screen", children: ["// audit-inline-style-ok: dynamic CSS", _jsxs(Row, { justify: "between", className: "sticky z-10 bg-white/95 dark:bg-slate-900/95 backdrop-blur-sm border-b border-zinc-200 dark:border-slate-700 px-4 py-3", style: { top: "var(--header-height, 0px)" }, children: [_jsxs(Stack, { gap: "none", children: [_jsx(Heading, { level: 2, className: "text-base font-semibold text-zinc-900 dark:text-zinc-100", children: "Pickup Addresses" }), _jsx(Text, { size: "xs", color: "muted", className: "mt-0.5", children: "Manage your store's pickup and return locations" })] }), _jsxs(Button, { size: "sm", onClick: openAdd, className: "flex items-center gap-1.5", children: [_jsx(Plus, { className: "h-4 w-4" }), _jsx(Span, { children: "Add Address" })] })] }), _jsxs(Div, { className: "py-6 px-4 sm:px-6 max-w-2xl", children: [errorMessage && (_jsx(Div, { className: "mb-4 rounded-xl border border-error/20 bg-error-surface px-4 py-3 text-sm text-error", children: errorMessage })), isLoading ? (_jsx(Row, { justify: "center", className: "py-16", children: _jsx(Div, { className: "h-6 w-6 animate-spin rounded-full border-2 border-[var(--appkit-color-primary)] border-t-transparent" }) })) : addresses.length === 0 ? (_jsxs(Div, { className: "rounded-xl border-2 border-dashed border-zinc-200 dark:border-slate-700 py-16 flex flex-col items-center gap-3", children: [_jsx(MapPin, { className: "h-8 w-8 text-zinc-300 dark:text-slate-600" }), _jsx(Text, { className: "text-sm text-zinc-500 dark:text-zinc-400", children: "No pickup addresses yet" }), _jsx(Button, { size: "sm", variant: "outline", onClick: openAdd, children: "Add your first address" })] })) : (_jsxs(_Fragment, { children: [_jsxs(Row, { justify: "end", className: "mb-2", children: [_jsx(Button, { size: "sm", variant: listView === "table" ? "primary" : "ghost", onClick: () => setListView("table"), children: "Table" }), _jsx(Button, { size: "sm", variant: listView === "cards" ? "primary" : "ghost", onClick: () => setListView("cards"), children: "Cards" })] }), listView === "cards" ? (_jsx(Grid, { gap: "sm", children: addresses.map((addr) => (_jsx(Div, { className: deletingId === addr.id ? "opacity-50 pointer-events-none" : "", children: _jsx(AddressCard, { address: addr, onEdit: () => openEdit(addr), onDelete: () => handleDelete(addr) }) }, addr.id))) })) : (_jsx(Div, { className: `${__O.xAuto} rounded-lg border border-zinc-200 dark:border-slate-700`, children: _jsxs(Table, { className: "w-full text-sm", children: [_jsx(Thead, { className: "bg-zinc-50 dark:bg-slate-800", children: _jsxs(Tr, { children: [_jsx(Th, { className: "text-left px-3 py-2 font-semibold", children: "Label" }), _jsx(Th, { className: "text-left px-3 py-2 font-semibold", children: "Name" }), _jsx(Th, { className: "text-left px-3 py-2 font-semibold", children: "City" }), _jsx(Th, { className: "text-left px-3 py-2 font-semibold", children: "Phone" }), _jsx(Th, { className: "text-right px-3 py-2 font-semibold", children: "Actions" })] }) }), _jsx(Tbody, { children: addresses.map((addr) => (_jsxs(Tr, { className: `border-t border-zinc-100 dark:border-slate-700 ${deletingId === addr.id ? "opacity-50" : ""}`, children: [_jsx(Td, { className: "px-3 py-2", children: addr.label }), _jsx(Td, { className: "px-3 py-2", children: addr.fullName }), _jsxs(Td, { className: "px-3 py-2", children: [addr.city, ", ", addr.state] }), _jsx(Td, { className: "px-3 py-2 tabular-nums", children: addr.phone }), _jsx(Td, { className: "px-3 py-2 text-right", children: _jsxs(Row, { justify: "end", className: "gap-1", children: [_jsx(Button, { size: "sm", variant: "ghost", onClick: () => openEdit(addr), children: ROW_ACTION_META[ROW_ACTION_ID.EDIT].label }), _jsx(Button, { size: "sm", variant: "ghost", onClick: () => handleDelete(addr), children: ROW_ACTION_META[ROW_ACTION_ID.DELETE].label })] }) })] }, addr.id))) })] }) }))] }))] }), _jsx(SideDrawer, { isOpen: drawerOpen, onClose: closeDrawer, title: editingId ? "Edit Address" : "Add Address", footer: _jsxs(Row, { gap: "xs", children: [_jsx(Button, { variant: "outline", onClick: closeDrawer, className: "flex-1", children: "Cancel" }), _jsx(Button, { onClick: handleSave, disabled: saving, className: "flex-1", children: saving ? "Saving…" : editingId ? "Save Changes" : "Add Address" })] }), children: _jsxs(Stack, { gap: "md", className: "py-1", children: [saveError && (_jsx(Div, { className: "rounded-lg border border-error/20 bg-error-surface px-3 py-2 text-sm text-error", children: saveError })), _jsx(Field, { label: "Label *", hint: "e.g. Warehouse, Shop, Home", children: _jsx("input", { type: "text", value: draft.label, onChange: handleTextField("label"), placeholder: "Warehouse", maxLength: 60, className: INPUT_CLS }) }), _jsxs(Grid, { cols: 2, gap: "sm", children: [_jsx(Field, { label: "Full Name *", children: _jsx("input", { type: "text", value: draft.fullName, onChange: handleTextField("fullName"), placeholder: "Ravi Kumar", maxLength: 100, className: INPUT_CLS }) }), _jsx(Field, { label: "Phone *", children: _jsx("input", { type: "tel", value: draft.phone, onChange: handleTextField("phone"), placeholder: "+91 98765 43210", maxLength: 20, className: INPUT_CLS }) })] }), _jsx(Field, { label: "Address Line 1 *", children: _jsx("input", { type: "text", value: draft.addressLine1, onChange: handleTextField("addressLine1"), placeholder: "Shop 12, Main Market", maxLength: 200, className: INPUT_CLS }) }), _jsx(Field, { label: "Address Line 2", children: _jsx("input", { type: "text", value: draft.addressLine2, onChange: handleTextField("addressLine2"), placeholder: "Building / Floor (optional)", maxLength: 200, className: INPUT_CLS }) }), _jsx(Field, { label: "Landmark", children: _jsx("input", { type: "text", value: draft.landmark, onChange: handleTextField("landmark"), placeholder: "Near metro station (optional)", maxLength: 100, className: INPUT_CLS }) }), _jsxs(Grid, { cols: 2, gap: "sm", children: [_jsx(Field, { label: "City *", children: _jsx("input", { type: "text", value: draft.city, onChange: handleTextField("city"), placeholder: "Mumbai", maxLength: 100, className: INPUT_CLS }) }), _jsx(Field, { label: "State *", children: _jsx("input", { type: "text", value: draft.state, onChange: handleTextField("state"), placeholder: "Maharashtra", maxLength: 100, className: INPUT_CLS }) })] }), _jsxs(Grid, { cols: 2, gap: "sm", children: [_jsx(Field, { label: "Postal Code *", children: _jsx("input", { type: "text", value: draft.postalCode, onChange: handleTextField("postalCode"), placeholder: "400001", maxLength: 10, className: INPUT_CLS }) }), _jsx(Field, { label: "Country *", children: _jsx("input", { type: "text", value: draft.country, onChange: handleTextField("country"), placeholder: "India", maxLength: 60, className: INPUT_CLS }) })] }), _jsxs("label", { className: "flex items-center gap-3 cursor-pointer", children: [_jsx("input", { type: "checkbox", checked: draft.isDefault, onChange: (e) => set("isDefault", e.target.checked), className: "h-4 w-4 rounded border-zinc-300 dark:border-slate-600 text-[var(--appkit-color-primary)] focus:ring-[var(--appkit-color-primary)]" }), _jsx(Span, { size: "sm", className: "text-zinc-700 dark:text-zinc-300", children: "Set as default pickup address" })] })] }) }), deleteTargetAddr && (_jsx(ConfirmDeleteModal, { isOpen: true, title: "Delete Address", message: `Delete address "${deleteTargetAddr.label}"? This cannot be undone.`, onConfirm: () => { deleteById(deleteTargetAddr.id); setDeleteTargetAddr(null); }, onClose: () => setDeleteTargetAddr(null), isDeleting: deletingId === deleteTargetAddr.id }))] }));
|
|
143
144
|
}
|
|
@@ -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, { useState, useCallback } from "react";
|
|
4
6
|
import { useEntityDelete } from "../../../react/hooks/useEntityDelete";
|
|
5
7
|
import { ConfirmDeleteModal, FilterChipGroup, ListingLayout, RowActionMenu } from "../../../ui";
|
|
@@ -36,14 +38,14 @@ export function SellerAuctionsView({ children, onEditClick, onDelete, onBulkDele
|
|
|
36
38
|
searchPlaceholder: "Search auctions by product name",
|
|
37
39
|
emptyLabel: "No auctions found",
|
|
38
40
|
filterKeys: ["status"],
|
|
39
|
-
defaultSort: "endsAt",
|
|
41
|
+
defaultSort: sortBy("endsAt", "ASC"),
|
|
40
42
|
queryKey: ["seller", "auctions", "listing"],
|
|
41
43
|
endpoint: SELLER_ENDPOINTS.AUCTIONS,
|
|
42
44
|
sortOptions: [
|
|
43
45
|
{ value: "endsAt", label: "Ending soon" },
|
|
44
|
-
{ value: "
|
|
45
|
-
{ value: "
|
|
46
|
-
{ value: "createdAt", label: "Oldest" },
|
|
46
|
+
{ value: sortBy("endsAt", "DESC"), label: "Ending latest" },
|
|
47
|
+
{ value: sortBy("createdAt", "DESC"), label: "Newest" },
|
|
48
|
+
{ value: sortBy("createdAt", "ASC"), label: "Oldest" },
|
|
47
49
|
],
|
|
48
50
|
mapRows: (response) => toRecordArray(response.auctions).map((item, index) => ({
|
|
49
51
|
id: toStringValue(item.id, `auction-${index}`),
|
|
@@ -58,7 +60,7 @@ export function SellerAuctionsView({ children, onEditClick, onDelete, onBulkDele
|
|
|
58
60
|
getTotal: (response, mappedRows) => typeof response.meta?.total === "number"
|
|
59
61
|
? response.meta.total
|
|
60
62
|
: mappedRows.length,
|
|
61
|
-
buildFilters: (state) => state.status && state.status !== "All" ?
|
|
63
|
+
buildFilters: (state) => state.status && state.status !== "All" ? sieveFilter("status", SIEVE_OP.EQ, state.status) : undefined,
|
|
62
64
|
buildBulkActions: onBulkDelete
|
|
63
65
|
? (selection) => [
|
|
64
66
|
{
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, 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, { useState, useCallback } from "react";
|
|
4
6
|
import { useUrlTable } from "../../../react/hooks/useUrlTable";
|
|
5
7
|
import { useBulkSelection } from "../../../react/hooks/useBulkSelection";
|
|
@@ -18,9 +20,9 @@ const PAGE_SIZE = 25;
|
|
|
18
20
|
const FILTER_KEYS = ["status"];
|
|
19
21
|
const DEFAULT_SORT = "-bidDate";
|
|
20
22
|
const SORT_OPTIONS = [
|
|
21
|
-
{ value: "
|
|
23
|
+
{ value: sortBy("bidDate", "DESC"), label: "Newest" },
|
|
22
24
|
{ value: "bidDate", label: "Oldest" },
|
|
23
|
-
{ value: "
|
|
25
|
+
{ value: sortBy("bidAmount", "DESC"), label: "Highest Bid" },
|
|
24
26
|
{ value: "bidAmount", label: "Lowest Bid" },
|
|
25
27
|
];
|
|
26
28
|
const STATUS_OPTIONS = SELLER_BID_STATUS_TABS;
|
|
@@ -67,7 +69,7 @@ export function SellerBidsView({ endpoint = SELLER_ENDPOINTS.BIDS }) {
|
|
|
67
69
|
const activeFilterCount = FILTER_KEYS.filter((k) => !!table.get(k)).length;
|
|
68
70
|
const hasActiveState = !!table.get("q") || table.get("sort") !== DEFAULT_SORT || activeFilterCount > 0;
|
|
69
71
|
const statusRaw = table.get("status");
|
|
70
|
-
const filters = statusRaw ?
|
|
72
|
+
const filters = statusRaw ? sieveFilter("status", SIEVE_OP.EQ, statusRaw) : undefined;
|
|
71
73
|
const productIdFilter = table.get("productId") || undefined;
|
|
72
74
|
const endpointWithProduct = productIdFilter
|
|
73
75
|
? `${endpoint}?productId=${encodeURIComponent(productIdFilter)}`
|
|
@@ -165,7 +167,9 @@ export function SellerBidsView({ endpoint = SELLER_ENDPOINTS.BIDS }) {
|
|
|
165
167
|
buildBulkAction(ACTIONS.SELLER["cancel-bid"], () => void bulkCancel()),
|
|
166
168
|
];
|
|
167
169
|
useBottomActions(selection.selectedCount > 0 ? { bulk: { selectedCount: selection.selectedCount, onClearSelection: selection.clearSelection, actions: bulkActions } } : {});
|
|
168
|
-
return (_jsxs(Div, { className: "min-h-screen", children: [_jsx(ListingToolbar, { filterCount: activeFilterCount, onFiltersClick: openFilters, searchValue: searchInput, searchPlaceholder: "Search by bidder name", 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 }), 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: currentPage, totalPages: totalPages, onPageChange: (p) => table.setPage(p) }) })), selection.selectedIds.length > 0 && (_jsx(Div, { className: "sticky z-20 px-3 sm:px-4 py-2 bg-white/95 dark:bg-slate-900/95 backdrop-blur-sm border-b border-zinc-200 dark:border-slate-700",
|
|
170
|
+
return (_jsxs(Div, { className: "min-h-screen", children: [_jsx(ListingToolbar, { filterCount: activeFilterCount, onFiltersClick: openFilters, searchValue: searchInput, searchPlaceholder: "Search by bidder name", 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 }), 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: currentPage, totalPages: totalPages, onPageChange: (p) => table.setPage(p) }) })), selection.selectedIds.length > 0 && (_jsx(Div, { className: "sticky z-20 px-3 sm:px-4 py-2 bg-white/95 dark:bg-slate-900/95 backdrop-blur-sm border-b border-zinc-200 dark:border-slate-700",
|
|
171
|
+
// audit-inline-style-ok: sticky header offset
|
|
172
|
+
style: { top: "calc(var(--header-height, 0px) + 88px)" }, children: _jsx(BulkActionBar, { selectedCount: selection.selectedIds.length, onClearSelection: selection.clearSelection, actions: bulkActions }) })), _jsxs(Div, { className: "py-4 px-3 sm:px-4", children: [errorMessage && (_jsx(Div, { className: "mb-4 rounded-xl border border-error/20 bg-error-surface px-4 py-3 text-sm text-error", children: errorMessage })), table.get("grouped") === "0" ? (_jsx(DataTable, { rows: rows, columns: columns, isLoading: isLoading, emptyLabel: "No bids found for your auctions", selectedIds: selection.selectedIdSet, onToggleSelect: selection.toggle, onToggleSelectAll: () => selection.toggleAll() })) : (_jsxs(Div, { className: "space-y-3", children: [groupedRows.length === 0 && !isLoading && (_jsx(Text, { className: "text-sm text-zinc-500 dark:text-zinc-400", children: "No bids found for your auctions." })), groupedRows.map((group) => {
|
|
169
173
|
const collapsed = collapsedGroups.has(group.id);
|
|
170
174
|
return (_jsxs(Div, { className: "rounded-lg border border-[var(--appkit-color-border)] bg-[var(--appkit-color-surface)]", children: [_jsxs("button", { type: "button", onClick: () => toggleGroup(group.id), className: "w-full flex items-center justify-between px-4 py-2.5 text-sm font-semibold text-[var(--appkit-color-text)] hover:bg-[var(--appkit-color-surface-raised)]", children: [_jsxs(Span, { className: "truncate", children: [group.title, " ", _jsxs(Span, { size: "xs", weight: "normal", className: "text-[var(--appkit-color-text-muted)]", children: ["\u00B7 ", group.bids.length, " bid", group.bids.length === 1 ? "" : "s"] })] }), _jsx(Span, { "aria-hidden": true, className: "text-[var(--appkit-color-text-muted)]", children: collapsed ? "▸" : "▾" })] }), !collapsed && (_jsx(Div, { className: "border-t border-[var(--appkit-color-border)]", children: _jsx(DataTable, { rows: group.bids, columns: columns, isLoading: false, emptyLabel: "", selectedIds: selection.selectedIdSet, onToggleSelect: selection.toggle }) }))] }, group.id));
|
|
171
175
|
})] }))] }), _jsx(ListingFilterDrawer, { open: filterOpen, onClose: () => setFilterOpen(false), onApply: applyFilters, onClear: clearFilters, activeCount: activeFilterCount, children: _jsx(FilterChipGroup, { label: "Bid Status", tabs: STATUS_OPTIONS, value: pendingFilters.status ?? "", onChange: (id) => setPendingFilters((p) => ({ ...p, status: id })), allId: "" }) })] }));
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { sortBy } from "@mohasinac/appkit";
|
|
3
4
|
import { useState, useCallback } from "react";
|
|
4
5
|
import { useEntityDelete } from "../../../react/hooks/useEntityDelete";
|
|
5
6
|
import { ConfirmDeleteModal, RowActionMenu, Text } from "../../../ui";
|
|
@@ -60,16 +61,16 @@ export function SellerBundlesView({ onCreateClick, onEditClick, onDelete, onBulk
|
|
|
60
61
|
searchPlaceholder: "Search bundles...",
|
|
61
62
|
emptyLabel: "No bundles yet — create a bundle to group multiple products together",
|
|
62
63
|
filterKeys: [],
|
|
63
|
-
defaultSort: "
|
|
64
|
+
defaultSort: sortBy("createdAt", "DESC"),
|
|
64
65
|
queryKey: ["seller", "bundles"],
|
|
65
66
|
endpoint: SELLER_ENDPOINTS.PRODUCTS,
|
|
66
67
|
sortOptions: [
|
|
67
|
-
{ value: "
|
|
68
|
-
{ value: "createdAt", label: "Oldest" },
|
|
68
|
+
{ value: sortBy("createdAt", "DESC"), label: "Newest" },
|
|
69
|
+
{ value: sortBy("createdAt", "ASC"), label: "Oldest" },
|
|
69
70
|
{ value: "productTitle", label: "Name A–Z" },
|
|
70
|
-
{ value: "
|
|
71
|
-
{ value: "price", label: "Price: Low–High" },
|
|
72
|
-
{ value: "
|
|
71
|
+
{ value: sortBy("productTitle", "DESC"), label: "Name Z–A" },
|
|
72
|
+
{ value: sortBy("price", "ASC"), label: "Price: Low–High" },
|
|
73
|
+
{ value: sortBy("price", "DESC"), label: "Price: High–Low" },
|
|
73
74
|
],
|
|
74
75
|
columns: COLUMNS,
|
|
75
76
|
mapRows: (response) => toRecordArray(response.products).map((item, index) => ({
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { sortBy } from "@mohasinac/appkit";
|
|
3
4
|
import { useState, useCallback } from "react";
|
|
4
5
|
import { useEntityDelete } from "../../../react/hooks/useEntityDelete";
|
|
5
6
|
import { ConfirmDeleteModal, RowActionMenu, Text } from "../../../ui";
|
|
@@ -66,15 +67,15 @@ export function SellerClassifiedView({ onCreateClick, onEditClick, onDelete, onB
|
|
|
66
67
|
searchPlaceholder: "Search classified listings...",
|
|
67
68
|
emptyLabel: "No classified listings yet — post your first buy/sell/trade ad",
|
|
68
69
|
filterKeys: [],
|
|
69
|
-
defaultSort: "
|
|
70
|
+
defaultSort: sortBy("createdAt", "DESC"),
|
|
70
71
|
queryKey: ["seller", "classified"],
|
|
71
72
|
endpoint: SELLER_ENDPOINTS.PRODUCTS,
|
|
72
73
|
sortOptions: [
|
|
73
|
-
{ value: "
|
|
74
|
-
{ value: "createdAt", label: "Oldest" },
|
|
74
|
+
{ value: sortBy("createdAt", "DESC"), label: "Newest" },
|
|
75
|
+
{ value: sortBy("createdAt", "ASC"), label: "Oldest" },
|
|
75
76
|
{ value: "productTitle", label: "Name A–Z" },
|
|
76
|
-
{ value: "price", label: "Price: Low–High" },
|
|
77
|
-
{ value: "
|
|
77
|
+
{ value: sortBy("price", "ASC"), label: "Price: Low–High" },
|
|
78
|
+
{ value: sortBy("price", "DESC"), label: "Price: High–Low" },
|
|
78
79
|
],
|
|
79
80
|
columns: COLUMNS,
|
|
80
81
|
mapRows: (response) => toRecordArray(response.products).map((item, index) => {
|
|
@@ -69,7 +69,9 @@ export function SellerCouponEditorView({ couponId, initial, onSave, onCancel, })
|
|
|
69
69
|
}
|
|
70
70
|
};
|
|
71
71
|
const isEdit = Boolean(couponId);
|
|
72
|
-
return (_jsx("form", { onSubmit: handleSubmit, noValidate: true, children: _jsxs(Stack, { gap: "none", className: `max-w-lg mx-auto rounded-xl border border-[var(--appkit-color-border)] bg-[var(--appkit-color-surface)] shadow-sm ${__O.hidden}`, children: [_jsx("div", { className: "h-[3px] w-full",
|
|
72
|
+
return (_jsx("form", { onSubmit: handleSubmit, noValidate: true, children: _jsxs(Stack, { gap: "none", className: `max-w-lg mx-auto rounded-xl border border-[var(--appkit-color-border)] bg-[var(--appkit-color-surface)] shadow-sm ${__O.hidden}`, children: [_jsx("div", { className: "h-[3px] w-full",
|
|
73
|
+
// audit-inline-style-ok: runtime theme gradient
|
|
74
|
+
style: { background: "linear-gradient(to right,var(--appkit-color-primary-700,#1343de) 0%,var(--appkit-color-cobalt,#3570fc) 55%,var(--appkit-color-secondary-400,#84e122) 100%)" }, "aria-hidden": "true" }), _jsx(Div, { className: "border-b border-[var(--appkit-color-border)] px-6 py-5", children: _jsxs(Row, { justify: "between", className: "gap-3", children: [_jsx(Heading, { level: 2, className: "text-lg font-semibold text-[var(--appkit-color-text)]", children: isEdit ? "Edit Coupon" : "Create Coupon" }), isEdit && (_jsx(Badge, { variant: draft.isActive ? "success" : "default", children: draft.isActive ? "Active" : "Inactive" }))] }) }), _jsxs(Stack, { gap: "5", className: "px-6 py-6", children: [error && (_jsx(Div, { className: "rounded-lg border border-error/20 bg-error-surface px-4 py-3 text-sm text-error", children: error })), _jsx(Input, { label: "Coupon Code", value: draft.code, onChange: (e) => set("code", e.target.value.toUpperCase().replace(/\s+/g, "")), placeholder: "e.g. WELCOME10", required: true, disabled: isEdit, helperText: isEdit ? "Code cannot be changed after creation" : "Customers enter this at checkout" }), _jsx(Select, { label: "Discount Type", value: draft.type, options: TYPE_OPTIONS, onChange: (e) => set("type", e.target.value) }), draft.type !== "free_shipping" && (_jsx(Input, { label: draft.type === "percentage" ? "Discount Percentage (%)" : "Discount Amount (₹)", type: "number", min: 1, max: draft.type === "percentage" ? 100 : undefined, value: draft.value, onChange: (e) => set("value", e.target.value), placeholder: draft.type === "percentage" ? "e.g. 10" : "e.g. 50", required: true, helperText: draft.type === "percentage"
|
|
73
75
|
? "Enter a value between 1 and 100"
|
|
74
76
|
: "Fixed rupee discount applied to the order" })), draft.type === "percentage" && (_jsx(Input, { label: "Max Discount Cap (\u20B9, optional)", type: "number", min: 0, value: draft.maxDiscount, onChange: (e) => set("maxDiscount", e.target.value), placeholder: "Leave blank for no cap", helperText: "Maximum rupee discount regardless of percentage" })), _jsx(Input, { label: "Minimum Order Amount (\u20B9, optional)", type: "number", min: 0, value: draft.minPurchase, onChange: (e) => set("minPurchase", e.target.value), placeholder: "Leave blank for no minimum" }), _jsxs(Div, { children: [_jsx(Text, { size: "sm", className: CLS_SECTION_LABEL, children: "Usage Limits" }), _jsxs(Div, { className: "grid grid-cols-2 gap-3", children: [_jsx(Input, { label: "Total Uses", type: "number", min: 0, value: draft.totalLimit, onChange: (e) => set("totalLimit", e.target.value), placeholder: "0 = unlimited" }), _jsx(Input, { label: "Per Customer", type: "number", min: 0, value: draft.perUserLimit, onChange: (e) => set("perUserLimit", e.target.value), placeholder: "0 = unlimited" })] })] }), _jsxs(Div, { children: [_jsx(Text, { size: "sm", className: CLS_SECTION_LABEL, children: "Validity Period" }), _jsxs(Div, { className: "grid grid-cols-2 gap-3", children: [_jsx(Input, { label: "Start Date", type: "date", value: draft.startDate, onChange: (e) => set("startDate", e.target.value), required: true }), _jsx(Input, { label: "End Date", type: "date", value: draft.endDate, onChange: (e) => set("endDate", e.target.value), required: true })] })] }), _jsxs(Div, { children: [_jsx(Text, { size: "sm", className: CLS_SECTION_LABEL, children: "Applicability (optional)" }), _jsxs(Stack, { gap: "sm", children: [_jsxs(Div, { children: [_jsx(Text, { size: "xs", className: "mb-1 text-[var(--appkit-color-text-secondary)]", children: "Applicable products" }), _jsx(ProductInlineSelect, { scope: "store", multiple: true, value: draft.applicableProducts, onChange: (v) => set("applicableProducts", v), placeholder: "Restrict to specific products\u2026" })] }), _jsxs(Div, { children: [_jsx(Text, { size: "xs", className: "mb-1 text-[var(--appkit-color-text-secondary)]", children: "Applicable categories" }), _jsx(CategoryInlineSelect, { value: "", onChange: (id) => {
|
|
75
77
|
if (!id || draft.applicableCategories.includes(id))
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, 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, { useState, useCallback } from "react";
|
|
4
6
|
import { useEntityDelete } from "../../../react/hooks/useEntityDelete";
|
|
5
7
|
import { Div, ListingLayout, Text, useToast } from "../../../ui";
|
|
@@ -48,12 +50,12 @@ export function SellerCouponsView({ onCreateClick, onEditClick, onToggle, onDele
|
|
|
48
50
|
searchPlaceholder: "Search by coupon code",
|
|
49
51
|
emptyLabel: "No coupons found — create your first coupon",
|
|
50
52
|
filterKeys: ["isActive"],
|
|
51
|
-
defaultSort: "
|
|
53
|
+
defaultSort: sortBy("createdAt", "DESC"),
|
|
52
54
|
queryKey: ["seller", "coupons", "listing"],
|
|
53
55
|
endpoint: SELLER_ENDPOINTS.COUPONS,
|
|
54
56
|
sortOptions: [
|
|
55
|
-
{ value: "
|
|
56
|
-
{ value: "createdAt", label: "Oldest" },
|
|
57
|
+
{ value: sortBy("createdAt", "DESC"), label: "Newest" },
|
|
58
|
+
{ value: sortBy("createdAt", "ASC"), label: "Oldest" },
|
|
57
59
|
{ value: "code", label: "Code A–Z" },
|
|
58
60
|
],
|
|
59
61
|
hideTableView: true,
|
|
@@ -63,7 +65,7 @@ export function SellerCouponsView({ onCreateClick, onEditClick, onToggle, onDele
|
|
|
63
65
|
isActive: getIsActive(item),
|
|
64
66
|
})),
|
|
65
67
|
getTotal: (response, mappedRows) => typeof response.total === "number" ? response.total : mappedRows.length,
|
|
66
|
-
buildFilters: (state) => state.isActive ?
|
|
68
|
+
buildFilters: (state) => state.isActive ? sieveFilter("isActive", SIEVE_OP.EQ, state.isActive) : undefined,
|
|
67
69
|
primaryAction: onCreateClick
|
|
68
70
|
? { label: "Add Coupon", onClick: () => onCreateClick() }
|
|
69
71
|
: undefined,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { sortBy } from "@mohasinac/appkit";
|
|
3
4
|
import { useState, useCallback } from "react";
|
|
4
5
|
import { useEntityDelete } from "../../../react/hooks/useEntityDelete";
|
|
5
6
|
import { ConfirmDeleteModal, RowActionMenu, Span, Text } from "../../../ui";
|
|
@@ -69,14 +70,14 @@ export function SellerDigitalCodesView({ onCreateClick, onEditClick, onDelete, o
|
|
|
69
70
|
searchPlaceholder: "Search digital code listings...",
|
|
70
71
|
emptyLabel: "No digital code listings yet",
|
|
71
72
|
filterKeys: [],
|
|
72
|
-
defaultSort: "
|
|
73
|
+
defaultSort: sortBy("createdAt", "DESC"),
|
|
73
74
|
queryKey: ["seller", "digital-codes"],
|
|
74
75
|
endpoint: SELLER_ENDPOINTS.PRODUCTS,
|
|
75
76
|
sortOptions: [
|
|
76
|
-
{ value: "
|
|
77
|
-
{ value: "createdAt", label: "Oldest" },
|
|
77
|
+
{ value: sortBy("createdAt", "DESC"), label: "Newest" },
|
|
78
|
+
{ value: sortBy("createdAt", "ASC"), label: "Oldest" },
|
|
78
79
|
{ value: "productTitle", label: "Name A–Z" },
|
|
79
|
-
{ value: "price", label: "Price: Low–High" },
|
|
80
|
+
{ value: sortBy("price", "ASC"), label: "Price: Low–High" },
|
|
80
81
|
],
|
|
81
82
|
columns: COLUMNS,
|
|
82
83
|
mapRows: (response) => toRecordArray(response.products).map((item, index) => {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { sortBy } from "@mohasinac/appkit";
|
|
3
4
|
import { Badge, Button, Div, Span } from "../../../ui";
|
|
4
5
|
import { SELLER_ENDPOINTS } from "../../../constants/api-endpoints";
|
|
5
6
|
import { ACTIONS } from "../../../_internal/shared/actions/action-registry";
|
|
@@ -56,14 +57,14 @@ export function SellerGroupedListingsView({ onCreateClick, onEditClick, onDelete
|
|
|
56
57
|
searchPlaceholder: "Search grouped listings",
|
|
57
58
|
emptyLabel: "No grouped listings yet",
|
|
58
59
|
filterKeys: [],
|
|
59
|
-
defaultSort: "
|
|
60
|
+
defaultSort: sortBy("createdAt", "DESC"),
|
|
60
61
|
queryKey: ["seller", "grouped-listings"],
|
|
61
62
|
endpoint: SELLER_ENDPOINTS.GROUPED_LISTINGS,
|
|
62
63
|
sortOptions: [
|
|
63
|
-
{ value: "
|
|
64
|
-
{ value: "createdAt", label: "Oldest" },
|
|
64
|
+
{ value: sortBy("createdAt", "DESC"), label: "Newest" },
|
|
65
|
+
{ value: sortBy("createdAt", "ASC"), label: "Oldest" },
|
|
65
66
|
{ value: "title", label: "Title A–Z" },
|
|
66
|
-
{ value: "
|
|
67
|
+
{ value: sortBy("title", "DESC"), label: "Title Z–A" },
|
|
67
68
|
],
|
|
68
69
|
columns: COLUMNS,
|
|
69
70
|
mapRows: (response) => toRecordArray(response.items).map((item, index) => ({
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { sortBy } from "@mohasinac/appkit";
|
|
3
4
|
import { useState, useCallback } from "react";
|
|
4
5
|
import { useEntityDelete } from "../../../react/hooks/useEntityDelete";
|
|
5
6
|
import { ConfirmDeleteModal, Div, RowActionMenu, Text } from "../../../ui";
|
|
@@ -70,15 +71,15 @@ export function SellerLiveView({ onCreateClick, onEditClick, onDelete, onBulkDel
|
|
|
70
71
|
searchPlaceholder: "Search live item listings...",
|
|
71
72
|
emptyLabel: "No live item listings yet",
|
|
72
73
|
filterKeys: [],
|
|
73
|
-
defaultSort: "
|
|
74
|
+
defaultSort: sortBy("createdAt", "DESC"),
|
|
74
75
|
queryKey: ["seller", "live-items"],
|
|
75
76
|
endpoint: SELLER_ENDPOINTS.PRODUCTS,
|
|
76
77
|
sortOptions: [
|
|
77
|
-
{ value: "
|
|
78
|
-
{ value: "createdAt", label: "Oldest" },
|
|
78
|
+
{ value: sortBy("createdAt", "DESC"), label: "Newest" },
|
|
79
|
+
{ value: sortBy("createdAt", "ASC"), label: "Oldest" },
|
|
79
80
|
{ value: "productTitle", label: "Name A–Z" },
|
|
80
|
-
{ value: "price", label: "Price: Low–High" },
|
|
81
|
-
{ value: "
|
|
81
|
+
{ value: sortBy("price", "ASC"), label: "Price: Low–High" },
|
|
82
|
+
{ value: sortBy("price", "DESC"), label: "Price: High–Low" },
|
|
82
83
|
],
|
|
83
84
|
columns: COLUMNS,
|
|
84
85
|
mapRows: (response) => toRecordArray(response.products).map((item, index) => {
|
|
@@ -115,6 +115,7 @@ export function SellerOffersPanel({ fetchEndpoint = "/api/store/offers", onRespo
|
|
|
115
115
|
const [showLoginModal, setShowLoginModal] = useState(false);
|
|
116
116
|
const [statusFilter, setStatusFilter] = useState("all");
|
|
117
117
|
const loadOffers = useCallback(async () => {
|
|
118
|
+
// toast-intentionally-silent — error rendered inline via setFetchError()
|
|
118
119
|
setLoading(true);
|
|
119
120
|
setFetchError("");
|
|
120
121
|
try {
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx } 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, RowActionMenu } from "../../../ui";
|
|
5
7
|
import { SELLER_ENDPOINTS } from "../../../constants/api-endpoints";
|
|
@@ -17,12 +19,12 @@ export function SellerOffersView({ children, onAcceptOffer, onRejectOffer, onCou
|
|
|
17
19
|
searchPlaceholder: "Search offers by product or buyer name",
|
|
18
20
|
emptyLabel: "No offers received",
|
|
19
21
|
filterKeys: ["status"],
|
|
20
|
-
defaultSort: "
|
|
22
|
+
defaultSort: sortBy("createdAt", "DESC"),
|
|
21
23
|
queryKey: ["seller", "offers", "listing"],
|
|
22
24
|
endpoint: SELLER_ENDPOINTS.OFFERS,
|
|
23
25
|
sortOptions: [
|
|
24
|
-
{ value: "
|
|
25
|
-
{ value: "createdAt", label: "Oldest" },
|
|
26
|
+
{ value: sortBy("createdAt", "DESC"), label: "Newest" },
|
|
27
|
+
{ value: sortBy("createdAt", "ASC"), label: "Oldest" },
|
|
26
28
|
],
|
|
27
29
|
mapRows: (response) => toRecordArray(response.offers).map((item, index) => ({
|
|
28
30
|
id: toStringValue(item.id, `offer-${index}`),
|
|
@@ -37,7 +39,7 @@ export function SellerOffersView({ children, onAcceptOffer, onRejectOffer, onCou
|
|
|
37
39
|
getTotal: (response, mappedRows) => typeof response.meta?.total === "number"
|
|
38
40
|
? response.meta.total
|
|
39
41
|
: mappedRows.length,
|
|
40
|
-
buildFilters: (state) => state.status && state.status !== "All" ?
|
|
42
|
+
buildFilters: (state) => state.status && state.status !== "All" ? sieveFilter("status", SIEVE_OP.EQ, state.status) : undefined,
|
|
41
43
|
renderRowActions: (row) => (_jsx(RowActionMenu, { actions: [
|
|
42
44
|
...(onAcceptOffer
|
|
43
45
|
? [{ label: ACTIONS.STORE["accept-offer"].label, onClick: () => void onAcceptOffer(row.id) }]
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, 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, { useState, useCallback } from "react";
|
|
4
6
|
import { Eye, Printer, MapPin, Truck } from "lucide-react";
|
|
5
7
|
import { useUrlTable } from "../../../react/hooks/useUrlTable";
|
|
@@ -25,8 +27,8 @@ const PAGE_SIZE = 25;
|
|
|
25
27
|
const FILTER_KEYS = ["status"];
|
|
26
28
|
const DEFAULT_SORT = "-createdAt";
|
|
27
29
|
const SORT_OPTIONS = [
|
|
28
|
-
{ value: "
|
|
29
|
-
{ value: "createdAt", label: "Oldest" },
|
|
30
|
+
{ value: sortBy("createdAt", "DESC"), label: "Newest" },
|
|
31
|
+
{ value: sortBy("createdAt", "ASC"), label: "Oldest" },
|
|
30
32
|
];
|
|
31
33
|
const STATUS_OPTIONS = SELLER_ORDER_STATUS_TABS;
|
|
32
34
|
const STATUS_BADGE_VARIANT = {
|
|
@@ -155,7 +157,7 @@ export function SellerOrdersView({ orderDetailApiBase = SELLER_ENDPOINTS.ORDERS,
|
|
|
155
157
|
const activeFilterCount = FILTER_KEYS.filter((k) => !!table.get(k)).length;
|
|
156
158
|
const hasActiveState = !!table.get("q") || table.get("sort") !== DEFAULT_SORT || activeFilterCount > 0;
|
|
157
159
|
const statusRaw = table.get("status");
|
|
158
|
-
const filters = statusRaw && statusRaw !== "All" ?
|
|
160
|
+
const filters = statusRaw && statusRaw !== "All" ? sieveFilter("status", SIEVE_OP.EQ, statusRaw) : undefined;
|
|
159
161
|
const { rows, total, isLoading, errorMessage } = useSellerListingData({
|
|
160
162
|
queryKey: ["seller", "orders", "listing"],
|
|
161
163
|
endpoint: SELLER_ENDPOINTS.ORDERS,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { sortBy } from "@mohasinac/appkit";
|
|
3
4
|
import { useState, useCallback } from "react";
|
|
4
5
|
import { useEntityDelete } from "../../../react/hooks/useEntityDelete";
|
|
5
6
|
import { Plus } from "lucide-react";
|
|
@@ -13,8 +14,8 @@ import { TABLE_KEYS } from "../../../constants/table-keys";
|
|
|
13
14
|
const PAGE_SIZE = 50;
|
|
14
15
|
const DEFAULT_SORT = "-createdAt";
|
|
15
16
|
const SORT_OPTIONS = [
|
|
16
|
-
{ value: "
|
|
17
|
-
{ value: "createdAt", label: "Oldest" },
|
|
17
|
+
{ value: sortBy("createdAt", "DESC"), label: "Newest" },
|
|
18
|
+
{ value: sortBy("createdAt", "ASC"), label: "Oldest" },
|
|
18
19
|
{ value: "label", label: "Label A–Z" },
|
|
19
20
|
];
|
|
20
21
|
function getMaskedIdentifier(item) {
|
|
@@ -69,6 +70,7 @@ export function SellerPayoutMethodsView({ onCreateClick, onEditClick, onDelete,
|
|
|
69
70
|
})),
|
|
70
71
|
});
|
|
71
72
|
const handleDelete = useCallback(async (id) => {
|
|
73
|
+
// toast-handled-by-hook (useEntityDelete)
|
|
72
74
|
await performDelete(id);
|
|
73
75
|
setDeleteTargetId(null);
|
|
74
76
|
}, [performDelete]);
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx } 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, RowActionMenu } from "../../../ui";
|
|
5
7
|
import { SELLER_ENDPOINTS } from "../../../constants/api-endpoints";
|
|
@@ -17,12 +19,12 @@ export function SellerPayoutsView({ children, onViewClick, onExportClick, ...pro
|
|
|
17
19
|
searchPlaceholder: "Search payouts by payout # or amount",
|
|
18
20
|
emptyLabel: "No payouts found",
|
|
19
21
|
filterKeys: ["status"],
|
|
20
|
-
defaultSort: "
|
|
22
|
+
defaultSort: sortBy("createdAt", "DESC"),
|
|
21
23
|
queryKey: ["seller", "payouts", "listing"],
|
|
22
24
|
endpoint: SELLER_ENDPOINTS.PAYOUTS,
|
|
23
25
|
sortOptions: [
|
|
24
|
-
{ value: "
|
|
25
|
-
{ value: "createdAt", label: "Oldest" },
|
|
26
|
+
{ value: sortBy("createdAt", "DESC"), label: "Newest" },
|
|
27
|
+
{ value: sortBy("createdAt", "ASC"), label: "Oldest" },
|
|
26
28
|
],
|
|
27
29
|
mapRows: (response) => toRecordArray(response.payouts).map((item, index) => ({
|
|
28
30
|
id: toStringValue(item.id, `payout-${index}`),
|
|
@@ -37,7 +39,7 @@ export function SellerPayoutsView({ children, onViewClick, onExportClick, ...pro
|
|
|
37
39
|
getTotal: (response, mappedRows) => typeof response.meta?.total === "number"
|
|
38
40
|
? response.meta.total
|
|
39
41
|
: mappedRows.length,
|
|
40
|
-
buildFilters: (state) => state.status && state.status !== "All" ?
|
|
42
|
+
buildFilters: (state) => state.status && state.status !== "All" ? sieveFilter("status", SIEVE_OP.EQ, state.status) : undefined,
|
|
41
43
|
renderRowActions: (row) => (_jsx(RowActionMenu, { actions: [
|
|
42
44
|
...(onViewClick
|
|
43
45
|
? [{ label: ACTIONS.STORE["view-payout"].label, onClick: () => onViewClick(row.id) }]
|