@mohasinac/appkit 3.6.5 → 3.7.0
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/DashboardLayoutClient.d.ts +17 -3
- package/dist/_internal/client/features/layout/DashboardLayoutClient.js +7 -2
- package/dist/_internal/client/features/tour/TourProvider.d.ts +5 -2
- package/dist/_internal/client/features/tour/TourProvider.js +125 -12
- package/dist/_internal/client/theme/ThemeProvider.js +1 -1
- package/dist/_internal/server/features/faqs/og.js +5 -1
- package/dist/_internal/server/features/reviews/og.js +5 -1
- package/dist/_internal/server/features/seo/manifest.js +2 -1
- package/dist/_internal/server/features/seo/og.js +7 -1
- package/dist/_internal/server/features/tester/visibility.d.ts +13 -0
- package/dist/_internal/server/features/tester/visibility.js +28 -0
- package/dist/_internal/server/functions/scheduled.d.ts +2 -1
- package/dist/_internal/server/functions/scheduled.js +9 -1
- package/dist/_internal/server/jobs/core/jobRunners.js +5 -0
- package/dist/_internal/server/jobs/core/resetOtpVerification.d.ts +17 -0
- package/dist/_internal/server/jobs/core/resetOtpVerification.js +88 -0
- package/dist/_internal/server/jobs/core/testerSandboxCleanup.d.ts +6 -0
- package/dist/_internal/server/jobs/core/testerSandboxCleanup.js +35 -0
- package/dist/_internal/server/jobs/handlers/_helpers.d.ts +6 -0
- package/dist/_internal/server/jobs/handlers/_helpers.js +12 -0
- package/dist/_internal/server/jobs/handlers/index.d.ts +1 -0
- package/dist/_internal/server/jobs/handlers/index.js +2 -0
- package/dist/_internal/server/jobs/handlers/messages.d.ts +2 -0
- package/dist/_internal/server/jobs/handlers/messages.js +2 -0
- package/dist/_internal/server/jobs/handlers/testerSandboxCleanup.d.ts +2 -0
- package/dist/_internal/server/jobs/handlers/testerSandboxCleanup.js +2 -0
- package/dist/_internal/shared/actions/action-registry.d.ts +1 -1
- package/dist/_internal/shared/actions/action-registry.js +48 -0
- package/dist/_internal/shared/tokens/index.d.ts +12 -12
- package/dist/client.d.ts +15 -3
- package/dist/client.js +10 -2
- package/dist/constants/api-endpoints.d.ts +36 -12
- package/dist/constants/api-endpoints.js +16 -8
- package/dist/constants/field-names.d.ts +9 -0
- package/dist/constants/field-names.js +12 -0
- package/dist/constants/index.d.ts +1 -1
- package/dist/constants/index.js +1 -1
- package/dist/features/account/components/LinkedAccountsSection.d.ts +11 -0
- package/dist/features/account/components/LinkedAccountsSection.js +11 -0
- package/dist/features/account/components/UserSidebar.d.ts +3 -1
- package/dist/features/account/components/UserSidebar.js +9 -13
- package/dist/features/account/hooks/useCollapsedSections.d.ts +20 -0
- package/dist/features/account/hooks/useCollapsedSections.js +63 -0
- package/dist/features/account/hooks/useProfile.d.ts +8 -0
- package/dist/features/account/index.d.ts +1 -0
- package/dist/features/account/index.js +1 -0
- package/dist/features/admin/components/AdminAddressEditorView.js +2 -2
- package/dist/features/admin/components/AdminCarouselView.js +2 -2
- package/dist/features/admin/components/AdminCategoryEditorView.js +2 -2
- package/dist/features/admin/components/AdminProductEditorView.js +5 -2
- package/dist/features/admin/components/AdminSectionsView.js +3 -18
- package/dist/features/admin/components/AdminSidebar.js +8 -6
- package/dist/features/admin/components/AdminSiteSettingsView.js +133 -127
- package/dist/features/admin/components/AdminTesterChecklistItemEditorView.d.ts +9 -0
- package/dist/features/admin/components/AdminTesterChecklistItemEditorView.js +129 -0
- package/dist/features/admin/components/AdminTesterChecklistView.d.ts +6 -0
- package/dist/features/admin/components/AdminTesterChecklistView.js +93 -0
- package/dist/features/admin/components/AdminUserEditorView.d.ts +3 -1
- package/dist/features/admin/components/AdminUserEditorView.js +7 -1
- package/dist/features/admin/components/AdminUsersView.js +1 -1
- package/dist/features/admin/components/DataListingView.js +2 -2
- package/dist/features/admin/components/analytics/AdminPageViewsReportView.d.ts +8 -0
- package/dist/features/admin/components/analytics/AdminPageViewsReportView.js +41 -0
- package/dist/features/admin/components/index.d.ts +6 -0
- package/dist/features/admin/components/index.js +3 -0
- package/dist/features/admin/schemas/firestore.d.ts +0 -7
- package/dist/features/admin/schemas/firestore.js +6 -6
- package/dist/features/analytics/components/PageViewTracker.d.ts +12 -0
- package/dist/features/analytics/components/PageViewTracker.js +22 -0
- package/dist/features/analytics/repository/page-views.repository.d.ts +32 -0
- package/dist/features/analytics/repository/page-views.repository.js +43 -0
- package/dist/features/analytics/types.d.ts +6 -0
- package/dist/features/analytics/types.js +13 -0
- package/dist/features/auth/components/SocialAuthButtons.js +1 -1
- package/dist/features/auth/hooks/useAuth.d.ts +12 -0
- package/dist/features/auth/hooks/useAuth.js +109 -0
- package/dist/features/auth/permissions/constants.d.ts +1 -1
- package/dist/features/auth/schemas/firestore.d.ts +17 -1
- package/dist/features/auth/schemas/firestore.js +2 -0
- package/dist/features/blog/components/BlogIndexListing.js +2 -2
- package/dist/features/blog/schemas/firestore.d.ts +4 -0
- package/dist/features/cart/actions/cart-actions.js +20 -2
- package/dist/features/categories/components/CategoriesIndexListing.js +2 -2
- package/dist/features/categories/components/CategoryBundlesListing.js +2 -2
- package/dist/features/categories/components/CategoryDetailPageView.js +3 -1
- package/dist/features/categories/components/CategoryProductsListing.js +2 -2
- package/dist/features/categories/schemas/firestore.d.ts +4 -0
- package/dist/features/classified/components/ClassifiedIndexListing.js +2 -2
- package/dist/features/digital-codes/components/DigitalCodesIndexListing.js +2 -2
- package/dist/features/email/primitives.d.ts +2 -2
- package/dist/features/email/primitives.js +2 -2
- package/dist/features/events/components/EventsIndexListing.js +2 -2
- package/dist/features/events/schemas/firestore.d.ts +4 -0
- package/dist/features/layout/BackToTop.d.ts +6 -1
- package/dist/features/layout/BackToTop.js +31 -6
- package/dist/features/live/components/LiveItemsIndexListing.js +2 -2
- package/dist/features/media/MediaVideo.js +5 -1
- package/dist/features/pre-orders/components/PreOrdersIndexListing.js +2 -2
- package/dist/features/products/components/AuctionsIndexListing.js +2 -2
- package/dist/features/products/components/PrizeDrawsIndexListing.js +2 -2
- package/dist/features/products/components/ProductsIndexListing.js +2 -2
- package/dist/features/products/constants/action-defs.d.ts +2 -0
- package/dist/features/products/constants/action-defs.js +2 -0
- package/dist/features/products/schemas/firestore.d.ts +4 -0
- package/dist/features/promotions/components/CouponsIndexListing.js +2 -2
- package/dist/features/reviews/components/ReviewsIndexListing.js +2 -2
- package/dist/features/seller/actions/seller-actions.js +11 -6
- package/dist/features/seller/components/SellerAddressesView.js +2 -2
- package/dist/features/seller/components/SellerBidsView.js +2 -2
- package/dist/features/seller/components/SellerOrdersView.js +2 -2
- package/dist/features/seller/components/SellerProductsView.js +2 -2
- package/dist/features/seller/components/SellerSidebar.d.ts +3 -1
- package/dist/features/seller/components/SellerSidebar.js +9 -8
- package/dist/features/seller/components/SellerStoreCategoriesView.js +2 -2
- package/dist/features/seller/components/SellerTemplatesView.js +2 -2
- package/dist/features/shell/StepForm.js +4 -4
- package/dist/features/stores/actions/store-query-actions.d.ts +5 -4
- package/dist/features/stores/actions/store-query-actions.js +11 -8
- package/dist/features/stores/components/StoreAuctionsListing.js +2 -2
- package/dist/features/stores/components/StoreClassifiedsListing.js +2 -2
- package/dist/features/stores/components/StoreDigitalCodesListing.js +2 -2
- package/dist/features/stores/components/StoreLiveItemsListing.js +2 -2
- package/dist/features/stores/components/StorePreOrdersListing.js +2 -2
- package/dist/features/stores/components/StoreProductsListing.js +2 -2
- package/dist/features/stores/components/StoreReviewsListing.js +2 -2
- package/dist/features/stores/components/StoresIndexListing.js +2 -2
- package/dist/features/stores/schemas/firestore.d.ts +4 -0
- package/dist/features/tester/actions/checklist-item-actions.d.ts +69 -0
- package/dist/features/tester/actions/checklist-item-actions.js +42 -0
- package/dist/features/tester/actions/index.d.ts +1 -0
- package/dist/features/tester/actions/index.js +1 -0
- package/dist/features/tester/components/AdminTesterFeedbackIssuesView.d.ts +2 -0
- package/dist/features/tester/components/AdminTesterFeedbackIssuesView.js +22 -0
- package/dist/features/tester/components/AdminTesterFeedbackListView.d.ts +3 -0
- package/dist/features/tester/components/AdminTesterFeedbackListView.js +100 -0
- package/dist/features/tester/components/AdminTesterFeedbackReportView.d.ts +2 -0
- package/dist/features/tester/components/AdminTesterFeedbackReportView.js +30 -0
- package/dist/features/tester/components/AdminTesterFeedbackView.d.ts +2 -0
- package/dist/features/tester/components/AdminTesterFeedbackView.js +9 -0
- package/dist/features/tester/components/TesterChecklistStepRow.d.ts +18 -0
- package/dist/features/tester/components/TesterChecklistStepRow.js +29 -0
- package/dist/features/tester/components/TesterFeedbackChart.d.ts +14 -0
- package/dist/features/tester/components/TesterFeedbackChart.js +18 -0
- package/dist/features/tester/components/TesterHubView.d.ts +5 -0
- package/dist/features/tester/components/TesterHubView.js +71 -0
- package/dist/features/tester/components/index.d.ts +11 -0
- package/dist/features/tester/components/index.js +7 -0
- package/dist/features/tester/index.d.ts +2 -0
- package/dist/features/tester/index.js +2 -0
- package/dist/features/tester/repository/index.d.ts +2 -0
- package/dist/features/tester/repository/index.js +2 -0
- package/dist/features/tester/repository/tester-checklist-item.repository.d.ts +13 -0
- package/dist/features/tester/repository/tester-checklist-item.repository.js +55 -0
- package/dist/features/tester/repository/tester-checklist-response.repository.d.ts +42 -0
- package/dist/features/tester/repository/tester-checklist-response.repository.js +98 -0
- package/dist/features/tester/schemas/firestore.d.ts +85 -0
- package/dist/features/tester/schemas/firestore.js +93 -0
- package/dist/features/tester/schemas/index.d.ts +1 -0
- package/dist/features/tester/schemas/index.js +1 -0
- package/dist/features/tester/seed-data/blog-tester-seed-data.d.ts +2 -0
- package/dist/features/tester/seed-data/blog-tester-seed-data.js +40 -0
- package/dist/features/tester/seed-data/categories-tester-seed-data.d.ts +2 -0
- package/dist/features/tester/seed-data/categories-tester-seed-data.js +177 -0
- package/dist/features/tester/seed-data/events-tester-seed-data.d.ts +2 -0
- package/dist/features/tester/seed-data/events-tester-seed-data.js +50 -0
- package/dist/features/tester/seed-data/index.d.ts +6 -0
- package/dist/features/tester/seed-data/index.js +6 -0
- package/dist/features/tester/seed-data/products-tester-seed-data.d.ts +2 -0
- package/dist/features/tester/seed-data/products-tester-seed-data.js +151 -0
- package/dist/features/tester/seed-data/stores-tester-seed-data.d.ts +2 -0
- package/dist/features/tester/seed-data/stores-tester-seed-data.js +40 -0
- package/dist/features/tester/seed-data/tester-checklist-seed-data.d.ts +2 -0
- package/dist/features/tester/seed-data/tester-checklist-seed-data.js +248 -0
- package/dist/features/tester/seed-data/tester-ttl.d.ts +4 -0
- package/dist/features/tester/seed-data/tester-ttl.js +6 -0
- package/dist/features/tester/server.d.ts +9 -0
- package/dist/features/tester/server.js +8 -0
- package/dist/index.d.ts +28 -2
- package/dist/index.js +51 -1
- package/dist/next/api/api-response.js +5 -1
- package/dist/next/api/routeHandler.js +10 -1
- package/dist/next/middleware/chain.js +1 -1
- package/dist/next/routing/route-map.d.ts +6 -7
- package/dist/next/routing/route-map.js +3 -7
- package/dist/providers/payment-manual/index.d.ts +2 -2
- package/dist/providers/payment-manual/index.js +2 -2
- package/dist/react/contexts/SessionContext.d.ts +4 -0
- package/dist/react/contexts/SessionContext.js +4 -0
- package/dist/repositories/index.d.ts +4 -0
- package/dist/repositories/index.js +3 -0
- package/dist/security/pii-encrypt.js +12 -2
- package/dist/seed/addresses-seed-data.js +1 -1
- package/dist/seed/bids-seed-data.js +1 -1
- package/dist/seed/blog-posts-seed-data.js +1 -1
- package/dist/seed/carousel-slides-seed-data.js +22 -16
- package/dist/seed/carousels-seed-data.js +1 -1
- package/dist/seed/cart-seed-data.js +1 -1
- package/dist/seed/categories-seed-data.js +1 -1
- package/dist/seed/claimed-coupons-seed-data.js +1 -1
- package/dist/seed/conversations-seed-data.js +1 -1
- package/dist/seed/coupon-usage-seed-data.js +1 -1
- package/dist/seed/coupons-seed-data.js +1 -1
- package/dist/seed/events-seed-data.js +1 -1
- package/dist/seed/faq-seed-data.js +119 -3
- package/dist/seed/grouped-listings-seed-data.d.ts +2 -0
- package/dist/seed/grouped-listings-seed-data.js +1 -1
- package/dist/seed/history-seed-data.js +1 -1
- package/dist/seed/homepage-sections-seed-data.js +1 -1
- package/dist/seed/index.d.ts +2 -2
- package/dist/seed/index.js +7 -3
- package/dist/seed/lottery-entries-seed-data.js +1 -1
- package/dist/seed/manifest.d.ts +4 -3
- package/dist/seed/manifest.js +13 -6
- package/dist/seed/notifications-seed-data.js +1 -1
- package/dist/seed/offers-seed-data.js +1 -1
- package/dist/seed/orders-seed-data.js +1 -1
- package/dist/seed/payouts-seed-data.js +1 -1
- package/dist/seed/products-art-seed-data.js +1 -1
- package/dist/seed/products-auctions-seed-data.js +1 -1
- package/dist/seed/products-classifieds-seed-data.js +1 -1
- package/dist/seed/products-digital-codes-seed-data.js +1 -1
- package/dist/seed/products-live-items-seed-data.js +1 -1
- package/dist/seed/products-preorders-seed-data.d.ts +2 -0
- package/dist/seed/products-preorders-seed-data.js +1 -1
- package/dist/seed/products-prize-draws-seed-data.js +1 -1
- package/dist/seed/products-standard-seed-data.js +1 -1
- package/dist/seed/products-stickers-seed-data.js +1 -1
- package/dist/seed/reviews-seed-data.js +1 -1
- package/dist/seed/scammers-seed-data.js +1 -1
- package/dist/seed/sessions-seed-data.js +1 -1
- package/dist/seed/site-settings-seed-data.js +22 -16
- package/dist/seed/store-addresses-seed-data.js +1 -1
- package/dist/seed/store-extensions-seed-data.js +1 -1
- package/dist/seed/stores-seed-data.js +1 -1
- package/dist/seed/support-tickets-seed-data.js +1 -1
- package/dist/seed/tester-checklist-seed-data.d.ts +2 -0
- package/dist/seed/tester-checklist-seed-data.js +248 -0
- package/dist/seed/users-seed-data.js +1 -1
- package/dist/seed/wishlists-seed-data.js +1 -1
- package/dist/server.d.ts +7 -2
- package/dist/server.js +19 -12
- package/dist/styles.css +163 -147
- package/dist/tailwind-utilities.css +1 -1
- package/dist/tokens/color-pairs.d.ts +46 -0
- package/dist/tokens/color-pairs.js +93 -0
- package/dist/tokens/index.d.ts +60 -60
- package/dist/tokens/index.js +30 -30
- package/dist/tokens/themes/cobalt-night.d.ts +3 -2
- package/dist/tokens/themes/cobalt-night.js +3 -2
- package/dist/tokens/themes/default-dark.d.ts +4 -1
- package/dist/tokens/themes/default-dark.js +44 -41
- package/dist/tokens/themes/default-light.d.ts +5 -1
- package/dist/tokens/themes/default-light.js +39 -35
- package/dist/tokens/themes/sunset.js +4 -4
- package/dist/tokens/tokens.css +110 -104
- package/dist/ui/components/CollapsibleSection.d.ts +15 -0
- package/dist/ui/components/CollapsibleSection.js +13 -0
- package/dist/ui/components/ListingToolbar.js +2 -1
- package/dist/ui/components/Semantic.style.css +3 -3
- package/dist/ui/components/SideDrawer.style.css +19 -19
- package/dist/ui/components/Slider.js +1 -1
- package/dist/ui/components/StickyToolbar.d.ts +36 -7
- package/dist/ui/components/StickyToolbar.js +63 -5
- package/dist/ui/components/Tabs.js +17 -1
- package/dist/ui/components/Tabs.style.css +10 -0
- package/dist/ui/components/Typography.js +7 -0
- package/dist/ui/components/surface-tokens.d.ts +0 -7
- package/dist/ui/components/surface-tokens.js +7 -0
- package/dist/ui/index.d.ts +6 -0
- package/dist/ui/index.js +3 -0
- package/dist/ui/rich-text/RichText.style.css +20 -20
- package/dist/utils/id-generators.d.ts +13 -0
- package/dist/utils/id-generators.js +17 -0
- package/package.json +1 -1
- package/scripts/seed-cli-loader.mjs +15 -0
- package/scripts/seed-cli.mjs +71 -17
|
@@ -3,7 +3,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
3
3
|
import { useState, useCallback } from "react";
|
|
4
4
|
import { useUrlTable } from "../../../react/hooks/useUrlTable";
|
|
5
5
|
import { useProducts } from "../../products/hooks/useProducts";
|
|
6
|
-
import { BulkActionBar, Div, FilterDrawer, ListingToolbar, LoginRequiredModal, Pagination, Row, Stack, Text, useToast } from "../../../ui";
|
|
6
|
+
import { BulkActionBar, Div, FilterDrawer, ListingToolbar, LoginRequiredModal, Pagination, Row, Stack, Text, useToast, StickyToolbar } from "../../../ui";
|
|
7
7
|
import { usePendingTable } from "../../../react/hooks/usePendingTable";
|
|
8
8
|
import { useAuthGate } from "../../../react/hooks/useAuthGate";
|
|
9
9
|
import { useBulkSelection } from "../../../react/hooks/useBulkSelection";
|
|
@@ -111,5 +111,5 @@ export function LiveItemsIndexListing({ initialData }) {
|
|
|
111
111
|
useBottomActions(selection.selectedCount > 0 ? { bulk: { selectedCount: selection.selectedCount, onClearSelection: selection.clearSelection, actions: [] } } : {});
|
|
112
112
|
return (_jsxs(Div, { className: "min-h-screen", children: [_jsx(ListingToolbar, { filterCount: filterActiveCount, onFiltersClick: openFilters, searchValue: searchInput, searchPlaceholder: "Search live items\u2026", onSearchChange: setSearchInput, onSearchCommit: commitSearch, onSearchKeyDown: (e) => { if (e.key === "Enter")
|
|
113
113
|
commitSearch(); }, sortValue: table.get(TABLE_KEYS.SORT) || DEFAULT_SORT, sortOptions: SORT_OPTIONS, onSortChange: (v) => { table.set(TABLE_KEYS.SORT, v); }, view: view, onViewChange: (v) => { if (v !== "table")
|
|
114
|
-
setView(v); }, onResetAll: resetAll, hasActiveState: hasActiveState, bulkMode: selection.isSelecting, bulkSelectedCount: selection.selectedCount, bulkTotalCount: products.length, onBulkSelectAll: selection.toggleAll, onBulkClear: selection.clearSelection }), _jsx(BulkActionBar, { selectedCount: selection.selectedCount, onClearSelection: selection.clearSelection, actions: [] }), totalPages > 1 && (_jsx(
|
|
114
|
+
setView(v); }, onResetAll: resetAll, hasActiveState: hasActiveState, bulkMode: selection.isSelecting, bulkSelectedCount: selection.selectedCount, bulkTotalCount: products.length, onBulkSelectAll: selection.toggleAll, onBulkClear: selection.clearSelection }), _jsx(BulkActionBar, { selectedCount: selection.selectedCount, onClearSelection: selection.clearSelection, actions: [] }), totalPages > 1 && (_jsx(StickyToolbar, { offset: "header+pagination", tone: "translucent", border: true, padding: "toolbar", children: _jsx(Row, { justify: "center", children: _jsx(Pagination, { currentPage: page, totalPages: totalPages, onPageChange: (p) => table.setPage(p) }) }) })), _jsx(Div, { padding: "y-lg", children: isLoading ? (_jsx(Div, { className: gridClass, children: Array.from({ length: 10 }).map((_, i) => (_jsxs(Div, { className: `${__O.hidden} animate-pulse`, border: "subtle", rounded: "xl", children: [_jsx(Div, { className: "aspect-square", surface: "subtle" }), _jsxs(Stack, { className: `${__P.p3}`, gap: "sm", children: [_jsx(Div, { className: "h-3 w-3/4", surface: "subtle", rounded: "default" }), _jsx(Div, { className: "h-4 w-1/3", surface: "subtle", rounded: "default" })] })] }, i))) })) : products.length === 0 ? (_jsx(Text, { paddingY: "3xl", color: "muted", size: "sm", align: "start", children: "No live item listings found." })) : (_jsx(Div, { className: view === "list" ? "flex flex-col divide-y divide-zinc-100 divide-[var(--appkit-color-border-subtle)] rounded-xl border border-[var(--appkit-color-border-subtle)]" : gridClass, children: products.map((product) => (_jsx(InteractiveProductCard, { product: product, href: String(ROUTES.PUBLIC.LIVE_DETAIL(product.id)), variant: view === "list" ? "list" : "grid", isWishlisted: wishlistActions.isWishlisted(product.id), onToggleWishlist: handleToggleWishlist, selectable: selection.isSelecting, isSelected: selection.isSelected(product.id), onSelect: (id) => selection.toggle(id) }, product.id))) })) }), _jsx(FilterDrawer, { open: filterOpen, onOpen: openFilters, onClose: () => setFilterOpen(false), onApply: applyFilters, onReset: onFilterClear, activeCount: filterActiveCount, hideTrigger: true, children: _jsx(LiveItemFilters, { table: pendingTable, categoryOptions: categoryOptions }) }), _jsx(LoginRequiredModal, { isOpen: modalOpen, onClose: closeModal, message: modalMessage })] }));
|
|
115
115
|
}
|
|
@@ -40,7 +40,11 @@ export function MediaVideo({ src, thumbnailUrl, alt = "Video", controls = true,
|
|
|
40
40
|
? null
|
|
41
41
|
: (watermark ?? siteSettings?.watermark ?? null);
|
|
42
42
|
if (!resolvedSrc) {
|
|
43
|
-
return (_jsx(Row
|
|
43
|
+
return (_jsx(Row
|
|
44
|
+
// audit-color-pair-function-ok: deliberate faded placeholder-icon shade, not a readability regression
|
|
45
|
+
, {
|
|
46
|
+
// audit-color-pair-function-ok: deliberate faded placeholder-icon shade, not a readability regression
|
|
47
|
+
className: "absolute inset-0 text-zinc-400 text-[length:var(--appkit-text-4xl)]", surface: "subtle", align: "center", justify: "center", role: "img", "aria-label": alt, children: _jsx(Span, { "aria-hidden": "true", children: "\uD83C\uDFAC" }) }));
|
|
44
48
|
}
|
|
45
49
|
return (_jsxs(_Fragment, { children: [_jsx("video", { ref: videoRef, src: resolvedSrc, poster: resolvedPoster, controls: controls, autoPlay: autoPlayMuted, muted: autoPlayMuted, loop: loop, playsInline: true, "aria-label": alt, className: `absolute inset-0 w-full h-full ${fitClass}` }), effectiveWatermark ? _jsx(MediaVideoWatermarkLayer, { config: effectiveWatermark }) : null] }));
|
|
46
50
|
}
|
|
@@ -4,7 +4,7 @@ import { useState, useCallback } from "react";
|
|
|
4
4
|
import { Columns, Heart, ShoppingCart } from "lucide-react";
|
|
5
5
|
import { useUrlTable } from "../../../react/hooks/useUrlTable";
|
|
6
6
|
import { useProducts } from "../../products/hooks/useProducts";
|
|
7
|
-
import { BulkActionBar, Div, FilterDrawer, ListingToolbar, LoginRequiredModal, Pagination, Row, Stack, Text, useToast } from "../../../ui";
|
|
7
|
+
import { BulkActionBar, Div, FilterDrawer, ListingToolbar, LoginRequiredModal, Pagination, Row, Stack, Text, useToast, StickyToolbar } from "../../../ui";
|
|
8
8
|
import { usePendingTable } from "../../../react/hooks/usePendingTable";
|
|
9
9
|
import { useAuthGate } from "../../../react/hooks/useAuthGate";
|
|
10
10
|
import { ACTION_ID, ACTION_META, COMPARE_MAX_ITEMS } from "../../products/constants/action-defs";
|
|
@@ -222,7 +222,7 @@ export function PreOrdersIndexListing({ initialData, categorySlug, brandName })
|
|
|
222
222
|
setCompareIds(ids);
|
|
223
223
|
},
|
|
224
224
|
},
|
|
225
|
-
] }), totalPages > 1 && (_jsx(
|
|
225
|
+
] }), totalPages > 1 && (_jsx(StickyToolbar, { offset: "header+pagination", tone: "translucent", border: true, padding: "toolbar", children: _jsx(Row, { justify: "center", children: _jsx(Pagination, { currentPage: page, totalPages: totalPages, onPageChange: (p) => table.setPage(p) }) }) })), _jsx(Div, { padding: "y-lg", children: isLoading ? (_jsx(Div, { className: gridClass, children: Array.from({ length: 10 }).map((_, i) => (_jsxs(Div, { className: `${__O.hidden} animate-pulse`, border: "subtle", rounded: "xl", children: [_jsx(Div, { className: "aspect-square", surface: "subtle" }), _jsxs(Stack, { className: `${__P.p3}`, gap: "sm", children: [_jsx(Div, { className: "h-3 w-3/4", surface: "subtle", rounded: "default" }), _jsx(Div, { className: "h-3 w-1/2", surface: "subtle", rounded: "default" }), _jsx(Div, { className: "h-4 w-1/3", surface: "subtle", rounded: "default" }), _jsx(Div, { className: "h-8", surface: "subtle", rounded: "default" })] })] }, i))) })) : preOrders.length === 0 ? (_jsx(Text, { paddingY: "3xl", color: "muted", size: "sm", align: "start", children: "No pre-orders found." })) : view === "list" ? (_jsx(Stack, { className: "divide-y divide-zinc-100 divide-[var(--appkit-color-border-subtle)]", border: "subtle", rounded: "xl", children: preOrders.map((product) => (_jsx(MarketplacePreorderCard, { product: product, variant: "list", hrefBuilder: (p) => String(ROUTES.PUBLIC.PRE_ORDER_DETAIL(p.id)), onAddToCart: handleAddToCart, wishlistActions: wishlistActions, selectable: selection.isSelecting, isSelected: selection.isSelected(product.id), onSelect: (id) => selection.toggle(id) }, product.id))) })) : (_jsx(Div, { className: gridClass, children: preOrders.map((product) => (_jsx(MarketplacePreorderCard, { product: product, variant: "grid", hrefBuilder: (p) => String(ROUTES.PUBLIC.PRE_ORDER_DETAIL(p.id)), onAddToCart: handleAddToCart, wishlistActions: wishlistActions, selectable: selection.isSelecting, isSelected: selection.isSelected(product.id), onSelect: (id) => selection.toggle(id) }, product.id))) })) }), _jsx(CompareOverlay, { isOpen: compareIds.length > 0, productIds: compareIds, productType: "preorder", onClose: () => {
|
|
226
226
|
setCompareIds([]);
|
|
227
227
|
selection.clearSelection();
|
|
228
228
|
}, onRemove: (id) => setCompareIds((ids) => ids.filter((i) => i !== id)) }), _jsx(FilterDrawer, { open: filterOpen, onOpen: openFilters, onClose: () => setFilterOpen(false), onApply: applyFilters, onReset: onFilterClear, activeCount: filterActiveCount, hideTrigger: true, children: _jsx(PreOrderFilters, { table: pendingTable, currencyPrefix: "\u20B9", categoryOptions: categoryOptions, brandOptions: brandOptions }) }), _jsx(LoginRequiredModal, { isOpen: modalOpen, onClose: closeModal, message: modalMessage })] }));
|
|
@@ -3,7 +3,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
3
3
|
import { useState, useCallback } from "react";
|
|
4
4
|
import { useUrlTable } from "../../../react/hooks/useUrlTable";
|
|
5
5
|
import { useProducts } from "../hooks/useProducts";
|
|
6
|
-
import { BulkActionBar, Div, FilterDrawer, ListingToolbar, LoginRequiredModal, Pagination, Row, Stack, useToast } from "../../../ui";
|
|
6
|
+
import { BulkActionBar, Div, FilterDrawer, ListingToolbar, LoginRequiredModal, Pagination, Row, Stack, useToast, StickyToolbar } from "../../../ui";
|
|
7
7
|
import { usePendingTable } from "../../../react/hooks/usePendingTable";
|
|
8
8
|
import { useBulkSelection } from "../../../react/hooks/useBulkSelection";
|
|
9
9
|
import { MarketplaceAuctionGrid } from "../../auctions/components/MarketplaceAuctionGrid";
|
|
@@ -155,5 +155,5 @@ export function AuctionsIndexListing({ initialData, categorySlug, brandName }) {
|
|
|
155
155
|
selection.clearSelection();
|
|
156
156
|
},
|
|
157
157
|
},
|
|
158
|
-
] }), totalPages > 1 && (_jsx(
|
|
158
|
+
] }), totalPages > 1 && (_jsx(StickyToolbar, { offset: "header+pagination", tone: "translucent", border: true, padding: "toolbar", children: _jsx(Row, { justify: "center", children: _jsx(Pagination, { currentPage: page, totalPages: totalPages, onPageChange: (p) => table.setPage(p) }) }) })), _jsx(Div, { padding: "y-lg", children: isLoading ? (_jsx(Div, { className: gridClass, children: Array.from({ length: 8 }).map((_, i) => (_jsxs(Div, { className: `${__O.hidden} animate-pulse`, border: "subtle", rounded: "xl", children: [_jsx(Div, { className: "aspect-square", surface: "subtle" }), _jsxs(Stack, { className: `${__P.p3}`, gap: "sm", children: [_jsx(Div, { className: "h-3 w-3/4", surface: "subtle", rounded: "default" }), _jsx(Div, { className: "h-4 w-1/2", surface: "subtle", rounded: "default" }), _jsx(Div, { className: "h-3 w-full", surface: "subtle", rounded: "default" }), _jsx(Div, { className: "h-8", surface: "subtle", rounded: "default" })] })] }, i))) })) : (_jsx(MarketplaceAuctionGrid, { auctions: auctions, variant: view === "list" ? "list" : "grid", gridClassName: view === "list" ? "flex flex-col gap-[var(--appkit-space-4)]" : gridClass, wishlistActions: wishlistActions })) }), _jsx(FilterDrawer, { open: filterOpen, onOpen: openFilters, onClose: () => setFilterOpen(false), onApply: applyFilters, onReset: onFilterClear, activeCount: filterActiveCount, hideTrigger: true, children: _jsx(AuctionFilters, { table: pendingTable, currencyPrefix: "\u20B9", categoryOptions: categoryOptions, brandOptions: brandOptions }) }), _jsx(LoginRequiredModal, { isOpen: modalOpen, onClose: closeModal, message: modalMessage })] }));
|
|
159
159
|
}
|
|
@@ -4,7 +4,7 @@ import { useState, useCallback } from "react";
|
|
|
4
4
|
import { useUrlTable } from "../../../react/hooks/useUrlTable";
|
|
5
5
|
import { usePendingTable } from "../../../react/hooks/usePendingTable";
|
|
6
6
|
import { useProducts } from "../hooks/useProducts";
|
|
7
|
-
import { Div, FilterDrawer, Label, ListingToolbar, Pagination, Row, Select, Stack, Text } from "../../../ui";
|
|
7
|
+
import { Div, FilterDrawer, Label, ListingToolbar, Pagination, Row, Select, Stack, Text, StickyToolbar } from "../../../ui";
|
|
8
8
|
import { useCategoryTree, categoriesToFacetOptions } from "../../categories/hooks/useCategoryTree";
|
|
9
9
|
import { useBrands } from "../hooks/useBrands";
|
|
10
10
|
import { MarketplacePrizeDrawCard } from "./MarketplacePrizeDrawCard";
|
|
@@ -88,7 +88,7 @@ export function PrizeDrawsIndexListing({ initialData, categorySlug, brandName, s
|
|
|
88
88
|
table.set(TABLE_KEYS.VIEW, v);
|
|
89
89
|
}, onResetAll: resetAll, hasActiveState: hasActiveState, toggles: [
|
|
90
90
|
{ label: "Show closed", active: showClosed, onChange: (next) => table.set(TABLE_KEYS.SHOW_CLOSED, next ? "true" : "") },
|
|
91
|
-
] }), totalPages > 1 && (_jsx(
|
|
91
|
+
] }), totalPages > 1 && (_jsx(StickyToolbar, { offset: "header+pagination", tone: "translucent", border: true, padding: "toolbar", children: _jsx(Row, { justify: "center", children: _jsx(Pagination, { currentPage: page, totalPages: totalPages, onPageChange: (p) => table.setPage(p) }) }) })), _jsx(Div, { padding: "y-lg", children: isLoading ? (_jsx(Div, { className: gridClass, children: Array.from({ length: 8 }).map((_, i) => (_jsxs(Div, { className: "overflow-hidden animate-pulse", border: "subtle", rounded: "xl", children: [_jsx(Div, { className: "aspect-square", surface: "subtle" }), _jsxs(Stack, { className: `${__P.p3}`, gap: "sm", children: [_jsx(Div, { className: "h-3 w-3/4", surface: "subtle", rounded: "default" }), _jsx(Div, { className: "h-3 w-1/2", surface: "subtle", rounded: "default" }), _jsx(Div, { className: "h-8", surface: "subtle", rounded: "default" })] })] }, i))) })) : filteredDraws.length === 0 ? (_jsx(Text, { paddingY: "3xl", color: "muted", size: "sm", align: "start", children: "No prize draws found." })) : (_jsx(Div, { className: gridClass, children: filteredDraws.map((product) => (_jsx(MarketplacePrizeDrawCard, { product: product, variant: view }, product.id))) })) }), _jsx(FilterDrawer, { open: filterOpen, onOpen: openFilters, onClose: () => setFilterOpen(false), onApply: applyFilters, onReset: onFilterClear, activeCount: filterActiveCount, hideTrigger: true, children: _jsxs(Stack, { gap: "md", children: [_jsxs(_Fragment, { children: [_jsx(Label, { htmlFor: "prizeRevealStatusFilter", size: "xs", weight: "semibold", color: "muted", className: "block mb-1.5", children: "Reveal status" }), _jsx(Select, { id: "prizeRevealStatusFilter", options: [
|
|
92
92
|
{ value: "", label: "Any" },
|
|
93
93
|
{ value: "pending", label: "Reveal pending" },
|
|
94
94
|
{ value: "open", label: "Reveal open" },
|
|
@@ -5,7 +5,7 @@ import { ShoppingCart, Heart, Columns } from "lucide-react";
|
|
|
5
5
|
import { useRouter } from "next/navigation";
|
|
6
6
|
import { useUrlTable } from "../../../react/hooks/useUrlTable";
|
|
7
7
|
import { useProducts } from "../hooks/useProducts";
|
|
8
|
-
import { BulkActionBar, Div, FilterDrawer, ListingToolbar, LoginRequiredModal, Pagination, Row, Stack, useToast } from "../../../ui";
|
|
8
|
+
import { BulkActionBar, Div, FilterDrawer, ListingToolbar, LoginRequiredModal, Pagination, Row, Stack, useToast, StickyToolbar } from "../../../ui";
|
|
9
9
|
import { usePendingTable } from "../../../react/hooks/usePendingTable";
|
|
10
10
|
import { useAuthGate } from "../../../react/hooks/useAuthGate";
|
|
11
11
|
import { ACTION_ID, ACTION_META, COMPARE_MAX_ITEMS } from "../constants/action-defs";
|
|
@@ -239,7 +239,7 @@ export function ProductsIndexListing({ initialData }) {
|
|
|
239
239
|
setCompareIds(ids);
|
|
240
240
|
},
|
|
241
241
|
},
|
|
242
|
-
] }), totalPages > 1 && (_jsx(
|
|
242
|
+
] }), totalPages > 1 && (_jsx(StickyToolbar, { offset: "header+pagination", tone: "translucent", border: true, padding: "toolbar", children: _jsx(Row, { justify: "center", children: _jsx(Pagination, { currentPage: page, totalPages: totalPages, onPageChange: (p) => table.setPage(p) }) }) })), _jsx(Div, { padding: "y-lg", children: isLoading ? (_jsx(Div, { layout: "grid", gap: "4", className: "grid-cols-2 sm:grid-cols-3 lg:grid-cols-4", children: Array.from({ length: 10 }).map((_, i) => (_jsxs(Div, { className: `${__O.hidden} animate-pulse`, border: "subtle", rounded: "xl", children: [_jsx(Div, { className: "aspect-square", surface: "subtle" }), _jsxs(Stack, { className: `${__P.p3}`, gap: "sm", children: [_jsx(Div, { className: "h-3 w-3/4", surface: "subtle", rounded: "default" }), _jsx(Div, { className: "h-3 w-1/2", surface: "subtle", rounded: "default" }), _jsx(Div, { className: "h-4 w-1/3", surface: "subtle", rounded: "default" })] })] }, i))) })) : (_jsx(ProductGrid, { products: products, getProductHref: (p) => String(ROUTES.PUBLIC.PRODUCT_DETAIL(p.slug || p.id)), view: view === "grid" ? "card" : "list", onWishlistToggle: handleWishlistToggle, wishlistedIds: wishlistedIds, onAddToCart: handleAddToCart, onBuyNow: handleBuyNow, selectionMode: selection.isSelecting, selectedIds: selection.selectedIdSet, onToggleSelect: selection.toggle })) }), _jsx(CompareOverlay, { isOpen: compareIds.length > 0, productIds: compareIds, productType: "product", onClose: () => {
|
|
243
243
|
setCompareIds([]);
|
|
244
244
|
selection.clearSelection();
|
|
245
245
|
}, onRemove: (id) => setCompareIds((ids) => ids.filter((i) => i !== id)) }), _jsx(FilterDrawer, { open: filterOpen, onOpen: openFilters, onClose: () => setFilterOpen(false), onApply: applyFilters, onReset: onFilterClear, activeCount: filterActiveCount, hideTrigger: true, children: _jsx(ProductFilters, { table: pendingTable, currencyPrefix: "\u20B9", categoryOptions: categoryOptions, brandOptions: brandOptions, featureOptions: featureOptions }) }), _jsx(LoginRequiredModal, { isOpen: modalOpen, onClose: closeModal, message: modalMessage })] }));
|
|
@@ -345,6 +345,8 @@ export declare const ADMIN_BULK_ACTIONS: {
|
|
|
345
345
|
readonly deals: readonly ["row-remove"];
|
|
346
346
|
readonly featured: readonly ["row-remove"];
|
|
347
347
|
readonly shipments: readonly ["row-mark-received", "row-delete"];
|
|
348
|
+
readonly testerChecklistItems: readonly ["row-delete"];
|
|
349
|
+
readonly testerFeedback: readonly ["row-mark-read"];
|
|
348
350
|
};
|
|
349
351
|
export declare const SELLER_BULK_ACTIONS: {
|
|
350
352
|
readonly products: readonly ["row-publish", "row-archive", "row-delete"];
|
|
@@ -445,6 +445,8 @@ export const ADMIN_BULK_ACTIONS = {
|
|
|
445
445
|
deals: [ROW_ACTION_ID.REMOVE],
|
|
446
446
|
featured: [ROW_ACTION_ID.REMOVE],
|
|
447
447
|
shipments: [ROW_ACTION_ID.MARK_RECEIVED, ROW_ACTION_ID.DELETE],
|
|
448
|
+
testerChecklistItems: [ROW_ACTION_ID.DELETE],
|
|
449
|
+
testerFeedback: [ROW_ACTION_ID.MARK_READ],
|
|
448
450
|
};
|
|
449
451
|
// Seller bulk actions per listing entity
|
|
450
452
|
export const SELLER_BULK_ACTIONS = {
|
|
@@ -124,6 +124,10 @@ export interface ProductDocument extends BaseDocument {
|
|
|
124
124
|
title: string;
|
|
125
125
|
description: string;
|
|
126
126
|
slug?: string;
|
|
127
|
+
/** Tester sandbox flag — set on shared admin-seeded test products; swept by testerSandboxCleanup. */
|
|
128
|
+
isTestData?: boolean;
|
|
129
|
+
/** When isTestData, the cutoff after which testerSandboxCleanup deletes this doc (cascades to bids). */
|
|
130
|
+
testDataExpiresAt?: Date;
|
|
127
131
|
seoTitle?: string;
|
|
128
132
|
seoDescription?: string;
|
|
129
133
|
seoKeywords?: string[];
|
|
@@ -3,7 +3,7 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
3
3
|
import { useState, useCallback, useMemo } from "react";
|
|
4
4
|
import { Search, SlidersHorizontal, X } from "lucide-react";
|
|
5
5
|
import { useUrlTable } from "../../../react/hooks/useUrlTable";
|
|
6
|
-
import { Button, DateInput, IconButton, Input, ListingFilterDrawer, Pagination, RadioGroup, SortDropdown, Div, Grid, Row, Span, Stack, Text, Heading } from "../../../ui";
|
|
6
|
+
import { Button, DateInput, IconButton, Input, ListingFilterDrawer, Pagination, RadioGroup, SortDropdown, Div, Grid, Row, Span, Stack, Text, Heading, StickyToolbar } from "../../../ui";
|
|
7
7
|
import { usePromotions } from "../hooks/usePromotions";
|
|
8
8
|
import { CouponCard } from "./CouponCard";
|
|
9
9
|
import { TABLE_KEYS } from "../../../constants/table-keys";
|
|
@@ -93,7 +93,7 @@ export function CouponsIndexListing({ initialCoupons, storeSlug: _storeSlug, sto
|
|
|
93
93
|
const clearFilters = () => {
|
|
94
94
|
table.setMany({ type: "", [TABLE_KEYS.DATE_FROM]: "", [TABLE_KEYS.DATE_TO]: "" });
|
|
95
95
|
};
|
|
96
|
-
return (_jsxs(Div, { className: "min-h-[40vh]", children: [_jsxs(
|
|
96
|
+
return (_jsxs(Div, { className: "min-h-[40vh]", children: [_jsxs(StickyToolbar, { offset: "header", tone: "default", border: true, padding: "md", z: "above-toolbar", dismissible: true, id: "coupons-toolbar", children: [_jsxs(Row, { gap: "xs", className: "max-w-full", children: [_jsxs(Button, { type: "button", variant: hasActiveFilters ? "outline" : "ghost", onClick: openFilters, gap: "sm", rounded: "lg", paddingX: "md", paddingY: "sm", textSize: "sm", weight: "medium", className: hasActiveFilters ? "border-primary bg-primary-50 text-primary-700 dark:bg-primary-900/30 dark:text-primary-300 shrink-0" : "border-[var(--appkit-color-border)] text-[var(--appkit-color-text-muted)] shrink-0", children: [_jsx(SlidersHorizontal, { className: "h-4 w-4" }), _jsxs(Span, { className: "hidden sm:inline", children: ["Filters", hasActiveFilters ? " •" : ""] })] }), _jsxs(Row, { surface: "default", className: `flex-1 ${__O.hidden}`, border: "strong", rounded: "lg", children: [_jsx(Input, { bare: true, type: "text", value: searchInput, onChange: (e) => setSearchInput(e.target.value), onKeyDown: handleKeyDown, placeholder: "Search by name or description\u2026", className: "min-w-0 flex-1 bg-transparent px-[var(--appkit-space-3)] py-[var(--appkit-space-2)] text-[length:var(--appkit-text-sm)] text-[var(--appkit-color-text)] placeholder-zinc-400 outline-none" }), searchInput && (_jsx(IconButton, { type: "button", onClick: () => { setSearchInput(""); table.set(TABLE_KEYS.QUERY, ""); }, "aria-label": "Clear search", variant: "ghost", size: "sm", children: _jsx(X, { className: "h-3.5 w-3.5" }) })), _jsx(IconButton, { type: "button", onClick: commitSearch, "aria-label": "Search", variant: "ghost", size: "sm", children: _jsx(Search, { className: "h-4 w-4" }) })] }), _jsxs(Row, { color: "muted", textSize: "sm", gap: "xs", className: "shrink-0", children: [_jsx(Span, { className: "hidden md:inline whitespace-nowrap", children: "Sort by" }), _jsx(SortDropdown, { value: table.get(TABLE_KEYS.SORT) || DEFAULT_SORT, onChange: (v) => { table.set(TABLE_KEYS.SORT, v); }, options: COUPON_SORT_OPTIONS })] })] }), hasActiveFilters && (_jsxs(Row, { gap: "xs", wrap: true, className: "mt-2", children: [activeType && (_jsxs(Span, { layout: "flex", gap: "xs", size: "xs", weight: "medium", className: "bg-primary-50 dark:bg-primary-900/30 text-primary-700 dark:text-primary-300", rounded: "full", padding: "pill-sm-tall", children: [COUPON_TYPES.find((t) => t.value === activeType)?.label ?? activeType, _jsx(Button, { variant: "ghost", type: "button", onClick: () => { table.set(TABLE_KEYS.TYPE, ""); }, "aria-label": "Remove type filter", className: CLS_CHIP_BTN, children: _jsx(X, { className: "h-3 w-3" }) })] })), table.get(TABLE_KEYS.DATE_FROM) && (_jsxs(Span, { layout: "flex", gap: "xs", size: "xs", weight: "medium", className: "bg-primary-50 dark:bg-primary-900/30 text-primary-700 dark:text-primary-300", rounded: "full", padding: "pill-sm-tall", children: ["From: ", table.get(TABLE_KEYS.DATE_FROM), _jsx(Button, { variant: "ghost", type: "button", onClick: () => { table.set(TABLE_KEYS.DATE_FROM, ""); }, "aria-label": "Remove from-date filter", className: CLS_CHIP_BTN, children: _jsx(X, { className: "h-3 w-3" }) })] })), table.get(TABLE_KEYS.DATE_TO) && (_jsxs(Span, { layout: "flex", gap: "xs", size: "xs", weight: "medium", className: "bg-primary-50 dark:bg-primary-900/30 text-primary-700 dark:text-primary-300", rounded: "full", padding: "pill-sm-tall", children: ["To: ", table.get(TABLE_KEYS.DATE_TO), _jsx(Button, { variant: "ghost", type: "button", onClick: () => { table.set(TABLE_KEYS.DATE_TO, ""); }, "aria-label": "Remove to-date filter", className: CLS_CHIP_BTN, children: _jsx(X, { className: "h-3 w-3" }) })] })), _jsx(Button, { variant: "ghost", type: "button", onClick: clearFilters, textSize: "xs", textColor: "muted", className: "underline", children: "Clear all" })] }))] }), _jsxs(Div, { paddingY: "y-lg", paddingX: "x-md", children: [isLoading ? (_jsx(Grid, { gap: "sm", className: "md:grid-cols-2 lg:grid-cols-3", children: Array.from({ length: 6 }).map((_, i) => (_jsxs(Stack, { border: "skeleton", gap: "sm", rounded: "xl", padding: "md", className: "animate-pulse", children: [_jsx(Div, { className: "h-6 w-2/3", surface: "subtle", rounded: "default" }), _jsx(Div, { className: "h-4 w-full", surface: "subtle", rounded: "default" }), _jsx(Div, { className: "h-3 w-1/2", surface: "subtle", rounded: "default" })] }, i))) })) : displayCoupons.length === 0 ? (_jsx(Div, { className: "text-left", padding: "y-4xl", children: _jsx(Text, { color: "faint", children: "No coupons match your search." }) })) : (_jsx(Grid, { gap: "sm", className: "md:grid-cols-2 lg:grid-cols-3", children: displayCoupons.map((coupon) => (_jsx(CouponCard, { coupon: coupon, labels: {
|
|
97
97
|
copy: "Copy",
|
|
98
98
|
copied: "Copied!",
|
|
99
99
|
expires: "Expires",
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { useState, useCallback, useMemo } from "react";
|
|
4
4
|
import { useUrlTable } from "../../../react/hooks/useUrlTable";
|
|
5
|
-
import { Div, ListingFilterDrawer, ListingToolbar, Pagination, Row, Stack, Text } from "../../../ui";
|
|
5
|
+
import { Div, ListingFilterDrawer, ListingToolbar, Pagination, Row, Stack, Text, StickyToolbar } from "../../../ui";
|
|
6
6
|
import { ReviewCard } from "./ReviewsList";
|
|
7
7
|
import { ReviewFilters, REVIEW_PUBLIC_SORT_OPTIONS } from "./ReviewFilters";
|
|
8
8
|
import { useReviews } from "../hooks/useReviews";
|
|
@@ -108,5 +108,5 @@ export function ReviewsIndexListing({ initialData, variant = "public", }) {
|
|
|
108
108
|
value: opt.value,
|
|
109
109
|
label: SORT_OPTION_LABELS[opt.key] ?? opt.key,
|
|
110
110
|
}));
|
|
111
|
-
return (_jsxs(Div, { className: "min-h-screen", children: [_jsx(ListingToolbar, { filterCount: activeFilterCount, onFiltersClick: openFilters, searchValue: searchInput, searchPlaceholder: "Search reviews by product name...", onSearchChange: setSearchInput, onSearchCommit: commitSearch, sortValue: sort, sortOptions: sortOptions, onSortChange: (v) => { table.set(TABLE_KEYS.SORT, v); }, view: view, onViewChange: handleViewToggle, onResetAll: resetAll, hasActiveState: hasActiveState }), totalPages > 1 && (_jsx(
|
|
111
|
+
return (_jsxs(Div, { className: "min-h-screen", children: [_jsx(ListingToolbar, { filterCount: activeFilterCount, onFiltersClick: openFilters, searchValue: searchInput, searchPlaceholder: "Search reviews by product name...", onSearchChange: setSearchInput, onSearchCommit: commitSearch, sortValue: sort, sortOptions: sortOptions, onSortChange: (v) => { table.set(TABLE_KEYS.SORT, v); }, view: view, onViewChange: handleViewToggle, onResetAll: resetAll, hasActiveState: hasActiveState }), totalPages > 1 && (_jsx(StickyToolbar, { offset: "header+pagination", tone: "translucent", border: true, padding: "toolbar", children: _jsx(Row, { justify: "center", children: _jsx(Pagination, { currentPage: currentPage, totalPages: totalPages, onPageChange: (p) => table.setPage(p) }) }) })), _jsx(Div, { padding: "y-lg", children: isLoading ? (_jsx(Div, { layout: "grid", gap: "6", className: "grid-cols-1 sm:grid-cols-2 lg:grid-cols-3", children: Array.from({ length: 6 }).map((_, i) => (_jsx(Div, { className: `${__O.hidden} animate-pulse`, border: "subtle", rounded: "xl", children: _jsxs(Stack, { className: `${__P.p4}`, gap: "3", children: [_jsx(Div, { className: "h-4 w-3/4", surface: "subtle", rounded: "default" }), _jsx(Div, { className: "h-3 w-full", surface: "subtle", rounded: "default" }), _jsx(Div, { className: "h-3 w-2/3", surface: "subtle", rounded: "default" })] }) }, i))) })) : reviews.length === 0 ? (_jsx(Text, { paddingY: "3xl", color: "muted", size: "sm", align: "start", children: "No reviews found." })) : view === "list" ? (_jsx(Stack, { className: "divide-y divide-zinc-100 divide-[var(--appkit-color-border-subtle)]", border: "subtle", rounded: "xl", children: reviews.map((review) => (_jsx(ReviewCard, { review: review }, review.id))) })) : (_jsx(Div, { layout: "grid", gap: "6", className: "grid-cols-1 sm:grid-cols-2 lg:grid-cols-3", children: reviews.map((review) => (_jsx(ReviewCard, { review: review }, review.id))) })) }), _jsx(ListingFilterDrawer, { open: filterOpen, onClose: () => setFilterOpen(false), onApply: applyFilters, onClear: clearFilters, activeCount: activeFilterCount, children: _jsx(ReviewFilters, { table: pendingTable, variant: variant }) })] }));
|
|
112
112
|
}
|
|
@@ -25,6 +25,7 @@ import { siteSettingsRepository } from "../../admin/repository/site-settings.rep
|
|
|
25
25
|
import { computePayoutDeduction } from "../../../_internal/shared/fees/calculator";
|
|
26
26
|
import { getDefaultCurrency } from "../../../core/baseline-resolver";
|
|
27
27
|
import { finalizeStagedMediaUrl, finalizeStagedMediaField, finalizeStagedMediaArray, } from "../../media/finalize";
|
|
28
|
+
import { StoreStatusValues } from "../../stores/schemas/firestore";
|
|
28
29
|
// --- Helper -------------------------------------------------------------------
|
|
29
30
|
async function finalizeProductMediaReferences(data) {
|
|
30
31
|
const finalized = { ...data };
|
|
@@ -58,12 +59,13 @@ export async function becomeSeller(userId) {
|
|
|
58
59
|
"pending",
|
|
59
60
|
};
|
|
60
61
|
}
|
|
62
|
+
const storeStatus = profile?.isTester ? "approved" : "pending";
|
|
61
63
|
await userRepository.update(userId, {
|
|
62
64
|
role: "seller",
|
|
63
|
-
storeStatus
|
|
65
|
+
storeStatus,
|
|
64
66
|
});
|
|
65
|
-
serverLogger.info("becomeSeller: application submitted", { userId });
|
|
66
|
-
return { storeStatus
|
|
67
|
+
serverLogger.info("becomeSeller: application submitted", { userId, storeStatus });
|
|
68
|
+
return { storeStatus };
|
|
67
69
|
}
|
|
68
70
|
// --- Create Store -------------------------------------------------------------
|
|
69
71
|
export async function createStore(userId, userName, input) {
|
|
@@ -79,23 +81,26 @@ export async function createStore(userId, userName, input) {
|
|
|
79
81
|
const suffix = `-${attempt}`;
|
|
80
82
|
storeSlug = `${baseSlug.slice(0, 80 - suffix.length)}${suffix}`;
|
|
81
83
|
}
|
|
84
|
+
const profile = await userRepository.findById(userId);
|
|
85
|
+
const isTester = profile?.isTester === true;
|
|
82
86
|
const store = await storeRepository.create({
|
|
83
87
|
storeSlug,
|
|
84
88
|
ownerId: userId,
|
|
85
89
|
storeName,
|
|
86
90
|
storeDescription: storeDescription || undefined,
|
|
87
91
|
storeCategory: storeCategory || undefined,
|
|
88
|
-
isPublic:
|
|
89
|
-
status:
|
|
92
|
+
isPublic: isTester,
|
|
93
|
+
status: isTester ? StoreStatusValues.ACTIVE : StoreStatusValues.PENDING,
|
|
90
94
|
});
|
|
91
95
|
await userRepository.update(userId, {
|
|
92
96
|
storeId: store.id,
|
|
93
97
|
storeSlug: store.storeSlug,
|
|
94
|
-
storeStatus: "pending",
|
|
98
|
+
storeStatus: isTester ? "approved" : "pending",
|
|
95
99
|
});
|
|
96
100
|
serverLogger.info("createStore: store created", {
|
|
97
101
|
userId,
|
|
98
102
|
storeSlug: store.storeSlug,
|
|
103
|
+
isTester,
|
|
99
104
|
});
|
|
100
105
|
return { store };
|
|
101
106
|
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
3
|
import { useCallback, useEffect, useState } from "react";
|
|
4
4
|
import { MapPin, Pencil, Plus, Trash2, Star } from "lucide-react";
|
|
5
|
-
import { Badge, Button, ConfirmDeleteModal, Div, Grid, Heading, IconButton, Row, SideDrawer, Span, Stack, Table, Thead, Tbody, Tr, Th, Td, Text } from "../../../ui";
|
|
5
|
+
import { Badge, Button, ConfirmDeleteModal, Div, Grid, Heading, IconButton, Row, SideDrawer, Span, Stack, Table, Thead, Tbody, Tr, Th, Td, Text, StickyToolbar } from "../../../ui";
|
|
6
6
|
import { FieldInput } from "../../../ui/forms/FieldInput";
|
|
7
7
|
import { FieldCheckbox } from "../../../ui/forms/FieldCheckbox";
|
|
8
8
|
import { ROW_ACTION_META, ROW_ACTION_ID } from "../../../features/products/constants/action-defs";
|
|
@@ -141,7 +141,7 @@ export function SellerAddressesView({ apiBase = SELLER_ENDPOINTS.STORE_ADDRESSES
|
|
|
141
141
|
const handleDelete = (addr) => setDeleteTargetAddr(addr);
|
|
142
142
|
const set = (key, value) => setDraft((p) => ({ ...p, [key]: value }));
|
|
143
143
|
const setField = (key) => (value) => set(key, value);
|
|
144
|
-
return (_jsxs(Div, { className: "min-h-screen", children: [
|
|
144
|
+
return (_jsxs(Div, { className: "min-h-screen", children: [_jsx(StickyToolbar, { offset: "header", tone: "default", border: true, padding: "md", children: _jsxs(Row, { justify: "between", children: [_jsxs(Stack, { gap: "none", children: [_jsx(Heading, { level: 2, size: "base", weight: "semibold", color: "primary", children: "Pickup Addresses" }), _jsx(Text, { size: "xs", color: "muted", className: "mt-0.5", children: "Manage your store's pickup and return locations" })] }), _jsxs(Button, { gap: "sm", size: "sm", onClick: openAdd, children: [_jsx(Plus, { className: "h-4 w-4" }), _jsx(Span, { children: "Add Address" })] })] }) }), _jsxs(Div, { paddingX: "x-md-lg", className: "max-w-2xl", padding: "y-lg", children: [errorMessage && (_jsx(Div, { textSize: "sm", className: "mb-4 border border-error/20", color: "error", surface: "danger-surface", padding: "inline", rounded: "xl", children: errorMessage })), isLoading ? (_jsx(Row, { justify: "center", padding: "y-4xl", children: _jsx(Div, { className: "h-6 w-6 animate-spin border-2 border-[var(--appkit-color-primary)] border-t-transparent", rounded: "full" }) })) : addresses.length === 0 ? (_jsxs(Stack, { border: "default", className: "border-2 border-dashed", padding: "y-4xl", align: "center", gap: "3", rounded: "xl", children: [_jsx(MapPin, { className: "h-8 w-8 text-zinc-300 text-[var(--appkit-color-text-muted)]" }), _jsx(Text, { size: "sm", color: "muted", 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: "default", children: _jsxs(Table, { size: "sm", children: [_jsx(Thead, { surface: "muted", children: _jsxs(Tr, { children: [_jsx(Th, { className: "text-left", padding: "sm", weight: "semibold", children: "Label" }), _jsx(Th, { className: "text-left", padding: "sm", weight: "semibold", children: "Name" }), _jsx(Th, { className: "text-left", padding: "sm", weight: "semibold", children: "City" }), _jsx(Th, { className: "text-left", padding: "sm", weight: "semibold", children: "Phone" }), _jsx(Th, { className: "text-right", padding: "sm", weight: "semibold", children: "Actions" })] }) }), _jsx(Tbody, { children: addresses.map((addr) => {
|
|
145
145
|
const isBanned = addr.banStatus === "banned";
|
|
146
146
|
return (_jsxs(Tr, { className: `border-t border-[var(--appkit-color-border)] ${deletingId === addr.id ? "opacity-50" : ""}`, children: [_jsx(Td, { padding: "sm", children: _jsxs(Row, { gap: "xs", align: "center", children: [_jsx(Span, { children: addr.label }), isBanned && _jsx(Badge, { variant: "danger", size: "sm", children: "Banned" })] }) }), _jsx(Td, { padding: "sm", children: addr.fullName }), _jsxs(Td, { padding: "sm", children: [addr.city, ", ", addr.state] }), _jsx(Td, { className: "tabular-nums", padding: "sm", children: addr.phone }), _jsx(Td, { className: "text-right", padding: "sm", children: isBanned ? (_jsx(Span, { size: "xs", color: "muted", title: "Contact support to resolve address ban", children: "Contact support" })) : (_jsxs(Row, { justify: "end", gap: "xs", 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));
|
|
147
147
|
}) })] }) }))] }))] }), _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", padding: "y-2xs", children: [saveError && (_jsx(Div, { textSize: "sm", className: "border border-error/20", color: "error", surface: "danger-surface", padding: "inlineSm", rounded: "lg", children: saveError })), _jsx(FieldInput, { name: "label", label: "Label *", hint: "e.g. Warehouse, Shop, Home", type: "text", value: draft.label, onChange: setField("label"), placeholder: "Warehouse", maxLength: 60 }), _jsxs(Grid, { cols: 2, gap: "sm", children: [_jsx(FieldInput, { name: "fullName", label: "Full Name *", type: "text", value: draft.fullName, onChange: setField("fullName"), placeholder: "Ravi Kumar", maxLength: 100 }), _jsx(FieldInput, { name: "phone", label: "Phone *", type: "tel", value: draft.phone, onChange: setField("phone"), placeholder: "+91 98765 43210", maxLength: 20 })] }), _jsx(FieldInput, { name: "addressLine1", label: "Address Line 1 *", type: "text", value: draft.addressLine1, onChange: setField("addressLine1"), placeholder: "Shop 12, Main Market", maxLength: 200 }), _jsx(FieldInput, { name: "addressLine2", label: "Address Line 2", type: "text", value: draft.addressLine2, onChange: setField("addressLine2"), placeholder: "Building / Floor (optional)", maxLength: 200 }), _jsx(FieldInput, { name: "landmark", label: "Landmark", type: "text", value: draft.landmark, onChange: setField("landmark"), placeholder: "Near metro station (optional)", maxLength: 100 }), _jsxs(Grid, { cols: 2, gap: "sm", children: [_jsx(FieldInput, { name: "city", label: "City *", type: "text", value: draft.city, onChange: setField("city"), placeholder: "Mumbai", maxLength: 100 }), _jsx(FieldInput, { name: "state", label: "State *", type: "text", value: draft.state, onChange: setField("state"), placeholder: "Maharashtra", maxLength: 100 })] }), _jsxs(Grid, { cols: 2, gap: "sm", children: [_jsx(FieldInput, { name: "postalCode", label: "Postal Code *", type: "text", value: draft.postalCode, onChange: setField("postalCode"), placeholder: "400001", maxLength: 10 }), _jsx(FieldInput, { name: "country", label: "Country *", type: "text", value: draft.country, onChange: setField("country"), placeholder: "India", maxLength: 60 })] }), _jsx(FieldCheckbox, { name: "isDefault", label: "Set as default pickup address", checked: draft.isDefault, onChange: (c) => set("isDefault", c) })] }) }), 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 }))] }));
|
|
@@ -6,7 +6,7 @@ import { sortBy } from "@mohasinac/appkit";
|
|
|
6
6
|
import React, { useState, useCallback } from "react";
|
|
7
7
|
import { useUrlTable } from "../../../react/hooks/useUrlTable";
|
|
8
8
|
import { useBulkSelection } from "../../../react/hooks/useBulkSelection";
|
|
9
|
-
import { Badge, Button, BulkActionBar, Div, FilterChipGroup, ListingFilterDrawer, ListingToolbar, Pagination, Span, Text, useToast } from "../../../ui";
|
|
9
|
+
import { Badge, Button, BulkActionBar, Div, FilterChipGroup, ListingFilterDrawer, ListingToolbar, Pagination, Span, Text, useToast, StickyToolbar } from "../../../ui";
|
|
10
10
|
import { SELLER_ENDPOINTS } from "../../../constants/api-endpoints";
|
|
11
11
|
import { ACTIONS } from "../../../_internal/shared/actions/action-registry";
|
|
12
12
|
import { buildBulkAction } from "../../../_internal/shared/actions/bulk-helpers";
|
|
@@ -172,7 +172,7 @@ export function SellerBidsView({ endpoint = SELLER_ENDPOINTS.BIDS }) {
|
|
|
172
172
|
buildBulkAction(ACTIONS.SELLER["cancel-bid"], () => void bulkCancel()),
|
|
173
173
|
];
|
|
174
174
|
useBottomActions(selection.selectedCount > 0 ? { bulk: { selectedCount: selection.selectedCount, onClearSelection: selection.clearSelection, actions: bulkActions } } : {});
|
|
175
|
-
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(
|
|
175
|
+
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(StickyToolbar, { offset: "header+pagination", tone: "translucent", border: true, padding: "toolbar", children: _jsx(Row, { justify: "center", children: _jsx(Pagination, { currentPage: currentPage, totalPages: totalPages, onPageChange: (p) => table.setPage(p) }) }) })), selection.selectedIds.length > 0 && (_jsx(StickyToolbar, { offset: "header+bulk-actions", tone: "default", border: true, padding: "sm", z: "above-toolbar", children: _jsx(BulkActionBar, { selectedCount: selection.selectedIds.length, onClearSelection: selection.clearSelection, actions: bulkActions }) })), _jsxs(Div, { paddingX: "x-sm-md", padding: "y-md", children: [errorMessage && (_jsx(Div, { textSize: "sm", className: "mb-4 border border-error/20", color: "error", surface: "danger-surface", padding: "inline", rounded: "xl", 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(Stack, { gap: "3", children: [groupedRows.length === 0 && !isLoading && (_jsx(Text, { size: "sm", color: "muted", children: "No bids found for your auctions." })), groupedRows.map((group) => {
|
|
176
176
|
const collapsed = collapsedGroups.has(group.id);
|
|
177
177
|
return (_jsxs(Div, { className: "border border-[var(--appkit-color-border)] bg-[var(--appkit-color-surface)]", rounded: "lg", children: [_jsxs(Button, { variant: "ghost", type: "button", onClick: () => toggleGroup(group.id), justify: "between", paddingX: "md", paddingY: "y-xs-tall", textSize: "sm", weight: "semibold", textColor: "default", className: "w-full 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));
|
|
178
178
|
})] }))] }), _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: "" }) })] }));
|
|
@@ -9,7 +9,7 @@ import { useUrlTable } from "../../../react/hooks/useUrlTable";
|
|
|
9
9
|
import { useBulkSelection } from "../../../react/hooks/useBulkSelection";
|
|
10
10
|
import { useActionDispatch } from "../../../react/hooks/use-action-dispatch";
|
|
11
11
|
import { SELLER_ENDPOINTS } from "../../../constants/api-endpoints";
|
|
12
|
-
import { BulkActionBar, Badge, Button, Div, FilterChipGroup, Heading, Input, ListingFilterDrawer, ListingToolbar, Pagination, ListingLayout, Select, SideDrawer, Span, Stack, Text, useToast } from "../../../ui";
|
|
12
|
+
import { BulkActionBar, Badge, Button, Div, FilterChipGroup, Heading, Input, ListingFilterDrawer, ListingToolbar, Pagination, ListingLayout, Select, SideDrawer, Span, Stack, Text, useToast, StickyToolbar } from "../../../ui";
|
|
13
13
|
import { SELLER_ORDER_STATUS_TABS } from "../../admin/constants/filter-tabs";
|
|
14
14
|
import { ACTIONS } from "../../../_internal/shared/actions/action-registry";
|
|
15
15
|
import { buildBulkAction } from "../../../_internal/shared/actions/bulk-helpers";
|
|
@@ -365,5 +365,5 @@ export function SellerOrdersView({ orderDetailApiBase = SELLER_ENDPOINTS.ORDERS,
|
|
|
365
365
|
if (hasChildren) {
|
|
366
366
|
return _jsx(ListingLayout, { portal: "seller", ...props, children: children });
|
|
367
367
|
}
|
|
368
|
-
return (_jsxs(Div, { className: "min-h-screen", children: [_jsx(ListingToolbar, { filterCount: activeFilterCount, onFiltersClick: openFilters, searchValue: searchInput, searchPlaceholder: "Search by order ID or buyer 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(
|
|
368
|
+
return (_jsxs(Div, { className: "min-h-screen", children: [_jsx(ListingToolbar, { filterCount: activeFilterCount, onFiltersClick: openFilters, searchValue: searchInput, searchPlaceholder: "Search by order ID or buyer 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(StickyToolbar, { offset: "header+pagination", tone: "translucent", border: true, padding: "toolbar", children: _jsx(Row, { justify: "center", children: _jsx(Pagination, { currentPage: currentPage, totalPages: totalPages, onPageChange: (p) => table.setPage(p) }) }) })), selection.selectedIds.length > 0 && (_jsx(StickyToolbar, { offset: "header+bulk-actions", tone: "default", border: true, padding: "sm", z: "above-toolbar", children: _jsx(BulkActionBar, { selectedCount: selection.selectedIds.length, onClearSelection: selection.clearSelection, actions: bulkActions }) })), _jsxs(Div, { paddingX: "x-sm-md", padding: "y-md", children: [errorMessage && (_jsx(Div, { textSize: "sm", className: "mb-4 border border-error/20", color: "error", surface: "danger-surface", padding: "inline", rounded: "xl", children: errorMessage })), _jsx(DataTable, { rows: rows, columns: columns, isLoading: isLoading, emptyLabel: "No orders yet", selectedIds: selection.selectedIdSet, onToggleSelect: selection.toggle, onToggleSelectAll: () => selection.toggleAll(), renderRowActions: renderRowActions })] }), _jsx(ListingFilterDrawer, { open: filterOpen, onClose: () => setFilterOpen(false), onApply: applyFilters, onClear: clearFilters, activeCount: activeFilterCount, children: _jsx(FilterChipGroup, { label: "Status", tabs: STATUS_OPTIONS, value: pendingFilters.status ?? "", onChange: (id) => setPendingFilters((p) => ({ ...p, status: id })) }) }), selectedOrderId && (_jsx(OrderDetailDrawer, { orderId: selectedOrderId, apiBase: orderDetailApiBase, onClose: () => setSelectedOrderId(null) })), setLocationOpen && (_jsx(PhysicalLocationModal, { count: selection.selectedIds.length, onSave: handleSetLocation, onClose: () => setSetLocationOpen(false) }))] }));
|
|
369
369
|
}
|
|
@@ -10,7 +10,7 @@ import { Eye, EyeOff, Pencil, Trash2, Printer, MapPin } from "lucide-react";
|
|
|
10
10
|
import { PhysicalLocationModal } from "./PhysicalLocationModal";
|
|
11
11
|
import { useUrlTable } from "../../../react/hooks/useUrlTable";
|
|
12
12
|
import { useBulkSelection } from "../../../react/hooks/useBulkSelection";
|
|
13
|
-
import { Alert, Badge, BulkActionBar, Button, Div, ListingToolbar, ListingLayout, Pagination, Row, Select, Span, Text, useToast } from "../../../ui";
|
|
13
|
+
import { Alert, Badge, BulkActionBar, Button, Div, ListingToolbar, ListingLayout, Pagination, Row, Select, Span, Text, useToast, StickyToolbar } from "../../../ui";
|
|
14
14
|
import { MediaImage } from "../../media/MediaImage";
|
|
15
15
|
import { SELLER_ENDPOINTS } from "../../../constants/api-endpoints";
|
|
16
16
|
import { SELLER_PRODUCT_STATUS_TABS } from "../../admin/constants/filter-tabs";
|
|
@@ -300,7 +300,7 @@ export function SellerProductsView({ onDeleteProduct, onCreateClick, children, .
|
|
|
300
300
|
};
|
|
301
301
|
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: [
|
|
302
302
|
{ label: "Show sold", active: showSold, onChange: (next) => table.set("showSold", next ? "true" : "") },
|
|
303
|
-
], extra: onCreateClick ? (_jsx(Button, { variant: "primary", size: "sm", onClick: onCreateClick, children: "+ New Listing" })) : null }), _jsx(TypeDropdown, { active: listingKind, onChange: handleKindChange }), totalPages > 1 && (_jsx(
|
|
303
|
+
], extra: onCreateClick ? (_jsx(Button, { variant: "primary", size: "sm", onClick: onCreateClick, children: "+ New Listing" })) : null }), _jsx(TypeDropdown, { active: listingKind, onChange: handleKindChange }), totalPages > 1 && (_jsx(StickyToolbar, { offset: "header+pagination", tone: "default", border: true, padding: "sm", children: _jsx(Row, { justify: "center", children: _jsx(Pagination, { currentPage: currentPage, totalPages: totalPages, onPageChange: (p) => table.setPage(p) }) }) })), selection.selectedIds.length > 0 && (_jsx(StickyToolbar, { offset: "header+bulk-actions", tone: "default", border: true, padding: "sm", z: "above-toolbar", children: _jsx(BulkActionBar, { selectedCount: selection.selectedIds.length, onClearSelection: selection.clearSelection, actions: bulkActions }) })), _jsxs(Div, { paddingX: "x-sm-lg-md", padding: "y-md", 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"
|
|
304
304
|
? `No ${listingKind} listings found`
|
|
305
305
|
: "No products listed yet", selectedIds: selection.selectedIdSet, onToggleSelect: selection.toggle, onToggleSelectAll: () => selection.toggleAll(), getRowHref: (row) =>
|
|
306
306
|
// S-STORE-2-D — row click → public detail/preview, not edit.
|
|
@@ -23,6 +23,8 @@ interface StoreSidebarProps {
|
|
|
23
23
|
/** Toggle callback for the desktop sidebar tab (open ↔ close). */
|
|
24
24
|
onToggle?: () => void;
|
|
25
25
|
className?: string;
|
|
26
|
+
/** Optional slot rendered below the scrollable nav, e.g. cross-dashboard links. */
|
|
27
|
+
renderFooter?: () => React.ReactNode;
|
|
26
28
|
}
|
|
27
|
-
export declare function StoreSidebar({ items, groups, activeHref, storeName, storeLogoURL, mobileOpen, desktopOpen, variant, onCloseMobile, onToggle, }: StoreSidebarProps): React.JSX.Element;
|
|
29
|
+
export declare function StoreSidebar({ items, groups, activeHref, storeName, storeLogoURL, mobileOpen, desktopOpen, variant, onCloseMobile, onToggle, renderFooter, }: StoreSidebarProps): React.JSX.Element;
|
|
28
30
|
export {};
|
|
@@ -32,13 +32,14 @@ function FlatContent({ items, activeHref, storeName, storeLogoURL, onItemClick,
|
|
|
32
32
|
}) }) })] }));
|
|
33
33
|
}
|
|
34
34
|
function GroupsContent({ groups, activeHref, storeName, storeLogoURL, onItemClick, }) {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
g.defaultOpen ?? g.items.some((i) => activeHref === i.href)
|
|
38
|
-
|
|
39
|
-
|
|
35
|
+
// Accordion — only one group open at a time.
|
|
36
|
+
const [openGroup, setOpenGroup] = useState(() => {
|
|
37
|
+
const match = groups.find((g) => g.defaultOpen ?? g.items.some((i) => activeHref === i.href));
|
|
38
|
+
return match?.title ?? null;
|
|
39
|
+
});
|
|
40
|
+
const toggle = useCallback((title) => setOpenGroup((p) => (p === title ? null : title)), []);
|
|
40
41
|
return (_jsxs(_Fragment, { children: [storeName && (_jsxs(Row, { border: "bottom-subtle", gap: "3", padding: "inline", children: [storeLogoURL ? (_jsx(Div, { className: CLS_STORE_AVATAR, children: _jsx(MediaImage, { src: storeLogoURL, alt: storeName, size: "thumbnail" }) })) : (_jsx(Div, { className: CLS_STORE_FALLBACK, children: storeName[0]?.toUpperCase() })), _jsx(Text, { className: CLS_STORE_NAME, children: storeName })] })), _jsx(Nav, { "aria-label": "Store navigation", padding: "y-xs", children: groups.map((group) => {
|
|
41
|
-
const isOpen =
|
|
42
|
+
const isOpen = openGroup === group.title;
|
|
42
43
|
const hasActive = group.items.some((i) => activeHref === i.href);
|
|
43
44
|
return (_jsxs(Div, { className: "mb-0.5", children: [_jsx(Button, { type: "button", variant: "ghost", onClick: () => toggle(group.title), paddingX: "md", paddingY: "sm", weight: "semibold", rounded: "none", className: `w-full text-[0.6875rem] uppercase tracking-widest transition-colors ${hasActive && !isOpen
|
|
44
45
|
? CLS_NAV_ICON_ACTIVE
|
|
@@ -48,7 +49,7 @@ function GroupsContent({ groups, activeHref, storeName, storeLogoURL, onItemClic
|
|
|
48
49
|
function DrawerPanel({ title, onClose, children }) {
|
|
49
50
|
return (_jsxs(Div, { className: "hidden lg:block", children: [_jsx(Div, { surface: "overlay-xs", className: "fixed inset-0 z-40 backdrop-blur-sm", onClick: onClose, "aria-hidden": "true" }), _jsxs(Stack, { border: "default", shadow: "2xl", role: "dialog", "aria-modal": "true", "aria-label": title, className: "fixed top-0 right-0 z-50 h-full w-64 border-l", surface: "default", children: [_jsxs(Row, { border: "bottom-subtle", paddingY: "y-sm-tall", className: "shrink-0", padding: "x-md", align: "center", justify: "between", children: [_jsx(Span, { size: "xs", weight: "semibold", transform: "uppercase", color: "muted", children: title }), _jsx(IconButton, { "aria-label": "Close", variant: "ghost", size: "sm", onClick: onClose, icon: _jsx("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", "aria-hidden": "true", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) }) })] }), _jsx(Div, { className: `flex-1 ${__O.yAuto}`, children: children })] })] }));
|
|
50
51
|
}
|
|
51
|
-
export function StoreSidebar({ items, groups, activeHref, storeName, storeLogoURL, mobileOpen = false, desktopOpen = false, variant = "overlay", onCloseMobile, onToggle, }) {
|
|
52
|
+
export function StoreSidebar({ items, groups, activeHref, storeName, storeLogoURL, mobileOpen = false, desktopOpen = false, variant = "overlay", onCloseMobile, onToggle, renderFooter, }) {
|
|
52
53
|
const close = onCloseMobile ?? (() => { });
|
|
53
54
|
const [mounted, setMounted] = useState(false);
|
|
54
55
|
useEffect(() => { setMounted(true); }, []);
|
|
@@ -60,7 +61,7 @@ export function StoreSidebar({ items, groups, activeHref, storeName, storeLogoUR
|
|
|
60
61
|
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 }));
|
|
61
62
|
if (variant === "sidebar") {
|
|
62
63
|
const handleToggle = onToggle ?? close;
|
|
63
|
-
return (_jsxs(_Fragment, { children: [desktopOpen && (_jsx(Div, { surface: "overlay-xs", className: "hidden lg:block fixed inset-0 backdrop-blur-[2px] z-30", onClick: handleToggle, "aria-hidden": "true" })), _jsxs(Div, { className: `hidden lg:flex fixed left-0 z-40 transition-transform duration-300 top-[var(--header-height,3.5rem)] h-[calc(100vh-var(--header-height,3.5rem))] w-[18rem] ${desktopOpen ? "translate-x-0" : "-translate-x-[calc(100%-1.25rem)]"}`, children: [_jsxs(Stack, { border: "default", surface: "sidePanel", className: `flex-1 border-r ${__O.hidden}`, shadow: "xl", children: [_jsx(Div, { border: "bottom-subtle", paddingY: "y-sm-tall", className: "shrink-0", padding: "x-md", children: _jsxs(Row, { className: "min-w-0", align: "center", gap: "3", children: [storeLogoURL ? (_jsx(Div, { className: CLS_STORE_AVATAR, children: _jsx(MediaImage, { src: storeLogoURL, alt: storeName ?? "", size: "thumbnail" }) })) : (_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: "lg: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 })) }) })] }));
|
|
64
|
+
return (_jsxs(_Fragment, { children: [desktopOpen && (_jsx(Div, { surface: "overlay-xs", className: "hidden lg:block fixed inset-0 backdrop-blur-[2px] z-30", onClick: handleToggle, "aria-hidden": "true" })), _jsxs(Div, { className: `hidden lg:flex fixed left-0 z-40 transition-transform duration-300 top-[var(--header-height,3.5rem)] h-[calc(100vh-var(--header-height,3.5rem))] w-[18rem] ${desktopOpen ? "translate-x-0" : "-translate-x-[calc(100%-1.25rem)]"}`, children: [_jsxs(Stack, { border: "default", surface: "sidePanel", className: `flex-1 border-r ${__O.hidden}`, shadow: "xl", children: [_jsx(Div, { border: "bottom-subtle", paddingY: "y-sm-tall", className: "shrink-0", padding: "x-md", children: _jsxs(Row, { className: "min-w-0", align: "center", gap: "3", children: [storeLogoURL ? (_jsx(Div, { className: CLS_STORE_AVATAR, children: _jsx(MediaImage, { src: storeLogoURL, alt: storeName ?? "", size: "thumbnail" }) })) : (_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 }), renderFooter && _jsx(Div, { border: "top", padding: "inline", children: renderFooter() })] }), _jsx(SidebarCollapseToggle, { expanded: desktopOpen, onToggle: handleToggle })] }), _jsx(Div, { className: "lg: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 })) }) })] }));
|
|
64
65
|
}
|
|
65
66
|
return (_jsxs(_Fragment, { children: [mounted && mobileOpen &&
|
|
66
67
|
createPortal(_jsx(DrawerPanel, { title: panelTitle, onClose: close, children: navContent }), document.body), _jsx(Div, { className: "lg: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 })) }) })] }));
|
|
@@ -7,7 +7,7 @@ import { useEntityDelete } from "../../../react/hooks/useEntityDelete";
|
|
|
7
7
|
import { Plus } from "lucide-react";
|
|
8
8
|
import { useUrlTable } from "../../../react/hooks/useUrlTable";
|
|
9
9
|
import { useBulkSelection } from "../../../react/hooks/useBulkSelection";
|
|
10
|
-
import { BulkActionBar, Button, ConfirmDeleteModal, DataTable, Div, ListingToolbar, Pagination, RowActionMenu, Text, useToast, } from "../../../ui";
|
|
10
|
+
import { BulkActionBar, Button, ConfirmDeleteModal, DataTable, Div, ListingToolbar, Pagination, RowActionMenu, Text, useToast, StickyToolbar, } from "../../../ui";
|
|
11
11
|
import { useBottomActions } from "../../layout";
|
|
12
12
|
import { SELLER_ENDPOINTS } from "../../../constants/api-endpoints";
|
|
13
13
|
import { ACTIONS } from "../../../_internal/shared/actions/action-registry";
|
|
@@ -101,7 +101,7 @@ export function SellerStoreCategoriesView({ onCreateClick, onEditClick, onDelete
|
|
|
101
101
|
window.location.href = String(ROUTES.STORE.STORE_CATEGORIES_NEW);
|
|
102
102
|
};
|
|
103
103
|
useBottomActions(selection.selectedCount > 0 ? { bulk: { selectedCount: selection.selectedCount, onClearSelection: selection.clearSelection, actions: bulkActions } } : {});
|
|
104
|
-
return (_jsxs(Div, { className: "min-h-screen", children: [_jsx(ListingToolbar, { filterCount: 0, searchValue: searchInput, searchPlaceholder: "Search categories by label...", onSearchChange: setSearchInput, onSearchCommit: commitSearch, sortValue: table.get(TABLE_KEYS.SORT) || DEFAULT_SORT, sortOptions: SORT_OPTIONS, onSortChange: (v) => { table.set(TABLE_KEYS.SORT, v); }, showTableView: true, view: "table", onViewChange: () => { }, onResetAll: resetAll, hasActiveState: hasActiveState, extra: _jsxs(Button, { gap: "sm", size: "sm", onClick: handleNavigateNew, children: [_jsx(Plus, { className: "h-4 w-4" }), _jsx(Span, { children: "New Category" })] }) }), totalPages > 1 && (_jsx(
|
|
104
|
+
return (_jsxs(Div, { className: "min-h-screen", children: [_jsx(ListingToolbar, { filterCount: 0, searchValue: searchInput, searchPlaceholder: "Search categories by label...", onSearchChange: setSearchInput, onSearchCommit: commitSearch, sortValue: table.get(TABLE_KEYS.SORT) || DEFAULT_SORT, sortOptions: SORT_OPTIONS, onSortChange: (v) => { table.set(TABLE_KEYS.SORT, v); }, showTableView: true, view: "table", onViewChange: () => { }, onResetAll: resetAll, hasActiveState: hasActiveState, extra: _jsxs(Button, { gap: "sm", size: "sm", onClick: handleNavigateNew, children: [_jsx(Plus, { className: "h-4 w-4" }), _jsx(Span, { children: "New Category" })] }) }), totalPages > 1 && (_jsx(StickyToolbar, { offset: "header+pagination", tone: "translucent", border: true, padding: "toolbar", children: _jsx(Row, { justify: "center", children: _jsx(Pagination, { currentPage: currentPage, totalPages: totalPages, onPageChange: (p) => table.setPage(p) }) }) })), selection.selectedCount > 0 && (_jsx(BulkActionBar, { selectedCount: selection.selectedCount, actions: bulkActions, onClearSelection: selection.clearSelection })), _jsxs(Div, { paddingX: "x-sm-md", padding: "y-md", children: [errorMessage && (_jsx(Div, { textSize: "sm", className: "mb-4 border border-error/20", color: "error", surface: "danger-surface", padding: "inline", rounded: "xl", children: errorMessage })), isLoading ? (_jsx(Stack, { gap: "sm", children: Array.from({ length: 5 }).map((_, i) => (_jsx(Div, { className: "h-14 animate-pulse", border: "subtle", surface: "muted", rounded: "xl" }, i))) })) : rows.length === 0 ? (_jsx(Div, { className: "text-center", padding: "y-4xl", children: _jsx(Text, { color: "faint", children: "No categories yet \u2014 add your first storefront category" }) })) : (_jsx(DataTable, { columns: COLUMNS, data: rows, keyExtractor: (r) => r.id, selectable: bulkActions.length > 0, selectedIds: selection.selectedIds, onSelectionChange: (ids) => selection.setSelectedIds(ids), actions: (row) => (_jsx(RowActionMenu, { actions: [
|
|
105
105
|
{
|
|
106
106
|
label: ACTIONS.STORE["edit-listing"].label,
|
|
107
107
|
onClick: () => onEditClick
|
|
@@ -7,7 +7,7 @@ import { useEntityDelete } from "../../../react/hooks/useEntityDelete";
|
|
|
7
7
|
import { Plus } from "lucide-react";
|
|
8
8
|
import { useUrlTable } from "../../../react/hooks/useUrlTable";
|
|
9
9
|
import { useBulkSelection } from "../../../react/hooks/useBulkSelection";
|
|
10
|
-
import { BulkActionBar, Button, ConfirmDeleteModal, DataTable, Div, FilterDrawer, Input, Label, ListingToolbar, Pagination, RowActionMenu, Select, SideDrawer, Span, Stack, Text, useToast, } from "../../../ui";
|
|
10
|
+
import { BulkActionBar, Button, ConfirmDeleteModal, DataTable, Div, FilterDrawer, Input, Label, ListingToolbar, Pagination, RowActionMenu, Select, SideDrawer, Span, Stack, Text, useToast, StickyToolbar, } from "../../../ui";
|
|
11
11
|
import { useBottomActions } from "../../layout";
|
|
12
12
|
import { SELLER_ENDPOINTS } from "../../../constants/api-endpoints";
|
|
13
13
|
import { ACTIONS } from "../../../_internal/shared/actions/action-registry";
|
|
@@ -254,7 +254,7 @@ export function SellerTemplatesView({ onDelete, onBulkDelete, onDuplicate, }) {
|
|
|
254
254
|
}),
|
|
255
255
|
];
|
|
256
256
|
useBottomActions(selection.selectedCount > 0 ? { bulk: { selectedCount: selection.selectedCount, onClearSelection: selection.clearSelection, actions: bulkActions } } : {});
|
|
257
|
-
return (_jsxs(Div, { className: "min-h-screen", children: [_jsx(ListingToolbar, { filterCount: filterActiveCount, onFiltersClick: openFilters, searchValue: searchInput, searchPlaceholder: "Search templates by name...", onSearchChange: setSearchInput, onSearchCommit: commitSearch, sortValue: sort, sortOptions: SORT_OPTIONS, onSortChange: (v) => { table.set(TABLE_KEYS.SORT, v); }, showTableView: true, view: "table", onViewChange: () => { }, onResetAll: resetAll, hasActiveState: hasActiveState, extra: _jsxs(Button, { gap: "sm", size: "sm", onClick: openCreate, children: [_jsx(Plus, { className: "h-4 w-4" }), _jsx(Span, { children: "New Template" })] }) }), totalPages > 1 && (_jsx(
|
|
257
|
+
return (_jsxs(Div, { className: "min-h-screen", children: [_jsx(ListingToolbar, { filterCount: filterActiveCount, onFiltersClick: openFilters, searchValue: searchInput, searchPlaceholder: "Search templates by name...", onSearchChange: setSearchInput, onSearchCommit: commitSearch, sortValue: sort, sortOptions: SORT_OPTIONS, onSortChange: (v) => { table.set(TABLE_KEYS.SORT, v); }, showTableView: true, view: "table", onViewChange: () => { }, onResetAll: resetAll, hasActiveState: hasActiveState, extra: _jsxs(Button, { gap: "sm", size: "sm", onClick: openCreate, children: [_jsx(Plus, { className: "h-4 w-4" }), _jsx(Span, { children: "New Template" })] }) }), totalPages > 1 && (_jsx(StickyToolbar, { offset: "header+pagination", tone: "translucent", border: true, padding: "toolbar", children: _jsx(Row, { justify: "center", children: _jsx(Pagination, { currentPage: safePage, totalPages: totalPages, onPageChange: (p) => table.setPage(p) }) }) })), selection.selectedCount > 0 && (_jsx(BulkActionBar, { selectedCount: selection.selectedCount, actions: bulkActions, onClearSelection: selection.clearSelection })), _jsxs(Div, { paddingX: "x-sm-md", padding: "y-md", children: [errorMessage && (_jsx(Div, { textSize: "sm", className: "mb-4 border border-error/20", color: "error", surface: "danger-surface", padding: "inline", rounded: "xl", children: errorMessage })), isLoading ? (_jsx(Stack, { gap: "sm", children: Array.from({ length: 5 }).map((_, i) => (_jsx(Div, { className: "h-14 animate-pulse", border: "subtle", surface: "muted", rounded: "xl" }, i))) })) : pageRows.length === 0 ? (_jsx(Div, { className: "text-center", padding: "y-4xl", children: _jsx(Text, { color: "faint", children: q || conditionFilter
|
|
258
258
|
? "No templates match your search or filters"
|
|
259
259
|
: "No templates yet — add your first product template" }) })) : (_jsx(DataTable, { columns: COLUMNS, data: pageRows, keyExtractor: (r) => r.id, selectable: bulkActions.length > 0, selectedIds: selection.selectedIds, onSelectionChange: (ids) => selection.setSelectedIds(ids), actions: (row) => (_jsx(RowActionMenu, { actions: [
|
|
260
260
|
{
|