@mohasinac/appkit 2.7.59 → 2.8.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/filters/filter-load-options.d.ts +4 -5
- package/dist/_internal/server/features/auctions/og.js +8 -32
- package/dist/_internal/server/features/blog/og.js +10 -49
- package/dist/_internal/server/features/checkout/actions.js +6 -0
- package/dist/_internal/server/features/classified/og.js +9 -51
- package/dist/_internal/server/features/digital-code/actions.d.ts +11 -0
- package/dist/_internal/server/features/digital-code/actions.js +30 -0
- package/dist/_internal/server/features/digital-code/index.d.ts +1 -0
- package/dist/_internal/server/features/digital-code/index.js +1 -0
- package/dist/_internal/server/features/digital-code/og.js +9 -51
- package/dist/_internal/server/features/events/og.js +10 -49
- package/dist/_internal/server/features/item-requests/data.d.ts +17 -0
- package/dist/_internal/server/features/item-requests/data.js +20 -0
- package/dist/_internal/server/features/item-requests/index.d.ts +2 -0
- package/dist/_internal/server/features/item-requests/index.js +2 -0
- package/dist/_internal/server/features/item-requests/og.d.ts +40 -0
- package/dist/_internal/server/features/item-requests/og.js +136 -0
- package/dist/_internal/server/features/live/actions.d.ts +5 -0
- package/dist/_internal/server/features/live/actions.js +24 -0
- package/dist/_internal/server/features/live/index.d.ts +1 -0
- package/dist/_internal/server/features/live/index.js +1 -0
- package/dist/_internal/server/features/live/og.js +9 -51
- package/dist/_internal/server/features/media/contextGuards.js +19 -8
- package/dist/_internal/server/features/pre-orders/og.js +8 -32
- package/dist/_internal/server/features/prize-draws/data.d.ts +17 -0
- package/dist/_internal/server/features/prize-draws/data.js +20 -0
- package/dist/_internal/server/features/prize-draws/index.d.ts +2 -0
- package/dist/_internal/server/features/prize-draws/index.js +2 -0
- package/dist/_internal/server/features/prize-draws/og.d.ts +30 -0
- package/dist/_internal/server/features/prize-draws/og.js +50 -0
- package/dist/_internal/server/features/products/og.js +8 -33
- package/dist/_internal/server/features/seo/og-layout.d.ts +42 -0
- package/dist/_internal/server/features/seo/og-layout.js +69 -0
- package/dist/_internal/server/features/stores/og.js +8 -41
- package/dist/_internal/server/features/sublisting-categories/og.js +11 -42
- package/dist/client.d.ts +10 -6
- package/dist/client.js +7 -3
- package/dist/constants/index.d.ts +4 -0
- package/dist/constants/index.js +2 -0
- package/dist/constants/notification-types.d.ts +20 -0
- package/dist/constants/notification-types.js +37 -0
- package/dist/constants/pagination-presets.d.ts +39 -0
- package/dist/constants/pagination-presets.js +38 -0
- package/dist/errors/messages.d.ts +0 -4
- package/dist/errors/messages.js +0 -4
- package/dist/features/account/components/UserOffersPanel.js +1 -1
- package/dist/features/account/components/UserSupportView.d.ts +1 -2
- package/dist/features/account/components/UserSupportView.js +9 -1
- package/dist/features/admin/actions/admin-actions.js +16 -1
- package/dist/features/admin/components/AdminAllEventEntriesView.d.ts +2 -3
- package/dist/features/admin/components/AdminAllEventEntriesView.js +50 -83
- package/dist/features/admin/components/AdminBidsView.d.ts +2 -3
- package/dist/features/admin/components/AdminBidsView.js +64 -98
- package/dist/features/admin/components/AdminBlogView.d.ts +3 -7
- package/dist/features/admin/components/AdminBlogView.js +53 -83
- package/dist/features/admin/components/AdminBrandsView.d.ts +2 -3
- package/dist/features/admin/components/AdminBrandsView.js +84 -83
- package/dist/features/admin/components/AdminBundlesView.js +82 -125
- package/dist/features/admin/components/AdminCarouselView.d.ts +2 -2
- package/dist/features/admin/components/AdminCarouselView.js +17 -52
- package/dist/features/admin/components/AdminCartsView.d.ts +2 -3
- package/dist/features/admin/components/AdminCartsView.js +39 -88
- package/dist/features/admin/components/AdminCategoriesView.d.ts +3 -3
- package/dist/features/admin/components/AdminCategoriesView.js +98 -92
- package/dist/features/admin/components/AdminCategoryEditorView.js +2 -2
- package/dist/features/admin/components/AdminClassifiedView.d.ts +3 -0
- package/dist/features/admin/components/AdminClassifiedView.js +44 -0
- package/dist/features/admin/components/AdminContactView.d.ts +2 -2
- package/dist/features/admin/components/AdminContactView.js +104 -111
- package/dist/features/admin/components/AdminCouponsView.d.ts +3 -6
- package/dist/features/admin/components/AdminCouponsView.js +66 -86
- package/dist/features/admin/components/AdminDigitalCodesView.d.ts +3 -0
- package/dist/features/admin/components/AdminDigitalCodesView.js +51 -0
- package/dist/features/admin/components/AdminFaqsView.d.ts +4 -4
- package/dist/features/admin/components/AdminFaqsView.js +77 -33
- package/dist/features/admin/components/AdminFeaturesView.d.ts +2 -3
- package/dist/features/admin/components/AdminFeaturesView.js +57 -70
- package/dist/features/admin/components/AdminGroupedListingsView.d.ts +3 -0
- package/dist/features/admin/components/AdminGroupedListingsView.js +43 -0
- package/dist/features/admin/components/AdminHistoryView.d.ts +2 -3
- package/dist/features/admin/components/AdminHistoryView.js +35 -52
- package/dist/features/admin/components/AdminListingScaffold.d.ts +2 -2
- package/dist/features/admin/components/AdminListingScaffold.js +3 -3
- package/dist/features/admin/components/AdminLiveView.d.ts +3 -0
- package/dist/features/admin/components/AdminLiveView.js +50 -0
- package/dist/features/admin/components/AdminNewsletterView.d.ts +2 -2
- package/dist/features/admin/components/AdminNewsletterView.js +67 -97
- package/dist/features/admin/components/AdminNotificationsView.d.ts +2 -3
- package/dist/features/admin/components/AdminNotificationsView.js +67 -93
- package/dist/features/admin/components/AdminOrderEditorView.js +10 -10
- package/dist/features/admin/components/AdminOrdersView.d.ts +2 -3
- package/dist/features/admin/components/AdminOrdersView.js +93 -107
- package/dist/features/admin/components/AdminPayoutsView.d.ts +2 -3
- package/dist/features/admin/components/AdminPayoutsView.js +51 -91
- package/dist/features/admin/components/AdminPrizeDrawsView.d.ts +2 -3
- package/dist/features/admin/components/AdminPrizeDrawsView.js +39 -76
- package/dist/features/admin/components/AdminProductEditorView.js +3 -3
- package/dist/features/admin/components/AdminProductsView.d.ts +4 -4
- package/dist/features/admin/components/AdminProductsView.js +167 -163
- package/dist/features/admin/components/AdminReturnRequestsView.d.ts +1 -1
- package/dist/features/admin/components/AdminReturnRequestsView.js +64 -66
- package/dist/features/admin/components/AdminReviewsView.d.ts +3 -7
- package/dist/features/admin/components/AdminReviewsView.js +94 -110
- package/dist/features/admin/components/AdminScammersView.d.ts +2 -3
- package/dist/features/admin/components/AdminScammersView.js +53 -97
- package/dist/features/admin/components/AdminSectionsView.js +1 -1
- package/dist/features/admin/components/AdminSessionsView.d.ts +2 -3
- package/dist/features/admin/components/AdminSessionsView.js +62 -89
- package/dist/features/admin/components/AdminStoreAddressesView.d.ts +1 -1
- package/dist/features/admin/components/AdminStoreAddressesView.js +39 -53
- package/dist/features/admin/components/AdminStoreEditorView.js +21 -8
- package/dist/features/admin/components/AdminStoresView.d.ts +2 -3
- package/dist/features/admin/components/AdminStoresView.js +67 -99
- package/dist/features/admin/components/AdminSublistingCategoriesView.d.ts +1 -1
- package/dist/features/admin/components/AdminSublistingCategoriesView.js +28 -44
- package/dist/features/admin/components/AdminSupportTicketDetailView.d.ts +10 -1
- package/dist/features/admin/components/AdminSupportTicketDetailView.js +191 -5
- package/dist/features/admin/components/AdminSupportTicketsView.d.ts +2 -3
- package/dist/features/admin/components/AdminSupportTicketsView.js +65 -96
- package/dist/features/admin/components/AdminTeamView.d.ts +2 -2
- package/dist/features/admin/components/AdminTeamView.js +40 -74
- package/dist/features/admin/components/AdminUserEditorView.d.ts +11 -1
- package/dist/features/admin/components/AdminUserEditorView.js +80 -6
- package/dist/features/admin/components/AdminUsersView.d.ts +2 -3
- package/dist/features/admin/components/AdminUsersView.js +108 -100
- package/dist/features/admin/components/AdminViewCards.d.ts +1 -1
- package/dist/features/admin/components/AdminWishlistsView.d.ts +2 -3
- package/dist/features/admin/components/AdminWishlistsView.js +36 -62
- package/dist/features/admin/components/DataListingView.d.ts +122 -0
- package/dist/features/admin/components/DataListingView.js +66 -0
- package/dist/features/admin/components/index.d.ts +10 -4
- package/dist/features/admin/components/index.js +6 -2
- package/dist/features/admin/constants/filter-tabs.d.ts +23 -17
- package/dist/features/admin/constants/filter-tabs.js +21 -17
- package/dist/features/admin/hooks/useAdminListing.d.ts +1 -0
- package/dist/features/admin/hooks/useAdminListing.js +1 -1
- package/dist/features/admin/schemas/firestore.js +6 -7
- package/dist/features/auctions/server.d.ts +0 -1
- package/dist/features/auctions/server.js +0 -1
- package/dist/features/auth/actions/realtime-token-actions.js +1 -1
- package/dist/features/auth/repository/user.repository.js +1 -1
- package/dist/features/cart/repository/cart.repository.d.ts +4 -1
- package/dist/features/cart/repository/cart.repository.js +12 -0
- package/dist/features/checkout/hooks/useCheckoutApi.d.ts +0 -2
- package/dist/features/checkout/index.d.ts +1 -1
- package/dist/features/events/components/AdminEventsView.d.ts +3 -3
- package/dist/features/events/components/AdminEventsView.js +50 -86
- package/dist/features/events/components/EventOfferCard.d.ts +19 -0
- package/dist/features/events/components/EventOfferCard.js +29 -0
- package/dist/features/events/components/EventRaffleEntryForm.d.ts +25 -0
- package/dist/features/events/components/EventRaffleEntryForm.js +37 -0
- package/dist/features/events/components/EventRafflesSection.d.ts +1 -4
- package/dist/features/events/components/EventRafflesSection.js +17 -6
- package/dist/features/events/components/EventSaleBanner.d.ts +21 -0
- package/dist/features/events/components/EventSaleBanner.js +18 -0
- package/dist/features/events/components/index.d.ts +6 -0
- package/dist/features/events/components/index.js +4 -0
- package/dist/features/events/repository/event-entry.repository.d.ts +5 -0
- package/dist/features/events/repository/event-entry.repository.js +7 -0
- package/dist/features/filters/AsyncFacetSection.d.ts +1 -1
- package/dist/features/homepage/components/FAQSection.d.ts +0 -5
- package/dist/features/homepage/lib/live-stats.js +1 -1
- package/dist/features/homepage/schemas/firestore.d.ts +0 -2
- package/dist/features/layout/index.d.ts +0 -2
- package/dist/features/layout/index.js +0 -1
- package/dist/features/pre-orders/server.d.ts +0 -1
- package/dist/features/pre-orders/server.js +0 -1
- package/dist/features/products/components/GroupSettingsPanel.js +2 -2
- package/dist/features/products/components/PrizeDrawItemsEditor.js +2 -2
- package/dist/features/products/components/PrizeDrawsSection.d.ts +1 -4
- package/dist/features/products/components/PrizeDrawsSection.js +17 -6
- package/dist/features/products/components/PrizeRevealModal.js +1 -1
- package/dist/features/products/components/ProductCardMetadataSection.d.ts +11 -0
- package/dist/features/products/components/ProductCardMetadataSection.js +25 -0
- package/dist/features/products/components/ProductDetailPageView.js +3 -1
- package/dist/features/products/components/ProductFeaturesSelector.js +1 -1
- package/dist/features/products/components/ProductGradingTab.d.ts +13 -0
- package/dist/features/products/components/ProductGradingTab.js +25 -0
- package/dist/features/products/components/ProductGrid.js +14 -2
- package/dist/features/products/components/ProductTabsShell.d.ts +5 -1
- package/dist/features/products/components/ProductTabsShell.js +6 -1
- package/dist/features/products/components/index.d.ts +4 -0
- package/dist/features/products/components/index.js +3 -0
- package/dist/features/products/constants/action-defs.d.ts +5 -0
- package/dist/features/products/constants/action-defs.js +52 -32
- package/dist/features/products/constants/sieve.d.ts +24 -4
- package/dist/features/products/constants/sieve.js +20 -11
- package/dist/features/products/schemas/firestore.d.ts +17 -0
- package/dist/features/products/schemas/product-features.validators.d.ts +2 -2
- package/dist/features/products/schemas/product-templates.d.ts +2 -4
- package/dist/features/products/types/index.d.ts +4 -0
- package/dist/features/promotions/server.d.ts +0 -1
- package/dist/features/promotions/server.js +0 -1
- package/dist/features/search/api/route.js +44 -1
- package/dist/features/search/components/Search.js +2 -0
- package/dist/features/search/hooks/useNavSuggestions.d.ts +5 -1
- package/dist/features/search/hooks/useNavSuggestions.js +31 -4
- package/dist/features/seller/components/BrandInlineSelect.js +2 -2
- package/dist/features/seller/components/CategoryInlineSelect.js +2 -2
- package/dist/features/seller/components/SellerAddressesView.js +1 -1
- package/dist/features/seller/components/SellerAuctionsView.d.ts +3 -3
- package/dist/features/seller/components/SellerAuctionsView.js +60 -90
- package/dist/features/seller/components/SellerBidsView.js +1 -1
- package/dist/features/seller/components/SellerBundlesView.js +64 -89
- package/dist/features/seller/components/SellerClassifiedView.js +67 -90
- package/dist/features/seller/components/SellerCouponEditorView.js +1 -1
- package/dist/features/seller/components/SellerCouponsView.d.ts +2 -2
- package/dist/features/seller/components/SellerCouponsView.js +45 -84
- package/dist/features/seller/components/SellerDigitalCodesView.js +63 -88
- package/dist/features/seller/components/SellerGroupedListingsView.js +33 -49
- package/dist/features/seller/components/SellerLiveView.js +63 -84
- package/dist/features/seller/components/SellerOffersPanel.js +1 -1
- package/dist/features/seller/components/SellerOffersView.d.ts +2 -2
- package/dist/features/seller/components/SellerOffersView.js +37 -69
- package/dist/features/seller/components/SellerOrdersView.d.ts +2 -2
- package/dist/features/seller/components/SellerOrdersView.js +4 -4
- package/dist/features/seller/components/SellerPayoutMethodsView.js +1 -1
- package/dist/features/seller/components/SellerPayoutsView.d.ts +2 -2
- package/dist/features/seller/components/SellerPayoutsView.js +34 -68
- package/dist/features/seller/components/SellerPreOrdersView.d.ts +2 -2
- package/dist/features/seller/components/SellerPreOrdersView.js +49 -82
- package/dist/features/seller/components/SellerPrizeDrawsView.d.ts +2 -2
- package/dist/features/seller/components/SellerPrizeDrawsView.js +49 -82
- package/dist/features/seller/components/SellerProductShell.d.ts +1 -1
- package/dist/features/seller/components/SellerProductsView.d.ts +2 -2
- package/dist/features/seller/components/SellerProductsView.js +15 -10
- package/dist/features/seller/components/SellerShippingConfigsView.js +1 -1
- package/dist/features/seller/components/SellerSidebar.d.ts +0 -4
- package/dist/features/seller/components/SellerSidebar.js +0 -2
- package/dist/features/seller/components/SellerStoreCategoriesView.js +1 -1
- package/dist/features/seller/components/SellerTemplatesView.js +2 -2
- package/dist/features/seller/components/SellersListView.d.ts +1 -2
- package/dist/features/seller/components/analytics/SellerAnalyticsStats.d.ts +5 -0
- package/dist/features/seller/components/analytics/SellerAnalyticsStats.js +2 -8
- package/dist/features/seller/components/index.d.ts +0 -3
- package/dist/features/seller/components/index.js +0 -2
- package/dist/features/seller/server.d.ts +0 -1
- package/dist/features/seller/server.js +0 -1
- package/dist/features/shell/FormShell.d.ts +1 -1
- package/dist/features/shell/FormShell.js +4 -1
- package/dist/features/shell/field-groups/ImageFieldGroup.d.ts +18 -0
- package/dist/features/shell/field-groups/ImageFieldGroup.js +15 -0
- package/dist/features/shell/field-groups/SeoFieldGroup.d.ts +22 -0
- package/dist/features/shell/field-groups/SeoFieldGroup.js +16 -0
- package/dist/features/shell/field-groups/StatusFieldGroup.d.ts +35 -0
- package/dist/features/shell/field-groups/StatusFieldGroup.js +16 -0
- package/dist/features/shell/field-groups/TitleDescriptionGroup.d.ts +40 -0
- package/dist/features/shell/field-groups/TitleDescriptionGroup.js +16 -0
- package/dist/features/shell/field-groups/index.d.ts +13 -0
- package/dist/features/shell/field-groups/index.js +9 -0
- package/dist/features/shell/index.d.ts +2 -0
- package/dist/features/shell/index.js +1 -0
- package/dist/features/stores/components/StoreCapabilitiesGuideView.d.ts +1 -2
- package/dist/features/stores/components/StoreFinanceGuideView.d.ts +1 -2
- package/dist/features/stores/components/StoreHeader.js +2 -1
- package/dist/features/stores/components/StoreListingsGuideView.d.ts +1 -2
- package/dist/features/stores/components/StoreOrdersGuideView.d.ts +1 -2
- package/dist/features/stores/components/StoreScopedSearch.d.ts +16 -0
- package/dist/features/stores/components/StoreScopedSearch.js +27 -0
- package/dist/features/stores/components/StoreSettingsGuideView.d.ts +1 -2
- package/dist/features/stores/server.d.ts +0 -1
- package/dist/features/stores/server.js +0 -1
- package/dist/features/support/schemas/firestore.d.ts +22 -1
- package/dist/features/support/schemas/firestore.js +10 -0
- package/dist/features/wishlist/server.d.ts +0 -1
- package/dist/features/wishlist/server.js +0 -1
- package/dist/index.d.ts +9 -27
- package/dist/index.js +14 -50
- package/dist/next/routing/route-map.d.ts +8 -0
- package/dist/next/routing/route-map.js +4 -0
- package/dist/react/hooks/useListingTypeFlags.d.ts +32 -0
- package/dist/react/hooks/useListingTypeFlags.js +19 -0
- package/dist/security/index.d.ts +1 -1
- package/dist/security/index.js +1 -1
- package/dist/security/pii-redact.d.ts +8 -0
- package/dist/security/pii-redact.js +10 -1
- package/dist/seed/grouped-listings-seed-data.d.ts +4 -0
- package/dist/seed/products-preorders-seed-data.d.ts +4 -0
- package/dist/seed/products-prize-draws-seed-data.js +3 -0
- package/dist/seed/site-settings-seed-data.js +5 -5
- package/dist/seed/sub-listings-seed-data.d.ts +4 -0
- package/dist/server.d.ts +2 -0
- package/dist/server.js +4 -0
- package/dist/styles.css +54 -395
- package/dist/tailwind-utilities.css +1 -1
- package/dist/ui/components/BaseListingCard.d.ts +10 -0
- package/dist/ui/components/BaseListingCard.js +17 -1
- package/dist/ui/components/DetailPageGallery.d.ts +32 -0
- package/dist/ui/components/DetailPageGallery.js +47 -0
- package/dist/ui/components/DetailPageHero.d.ts +30 -0
- package/dist/ui/components/DetailPageHero.js +22 -0
- package/dist/ui/components/DetailPageTabs.d.ts +34 -0
- package/dist/ui/components/DetailPageTabs.js +38 -0
- package/dist/ui/components/HorizontalScroller.style.css +15 -2
- package/dist/ui/components/ListingLayout.d.ts +11 -2
- package/dist/ui/components/ListingLayout.js +12 -6
- package/dist/ui/components/PaginatedSelect.d.ts +66 -0
- package/dist/ui/components/PaginatedSelect.js +201 -0
- package/dist/ui/components/PaginatedSelect.style.css +254 -0
- package/dist/ui/components/Semantic.d.ts +0 -4
- package/dist/ui/components/Semantic.js +0 -2
- package/dist/ui/components/SettingsSection.d.ts +47 -0
- package/dist/ui/components/SettingsSection.js +38 -0
- package/dist/ui/components/index.style.css +1 -4
- package/dist/ui/index.d.ts +12 -14
- package/dist/ui/index.js +6 -7
- package/dist/utils/id-generators.d.ts +1 -18
- package/dist/utils/id-generators.js +51 -18
- package/dist/validation/schemas.d.ts +25 -0
- package/dist/validation/schemas.js +28 -0
- package/package.json +1 -1
|
@@ -9,7 +9,26 @@
|
|
|
9
9
|
* Client — useAuthGate() shows LoginRequiredModal for Tier 1 (public) actions
|
|
10
10
|
* Server — checkActionAllowed() enforces the same guards on every server action
|
|
11
11
|
* Admin — ActionPermissionsManager toggles defaultEnabled via siteSettings.actionConfig
|
|
12
|
+
*
|
|
13
|
+
* Label source of truth: `ACTIONS.{RESOURCE}["..."].label` in
|
|
14
|
+
* _internal/shared/actions/action-registry.ts. `ACTION_META` derives its labels
|
|
15
|
+
* via `regLabel()` where a registry counterpart exists; entries with no
|
|
16
|
+
* counterpart keep an inline literal until a registry leaf is added (W1-5).
|
|
17
|
+
*/
|
|
18
|
+
import { ACTIONS } from "../../../_internal/shared/actions/action-registry";
|
|
19
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
20
|
+
// Label-from-registry helper (W1-5)
|
|
21
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
22
|
+
/**
|
|
23
|
+
* Returns the label for `ACTIONS[resource][id]`. The `fallback` is used only
|
|
24
|
+
* when the registry has no leaf yet — orphan IDs should be added to ACTIONS
|
|
25
|
+
* over time. Adding the fallback parameter as required ensures every call
|
|
26
|
+
* site documents what the inline label was at migration time, simplifying
|
|
27
|
+
* the eventual cleanup.
|
|
12
28
|
*/
|
|
29
|
+
function regLabel(resource, id, fallback) {
|
|
30
|
+
return ACTIONS[resource]?.[id]?.label ?? fallback;
|
|
31
|
+
}
|
|
13
32
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
14
33
|
// § 1 Product / listing actions
|
|
15
34
|
// Used by: detail pages, BulkActionsBar, BuyBar
|
|
@@ -64,49 +83,50 @@ export const ACTION_ID = {
|
|
|
64
83
|
DELETE_ACCOUNT: "delete-account",
|
|
65
84
|
};
|
|
66
85
|
export const ACTION_META = {
|
|
67
|
-
[ACTION_ID.BUY_NOW]: { id: ACTION_ID.BUY_NOW, label: "Buy Now", variant: "primary", requiresAuth: true, authMessage: "You need to be signed in to purchase items." },
|
|
68
|
-
[ACTION_ID.ADD_TO_CART]: { id: ACTION_ID.ADD_TO_CART, label: "Add to Cart", variant: "secondary", iconName: "ShoppingCart" },
|
|
69
|
-
[ACTION_ID.ADD_TO_WISHLIST]: { id: ACTION_ID.ADD_TO_WISHLIST, label: "Add to Wishlist", variant: "ghost", iconName: "Heart", requiresAuth: true, authMessage: "You need to be signed in to save items to your wishlist." },
|
|
70
|
-
[ACTION_ID.REMOVE_FROM_WISHLIST]: { id: ACTION_ID.REMOVE_FROM_WISHLIST, label: "Remove from Wishlist", variant: "ghost", iconName: "HeartOff", requiresAuth: true, authMessage: "You need to be signed in to manage your wishlist." },
|
|
71
|
-
[ACTION_ID.MAKE_OFFER]: { id: ACTION_ID.MAKE_OFFER, label: "Make an Offer", variant: "outline", iconName: "Tag", requiresAuth: true, authMessage: "You need to be signed in to make an offer." },
|
|
72
|
-
[ACTION_ID.SHARE]: { id: ACTION_ID.SHARE, label: "Share", variant: "ghost", iconName: "Share2" },
|
|
73
|
-
[ACTION_ID.COMPARE]: { id: ACTION_ID.COMPARE, label: "Compare", variant: "secondary", iconName: "Columns" },
|
|
74
|
-
[ACTION_ID.PLACE_BID]: { id: ACTION_ID.PLACE_BID, label: "Place Bid", variant: "primary", requiresAuth: true, authMessage: "You need to be signed in to place a bid." },
|
|
75
|
-
[ACTION_ID.BUY_NOW_AUCTION]: { id: ACTION_ID.BUY_NOW_AUCTION, label: "Buy Now", variant: "secondary", requiresAuth: true, authMessage: "You need to be signed in to purchase items." },
|
|
76
|
-
[ACTION_ID.WATCH_AUCTION]: { id: ACTION_ID.WATCH_AUCTION, label: "Watch", variant: "ghost", iconName: "Eye", requiresAuth: true, authMessage: "You need to be signed in to watch auctions." },
|
|
77
|
-
[ACTION_ID.UNWATCH_AUCTION]: { id: ACTION_ID.UNWATCH_AUCTION, label: "Unwatch", variant: "ghost", iconName: "EyeOff", requiresAuth: true, authMessage: "You need to be signed in to manage your watchlist." },
|
|
78
|
-
[ACTION_ID.RESERVE_NOW]: { id: ACTION_ID.RESERVE_NOW, label: "Reserve Now", variant: "primary", requiresAuth: true, authMessage: "You need to be signed in to reserve a pre-order." },
|
|
79
|
-
[ACTION_ID.CANCEL_RESERVATION]: { id: ACTION_ID.CANCEL_RESERVATION, label: "Cancel Reservation", variant: "danger", iconName: "X", requiresAuth: true, authMessage: "You need to be signed in to cancel a reservation." },
|
|
86
|
+
[ACTION_ID.BUY_NOW]: { id: ACTION_ID.BUY_NOW, label: regLabel("PRODUCT", "buy-now", "Buy Now"), variant: "primary", requiresAuth: true, authMessage: "You need to be signed in to purchase items." },
|
|
87
|
+
[ACTION_ID.ADD_TO_CART]: { id: ACTION_ID.ADD_TO_CART, label: regLabel("PRODUCT", "add-to-cart", "Add to Cart"), variant: "secondary", iconName: "ShoppingCart" },
|
|
88
|
+
[ACTION_ID.ADD_TO_WISHLIST]: { id: ACTION_ID.ADD_TO_WISHLIST, label: regLabel("PRODUCT", "add-to-wishlist", "Add to Wishlist"), variant: "ghost", iconName: "Heart", requiresAuth: true, authMessage: "You need to be signed in to save items to your wishlist." },
|
|
89
|
+
[ACTION_ID.REMOVE_FROM_WISHLIST]: { id: ACTION_ID.REMOVE_FROM_WISHLIST, label: regLabel("PRODUCT", "remove-from-wishlist", "Remove from Wishlist"), variant: "ghost", iconName: "HeartOff", requiresAuth: true, authMessage: "You need to be signed in to manage your wishlist." },
|
|
90
|
+
[ACTION_ID.MAKE_OFFER]: { id: ACTION_ID.MAKE_OFFER, label: regLabel("PRODUCT", "make-offer", "Make an Offer"), variant: "outline", iconName: "Tag", requiresAuth: true, authMessage: "You need to be signed in to make an offer." },
|
|
91
|
+
[ACTION_ID.SHARE]: { id: ACTION_ID.SHARE, label: regLabel("PRODUCT", "share", "Share"), variant: "ghost", iconName: "Share2" },
|
|
92
|
+
[ACTION_ID.COMPARE]: { id: ACTION_ID.COMPARE, label: regLabel("PRODUCT", "compare", "Compare"), variant: "secondary", iconName: "Columns" },
|
|
93
|
+
[ACTION_ID.PLACE_BID]: { id: ACTION_ID.PLACE_BID, label: regLabel("AUCTION", "place-bid", "Place Bid"), variant: "primary", requiresAuth: true, authMessage: "You need to be signed in to place a bid." },
|
|
94
|
+
[ACTION_ID.BUY_NOW_AUCTION]: { id: ACTION_ID.BUY_NOW_AUCTION, label: regLabel("AUCTION", "buy-it-now", "Buy Now"), variant: "secondary", requiresAuth: true, authMessage: "You need to be signed in to purchase items." },
|
|
95
|
+
[ACTION_ID.WATCH_AUCTION]: { id: ACTION_ID.WATCH_AUCTION, label: regLabel("AUCTION", "watch", "Watch"), variant: "ghost", iconName: "Eye", requiresAuth: true, authMessage: "You need to be signed in to watch auctions." },
|
|
96
|
+
[ACTION_ID.UNWATCH_AUCTION]: { id: ACTION_ID.UNWATCH_AUCTION, label: regLabel("AUCTION", "unwatch", "Unwatch"), variant: "ghost", iconName: "EyeOff", requiresAuth: true, authMessage: "You need to be signed in to manage your watchlist." },
|
|
97
|
+
[ACTION_ID.RESERVE_NOW]: { id: ACTION_ID.RESERVE_NOW, label: regLabel("PRE_ORDER", "reserve-now", "Reserve Now"), variant: "primary", requiresAuth: true, authMessage: "You need to be signed in to reserve a pre-order." },
|
|
98
|
+
[ACTION_ID.CANCEL_RESERVATION]: { id: ACTION_ID.CANCEL_RESERVATION, label: regLabel("PRE_ORDER", "cancel-reservation", "Cancel Reservation"), variant: "danger", iconName: "X", requiresAuth: true, authMessage: "You need to be signed in to cancel a reservation." },
|
|
80
99
|
// ── Checkout / navigation CTAs ────────────────────────────────────────────
|
|
81
|
-
[ACTION_ID.CHECKOUT]: { id: ACTION_ID.CHECKOUT, label: "Checkout", variant: "primary", requiresAuth: true, authMessage: "You need to be signed in to checkout." },
|
|
82
|
-
[ACTION_ID.CONTINUE_TO_VERIFY]: { id: ACTION_ID.CONTINUE_TO_VERIFY, label: "Continue", variant: "primary", requiresAuth: true, authMessage: "You need to be signed in to checkout." },
|
|
83
|
-
[ACTION_ID.SEND_OTP]: { id: ACTION_ID.SEND_OTP, label: "Send Code", variant: "primary", requiresAuth: true, authMessage: "You need to be signed in to checkout." },
|
|
84
|
-
[ACTION_ID.VERIFY_OTP]: { id: ACTION_ID.VERIFY_OTP, label: "Verify & Continue", variant: "primary", requiresAuth: true, authMessage: "You need to be signed in to checkout." },
|
|
85
|
-
[ACTION_ID.PAY_ONLINE]: { id: ACTION_ID.PAY_ONLINE, label: "Pay Online", variant: "primary", requiresAuth: true, authMessage: "You need to be signed in to checkout." },
|
|
86
|
-
[ACTION_ID.PAY_COD]: { id: ACTION_ID.PAY_COD, label: "Cash on Delivery", variant: "secondary", requiresAuth: true, authMessage: "You need to be signed in to checkout." },
|
|
87
|
-
[ACTION_ID.APPLY_COUPON]: { id: ACTION_ID.APPLY_COUPON, label: "Apply", variant: "secondary", requiresAuth: true, authMessage: "You need to be signed in to apply a coupon." },
|
|
88
|
-
[ACTION_ID.REMOVE_COUPON]: { id: ACTION_ID.REMOVE_COUPON, label: "Remove", variant: "ghost", requiresAuth: true, authMessage: "You need to be signed in to manage coupons." },
|
|
89
|
-
[ACTION_ID.ENTER_PRIZE_DRAW]: { id: ACTION_ID.ENTER_PRIZE_DRAW, label: "Enter Draw", variant: "primary", requiresAuth: true, authMessage: "You need to be signed in to enter a prize draw." },
|
|
100
|
+
[ACTION_ID.CHECKOUT]: { id: ACTION_ID.CHECKOUT, label: regLabel("CART", "checkout", "Checkout"), variant: "primary", requiresAuth: true, authMessage: "You need to be signed in to checkout." },
|
|
101
|
+
[ACTION_ID.CONTINUE_TO_VERIFY]: { id: ACTION_ID.CONTINUE_TO_VERIFY, label: regLabel("CHECKOUT", "continue-to-verification", "Continue"), variant: "primary", requiresAuth: true, authMessage: "You need to be signed in to checkout." },
|
|
102
|
+
[ACTION_ID.SEND_OTP]: { id: ACTION_ID.SEND_OTP, label: regLabel("CHECKOUT", "send-otp", "Send Code"), variant: "primary", requiresAuth: true, authMessage: "You need to be signed in to checkout." },
|
|
103
|
+
[ACTION_ID.VERIFY_OTP]: { id: ACTION_ID.VERIFY_OTP, label: regLabel("CHECKOUT", "verify-otp", "Verify & Continue"), variant: "primary", requiresAuth: true, authMessage: "You need to be signed in to checkout." },
|
|
104
|
+
[ACTION_ID.PAY_ONLINE]: { id: ACTION_ID.PAY_ONLINE, label: regLabel("CHECKOUT", "pay-online", "Pay Online"), variant: "primary", requiresAuth: true, authMessage: "You need to be signed in to checkout." },
|
|
105
|
+
[ACTION_ID.PAY_COD]: { id: ACTION_ID.PAY_COD, label: regLabel("CHECKOUT", "pay-cod", "Cash on Delivery"), variant: "secondary", requiresAuth: true, authMessage: "You need to be signed in to checkout." },
|
|
106
|
+
[ACTION_ID.APPLY_COUPON]: { id: ACTION_ID.APPLY_COUPON, label: regLabel("CHECKOUT", "apply-coupon", "Apply"), variant: "secondary", requiresAuth: true, authMessage: "You need to be signed in to apply a coupon." },
|
|
107
|
+
[ACTION_ID.REMOVE_COUPON]: { id: ACTION_ID.REMOVE_COUPON, label: regLabel("CHECKOUT", "remove-coupon", "Remove"), variant: "ghost", requiresAuth: true, authMessage: "You need to be signed in to manage coupons." },
|
|
108
|
+
[ACTION_ID.ENTER_PRIZE_DRAW]: { id: ACTION_ID.ENTER_PRIZE_DRAW, label: regLabel("PRIZE_DRAW", "enter-draw", "Enter Draw"), variant: "primary", requiresAuth: true, authMessage: "You need to be signed in to enter a prize draw." },
|
|
109
|
+
// ── Inline literals: no registry counterpart yet (orphan IDs — add to ACTIONS in a follow-up sweep) ─
|
|
90
110
|
[ACTION_ID.ENTER_RAFFLE]: { id: ACTION_ID.ENTER_RAFFLE, label: "Enter Raffle", variant: "primary", requiresAuth: true, authMessage: "You need to be signed in to enter a raffle." },
|
|
91
111
|
[ACTION_ID.REPORT_LISTING]: { id: ACTION_ID.REPORT_LISTING, label: "Report Listing", variant: "ghost", requiresAuth: true, authMessage: "You need to be signed in to report a listing." },
|
|
92
|
-
[ACTION_ID.FOLLOW_STORE]: { id: ACTION_ID.FOLLOW_STORE, label: "Follow Store", variant: "outline", requiresAuth: true, authMessage: "You need to be signed in to follow a store." },
|
|
112
|
+
[ACTION_ID.FOLLOW_STORE]: { id: ACTION_ID.FOLLOW_STORE, label: regLabel("STORE", "follow", "Follow Store"), variant: "outline", requiresAuth: true, authMessage: "You need to be signed in to follow a store." },
|
|
93
113
|
// ── Reviews & social ──────────────────────────────────────────────────────
|
|
94
|
-
[ACTION_ID.WRITE_REVIEW]: { id: ACTION_ID.WRITE_REVIEW, label: "Write a Review", variant: "outline", requiresAuth: true, authMessage: "You need to be signed in to write a review." },
|
|
114
|
+
[ACTION_ID.WRITE_REVIEW]: { id: ACTION_ID.WRITE_REVIEW, label: regLabel("USER", "write-review", "Write a Review"), variant: "outline", requiresAuth: true, authMessage: "You need to be signed in to write a review." },
|
|
95
115
|
[ACTION_ID.MESSAGE_SELLER]: { id: ACTION_ID.MESSAGE_SELLER, label: "Message Seller", variant: "outline", requiresAuth: true, authMessage: "You need to be signed in to message a seller." },
|
|
96
116
|
// ── Seller CTAs ───────────────────────────────────────────────────────────
|
|
97
117
|
[ACTION_ID.BECOME_SELLER]: { id: ACTION_ID.BECOME_SELLER, label: "Apply as Seller", variant: "primary", requiresAuth: true, authMessage: "You need to be signed in to apply as a seller." },
|
|
98
|
-
[ACTION_ID.REQUEST_PAYOUT]: { id: ACTION_ID.REQUEST_PAYOUT, label: "Request Payout", variant: "outline", requiresAuth: true, authMessage: "You need to be signed in to request a payout.", requiredPermission: "seller.payouts.request" },
|
|
99
|
-
[ACTION_ID.RESPOND_TO_REVIEW]: { id: ACTION_ID.RESPOND_TO_REVIEW, label: "Respond to Review", variant: "outline", requiresAuth: true, authMessage: "You need to be signed in to respond to a review.", requiredPermission: "seller.reviews.respond" },
|
|
118
|
+
[ACTION_ID.REQUEST_PAYOUT]: { id: ACTION_ID.REQUEST_PAYOUT, label: regLabel("STORE", "request-payout", "Request Payout"), variant: "outline", requiresAuth: true, authMessage: "You need to be signed in to request a payout.", requiredPermission: "seller.payouts.request" },
|
|
119
|
+
[ACTION_ID.RESPOND_TO_REVIEW]: { id: ACTION_ID.RESPOND_TO_REVIEW, label: regLabel("STORE", "reply-review", "Respond to Review"), variant: "outline", requiresAuth: true, authMessage: "You need to be signed in to respond to a review.", requiredPermission: "seller.reviews.respond" },
|
|
100
120
|
// ── User account actions ──────────────────────────────────────────────────
|
|
101
|
-
[ACTION_ID.CANCEL_ORDER]: { id: ACTION_ID.CANCEL_ORDER, label: "Cancel Order", variant: "danger", requiresAuth: true, authMessage: "You need to be signed in to cancel an order." },
|
|
102
|
-
[ACTION_ID.REQUEST_RETURN]: { id: ACTION_ID.REQUEST_RETURN, label: "Request Return", variant: "outline", requiresAuth: true, authMessage: "You need to be signed in to request a return." },
|
|
103
|
-
[ACTION_ID.REORDER]: { id: ACTION_ID.REORDER, label: "Reorder", variant: "secondary", requiresAuth: true, authMessage: "You need to be signed in to reorder." },
|
|
104
|
-
[ACTION_ID.TRACK_ORDER]: { id: ACTION_ID.TRACK_ORDER, label: "Track Order", variant: "ghost", requiresAuth: true, authMessage: "You need to be signed in to track your order." },
|
|
121
|
+
[ACTION_ID.CANCEL_ORDER]: { id: ACTION_ID.CANCEL_ORDER, label: regLabel("USER", "cancel-order", "Cancel Order"), variant: "danger", requiresAuth: true, authMessage: "You need to be signed in to cancel an order." },
|
|
122
|
+
[ACTION_ID.REQUEST_RETURN]: { id: ACTION_ID.REQUEST_RETURN, label: regLabel("USER", "request-return", "Request Return"), variant: "outline", requiresAuth: true, authMessage: "You need to be signed in to request a return." },
|
|
123
|
+
[ACTION_ID.REORDER]: { id: ACTION_ID.REORDER, label: regLabel("USER", "reorder", "Reorder"), variant: "secondary", requiresAuth: true, authMessage: "You need to be signed in to reorder." },
|
|
124
|
+
[ACTION_ID.TRACK_ORDER]: { id: ACTION_ID.TRACK_ORDER, label: regLabel("USER", "track-order", "Track Order"), variant: "ghost", requiresAuth: true, authMessage: "You need to be signed in to track your order." },
|
|
105
125
|
[ACTION_ID.EDIT_PROFILE]: { id: ACTION_ID.EDIT_PROFILE, label: "Edit Profile", variant: "outline", requiresAuth: true, authMessage: "You need to be signed in to edit your profile." },
|
|
106
126
|
[ACTION_ID.ADD_ADDRESS]: { id: ACTION_ID.ADD_ADDRESS, label: "Add Address", variant: "outline", requiresAuth: true, authMessage: "You need to be signed in to add an address." },
|
|
107
127
|
[ACTION_ID.EDIT_ADDRESS]: { id: ACTION_ID.EDIT_ADDRESS, label: "Edit Address", variant: "ghost", requiresAuth: true, authMessage: "You need to be signed in to edit an address." },
|
|
108
|
-
[ACTION_ID.DELETE_ADDRESS]: { id: ACTION_ID.DELETE_ADDRESS, label: "Delete Address", variant: "danger", requiresAuth: true, authMessage: "You need to be signed in to delete an address." },
|
|
109
|
-
[ACTION_ID.CHANGE_PASSWORD]: { id: ACTION_ID.CHANGE_PASSWORD, label: "Change Password", variant: "outline", requiresAuth: true, authMessage: "You need to be signed in to change your password." },
|
|
128
|
+
[ACTION_ID.DELETE_ADDRESS]: { id: ACTION_ID.DELETE_ADDRESS, label: regLabel("USER", "delete-address", "Delete Address"), variant: "danger", requiresAuth: true, authMessage: "You need to be signed in to delete an address." },
|
|
129
|
+
[ACTION_ID.CHANGE_PASSWORD]: { id: ACTION_ID.CHANGE_PASSWORD, label: regLabel("USER", "update-password", "Change Password"), variant: "outline", requiresAuth: true, authMessage: "You need to be signed in to change your password." },
|
|
110
130
|
[ACTION_ID.DELETE_ACCOUNT]: { id: ACTION_ID.DELETE_ACCOUNT, label: "Delete Account", variant: "danger", requiresAuth: true, authMessage: "You need to be signed in to delete your account.", requiredPermission: "user.account.delete" },
|
|
111
131
|
};
|
|
112
132
|
// Detail page action groups — ordered top-to-bottom in the right-hand panel
|
|
@@ -2,6 +2,20 @@ export type SortOption = {
|
|
|
2
2
|
readonly value: string;
|
|
3
3
|
readonly label: string;
|
|
4
4
|
};
|
|
5
|
+
/** Time + price sorts, the common subset across most listing-type pickers. */
|
|
6
|
+
export declare const BASE_SORT_OPTIONS: readonly [{
|
|
7
|
+
readonly value: string;
|
|
8
|
+
readonly label: "Newest First";
|
|
9
|
+
}, {
|
|
10
|
+
readonly value: string;
|
|
11
|
+
readonly label: "Oldest First";
|
|
12
|
+
}, {
|
|
13
|
+
readonly value: string;
|
|
14
|
+
readonly label: "Price: Low to High";
|
|
15
|
+
}, {
|
|
16
|
+
readonly value: string;
|
|
17
|
+
readonly label: "Price: High to Low";
|
|
18
|
+
}];
|
|
5
19
|
export declare const STANDARD_SORT_OPTIONS: readonly [{
|
|
6
20
|
readonly value: string;
|
|
7
21
|
readonly label: "Newest First";
|
|
@@ -108,10 +122,13 @@ export declare const PREORDER_SORT_OPTIONS: readonly [{
|
|
|
108
122
|
}, {
|
|
109
123
|
readonly value: string;
|
|
110
124
|
readonly label: "Latest Delivery";
|
|
111
|
-
}, {
|
|
125
|
+
}, ...({
|
|
112
126
|
readonly value: string;
|
|
113
127
|
readonly label: "Newest First";
|
|
114
|
-
}
|
|
128
|
+
} | {
|
|
129
|
+
readonly value: string;
|
|
130
|
+
readonly label: "Oldest First";
|
|
131
|
+
})[], {
|
|
115
132
|
readonly value: string;
|
|
116
133
|
readonly label: "Price: Low to High";
|
|
117
134
|
}, {
|
|
@@ -124,10 +141,13 @@ export declare const PREORDER_SORT_OPTIONS: readonly [{
|
|
|
124
141
|
readonly value: string;
|
|
125
142
|
readonly label: "Lowest Deposit First";
|
|
126
143
|
}];
|
|
127
|
-
export declare const BUNDLE_SORT_OPTIONS: readonly [{
|
|
144
|
+
export declare const BUNDLE_SORT_OPTIONS: readonly [...({
|
|
128
145
|
readonly value: string;
|
|
129
146
|
readonly label: "Newest First";
|
|
130
|
-
}
|
|
147
|
+
} | {
|
|
148
|
+
readonly value: string;
|
|
149
|
+
readonly label: "Oldest First";
|
|
150
|
+
})[], {
|
|
131
151
|
readonly value: string;
|
|
132
152
|
readonly label: "Price: Low to High";
|
|
133
153
|
}, {
|
|
@@ -5,13 +5,25 @@ const LABEL_PRICE_LOW = "Price: Low to High";
|
|
|
5
5
|
const LABEL_NEWEST = "Newest First";
|
|
6
6
|
const LABEL_OLDEST = "Oldest First";
|
|
7
7
|
// ---------------------------------------------------------------------------
|
|
8
|
-
//
|
|
8
|
+
// W2-6 — Base sort options shared by standard / pre-order / bundle / prize-draw.
|
|
9
|
+
// Auctions get their own base (auctionEndDate primary) because the "Ending Soon"
|
|
10
|
+
// dimension dominates browse intent.
|
|
9
11
|
// ---------------------------------------------------------------------------
|
|
10
|
-
|
|
12
|
+
const BASE_TIME_SORTS = [
|
|
11
13
|
{ value: sortBy(PRODUCT_FIELDS.CREATED_AT), label: LABEL_NEWEST },
|
|
12
14
|
{ value: sortBy(PRODUCT_FIELDS.CREATED_AT, "ASC"), label: LABEL_OLDEST },
|
|
15
|
+
];
|
|
16
|
+
const BASE_PRICE_SORTS = [
|
|
13
17
|
{ value: sortBy(PRODUCT_FIELDS.PRICE, "ASC"), label: LABEL_PRICE_LOW },
|
|
14
18
|
{ value: sortBy(PRODUCT_FIELDS.PRICE), label: LABEL_PRICE_HIGH },
|
|
19
|
+
];
|
|
20
|
+
/** Time + price sorts, the common subset across most listing-type pickers. */
|
|
21
|
+
export const BASE_SORT_OPTIONS = [...BASE_TIME_SORTS, ...BASE_PRICE_SORTS];
|
|
22
|
+
// ---------------------------------------------------------------------------
|
|
23
|
+
// Standard Products
|
|
24
|
+
// ---------------------------------------------------------------------------
|
|
25
|
+
export const STANDARD_SORT_OPTIONS = [
|
|
26
|
+
...BASE_SORT_OPTIONS,
|
|
15
27
|
{ value: sortBy(PRODUCT_FIELDS.TITLE, "ASC"), label: "Name: A–Z" },
|
|
16
28
|
{ value: sortBy(PRODUCT_FIELDS.TITLE), label: "Name: Z–A" },
|
|
17
29
|
{ value: sortBy(PRODUCT_FIELDS.FEATURED), label: "Featured First" },
|
|
@@ -29,7 +41,7 @@ export const STANDARD_PUBLIC_SORT_OPTIONS = [
|
|
|
29
41
|
STANDARD_SORT_OPTIONS[9],
|
|
30
42
|
];
|
|
31
43
|
// ---------------------------------------------------------------------------
|
|
32
|
-
// Auctions
|
|
44
|
+
// Auctions — auction-specific base puts auctionEndDate primary
|
|
33
45
|
// ---------------------------------------------------------------------------
|
|
34
46
|
export const AUCTION_SORT_OPTIONS = [
|
|
35
47
|
{ value: sortBy(PRODUCT_FIELDS.AUCTION_END_DATE, "ASC"), label: "Ending Soon" },
|
|
@@ -56,9 +68,8 @@ export const AUCTION_PUBLIC_SORT_OPTIONS = [
|
|
|
56
68
|
export const PREORDER_SORT_OPTIONS = [
|
|
57
69
|
{ value: sortBy(PRODUCT_FIELDS.PRE_ORDER_DELIVERY_DATE, "ASC"), label: "Earliest Delivery" },
|
|
58
70
|
{ value: sortBy(PRODUCT_FIELDS.PRE_ORDER_DELIVERY_DATE), label: "Latest Delivery" },
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
{ value: sortBy(PRODUCT_FIELDS.PRICE), label: LABEL_PRICE_HIGH },
|
|
71
|
+
...BASE_TIME_SORTS.slice(0, 1), // Newest First
|
|
72
|
+
...BASE_PRICE_SORTS,
|
|
62
73
|
{ value: sortBy(PRODUCT_FIELDS.PRE_ORDER_CURRENT_COUNT), label: "Fewest Slots Left" },
|
|
63
74
|
{ value: sortBy(PRODUCT_FIELDS.PRE_ORDER_DEPOSIT_AMOUNT, "ASC"), label: "Lowest Deposit First" },
|
|
64
75
|
];
|
|
@@ -66,9 +77,8 @@ export const PREORDER_SORT_OPTIONS = [
|
|
|
66
77
|
// Bundles
|
|
67
78
|
// ---------------------------------------------------------------------------
|
|
68
79
|
export const BUNDLE_SORT_OPTIONS = [
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
{ value: sortBy(PRODUCT_FIELDS.PRICE), label: LABEL_PRICE_HIGH },
|
|
80
|
+
...BASE_TIME_SORTS.slice(0, 1), // Newest First
|
|
81
|
+
...BASE_PRICE_SORTS,
|
|
72
82
|
{ value: "-savingsAmount", label: "Most Savings" },
|
|
73
83
|
{ value: "-bundleItemCount", label: "Most Items" },
|
|
74
84
|
];
|
|
@@ -76,8 +86,7 @@ export const BUNDLE_SORT_OPTIONS = [
|
|
|
76
86
|
// Prize Draws
|
|
77
87
|
// ---------------------------------------------------------------------------
|
|
78
88
|
export const PRIZE_DRAW_SORT_OPTIONS = [
|
|
79
|
-
|
|
80
|
-
{ value: sortBy(PRODUCT_FIELDS.CREATED_AT, "ASC"), label: LABEL_OLDEST },
|
|
89
|
+
...BASE_TIME_SORTS,
|
|
81
90
|
{ value: sortBy(PRODUCT_FIELDS.PRIZE_REVEAL_WINDOW_START, "ASC"), label: "Reveal: Soonest" },
|
|
82
91
|
{ value: sortBy(PRODUCT_FIELDS.PRIZE_REVEAL_WINDOW_START), label: "Reveal: Furthest" },
|
|
83
92
|
{ value: sortBy(PRODUCT_FIELDS.PRICE, "ASC"), label: "Entry: Low to High" },
|
|
@@ -132,6 +132,10 @@ export interface ProductDocument {
|
|
|
132
132
|
status: ProductStatus;
|
|
133
133
|
storeId: string;
|
|
134
134
|
storeName?: string;
|
|
135
|
+
/** W1-34 — denormalized seller rating (0–5) shown on product detail store card. */
|
|
136
|
+
storeRating?: number;
|
|
137
|
+
/** W1-34 — denormalized seller total review count shown alongside the rating. */
|
|
138
|
+
storeReviewCount?: number;
|
|
135
139
|
featured: boolean;
|
|
136
140
|
tags: string[];
|
|
137
141
|
specifications?: ProductSpecification[];
|
|
@@ -194,6 +198,19 @@ export interface ProductDocument {
|
|
|
194
198
|
groupParentSlug?: string;
|
|
195
199
|
groupChildSlugs?: string[];
|
|
196
200
|
groupTitle?: string;
|
|
201
|
+
/**
|
|
202
|
+
* W1-45 — optional icon shown as an overlay badge on every card whose
|
|
203
|
+
* product belongs to this group. Set once on the group parent; cards
|
|
204
|
+
* inherit it via the snapshot pipeline. Either an emoji or a media slug
|
|
205
|
+
* (rendered via `/media/<slug>`).
|
|
206
|
+
*/
|
|
207
|
+
groupIcon?: string;
|
|
208
|
+
/**
|
|
209
|
+
* W1-45 — denormalized icon from the sublisting category (`display.icon`).
|
|
210
|
+
* Mirrored onto the product snapshot at create/update time so cards can
|
|
211
|
+
* render it without an extra category lookup per row.
|
|
212
|
+
*/
|
|
213
|
+
sublistingIcon?: string;
|
|
197
214
|
/**
|
|
198
215
|
* Required since Phase 4 dropped the legacy `isAuction` / `isPreOrder`
|
|
199
216
|
* booleans. Every product document carries this; queries route through
|
|
@@ -89,8 +89,8 @@ export declare const productFeatureUpdateSchema: z.ZodObject<{
|
|
|
89
89
|
label?: string | undefined;
|
|
90
90
|
icon?: string | undefined;
|
|
91
91
|
isActive?: boolean | undefined;
|
|
92
|
-
iconColor?: string | undefined;
|
|
93
92
|
displayOrder?: number | undefined;
|
|
93
|
+
iconColor?: string | undefined;
|
|
94
94
|
productTypes?: ("auction" | "prize-draw" | "classified" | "digital-code" | "live" | "all" | "product" | "preorder")[] | undefined;
|
|
95
95
|
}, {
|
|
96
96
|
category?: "seller" | "custom" | "auction" | "condition" | "shipping" | "preorder" | "platform" | undefined;
|
|
@@ -98,8 +98,8 @@ export declare const productFeatureUpdateSchema: z.ZodObject<{
|
|
|
98
98
|
label?: string | undefined;
|
|
99
99
|
icon?: string | undefined;
|
|
100
100
|
isActive?: boolean | undefined;
|
|
101
|
-
iconColor?: string | undefined;
|
|
102
101
|
displayOrder?: number | undefined;
|
|
102
|
+
iconColor?: string | undefined;
|
|
103
103
|
productTypes?: ("auction" | "prize-draw" | "classified" | "digital-code" | "live" | "all" | "product" | "preorder")[] | undefined;
|
|
104
104
|
}>;
|
|
105
105
|
export type ProductFeatureAdminCreatePayload = z.infer<typeof productFeatureAdminCreateSchema>;
|
|
@@ -22,7 +22,5 @@ export interface ProductTemplateDocument {
|
|
|
22
22
|
createdAt: Date | string;
|
|
23
23
|
updatedAt: Date | string;
|
|
24
24
|
}
|
|
25
|
-
export
|
|
26
|
-
|
|
27
|
-
export interface ProductTemplateUpdateInput extends Partial<Omit<ProductTemplateDocument, "id" | "storeId" | "createdAt">> {
|
|
28
|
-
}
|
|
25
|
+
export type ProductTemplateCreateInput = Omit<ProductTemplateDocument, "id" | "createdAt" | "updatedAt">;
|
|
26
|
+
export type ProductTemplateUpdateInput = Partial<Omit<ProductTemplateDocument, "id" | "storeId" | "createdAt">>;
|
|
@@ -65,6 +65,10 @@ export interface ProductItem {
|
|
|
65
65
|
groupParentSlug?: string;
|
|
66
66
|
groupChildSlugs?: string[];
|
|
67
67
|
groupTitle?: string;
|
|
68
|
+
/** W1-45 — icon shown as a card overlay; emoji or `/media/<slug>`. */
|
|
69
|
+
groupIcon?: string;
|
|
70
|
+
/** W1-45 — denormalized icon from the sublisting category. */
|
|
71
|
+
sublistingIcon?: string;
|
|
68
72
|
isOnSale?: boolean;
|
|
69
73
|
isSold?: boolean;
|
|
70
74
|
inStock?: boolean;
|
|
@@ -4,6 +4,5 @@
|
|
|
4
4
|
* Server-only entry point for promotions repositories and API route handlers.
|
|
5
5
|
*/
|
|
6
6
|
export * from "./actions";
|
|
7
|
-
export { PromotionsRepository } from "./repository/promotions.repository";
|
|
8
7
|
export { couponsRepository } from "./repository/coupons.repository";
|
|
9
8
|
export { GET as promotionsGET, GET } from "./api/route";
|
|
@@ -4,6 +4,5 @@
|
|
|
4
4
|
* Server-only entry point for promotions repositories and API route handlers.
|
|
5
5
|
*/
|
|
6
6
|
export * from "./actions";
|
|
7
|
-
export { PromotionsRepository } from "./repository/promotions.repository";
|
|
8
7
|
export { couponsRepository } from "./repository/coupons.repository";
|
|
9
8
|
export { GET as promotionsGET, GET } from "./api/route";
|
|
@@ -21,6 +21,8 @@
|
|
|
21
21
|
import { NextResponse } from "next/server.js";
|
|
22
22
|
import { getProviders } from "../../../contracts";
|
|
23
23
|
import { SearchRepository } from "../repository/search.repository";
|
|
24
|
+
import { isListingTypeEnabled, enabledListingTypes, } from "../../../_internal/shared/listing-types/feature-flags";
|
|
25
|
+
import { getSiteSettingsGlobal } from "../../admin/utils/getSiteSettingsGlobal";
|
|
24
26
|
function param(url, key) {
|
|
25
27
|
return url.searchParams.get(key);
|
|
26
28
|
}
|
|
@@ -55,6 +57,32 @@ export async function GET(request) {
|
|
|
55
57
|
const maxPriceRaw = numParam(url, "maxPrice", 0);
|
|
56
58
|
const page = numParam(url, "page", 1);
|
|
57
59
|
const pageSize = Math.min(numParam(url, "pageSize", 20), 100);
|
|
60
|
+
// W1-43 — listing-type feature flag gating. Reject a search scoped to a
|
|
61
|
+
// disabled listing type with an empty result; for unscoped searches,
|
|
62
|
+
// strip disabled types post-query so search-bar suggestions stay clean.
|
|
63
|
+
let siteSettings = null;
|
|
64
|
+
try {
|
|
65
|
+
siteSettings = await getSiteSettingsGlobal();
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
siteSettings = null;
|
|
69
|
+
}
|
|
70
|
+
if (listingType && siteSettings && !isListingTypeEnabled(listingType, siteSettings)) {
|
|
71
|
+
return NextResponse.json({
|
|
72
|
+
success: true,
|
|
73
|
+
data: {
|
|
74
|
+
items: [],
|
|
75
|
+
total: 0,
|
|
76
|
+
page,
|
|
77
|
+
pageSize,
|
|
78
|
+
totalPages: 0,
|
|
79
|
+
hasMore: false,
|
|
80
|
+
backend: "firestore",
|
|
81
|
+
listingTypeDisabled: true,
|
|
82
|
+
},
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
const enabledSet = new Set(siteSettings ? enabledListingTypes(siteSettings) : []);
|
|
58
86
|
const repo = new SearchRepository(db.getRepository("products"));
|
|
59
87
|
const result = await repo.search({
|
|
60
88
|
q: param(url, "q") ?? undefined,
|
|
@@ -70,9 +98,24 @@ export async function GET(request) {
|
|
|
70
98
|
page,
|
|
71
99
|
pageSize,
|
|
72
100
|
});
|
|
101
|
+
// W1-43 — when no specific listingType filter, strip disabled types from
|
|
102
|
+
// the surface. Skipped when all types are enabled or settings failed to load.
|
|
103
|
+
let filteredItems = result.items;
|
|
104
|
+
let filteredTotal = result.total;
|
|
105
|
+
if (!listingType && enabledSet.size > 0 && enabledSet.size < 7) {
|
|
106
|
+
const before = filteredItems.length;
|
|
107
|
+
filteredItems = filteredItems.filter((it) => enabledSet.has(it.listingType ?? "standard"));
|
|
108
|
+
const removed = before - filteredItems.length;
|
|
109
|
+
filteredTotal = Math.max(0, filteredTotal - removed);
|
|
110
|
+
}
|
|
73
111
|
return NextResponse.json({
|
|
74
112
|
success: true,
|
|
75
|
-
data: {
|
|
113
|
+
data: {
|
|
114
|
+
...result,
|
|
115
|
+
items: filteredItems,
|
|
116
|
+
total: filteredTotal,
|
|
117
|
+
backend: "firestore",
|
|
118
|
+
},
|
|
76
119
|
});
|
|
77
120
|
}
|
|
78
121
|
catch (error) {
|
|
@@ -12,12 +12,14 @@ const DEFAULT_TYPE_ICONS = {
|
|
|
12
12
|
category: "🗂️",
|
|
13
13
|
blog: "✍️",
|
|
14
14
|
event: "🎉",
|
|
15
|
+
product: "📦",
|
|
15
16
|
};
|
|
16
17
|
const DEFAULT_TYPE_BADGES = {
|
|
17
18
|
page: "bg-zinc-100 text-zinc-600 dark:bg-zinc-800 dark:text-zinc-300",
|
|
18
19
|
category: "bg-blue-100 text-blue-600 dark:bg-blue-900/40 dark:text-blue-300",
|
|
19
20
|
blog: "bg-fuchsia-100 text-fuchsia-600 dark:bg-fuchsia-900/40 dark:text-fuchsia-300",
|
|
20
21
|
event: "bg-amber-100 text-amber-600 dark:bg-amber-900/40 dark:text-amber-300",
|
|
22
|
+
product: "bg-emerald-100 text-emerald-600 dark:bg-emerald-900/40 dark:text-emerald-300",
|
|
21
23
|
};
|
|
22
24
|
function SuggestionItem({ suggestion, itemIndex, activeIndex, onSelect, onHover, typeIcons, typeBadges, }) {
|
|
23
25
|
const isActive = activeIndex === itemIndex;
|
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
export interface NavSuggestionRecord {
|
|
2
2
|
objectID: string;
|
|
3
|
-
type: "page" | "category" | "blog" | "event";
|
|
3
|
+
type: "page" | "category" | "blog" | "event" | "product";
|
|
4
4
|
title: string;
|
|
5
5
|
subtitle?: string;
|
|
6
6
|
url: string;
|
|
7
7
|
}
|
|
8
|
+
/**
|
|
9
|
+
* W1-19 — wired to `/api/search/suggestions` 2026-05-23. Fetches up to 20
|
|
10
|
+
* matches (5 per resource type) and surfaces them as typeahead rows.
|
|
11
|
+
*/
|
|
8
12
|
export declare function useNavSuggestions(query: string, selectedType?: string, debounceMs?: number): {
|
|
9
13
|
suggestions: NavSuggestionRecord[];
|
|
10
14
|
isLoading: boolean;
|
|
@@ -1,23 +1,48 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { useEffect, useRef, useState } from "react";
|
|
3
|
+
const SUGGESTIONS_ENDPOINT = "/api/search/suggestions";
|
|
4
|
+
/**
|
|
5
|
+
* W1-19 — wired to `/api/search/suggestions` 2026-05-23. Fetches up to 20
|
|
6
|
+
* matches (5 per resource type) and surfaces them as typeahead rows.
|
|
7
|
+
*/
|
|
3
8
|
export function useNavSuggestions(query, selectedType, debounceMs = 250) {
|
|
4
9
|
const [suggestions, setSuggestions] = useState([]);
|
|
5
10
|
const [isLoading, setIsLoading] = useState(false);
|
|
6
11
|
const timerRef = useRef(null);
|
|
12
|
+
const abortRef = useRef(null);
|
|
7
13
|
useEffect(() => {
|
|
8
14
|
if (timerRef.current)
|
|
9
15
|
clearTimeout(timerRef.current);
|
|
10
|
-
if (
|
|
16
|
+
if (abortRef.current)
|
|
17
|
+
abortRef.current.abort();
|
|
18
|
+
const trimmed = query.trim();
|
|
19
|
+
if (!trimmed) {
|
|
11
20
|
setSuggestions([]);
|
|
21
|
+
setIsLoading(false);
|
|
12
22
|
return;
|
|
13
23
|
}
|
|
14
24
|
timerRef.current = setTimeout(async () => {
|
|
15
25
|
setIsLoading(true);
|
|
26
|
+
const ctrl = new AbortController();
|
|
27
|
+
abortRef.current = ctrl;
|
|
16
28
|
try {
|
|
17
|
-
|
|
29
|
+
const params = new URLSearchParams({ q: trimmed });
|
|
30
|
+
if (selectedType && selectedType !== "all") {
|
|
31
|
+
params.set("type", selectedType);
|
|
32
|
+
}
|
|
33
|
+
const res = await fetch(`${SUGGESTIONS_ENDPOINT}?${params.toString()}`, { signal: ctrl.signal, credentials: "same-origin" });
|
|
34
|
+
if (!res.ok) {
|
|
35
|
+
setSuggestions([]);
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
const body = (await res.json());
|
|
39
|
+
const items = body.data?.suggestions ?? body.suggestions ?? [];
|
|
40
|
+
setSuggestions(items);
|
|
18
41
|
}
|
|
19
|
-
catch {
|
|
20
|
-
|
|
42
|
+
catch (err) {
|
|
43
|
+
if (err.name !== "AbortError") {
|
|
44
|
+
setSuggestions([]);
|
|
45
|
+
}
|
|
21
46
|
}
|
|
22
47
|
finally {
|
|
23
48
|
setIsLoading(false);
|
|
@@ -26,6 +51,8 @@ export function useNavSuggestions(query, selectedType, debounceMs = 250) {
|
|
|
26
51
|
return () => {
|
|
27
52
|
if (timerRef.current)
|
|
28
53
|
clearTimeout(timerRef.current);
|
|
54
|
+
if (abortRef.current)
|
|
55
|
+
abortRef.current.abort();
|
|
29
56
|
};
|
|
30
57
|
}, [query, selectedType, debounceMs]);
|
|
31
58
|
return { suggestions, isLoading };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
-
import {
|
|
3
|
+
import { PaginatedSelect } from "../../../ui/components/PaginatedSelect";
|
|
4
4
|
import { BrandQuickCreateForm } from "../../admin/components/BrandQuickCreateForm";
|
|
5
5
|
import { apiClient } from "../../../http";
|
|
6
6
|
import { ADMIN_ENDPOINTS } from "../../../constants/api-endpoints";
|
|
@@ -40,7 +40,7 @@ async function loadPublicBrandOptions(query, page) {
|
|
|
40
40
|
}
|
|
41
41
|
export function BrandInlineSelect({ value, onChange, placeholder = "Search brands…", disabled, allowCreate = true, }) {
|
|
42
42
|
const loadOptions = allowCreate ? loadAdminBrandOptions : loadPublicBrandOptions;
|
|
43
|
-
return (_jsx(
|
|
43
|
+
return (_jsx(PaginatedSelect, { value: value || null, onChange: (v) => onChange(v ?? ""), loadOptions: loadOptions, placeholder: placeholder, disabled: disabled, createLabel: "brand", drawerTitle: "Create Brand", renderCreateForm: allowCreate
|
|
44
44
|
? ({ onCreated, onCancel }) => (_jsx(BrandQuickCreateForm, { onSaved: (id, name) => onCreated({ value: id, label: name }), onCancel: onCancel }))
|
|
45
45
|
: undefined }));
|
|
46
46
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
-
import {
|
|
3
|
+
import { PaginatedSelect } from "../../../ui/components/PaginatedSelect";
|
|
4
4
|
import { CategoryQuickCreateForm } from "../../admin/components/CategoryQuickCreateForm";
|
|
5
5
|
import { apiClient } from "../../../http";
|
|
6
6
|
import { ADMIN_ENDPOINTS } from "../../../constants/api-endpoints";
|
|
@@ -37,7 +37,7 @@ async function loadPublicCategoryOptions(query, _page) {
|
|
|
37
37
|
}
|
|
38
38
|
export function CategoryInlineSelect({ value, onChange, placeholder = "Search categories…", disabled, allowCreate = false, }) {
|
|
39
39
|
const loadOptions = allowCreate ? loadAdminCategoryOptions : loadPublicCategoryOptions;
|
|
40
|
-
return (_jsx(
|
|
40
|
+
return (_jsx(PaginatedSelect, { value: value || null, onChange: (v) => onChange(v ?? ""), loadOptions: loadOptions, placeholder: placeholder, disabled: disabled, createLabel: "category", drawerTitle: "Create Category", renderCreateForm: allowCreate
|
|
41
41
|
? ({ onCreated, onCancel }) => (_jsx(CategoryQuickCreateForm, { onSaved: (id, name) => onCreated({ value: id, label: name }), onCancel: onCancel }))
|
|
42
42
|
: undefined }));
|
|
43
43
|
}
|
|
@@ -135,5 +135,5 @@ export function SellerAddressesView({ apiBase = SELLER_ENDPOINTS.STORE_ADDRESSES
|
|
|
135
135
|
const handleDelete = (addr) => setDeleteTargetAddr(addr);
|
|
136
136
|
const set = (key, value) => setDraft((p) => ({ ...p, [key]: value }));
|
|
137
137
|
const handleTextField = (key) => (e) => set(key, e.target.value);
|
|
138
|
-
return (_jsxs("div", { className: "min-h-screen", children: [_jsxs("div", { className: "sticky z-10 bg-white/95 dark:bg-slate-900/95 backdrop-blur-sm border-b border-zinc-200 dark:border-slate-700 px-4 py-3 flex items-center justify-between", style: { top: "var(--header-height, 0px)" }, children: [_jsxs(_Fragment, { children: [_jsx(Heading, { level: 2, className: "text-base font-semibold text-zinc-900 dark:text-zinc-100", children: "Pickup Addresses" }), _jsx(Text, { className: "text-xs text-zinc-500 dark:text-zinc-400 mt-0.5", children: "Manage your store's pickup and return locations" })] }), _jsxs(Button, { size: "sm", onClick: openAdd, className: "flex items-center gap-1.5", children: [_jsx(Plus, { className: "h-4 w-4" }), _jsx("span", { children: "Add Address" })] })] }), _jsxs("div", { className: "py-6 px-4 sm:px-6 max-w-2xl", children: [errorMessage && (_jsx(Div, { className: "mb-4 rounded-xl border border-
|
|
138
|
+
return (_jsxs("div", { className: "min-h-screen", children: [_jsxs("div", { className: "sticky z-10 bg-white/95 dark:bg-slate-900/95 backdrop-blur-sm border-b border-zinc-200 dark:border-slate-700 px-4 py-3 flex items-center justify-between", style: { top: "var(--header-height, 0px)" }, children: [_jsxs(_Fragment, { children: [_jsx(Heading, { level: 2, className: "text-base font-semibold text-zinc-900 dark:text-zinc-100", children: "Pickup Addresses" }), _jsx(Text, { className: "text-xs text-zinc-500 dark:text-zinc-400 mt-0.5", children: "Manage your store's pickup and return locations" })] }), _jsxs(Button, { size: "sm", onClick: openAdd, className: "flex items-center gap-1.5", children: [_jsx(Plus, { className: "h-4 w-4" }), _jsx("span", { children: "Add Address" })] })] }), _jsxs("div", { className: "py-6 px-4 sm:px-6 max-w-2xl", children: [errorMessage && (_jsx(Div, { className: "mb-4 rounded-xl border border-error/20 bg-error-surface px-4 py-3 text-sm text-error", children: errorMessage })), isLoading ? (_jsx("div", { className: "flex justify-center py-16", children: _jsx("div", { className: "h-6 w-6 animate-spin rounded-full border-2 border-[var(--appkit-color-primary)] border-t-transparent" }) })) : addresses.length === 0 ? (_jsxs(Div, { className: "rounded-xl border-2 border-dashed border-zinc-200 dark:border-slate-700 py-16 flex flex-col items-center gap-3", children: [_jsx(MapPin, { className: "h-8 w-8 text-zinc-300 dark:text-slate-600" }), _jsx(Text, { className: "text-sm text-zinc-500 dark:text-zinc-400", children: "No pickup addresses yet" }), _jsx(Button, { size: "sm", variant: "outline", onClick: openAdd, children: "Add your first address" })] })) : (_jsxs(_Fragment, { children: [_jsxs(Row, { justify: "end", className: "mb-2", children: [_jsx(Button, { size: "sm", variant: listView === "table" ? "primary" : "ghost", onClick: () => setListView("table"), children: "Table" }), _jsx(Button, { size: "sm", variant: listView === "cards" ? "primary" : "ghost", onClick: () => setListView("cards"), children: "Cards" })] }), listView === "cards" ? (_jsx("div", { className: "grid gap-3", 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: "overflow-x-auto rounded-lg border border-zinc-200 dark:border-slate-700", children: _jsxs("table", { className: "w-full text-sm", children: [_jsx("thead", { className: "bg-zinc-50 dark:bg-slate-800", children: _jsxs("tr", { children: [_jsx("th", { className: "text-left px-3 py-2 font-semibold", children: "Label" }), _jsx("th", { className: "text-left px-3 py-2 font-semibold", children: "Name" }), _jsx("th", { className: "text-left px-3 py-2 font-semibold", children: "City" }), _jsx("th", { className: "text-left px-3 py-2 font-semibold", children: "Phone" }), _jsx("th", { className: "text-right px-3 py-2 font-semibold", children: "Actions" })] }) }), _jsx("tbody", { children: addresses.map((addr) => (_jsxs("tr", { className: `border-t border-zinc-100 dark:border-slate-700 ${deletingId === addr.id ? "opacity-50" : ""}`, children: [_jsx("td", { className: "px-3 py-2", children: addr.label }), _jsx("td", { className: "px-3 py-2", children: addr.fullName }), _jsxs("td", { className: "px-3 py-2", children: [addr.city, ", ", addr.state] }), _jsx("td", { className: "px-3 py-2 tabular-nums", children: addr.phone }), _jsx("td", { className: "px-3 py-2 text-right", children: _jsxs(Row, { justify: "end", className: "gap-1", children: [_jsx(Button, { size: "sm", variant: "ghost", onClick: () => openEdit(addr), children: ROW_ACTION_META[ROW_ACTION_ID.EDIT].label }), _jsx(Button, { size: "sm", variant: "ghost", onClick: () => handleDelete(addr), children: ROW_ACTION_META[ROW_ACTION_ID.DELETE].label })] }) })] }, addr.id))) })] }) }))] }))] }), _jsx(SideDrawer, { isOpen: drawerOpen, onClose: closeDrawer, title: editingId ? "Edit Address" : "Add Address", footer: _jsxs("div", { className: "flex gap-2", 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("div", { className: "space-y-4 py-1", children: [saveError && (_jsx(Div, { className: "rounded-lg border border-error/20 bg-error-surface px-3 py-2 text-sm text-error", children: saveError })), _jsx(Field, { label: "Label *", hint: "e.g. Warehouse, Shop, Home", children: _jsx("input", { type: "text", value: draft.label, onChange: handleTextField("label"), placeholder: "Warehouse", maxLength: 60, className: INPUT_CLS }) }), _jsxs("div", { className: CLS_GRID_2_COL, children: [_jsx(Field, { label: "Full Name *", children: _jsx("input", { type: "text", value: draft.fullName, onChange: handleTextField("fullName"), placeholder: "Ravi Kumar", maxLength: 100, className: INPUT_CLS }) }), _jsx(Field, { label: "Phone *", children: _jsx("input", { type: "tel", value: draft.phone, onChange: handleTextField("phone"), placeholder: "+91 98765 43210", maxLength: 20, className: INPUT_CLS }) })] }), _jsx(Field, { label: "Address Line 1 *", children: _jsx("input", { type: "text", value: draft.addressLine1, onChange: handleTextField("addressLine1"), placeholder: "Shop 12, Main Market", maxLength: 200, className: INPUT_CLS }) }), _jsx(Field, { label: "Address Line 2", children: _jsx("input", { type: "text", value: draft.addressLine2, onChange: handleTextField("addressLine2"), placeholder: "Building / Floor (optional)", maxLength: 200, className: INPUT_CLS }) }), _jsx(Field, { label: "Landmark", children: _jsx("input", { type: "text", value: draft.landmark, onChange: handleTextField("landmark"), placeholder: "Near metro station (optional)", maxLength: 100, className: INPUT_CLS }) }), _jsxs("div", { className: CLS_GRID_2_COL, children: [_jsx(Field, { label: "City *", children: _jsx("input", { type: "text", value: draft.city, onChange: handleTextField("city"), placeholder: "Mumbai", maxLength: 100, className: INPUT_CLS }) }), _jsx(Field, { label: "State *", children: _jsx("input", { type: "text", value: draft.state, onChange: handleTextField("state"), placeholder: "Maharashtra", maxLength: 100, className: INPUT_CLS }) })] }), _jsxs("div", { className: CLS_GRID_2_COL, children: [_jsx(Field, { label: "Postal Code *", children: _jsx("input", { type: "text", value: draft.postalCode, onChange: handleTextField("postalCode"), placeholder: "400001", maxLength: 10, className: INPUT_CLS }) }), _jsx(Field, { label: "Country *", children: _jsx("input", { type: "text", value: draft.country, onChange: handleTextField("country"), placeholder: "India", maxLength: 60, className: INPUT_CLS }) })] }), _jsxs("label", { className: "flex items-center gap-3 cursor-pointer", children: [_jsx("input", { type: "checkbox", checked: draft.isDefault, onChange: (e) => set("isDefault", e.target.checked), className: "h-4 w-4 rounded border-zinc-300 dark:border-slate-600 text-[var(--appkit-color-primary)] focus:ring-[var(--appkit-color-primary)]" }), _jsx("span", { className: "text-sm text-zinc-700 dark:text-zinc-300", children: "Set as default pickup address" })] })] }) }), deleteTargetAddr && (_jsx(ConfirmDeleteModal, { isOpen: true, title: "Delete Address", message: `Delete address "${deleteTargetAddr.label}"? This cannot be undone.`, onConfirm: () => { deleteById(deleteTargetAddr.id); setDeleteTargetAddr(null); }, onClose: () => setDeleteTargetAddr(null), isDeleting: deletingId === deleteTargetAddr.id }))] }));
|
|
139
139
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import type {
|
|
3
|
-
export interface SellerAuctionsViewProps extends
|
|
2
|
+
import type { ListingLayoutProps } from "../../../ui";
|
|
3
|
+
export interface SellerAuctionsViewProps extends ListingLayoutProps {
|
|
4
4
|
renderHeader?: (onAdd: () => void) => React.ReactNode;
|
|
5
5
|
onEditClick?: (id: string) => void;
|
|
6
6
|
onDelete?: (id: string) => Promise<void>;
|
|
7
7
|
onBulkDelete?: (ids: string[]) => Promise<void>;
|
|
8
8
|
}
|
|
9
|
-
export declare function SellerAuctionsView({
|
|
9
|
+
export declare function SellerAuctionsView({ children, onEditClick, onDelete, onBulkDelete, ...props }: SellerAuctionsViewProps): import("react/jsx-runtime").JSX.Element;
|