@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
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } 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 { Badge, ConfirmDeleteModal, Div, FilterChipGroup, ListingLayout, RowActionMenu, Span, Text } from "../../../ui";
|
|
@@ -78,12 +80,12 @@ export function SellerPreOrdersView({ children, onDelete, ...props }) {
|
|
|
78
80
|
searchPlaceholder: "Search pre-orders by name…",
|
|
79
81
|
emptyLabel: "No pre-orders listed yet",
|
|
80
82
|
filterKeys: ["status"],
|
|
81
|
-
defaultSort: "
|
|
83
|
+
defaultSort: sortBy("createdAt", "DESC"),
|
|
82
84
|
queryKey: ["seller", "pre-orders", "listing"],
|
|
83
85
|
endpoint: SELLER_ENDPOINTS.PRODUCTS,
|
|
84
86
|
sortOptions: [
|
|
85
|
-
{ value: "
|
|
86
|
-
{ value: "createdAt", label: "Oldest" },
|
|
87
|
+
{ value: sortBy("createdAt", "DESC"), label: "Newest" },
|
|
88
|
+
{ value: sortBy("createdAt", "ASC"), label: "Oldest" },
|
|
87
89
|
{ value: "title", label: "Title A–Z" },
|
|
88
90
|
{ value: "preorderAvailableDate", label: "Delivery Soon" },
|
|
89
91
|
],
|
|
@@ -105,7 +107,7 @@ export function SellerPreOrdersView({ children, onDelete, ...props }) {
|
|
|
105
107
|
}),
|
|
106
108
|
getTotal: (response, mappedRows) => typeof response.meta?.total === "number" ? response.meta.total : mappedRows.length,
|
|
107
109
|
buildFilters: (state) => {
|
|
108
|
-
const status = state.status && state.status !== "All" ?
|
|
110
|
+
const status = state.status && state.status !== "All" ? sieveFilter("status", SIEVE_OP.EQ, state.status) : null;
|
|
109
111
|
return ["listingType==pre-order", status].filter(Boolean).join(",");
|
|
110
112
|
},
|
|
111
113
|
getRowHref: (row) => String(ROUTES.STORE.PRE_ORDERS_EDIT(row.id)),
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } 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 { Badge, ConfirmDeleteModal, Div, FilterChipGroup, ListingLayout, RowActionMenu, Span, Text } from "../../../ui";
|
|
@@ -75,12 +77,12 @@ export function SellerPrizeDrawsView({ children, onDelete, ...props }) {
|
|
|
75
77
|
searchPlaceholder: "Search prize draws by name…",
|
|
76
78
|
emptyLabel: "No prize draws listed yet",
|
|
77
79
|
filterKeys: ["status"],
|
|
78
|
-
defaultSort: "
|
|
80
|
+
defaultSort: sortBy("createdAt", "DESC"),
|
|
79
81
|
queryKey: ["seller", "prize-draws", "listing"],
|
|
80
82
|
endpoint: SELLER_ENDPOINTS.PRODUCTS,
|
|
81
83
|
sortOptions: [
|
|
82
|
-
{ value: "
|
|
83
|
-
{ value: "createdAt", label: "Oldest" },
|
|
84
|
+
{ value: sortBy("createdAt", "DESC"), label: "Newest" },
|
|
85
|
+
{ value: sortBy("createdAt", "ASC"), label: "Oldest" },
|
|
84
86
|
{ value: "title", label: "Title A–Z" },
|
|
85
87
|
{ value: "prizeDrawEndDate", label: "Draw Date Soon" },
|
|
86
88
|
],
|
|
@@ -102,7 +104,7 @@ export function SellerPrizeDrawsView({ children, onDelete, ...props }) {
|
|
|
102
104
|
}),
|
|
103
105
|
getTotal: (response, mappedRows) => typeof response.meta?.total === "number" ? response.meta.total : mappedRows.length,
|
|
104
106
|
buildFilters: (state) => {
|
|
105
|
-
const status = state.status && state.status !== "All" ?
|
|
107
|
+
const status = state.status && state.status !== "All" ? sieveFilter("status", SIEVE_OP.EQ, state.status) : null;
|
|
106
108
|
return ["listingType==prize-draw", status].filter(Boolean).join(",");
|
|
107
109
|
},
|
|
108
110
|
getRowHref: (row) => String(ROUTES.STORE.PRIZE_DRAWS_EDIT(row.id)),
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } 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 { useActionDispatch } from "../../../react/hooks/use-action-dispatch";
|
|
@@ -34,12 +36,12 @@ const FILTER_KEYS = [
|
|
|
34
36
|
];
|
|
35
37
|
const DEFAULT_SORT = "-createdAt";
|
|
36
38
|
const SORT_OPTIONS = [
|
|
37
|
-
{ value: "
|
|
38
|
-
{ value: "createdAt", label: "Oldest" },
|
|
39
|
+
{ value: sortBy("createdAt", "DESC"), label: "Newest" },
|
|
40
|
+
{ value: sortBy("createdAt", "ASC"), label: "Oldest" },
|
|
39
41
|
{ value: "title", label: "Title A–Z" },
|
|
40
|
-
{ value: "
|
|
41
|
-
{ value: "
|
|
42
|
-
{ value: "price", label: "Price Low" },
|
|
42
|
+
{ value: sortBy("title", "DESC"), label: "Title Z–A" },
|
|
43
|
+
{ value: sortBy("price", "DESC"), label: "Price High" },
|
|
44
|
+
{ value: sortBy("price", "ASC"), label: "Price Low" },
|
|
43
45
|
];
|
|
44
46
|
const STATUS_OPTIONS = SELLER_PRODUCT_STATUS_TABS;
|
|
45
47
|
// S-STORE-2-A — `<TypeDropdown>` replaces the legacy chip strip. Same width on
|
|
@@ -163,10 +165,10 @@ export function SellerProductsView({ onDeleteProduct, onCreateClick, children, .
|
|
|
163
165
|
listingKind !== "all" ||
|
|
164
166
|
showSold;
|
|
165
167
|
const statusRaw = table.get("status");
|
|
166
|
-
const statusFilter = statusRaw && statusRaw !== "All" ?
|
|
168
|
+
const statusFilter = statusRaw && statusRaw !== "All" ? sieveFilter("status", SIEVE_OP.EQ, statusRaw) : undefined;
|
|
167
169
|
// SB1-G — single-field listingType clause. The repository's Sieve aliases
|
|
168
170
|
// accept both `==auction|preorder|standard` and `==pre-order` directly.
|
|
169
|
-
const kindFilter = listingKind === "all" ? undefined :
|
|
171
|
+
const kindFilter = listingKind === "all" ? undefined : sieveFilter("listingType", SIEVE_OP.EQ, listingKind);
|
|
170
172
|
const soldFilter = showSold ? undefined : "isSold==false";
|
|
171
173
|
const filters = [statusFilter, kindFilter, soldFilter].filter(Boolean).join(",") || undefined;
|
|
172
174
|
const { rows, total, isLoading, errorMessage } = useSellerListingData({
|
|
@@ -291,7 +293,11 @@ export function SellerProductsView({ onDeleteProduct, onCreateClick, children, .
|
|
|
291
293
|
useBottomActions(selection.selectedCount > 0 ? { bulk: { selectedCount: selection.selectedCount, onClearSelection: selection.clearSelection, actions: bulkActions } } : {});
|
|
292
294
|
return (_jsxs(_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, toggles: [
|
|
293
295
|
{ label: "Show sold", active: showSold, onChange: (next) => table.set("showSold", next ? "true" : "") },
|
|
294
|
-
], extra: onCreateClick ? (_jsx(Button, { variant: "primary", size: "sm", onClick: onCreateClick, children: "+ New Listing" })) : null }), _jsx(TypeDropdown, { 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",
|
|
296
|
+
], extra: onCreateClick ? (_jsx(Button, { variant: "primary", size: "sm", onClick: onCreateClick, children: "+ New Listing" })) : null }), _jsx(TypeDropdown, { 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",
|
|
297
|
+
// audit-inline-style-ok: sticky header offset
|
|
298
|
+
style: { top: "calc(var(--header-height, 0px) + 44px)" }, children: _jsx(Pagination, { currentPage: currentPage, totalPages: totalPages, onPageChange: (p) => table.setPage(p) }) })), selection.selectedIds.length > 0 && (_jsx(Div, { className: "sticky z-20 px-3 lg:px-4 py-2 bg-[var(--appkit-color-surface)]/95 backdrop-blur-sm border-b border-[var(--appkit-color-border)]",
|
|
299
|
+
// audit-inline-style-ok: sticky header offset
|
|
300
|
+
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 lg:px-4", children: [errorMessage && (_jsx(Alert, { variant: "error", className: "mb-4", children: errorMessage })), view !== "table" && (_jsx(SellerProductsCards, { view: view, rows: visibleRows, isLoading: isLoading, listingKind: listingKind, selectedIds: selection.selectedIdSet, toggle: selection.toggle, onEdit: handleEdit, onDuplicate: (row) => void handleDuplicate(row), onDelete: onDeleteProduct ? (row) => void handleDelete(row) : undefined })), view === "table" && (_jsx(DataTable, { columns: PRODUCT_COLUMNS, rows: visibleRows, isLoading: isLoading, emptyLabel: listingKind !== "all"
|
|
295
301
|
? `No ${listingKind} listings found`
|
|
296
302
|
: "No products listed yet", selectedIds: selection.selectedIdSet, onToggleSelect: selection.toggle, onToggleSelectAll: () => selection.toggleAll(), getRowHref: (row) =>
|
|
297
303
|
// S-STORE-2-D — row click → public detail/preview, not edit.
|
|
@@ -93,6 +93,7 @@ export function SellerReviewsView({ reviewsApiBase = "/api/store/reviews", reply
|
|
|
93
93
|
}, [feedbackTarget, feedbackText]);
|
|
94
94
|
const fetchReviewsRef = useMemo(() => ({ current: null }), []);
|
|
95
95
|
const fetchReviews = useCallback(async () => {
|
|
96
|
+
// toast-intentionally-silent — error stored in setError() for UI inline render
|
|
96
97
|
setLoading(true);
|
|
97
98
|
setError(null);
|
|
98
99
|
try {
|
|
@@ -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
|
const COLUMNS = [
|
|
@@ -80,6 +81,7 @@ export function SellerShippingConfigsView({ onCreateClick, onEditClick, onDelete
|
|
|
80
81
|
})),
|
|
81
82
|
});
|
|
82
83
|
const handleDelete = useCallback(async (id) => {
|
|
84
|
+
// toast-handled-by-hook (useEntityDelete)
|
|
83
85
|
await performDelete(id);
|
|
84
86
|
setDeleteTargetId(null);
|
|
85
87
|
}, [performDelete]);
|
|
@@ -25,7 +25,9 @@ function NavLink({ item, isActive, onClick }) {
|
|
|
25
25
|
: "text-zinc-500 dark:text-zinc-400 hover:bg-zinc-50 dark:hover:bg-slate-800/60 hover:text-zinc-800 dark:hover:text-zinc-200"}`, children: [item.icon && _jsx(Span, { size: "base", className: "shrink-0 opacity-60", children: item.icon }), _jsx(Span, { className: "flex-1 truncate", children: item.label }), item.badge != null && item.badge > 0 && (_jsx(Span, { weight: "bold", className: CLS_NAV_BADGE, children: item.badge }))] }));
|
|
26
26
|
}
|
|
27
27
|
function FlatContent({ items, activeHref, storeName, storeLogoURL, onItemClick, }) {
|
|
28
|
-
return (_jsxs(_Fragment, { children: [storeName && (_jsxs(Row, { gap: "3", className: "px-4 py-3 border-b border-zinc-100 dark:border-slate-700", children: [storeLogoURL ? (
|
|
28
|
+
return (_jsxs(_Fragment, { children: [storeName && (_jsxs(Row, { gap: "3", className: "px-4 py-3 border-b border-zinc-100 dark:border-slate-700", children: [storeLogoURL ? (
|
|
29
|
+
// audit-inline-style-ok: dynamic image URL
|
|
30
|
+
_jsx(Div, { role: "img", "aria-label": storeName, className: CLS_STORE_AVATAR, style: { backgroundImage: `url(${storeLogoURL})` } })) : (_jsx(Div, { className: CLS_STORE_FALLBACK, children: storeName[0]?.toUpperCase() })), _jsx(Text, { className: CLS_STORE_NAME, children: storeName })] })), _jsx(Nav, { "aria-label": "Store navigation", className: "py-3", children: _jsx(Ul, { className: "space-y-0.5 px-3", children: items.map((item) => {
|
|
29
31
|
const isActive = activeHref === item.href;
|
|
30
32
|
return (_jsx(Li, { children: _jsx(NavLink, { item: item, isActive: isActive, onClick: onItemClick }) }, item.href));
|
|
31
33
|
}) }) })] }));
|
|
@@ -36,7 +38,9 @@ function GroupsContent({ groups, activeHref, storeName, storeLogoURL, onItemClic
|
|
|
36
38
|
g.defaultOpen ?? g.items.some((i) => activeHref === i.href),
|
|
37
39
|
])));
|
|
38
40
|
const toggle = useCallback((title) => setOpenGroups((p) => ({ ...p, [title]: !p[title] })), []);
|
|
39
|
-
return (_jsxs(_Fragment, { children: [storeName && (_jsxs(Row, { gap: "3", className: "px-4 py-3 border-b border-zinc-100 dark:border-slate-700", children: [storeLogoURL ? (
|
|
41
|
+
return (_jsxs(_Fragment, { children: [storeName && (_jsxs(Row, { gap: "3", className: "px-4 py-3 border-b border-zinc-100 dark:border-slate-700", children: [storeLogoURL ? (
|
|
42
|
+
// audit-inline-style-ok: dynamic image URL
|
|
43
|
+
_jsx(Div, { role: "img", "aria-label": storeName, className: CLS_STORE_AVATAR, style: { backgroundImage: `url(${storeLogoURL})` } })) : (_jsx(Div, { className: CLS_STORE_FALLBACK, children: storeName[0]?.toUpperCase() })), _jsx(Text, { className: CLS_STORE_NAME, children: storeName })] })), _jsx(Nav, { "aria-label": "Store navigation", className: "py-2", children: groups.map((group) => {
|
|
40
44
|
const isOpen = openGroups[group.title] ?? false;
|
|
41
45
|
const hasActive = group.items.some((i) => activeHref === i.href);
|
|
42
46
|
return (_jsxs(Div, { className: "mb-0.5", children: [_jsxs("button", { type: "button", onClick: () => toggle(group.title), className: `flex w-full items-center justify-between px-4 py-2 text-[0.6875rem] font-semibold uppercase tracking-widest transition-colors ${hasActive && !isOpen
|
|
@@ -59,12 +63,16 @@ export function StoreSidebar({ items, groups, activeHref, storeName, storeLogoUR
|
|
|
59
63
|
const navContent = groups ? (_jsx(GroupsContent, { groups: groups, activeHref: activeHref, storeName: storeName, storeLogoURL: storeLogoURL, onItemClick: close })) : (_jsx(FlatContent, { items: items, activeHref: activeHref, storeName: storeName, storeLogoURL: storeLogoURL, onItemClick: close }));
|
|
60
64
|
if (variant === "sidebar") {
|
|
61
65
|
const handleToggle = onToggle ?? close;
|
|
62
|
-
return (_jsxs(_Fragment, { children: [desktopOpen && (_jsx(Div, { className: "hidden md:block fixed inset-0 bg-black/40 backdrop-blur-[2px] z-30", onClick: handleToggle, "aria-hidden": "true" })), _jsxs(Div, { className: "hidden md:flex fixed left-0 z-40 transition-transform duration-300",
|
|
66
|
+
return (_jsxs(_Fragment, { children: [desktopOpen && (_jsx(Div, { className: "hidden md:block fixed inset-0 bg-black/40 backdrop-blur-[2px] z-30", onClick: handleToggle, "aria-hidden": "true" })), _jsxs(Div, { className: "hidden md:flex fixed left-0 z-40 transition-transform duration-300",
|
|
67
|
+
// audit-inline-style-ok: dynamic CSS
|
|
68
|
+
style: {
|
|
63
69
|
top: "var(--header-height, 3.5rem)",
|
|
64
70
|
height: "calc(100vh - var(--header-height, 3.5rem))",
|
|
65
71
|
width: "18rem",
|
|
66
72
|
transform: desktopOpen ? "translateX(0)" : "translateX(calc(-100% + 1.25rem))",
|
|
67
|
-
}, children: [_jsxs(Div, { surface: "sidePanel", className: `flex-1 border-r border-zinc-200 dark:border-slate-700 flex flex-col ${__O.hidden} shadow-xl`, children: [_jsx(Div, { className: "px-4 py-3.5 border-b border-zinc-100 dark:border-slate-800 shrink-0", children: _jsxs(Div, { className: "flex items-center gap-3 min-w-0", children: [storeLogoURL ? (
|
|
73
|
+
}, children: [_jsxs(Div, { surface: "sidePanel", className: `flex-1 border-r border-zinc-200 dark:border-slate-700 flex flex-col ${__O.hidden} shadow-xl`, children: [_jsx(Div, { className: "px-4 py-3.5 border-b border-zinc-100 dark:border-slate-800 shrink-0", children: _jsxs(Div, { className: "flex items-center gap-3 min-w-0", children: [storeLogoURL ? (
|
|
74
|
+
// audit-inline-style-ok: dynamic image URL
|
|
75
|
+
_jsx(Div, { role: "img", "aria-label": storeName, className: CLS_STORE_AVATAR, style: { backgroundImage: `url(${storeLogoURL})` } })) : (_jsx(Div, { className: CLS_STORE_FALLBACK, children: storeName?.[0]?.toUpperCase() })), _jsx(Text, { className: CLS_STORE_NAME, children: storeName || panelTitle })] }) }), _jsx(Div, { className: `flex-1 ${__O.yAuto}`, children: navContent })] }), _jsx(SidebarCollapseToggle, { expanded: desktopOpen, onToggle: handleToggle })] }), _jsx(Div, { className: "md:hidden", children: _jsx(BottomSheet, { open: mobileOpen, onClose: close, title: panelTitle, children: groups ? (_jsx(GroupsContent, { groups: groups, activeHref: activeHref, storeName: storeName, storeLogoURL: storeLogoURL, onItemClick: close })) : (_jsx(FlatContent, { items: items, activeHref: activeHref, storeName: storeName, storeLogoURL: storeLogoURL, onItemClick: close })) }) })] }));
|
|
68
76
|
}
|
|
69
77
|
return (_jsxs(_Fragment, { children: [mounted && mobileOpen &&
|
|
70
78
|
createPortal(_jsx(DrawerPanel, { title: panelTitle, onClose: close, children: navContent }), document.body), _jsx(Div, { className: "md:hidden", children: _jsx(BottomSheet, { open: mobileOpen, onClose: close, title: panelTitle, children: groups ? (_jsx(GroupsContent, { groups: groups, activeHref: activeHref, storeName: storeName, storeLogoURL: storeLogoURL, onItemClick: close })) : (_jsx(FlatContent, { items: items, activeHref: activeHref, storeName: storeName, storeLogoURL: storeLogoURL, onItemClick: close })) }) })] }));
|
|
@@ -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";
|
|
@@ -16,10 +17,10 @@ import { TABLE_KEYS } from "../../../constants/table-keys";
|
|
|
16
17
|
const PAGE_SIZE = 25;
|
|
17
18
|
const DEFAULT_SORT = "displayOrder";
|
|
18
19
|
const SORT_OPTIONS = [
|
|
19
|
-
{ value: "displayOrder", label: "Display Order" },
|
|
20
|
+
{ value: sortBy("displayOrder", "ASC"), label: "Display Order" },
|
|
20
21
|
{ value: "label", label: "Label A–Z" },
|
|
21
|
-
{ value: "
|
|
22
|
-
{ value: "
|
|
22
|
+
{ value: sortBy("label", "DESC"), label: "Label Z–A" },
|
|
23
|
+
{ value: sortBy("createdAt", "DESC"), label: "Newest" },
|
|
23
24
|
];
|
|
24
25
|
const COLUMNS = [
|
|
25
26
|
{
|
|
@@ -76,6 +77,7 @@ export function SellerStoreCategoriesView({ onCreateClick, onEditClick, onDelete
|
|
|
76
77
|
const totalPages = Math.ceil(total / PAGE_SIZE);
|
|
77
78
|
const selection = useBulkSelection({ items: rows, keyExtractor: (r) => r.id });
|
|
78
79
|
const handleDelete = useCallback(async (id) => {
|
|
80
|
+
// toast-handled-by-hook (useEntityDelete)
|
|
79
81
|
if (!onDelete)
|
|
80
82
|
return;
|
|
81
83
|
await performDelete(id);
|
|
@@ -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, useMemo } from "react";
|
|
4
5
|
import { useEntityDelete } from "../../../react/hooks/useEntityDelete";
|
|
5
6
|
import { Plus } from "lucide-react";
|
|
@@ -18,9 +19,9 @@ const __P = {
|
|
|
18
19
|
const PAGE_SIZE = 25;
|
|
19
20
|
const DEFAULT_SORT = "name";
|
|
20
21
|
const SORT_OPTIONS = [
|
|
21
|
-
{ value: "name", label: "Name A–Z" },
|
|
22
|
-
{ value: "
|
|
23
|
-
{ value: "
|
|
22
|
+
{ value: sortBy("name", "ASC"), label: "Name A–Z" },
|
|
23
|
+
{ value: sortBy("name", "DESC"), label: "Name Z–A" },
|
|
24
|
+
{ value: sortBy("createdAt", "DESC"), label: "Newest" },
|
|
24
25
|
];
|
|
25
26
|
const CONDITION_OPTIONS = [
|
|
26
27
|
{ value: "", label: "Any condition" },
|
|
@@ -195,6 +196,7 @@ export function SellerTemplatesView({ onDelete, onBulkDelete, onDuplicate, }) {
|
|
|
195
196
|
}
|
|
196
197
|
}, [draft, drawerMode, editingId, closeDrawer, refetch, showToast]);
|
|
197
198
|
const handleDelete = useCallback(async (id) => {
|
|
199
|
+
// toast-handled-by-hook (useEntityDelete)
|
|
198
200
|
await performDelete(id);
|
|
199
201
|
setDeleteTargetId(null);
|
|
200
202
|
}, [performDelete]);
|
|
@@ -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 { PaginatedSelect } from "../../../ui/components/PaginatedSelect";
|
|
4
5
|
import { apiClient } from "../../../http";
|
|
5
6
|
import { ADMIN_ENDPOINTS } from "../../../constants/api-endpoints";
|
|
@@ -7,7 +8,7 @@ async function loadSublistingOptions(query, page) {
|
|
|
7
8
|
const params = new URLSearchParams({
|
|
8
9
|
page: String(page),
|
|
9
10
|
pageSize: "25",
|
|
10
|
-
sorts: "name",
|
|
11
|
+
sorts: sortBy("name", "ASC"),
|
|
11
12
|
});
|
|
12
13
|
if (query.trim())
|
|
13
14
|
params.set("q", query.trim());
|
|
@@ -12,14 +12,14 @@ export declare function useSellerPayouts(params?: {
|
|
|
12
12
|
totalPages: number;
|
|
13
13
|
isLoading: boolean;
|
|
14
14
|
error: string | null;
|
|
15
|
-
refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<
|
|
15
|
+
refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<PayoutListResponse, Error>>;
|
|
16
16
|
};
|
|
17
17
|
export declare function useSellerPayoutSettings(opts?: {
|
|
18
18
|
enabled?: boolean;
|
|
19
19
|
endpoint?: string;
|
|
20
20
|
}): {
|
|
21
|
-
settings:
|
|
21
|
+
settings: SellerPayoutSettings | null;
|
|
22
22
|
isLoading: boolean;
|
|
23
23
|
error: string | null;
|
|
24
|
-
refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<
|
|
24
|
+
refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<SellerPayoutSettings | null, Error>>;
|
|
25
25
|
};
|
|
@@ -3,28 +3,28 @@ export declare function useSellerStore(opts?: {
|
|
|
3
3
|
enabled?: boolean;
|
|
4
4
|
endpoint?: string;
|
|
5
5
|
}): {
|
|
6
|
-
store:
|
|
6
|
+
store: SellerStore | null;
|
|
7
7
|
isLoading: boolean;
|
|
8
8
|
error: string | null;
|
|
9
|
-
refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<
|
|
9
|
+
refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<SellerStore | null, Error>>;
|
|
10
10
|
};
|
|
11
11
|
export declare function useSellerDashboard(opts?: {
|
|
12
12
|
enabled?: boolean;
|
|
13
13
|
endpoint?: string;
|
|
14
14
|
}): {
|
|
15
|
-
stats:
|
|
15
|
+
stats: SellerDashboardStats | null;
|
|
16
16
|
isLoading: boolean;
|
|
17
17
|
error: string | null;
|
|
18
|
-
refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<
|
|
18
|
+
refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<SellerDashboardStats, Error>>;
|
|
19
19
|
};
|
|
20
20
|
export declare function useSellerAnalytics(period?: string, opts?: {
|
|
21
21
|
enabled?: boolean;
|
|
22
22
|
endpoint?: string;
|
|
23
23
|
}): {
|
|
24
|
-
analytics:
|
|
24
|
+
analytics: SellerAnalytics | null;
|
|
25
25
|
isLoading: boolean;
|
|
26
26
|
error: string | null;
|
|
27
|
-
refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<
|
|
27
|
+
refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<SellerAnalytics, Error>>;
|
|
28
28
|
};
|
|
29
29
|
/** @deprecated Use useStoreDashboard */
|
|
30
30
|
export { useSellerDashboard as useStoreDashboard };
|
|
@@ -9,8 +9,8 @@ export declare function useSellerStorefront(sellerId: string, options?: {
|
|
|
9
9
|
seller: PublicUserProfile | undefined;
|
|
10
10
|
loading: boolean;
|
|
11
11
|
profileError: string;
|
|
12
|
-
productsData:
|
|
12
|
+
productsData: ProductsApiResponse | undefined;
|
|
13
13
|
productsLoading: boolean;
|
|
14
|
-
reviewsData:
|
|
14
|
+
reviewsData: SellerReviewsData | undefined;
|
|
15
15
|
reviewsLoading: boolean;
|
|
16
16
|
};
|
|
@@ -113,8 +113,16 @@ export function FormShell({ isOpen, onClose, title, breadcrumb, isDirty = false,
|
|
|
113
113
|
};
|
|
114
114
|
if (!isOpen)
|
|
115
115
|
return null;
|
|
116
|
-
return (_jsxs(_Fragment, { children: [_jsx(Div, { className: "fixed inset-0 bg-black/50 backdrop-blur-[2px]",
|
|
116
|
+
return (_jsxs(_Fragment, { children: [_jsx(Div, { className: "fixed inset-0 bg-black/50 backdrop-blur-[2px]",
|
|
117
|
+
// audit-inline-style-ok: z-index token
|
|
118
|
+
style: { zIndex: "calc(var(--appkit-z-modal) - 1)" }, "aria-hidden": "true", onClick: attemptClose }), _jsxs(Div, { ref: panelRef, role: "dialog", "aria-modal": "true", "aria-label": title, className: "fixed top-0 bottom-0 left-0 right-0 lg:left-[10%] lg:right-[10%] flex flex-col bg-[var(--appkit-color-surface)] shadow-2xl",
|
|
119
|
+
// audit-inline-style-ok: z-index token
|
|
120
|
+
style: { zIndex: "var(--appkit-z-modal)" }, children: [_jsxs(Row, { gap: "sm", className: "flex-shrink-0 sticky top-0 z-10 border-b border-[var(--appkit-color-border)] bg-[var(--appkit-color-surface)] px-5 py-3", children: [previewMode ? (_jsxs("button", { type: "button", onClick: () => setPreviewMode(false), "aria-label": "Back to edit", className: "rounded-lg p-1.5 text-[var(--appkit-color-text-muted)] hover:bg-[var(--appkit-color-border-subtle)] transition-colors flex-shrink-0 flex items-center gap-1.5 text-sm", children: [_jsx(ArrowLeft, { className: "w-4 h-4" }), _jsx(Span, { className: "hidden sm:inline", children: "Back to Edit" })] })) : (_jsx("button", { type: "button", onClick: attemptClose, "aria-label": "Close", className: "rounded-lg p-1.5 text-[var(--appkit-color-text-muted)] hover:bg-[var(--appkit-color-border-subtle)] transition-colors flex-shrink-0", children: _jsx(X, { className: "w-5 h-5" }) })), _jsxs(Div, { className: "flex-1 min-w-0", children: [breadcrumb && (_jsx(Text, { className: "text-xs text-[var(--appkit-color-text-muted)] truncate mb-0.5", children: breadcrumb })), _jsx(Text, { className: "text-sm font-semibold text-[var(--appkit-color-text)] truncate", children: previewMode ? `Preview — ${title}` : title })] }), _jsx(Row, { gap: "xs", className: "flex-shrink-0", children: previewMode ? null : (_jsxs(_Fragment, { children: [previewSlot && (_jsxs("button", { type: "button", onClick: () => setPreviewMode(true), className: "flex items-center gap-1.5 rounded-lg px-3 py-1.5 text-sm text-[var(--appkit-color-text-muted)] hover:bg-[var(--appkit-color-border-subtle)] transition-colors border border-[var(--appkit-color-border)]", children: [_jsx(Eye, { className: "w-4 h-4" }), _jsx(Span, { className: "hidden sm:inline", children: "Preview" })] })), onSaveDraft && (_jsx(Button, { variant: "outline", size: "sm", onClick: handleSaveDraft, disabled: isLoading || savingDraft || publishing, isLoading: savingDraft, children: saveLabel })), onPublish && (_jsx(Button, { variant: "primary", size: "sm", onClick: handlePublish, disabled: isLoading || savingDraft || publishing, isLoading: publishing, children: publishLabel }))] })) })] }), _jsxs(Div, { className: `flex flex-1 ${__O.hidden}`, children: [sections && sections.length > 0 && !previewMode && (_jsx("nav", { "aria-label": "Form sections", className: "hidden lg:flex flex-col flex-shrink-0 w-48 border-r border-[var(--appkit-color-border)] py-4 px-3 gap-1 overflow-y-auto", children: sections.map((sec) => (_jsx("button", { type: "button", onClick: () => scrollToSection(sec.id), className: "text-left text-sm px-3 py-2 rounded-lg text-[var(--appkit-color-text-muted)] hover:text-[var(--appkit-color-text)] hover:bg-[var(--appkit-color-border-subtle)] transition-colors", children: sec.label }, sec.id))) })), sections && sections.length > 0 && !previewMode && (_jsx(Row, { gap: "px", className: `lg:hidden fixed top-[var(--form-shell-topbar-h,57px)] left-0 right-0 z-10 ${__O.xAuto} px-5 py-2 bg-[var(--appkit-color-surface)] border-b border-[var(--appkit-color-border)]`, children: sections.map((sec) => (_jsx("button", { type: "button", onClick: () => scrollToSection(sec.id), className: "flex-shrink-0 text-xs px-3 py-1.5 rounded-full border border-[var(--appkit-color-border)] text-[var(--appkit-color-text-muted)] hover:border-[var(--appkit-color-primary)] hover:text-[var(--appkit-color-primary)] transition-colors whitespace-nowrap", children: sec.label }, sec.id))) })), _jsx(Div, { ref: bodyRef, className: classNames("flex-1 overflow-y-auto", sections && sections.length > 0 && !previewMode ? "pt-0 lg:pt-0" : ""), children: previewMode && previewSlot ? (_jsxs(_Fragment, { children: [_jsxs(Row, { gap: "xs", className: "sticky top-0 z-10 bg-[var(--appkit-color-warning-surface)] border-b border-[var(--appkit-color-warning)] px-4 py-2 text-sm text-[var(--appkit-color-warning-text,var(--appkit-color-warning))]", children: [_jsx(Eye, { className: "w-4 h-4 flex-shrink-0" }), _jsx(Span, { children: "Preview \u2014 not visible to buyers until published" })] }), _jsx(Div, { className: "py-4", children: previewSlot() })] })) : splitPreview && previewSlot ? (
|
|
117
121
|
// S-STORE-3-D — desktop 60/40 split: form left, preview right.
|
|
118
122
|
// Below `lg`, falls back to single-column form (preview-as-modal via existing toggle).
|
|
119
|
-
_jsxs(Div, { className: "lg:grid lg:grid-cols-[3fr_2fr] lg:gap-6 lg:px-6 lg:py-6 lg:max-w-[1400px] lg:mx-auto", children: [_jsx(Div, { className: "max-w-3xl mx-auto px-5 py-6 sm:px-6 lg:max-w-none lg:px-0 lg:py-0", children: children }), _jsxs(Div, { className: `hidden lg:block sticky lg:top-4 lg:self-start lg:max-h-[calc(100vh-6rem)] ${__O.yAuto} border border-[var(--appkit-color-border)] rounded-lg bg-[var(--appkit-color-surface-raised)] ${__P.p4}`, children: [_jsxs(Row, { gap: "xs", className: "mb-3 text-xs font-semibold uppercase tracking-wide text-[var(--appkit-color-text-muted)]", children: [_jsx(Eye, { className: "w-3.5 h-3.5" }), _jsx(Span, { children: "Live preview" })] }), previewSlot()] })] })) : (_jsx(Div, { className: "max-w-3xl mx-auto px-5 py-6 sm:px-6", children: children })) })] }), !previewMode && renderBottomBar ? (renderBottomBar()) : !previewMode && (onSaveDraft || onPublish) ? (_jsxs(Row, { justify: "between", className: "flex-shrink-0 sticky bottom-0 z-10 border-t border-[var(--appkit-color-border)] bg-[var(--appkit-color-surface)] px-5 py-3", children: [_jsx(Button, { variant: "ghost", size: "sm", onClick: attemptClose, disabled: isLoading, children: FORM_ACTION_META[FORM_ACTION_ID.DISCARD].label }), _jsxs(Row, { gap: "xs", children: [onSaveDraft && (_jsx(Button, { variant: "outline", size: "sm", onClick: handleSaveDraft, disabled: isLoading || savingDraft || publishing, isLoading: savingDraft, children: saveLabel })), onPublish && (_jsxs(Button, { variant: "primary", size: "sm", onClick: handlePublish, disabled: isLoading || savingDraft || publishing, isLoading: publishing, children: [publishLabel, " \u2192"] }))] })] })) : null] }), showUnsaved && (_jsxs(_Fragment, { children: [_jsx(Div, { className: "fixed inset-0 bg-black/60",
|
|
123
|
+
_jsxs(Div, { className: "lg:grid lg:grid-cols-[3fr_2fr] lg:gap-6 lg:px-6 lg:py-6 lg:max-w-[1400px] lg:mx-auto", children: [_jsx(Div, { className: "max-w-3xl mx-auto px-5 py-6 sm:px-6 lg:max-w-none lg:px-0 lg:py-0", children: children }), _jsxs(Div, { className: `hidden lg:block sticky lg:top-4 lg:self-start lg:max-h-[calc(100vh-6rem)] ${__O.yAuto} border border-[var(--appkit-color-border)] rounded-lg bg-[var(--appkit-color-surface-raised)] ${__P.p4}`, children: [_jsxs(Row, { gap: "xs", className: "mb-3 text-xs font-semibold uppercase tracking-wide text-[var(--appkit-color-text-muted)]", children: [_jsx(Eye, { className: "w-3.5 h-3.5" }), _jsx(Span, { children: "Live preview" })] }), previewSlot()] })] })) : (_jsx(Div, { className: "max-w-3xl mx-auto px-5 py-6 sm:px-6", children: children })) })] }), !previewMode && renderBottomBar ? (renderBottomBar()) : !previewMode && (onSaveDraft || onPublish) ? (_jsxs(Row, { justify: "between", className: "flex-shrink-0 sticky bottom-0 z-10 border-t border-[var(--appkit-color-border)] bg-[var(--appkit-color-surface)] px-5 py-3", children: [_jsx(Button, { variant: "ghost", size: "sm", onClick: attemptClose, disabled: isLoading, children: FORM_ACTION_META[FORM_ACTION_ID.DISCARD].label }), _jsxs(Row, { gap: "xs", children: [onSaveDraft && (_jsx(Button, { variant: "outline", size: "sm", onClick: handleSaveDraft, disabled: isLoading || savingDraft || publishing, isLoading: savingDraft, children: saveLabel })), onPublish && (_jsxs(Button, { variant: "primary", size: "sm", onClick: handlePublish, disabled: isLoading || savingDraft || publishing, isLoading: publishing, children: [publishLabel, " \u2192"] }))] })] })) : null] }), showUnsaved && (_jsxs(_Fragment, { children: [_jsx(Div, { className: "fixed inset-0 bg-black/60",
|
|
124
|
+
// audit-inline-style-ok: z-index token
|
|
125
|
+
style: { zIndex: "calc(var(--appkit-z-modal) + 5)" }, onClick: () => setShowUnsaved(false) }), _jsxs(Div, { className: "fixed top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-[90vw] max-w-sm bg-[var(--appkit-color-surface)] rounded-xl shadow-2xl p-6",
|
|
126
|
+
// audit-inline-style-ok: z-index token
|
|
127
|
+
style: { zIndex: "calc(var(--appkit-z-modal) + 5)" }, children: [_jsxs(Row, { gap: "sm", align: "start", className: "mb-4", children: [_jsx(Span, { className: "flex-shrink-0 w-10 h-10 rounded-full bg-[var(--appkit-color-warning-surface)] flex items-center justify-center", children: _jsx(AlertTriangle, { className: "w-5 h-5 text-[var(--appkit-color-warning)]" }) }), _jsxs(Stack, { gap: "xs", children: [_jsx(Text, { className: "font-semibold text-[var(--appkit-color-text)]", children: "Unsaved changes" }), _jsx(Text, { className: "text-sm text-[var(--appkit-color-text-muted)]", children: "You have unsaved changes. Leave without saving?" })] })] }), _jsxs(Row, { gap: "xs", justify: "end", children: [_jsx(Button, { variant: "outline", size: "sm", onClick: () => setShowUnsaved(false), children: "Stay" }), _jsx(Button, { variant: "danger", size: "sm", onClick: () => { setShowUnsaved(false); onClose(); }, children: "Leave" })] })] })] }))] }));
|
|
120
128
|
}
|
|
@@ -66,7 +66,6 @@ export function QuickFormDrawer({ isOpen, onClose, title, fields, defaultValues,
|
|
|
66
66
|
setValues(initValues(fields, defaultValues));
|
|
67
67
|
setErrors({});
|
|
68
68
|
onClose();
|
|
69
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
70
69
|
}, [fields, defaultValues, onClose]);
|
|
71
70
|
// Keyboard: Esc → close; Tab → trap focus
|
|
72
71
|
useEffect(() => {
|
|
@@ -104,7 +103,11 @@ export function QuickFormDrawer({ isOpen, onClose, title, fields, defaultValues,
|
|
|
104
103
|
if (!isOpen)
|
|
105
104
|
return null;
|
|
106
105
|
const busy = submitting || isLoading;
|
|
107
|
-
return (_jsxs(_Fragment, { children: [_jsx(Div, { className: "fixed inset-0 bg-black/40 backdrop-blur-[2px]",
|
|
106
|
+
return (_jsxs(_Fragment, { children: [_jsx(Div, { className: "fixed inset-0 bg-black/40 backdrop-blur-[2px]",
|
|
107
|
+
// audit-inline-style-ok: z-index token
|
|
108
|
+
style: { zIndex: "calc(var(--appkit-z-modal) + 1)" }, "aria-hidden": "true", onClick: handleClose }), _jsxs("div", { ref: drawerRef, role: "dialog", "aria-modal": "true", "aria-label": title, className: "fixed inset-y-0 right-0 flex flex-col bg-[var(--appkit-color-surface)] shadow-2xl w-full lg:w-[40%]",
|
|
109
|
+
// audit-inline-style-ok: z-index token
|
|
110
|
+
style: { zIndex: "calc(var(--appkit-z-modal) + 2)" }, children: [_jsxs(Div, { className: "flex-shrink-0 flex items-center gap-3 px-4 py-4 border-b border-[var(--appkit-color-border)]", children: [_jsx(Text, { className: "flex-1 text-base font-semibold text-[var(--appkit-color-text)]", children: title }), _jsx("button", { type: "button", onClick: handleClose, "aria-label": "Close", className: "rounded-lg p-1.5 text-[var(--appkit-color-text-muted)] hover:bg-[var(--appkit-color-border-subtle)] transition-colors", children: _jsx(X, { className: "w-5 h-5" }) })] }), _jsxs("form", { className: "flex-1 overflow-y-auto px-4 py-5 space-y-4", onSubmit: handleSubmit, noValidate: true, children: [fields.map((field) => {
|
|
108
111
|
const value = values[field.name];
|
|
109
112
|
if (field.type === "toggle") {
|
|
110
113
|
return (_jsxs(Div, { className: "space-y-1", children: [_jsx(Toggle, { checked: !!value, onChange: (checked) => set(field.name, checked), label: field.label }), field.helperText && (_jsx(Text, { className: "text-xs text-[var(--appkit-color-text-muted)]", children: field.helperText }))] }, field.name));
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* Public and seller-facing read functions for store listings, products,
|
|
5
5
|
* auctions and reviews. No auth — callers decide whether auth is needed.
|
|
6
6
|
*/
|
|
7
|
+
import { sieveFilter, SIEVE_OP } from "@mohasinac/appkit";
|
|
7
8
|
import { NotFoundError } from "../../../errors";
|
|
8
9
|
const ERR_STORE_NOT_FOUND = "Store not found";
|
|
9
10
|
import { maskPublicReview } from "../../../security";
|
|
@@ -35,7 +36,7 @@ export async function getStoreProducts(storeSlug, params = {}) {
|
|
|
35
36
|
throw new NotFoundError(ERR_STORE_NOT_FOUND);
|
|
36
37
|
}
|
|
37
38
|
const filtersArr = [
|
|
38
|
-
|
|
39
|
+
sieveFilter("storeId", SIEVE_OP.EQ, storeDoc.id),
|
|
39
40
|
"status==published",
|
|
40
41
|
"listingType==standard",
|
|
41
42
|
];
|
|
@@ -57,7 +58,7 @@ export async function getStoreAuctions(storeSlug, params = {}) {
|
|
|
57
58
|
throw new NotFoundError(ERR_STORE_NOT_FOUND);
|
|
58
59
|
}
|
|
59
60
|
const filtersArr = [
|
|
60
|
-
|
|
61
|
+
sieveFilter("storeId", SIEVE_OP.EQ, storeDoc.id),
|
|
61
62
|
"status==published",
|
|
62
63
|
"listingType==auction",
|
|
63
64
|
];
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { sieveFilter, sieveAnd, SIEVE_OP } from "@mohasinac/appkit";
|
|
3
|
+
import { sortBy } from "@mohasinac/appkit";
|
|
2
4
|
import { productRepository } from "../../../repositories";
|
|
3
5
|
import { getStoreBySlug } from "./StoreDetailLayoutView";
|
|
4
6
|
import { StoreAuctionsListing } from "./StoreAuctionsListing";
|
|
@@ -8,8 +10,8 @@ export async function StoreAuctionsPageView({ storeSlug }) {
|
|
|
8
10
|
const result = storeId
|
|
9
11
|
? await productRepository
|
|
10
12
|
.list({
|
|
11
|
-
filters:
|
|
12
|
-
sorts: "auctionEndDate",
|
|
13
|
+
filters: sieveAnd(sieveFilter("storeId", SIEVE_OP.EQ, storeId), sieveFilter("status", SIEVE_OP.EQ, "published"), sieveFilter("listingType", SIEVE_OP.EQ, "auction")),
|
|
14
|
+
sorts: sortBy("auctionEndDate", "ASC"),
|
|
13
15
|
page: 1,
|
|
14
16
|
pageSize: 24,
|
|
15
17
|
})
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ReactNode } from "react";
|
|
2
|
-
export declare const getStoreBySlug: (slug: string) => Promise<import("
|
|
2
|
+
export declare const getStoreBySlug: (slug: string) => Promise<import("@mohasinac/appkit").StoreDocument | null | undefined>;
|
|
3
3
|
export interface StoreDetailLayoutViewProps {
|
|
4
4
|
storeSlug: string;
|
|
5
5
|
/** The current active tab value: "products" | "auctions" | "reviews" | "about" */
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { sieveFilter, sieveAnd, SIEVE_OP } from "@mohasinac/appkit";
|
|
2
3
|
import { cache } from "react";
|
|
3
4
|
import { storeRepository, productRepository, categoriesRepository, siteSettingsRepository, reviewRepository, couponsRepository } from "../../../repositories";
|
|
4
5
|
import { ROUTES } from "../../../next";
|
|
@@ -30,19 +31,19 @@ export async function StoreDetailLayoutView({ storeSlug, activeTab, children, })
|
|
|
30
31
|
const [productsCount, auctionsCount, preOrdersCount, prizeDrawsCount, bundlesCount, couponsCount, reviewsCount] = storeId
|
|
31
32
|
? await Promise.all([
|
|
32
33
|
productRepository
|
|
33
|
-
.list({ filters:
|
|
34
|
+
.list({ filters: sieveAnd(sieveFilter("storeId", SIEVE_OP.EQ, storeId), sieveFilter("status", SIEVE_OP.EQ, "published"), sieveFilter("listingType", SIEVE_OP.EQ, "standard")), page: 1, pageSize: 1 })
|
|
34
35
|
.then((r) => r.total)
|
|
35
36
|
.catch(() => 0),
|
|
36
37
|
productRepository
|
|
37
|
-
.list({ filters:
|
|
38
|
+
.list({ filters: sieveAnd(sieveFilter("storeId", SIEVE_OP.EQ, storeId), sieveFilter("status", SIEVE_OP.EQ, "published"), sieveFilter("listingType", SIEVE_OP.EQ, "auction")), page: 1, pageSize: 1 })
|
|
38
39
|
.then((r) => r.total)
|
|
39
40
|
.catch(() => 0),
|
|
40
41
|
productRepository
|
|
41
|
-
.list({ filters:
|
|
42
|
+
.list({ filters: sieveAnd(sieveFilter("storeId", SIEVE_OP.EQ, storeId), sieveFilter("status", SIEVE_OP.EQ, "published"), sieveFilter("listingType", SIEVE_OP.EQ, "pre-order")), page: 1, pageSize: 1 })
|
|
42
43
|
.then((r) => r.total)
|
|
43
44
|
.catch(() => 0),
|
|
44
45
|
productRepository
|
|
45
|
-
.list({ filters:
|
|
46
|
+
.list({ filters: sieveAnd(sieveFilter("storeId", SIEVE_OP.EQ, storeId), sieveFilter("status", SIEVE_OP.EQ, "published"), sieveFilter("listingType", SIEVE_OP.EQ, "prize-draw")), page: 1, pageSize: 1 })
|
|
46
47
|
.then((r) => r.total)
|
|
47
48
|
.catch(() => 0),
|
|
48
49
|
// SB-UNI-D — bundles live on categories with categoryType:"bundle"
|
|
@@ -52,11 +53,11 @@ export async function StoreDetailLayoutView({ storeSlug, activeTab, children, })
|
|
|
52
53
|
.then((rows) => rows.filter((c) => c.createdByStoreId === storeId).length)
|
|
53
54
|
.catch(() => 0),
|
|
54
55
|
couponsRepository
|
|
55
|
-
.list({ filters:
|
|
56
|
+
.list({ filters: sieveAnd(sieveFilter("sellerId", SIEVE_OP.EQ, storeId), sieveFilter("validity.isActive", SIEVE_OP.EQ, "true")), page: 1, pageSize: 1 })
|
|
56
57
|
.then((r) => r.total)
|
|
57
58
|
.catch(() => 0),
|
|
58
59
|
reviewRepository
|
|
59
|
-
.listAll({ filters:
|
|
60
|
+
.listAll({ filters: sieveAnd(sieveFilter("storeId", SIEVE_OP.EQ, storeId), sieveFilter("status", SIEVE_OP.EQ, "approved")), page: 1, pageSize: 1 })
|
|
60
61
|
.then((r) => r.total)
|
|
61
62
|
.catch(() => 0),
|
|
62
63
|
])
|
|
@@ -11,7 +11,11 @@ const CLS_STARS = "inline-flex items-center gap-1 text-amber-500";
|
|
|
11
11
|
const CLS_FOLLOW_BTN = "rounded-lg border border-orange-500 px-4 py-2 text-sm font-medium text-orange-500 hover:bg-orange-50 transition-colors";
|
|
12
12
|
const CLS_WARN_BANNER = "mt-3 rounded-lg bg-yellow-50 dark:bg-yellow-900/20 border border-yellow-200 dark:border-yellow-800 px-3 py-2 text-sm text-yellow-700 dark:text-yellow-300";
|
|
13
13
|
export function StoreHeader({ store, labels = {}, onFollow, className = "", }) {
|
|
14
|
-
return (_jsxs(Section, { surface: "default", className: `border-b border-gray-200 dark:border-slate-700 ${className}`, children: [store.storeBannerURL && (_jsx(Div, { className: `h-40 md:h-56 ${__O.hidden} bg-gray-100 dark:bg-slate-800`, children: _jsx(Div, { role: "img", "aria-label": `${store.storeName} banner`, className: "h-full w-full bg-center bg-cover",
|
|
14
|
+
return (_jsxs(Section, { surface: "default", className: `border-b border-gray-200 dark:border-slate-700 ${className}`, children: [store.storeBannerURL && (_jsx(Div, { className: `h-40 md:h-56 ${__O.hidden} bg-gray-100 dark:bg-slate-800`, children: _jsx(Div, { role: "img", "aria-label": `${store.storeName} banner`, className: "h-full w-full bg-center bg-cover",
|
|
15
|
+
// audit-inline-style-ok: dynamic image URL
|
|
16
|
+
style: { backgroundImage: `url(${store.storeBannerURL})` } }) })), _jsxs(Div, { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-4", children: [_jsxs(Div, { className: "flex items-end gap-4", children: [store.storeLogoURL ? (_jsx(Div, { role: "img", "aria-label": store.storeName, className: "-mt-8 h-16 w-16 rounded-xl border-2 border-white dark:border-slate-800 bg-center bg-cover shadow-sm",
|
|
17
|
+
// audit-inline-style-ok: dynamic image URL
|
|
18
|
+
style: { backgroundImage: `url(${store.storeLogoURL})` } })) : (_jsx(Div, { className: CLS_AVATAR, children: store.storeName[0]?.toUpperCase() })), _jsxs(Div, { className: "flex-1 min-w-0", children: [_jsxs(Div, { className: "flex flex-wrap items-center gap-2 mb-0.5", children: [_jsx(Heading, { level: 1, className: "text-xl font-bold text-gray-900 dark:text-zinc-100", children: store.storeName }), store.averageRating != null && store.averageRating > 0 && (_jsxs(Span, { size: "sm", weight: "medium", className: CLS_STARS, children: ["\u2605 ", store.averageRating.toFixed(1)] }))] }), _jsxs(Row, { className: "gap-3 text-xs text-gray-500 dark:text-zinc-400 mb-0.5", children: [store.category && _jsx(Span, { className: "capitalize", children: store.category }), store.totalProducts != null && store.totalProducts > 0 && (_jsxs(Span, { children: [store.totalProducts, " ", labels.products ?? "products"] })), store.totalReviews != null && store.totalReviews > 0 && (_jsxs(Span, { children: [store.totalReviews, " ", labels.reviews ?? "reviews"] })), store.itemsSold != null && store.itemsSold > 0 && (_jsxs(Span, { children: [store.itemsSold, " ", labels.sold ?? "sold"] }))] }), store.storeDescription && (_jsx(RichText, { html: normalizeRichTextHtml(store.storeDescription), copyableCode: true, className: "mt-0.5" }))] }), _jsxs(Row, { gap: "sm", align: "center", className: "shrink-0", children: [_jsx(ShareButton, { title: store.storeName }), onFollow && (_jsx(Button, { type: "button", variant: "outline", size: "sm", onClick: () => onFollow(store.storeSlug), className: CLS_FOLLOW_BTN, children: labels.follow ?? "Follow" }))] })] }), store.isVacationMode && (_jsx(Text, { className: CLS_WARN_BANNER, children: store.vacationMessage ??
|
|
15
19
|
labels.vacationMode ??
|
|
16
20
|
"Store is on vacation mode" })), _jsx(Div, { className: "mt-3", children: _jsx(StoreScopedSearch, { storeId: store.storeSlug, storeName: store.storeName }) })] })] }));
|
|
17
21
|
}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { sieveFilter, sieveAnd, SIEVE_OP } from "@mohasinac/appkit";
|
|
3
|
+
import { sortBy } from "@mohasinac/appkit";
|
|
2
4
|
import { productRepository } from "../../../repositories";
|
|
3
5
|
import { getStoreBySlug } from "./StoreDetailLayoutView";
|
|
4
6
|
import { StorePreOrdersListing } from "./StorePreOrdersListing";
|
|
@@ -8,8 +10,8 @@ export async function StorePreOrdersPageView({ storeSlug }) {
|
|
|
8
10
|
const result = storeId
|
|
9
11
|
? await productRepository
|
|
10
12
|
.list({
|
|
11
|
-
filters:
|
|
12
|
-
sorts: "
|
|
13
|
+
filters: sieveAnd(sieveFilter("storeId", SIEVE_OP.EQ, storeId), sieveFilter("status", SIEVE_OP.EQ, "published"), sieveFilter("listingType", SIEVE_OP.EQ, "pre-order")),
|
|
14
|
+
sorts: sortBy("createdAt", "DESC"),
|
|
13
15
|
page: 1,
|
|
14
16
|
pageSize: 24,
|
|
15
17
|
})
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { sieveFilter, sieveAnd, SIEVE_OP } from "@mohasinac/appkit";
|
|
3
|
+
import { sortBy } from "@mohasinac/appkit";
|
|
2
4
|
import { productRepository } from "../../../repositories";
|
|
3
5
|
import { getStoreBySlug } from "./StoreDetailLayoutView";
|
|
4
6
|
import { PrizeDrawsIndexListing } from "../../products/components/PrizeDrawsIndexListing";
|
|
@@ -17,8 +19,8 @@ export async function StorePrizeDrawsPageView({ storeSlug, }) {
|
|
|
17
19
|
}
|
|
18
20
|
const result = await productRepository
|
|
19
21
|
.list({
|
|
20
|
-
filters:
|
|
21
|
-
sorts: "
|
|
22
|
+
filters: sieveAnd(sieveFilter("storeId", SIEVE_OP.EQ, storeId), sieveFilter("status", SIEVE_OP.EQ, "published"), sieveFilter("listingType", SIEVE_OP.EQ, "prize-draw")),
|
|
23
|
+
sorts: sortBy("createdAt", "DESC"),
|
|
22
24
|
page: 1,
|
|
23
25
|
pageSize: 24,
|
|
24
26
|
})
|