@mohasinac/appkit 2.8.2 → 2.8.3
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/classified/ClassifiedDetailView.js +7 -1
- package/dist/_internal/client/features/digital-code/CodeRevealPanel.js +4 -1
- package/dist/_internal/client/features/digital-code/DigitalCodeDetailView.js +7 -1
- package/dist/_internal/client/features/layout/DashboardLayoutClient.js +3 -2
- package/dist/_internal/client/features/live/LiveItemDetailView.js +11 -2
- package/dist/_internal/client/scaffolds/AppShell.js +2 -1
- package/dist/_internal/client/scaffolds/DashboardScaffold.js +2 -1
- package/dist/_internal/server/features/checkout/actions.js +40 -39
- package/dist/_internal/shared/actions/action-registry.js +6 -0
- package/dist/_internal/shared/config/index.d.ts +1 -1
- package/dist/_internal/shared/config/schema.d.ts +0 -8
- package/dist/client-entry.d.ts +1 -1
- package/dist/client.d.ts +1 -1
- package/dist/client.js +1 -1
- package/dist/configs/next.js +12 -22
- package/dist/constants/api-endpoints.d.ts +6 -0
- package/dist/constants/api-endpoints.js +2 -0
- package/dist/core/hooks/useSiteSettings.d.ts +1 -1
- package/dist/features/about/components/AboutView.js +5 -2
- package/dist/features/about/components/FAQPageView.js +3 -3
- package/dist/features/about/components/FeesView.js +13 -5
- package/dist/features/about/components/HelpPageView.js +9 -5
- package/dist/features/about/components/HowAuctionsWorkView.js +9 -5
- package/dist/features/about/components/HowCheckoutWorksView.js +9 -5
- package/dist/features/about/components/HowOffersWorkView.js +10 -5
- package/dist/features/about/components/HowOrdersWorkView.js +10 -5
- package/dist/features/about/components/HowPayoutsWorkView.js +9 -5
- package/dist/features/about/components/HowPreOrdersWorkView.js +9 -5
- package/dist/features/about/components/HowReviewsWorkView.js +9 -5
- package/dist/features/about/components/PolicyPageView.js +3 -3
- package/dist/features/about/components/PublicProfileView.js +11 -4
- package/dist/features/about/components/SecurityPrivacyView.js +8 -4
- package/dist/features/about/components/ShippingPolicyView.js +3 -2
- package/dist/features/about/components/TrackOrderView.js +2 -2
- package/dist/features/about/components/UnauthorizedView.js +3 -3
- package/dist/features/account/components/AddressBook.js +1 -1
- package/dist/features/account/components/AddressForm.js +2 -2
- package/dist/features/account/components/AddressInlineSelect.d.ts +24 -0
- package/dist/features/account/components/AddressInlineSelect.js +78 -0
- package/dist/features/account/components/AddressSelectorCreate.d.ts +2 -1
- package/dist/features/account/components/AddressSelectorCreate.js +5 -32
- package/dist/features/account/components/AddressesIndexListing.js +3 -3
- package/dist/features/account/components/ChatWindow.js +2 -1
- package/dist/features/account/components/NotificationBell.js +13 -7
- package/dist/features/account/components/NotificationPreferencesPanel.js +4 -1
- package/dist/features/account/components/UserOffersPanel.js +2 -1
- package/dist/features/account/components/UserSidebar.js +11 -7
- package/dist/features/account/components/UserSupportView.js +13 -4
- package/dist/features/account/components/index.d.ts +2 -0
- package/dist/features/account/components/index.js +1 -0
- package/dist/features/account/hooks/useAccount.d.ts +2 -2
- package/dist/features/account/hooks/useAddressSelector.d.ts +1 -1
- package/dist/features/account/hooks/useAddresses.d.ts +2 -2
- package/dist/features/account/hooks/useNotifications.d.ts +1 -1
- package/dist/features/account/hooks/useProfile.d.ts +1 -1
- package/dist/features/account/hooks/usePublicProfile.d.ts +2 -2
- package/dist/features/addresses/repository/addresses.repository.d.ts +1 -0
- package/dist/features/addresses/repository/addresses.repository.js +13 -0
- package/dist/features/admin/components/AdminAdEditorView.js +8 -5
- package/dist/features/admin/components/AdminAddressEditorView.js +5 -5
- package/dist/features/admin/components/AdminAdsView.js +10 -7
- package/dist/features/admin/components/AdminBlogEditorView.js +15 -9
- package/dist/features/admin/components/AdminBrandEditorView.js +10 -4
- package/dist/features/admin/components/AdminBrandsView.js +4 -4
- package/dist/features/admin/components/AdminBundleEditorView.js +4 -5
- package/dist/features/admin/components/AdminBundlesView.js +3 -3
- package/dist/features/admin/components/AdminCarouselEditorView.js +6 -3
- package/dist/features/admin/components/AdminCarouselView.js +6 -6
- package/dist/features/admin/components/AdminCatalogGuideView.js +2 -1
- package/dist/features/admin/components/AdminCategoriesView.js +5 -5
- package/dist/features/admin/components/AdminCategoryEditorView.js +11 -5
- package/dist/features/admin/components/AdminContactEditorView.js +8 -1
- package/dist/features/admin/components/AdminCouponEditorView.js +23 -5
- package/dist/features/admin/components/AdminEmployeeEditorView.js +7 -4
- package/dist/features/admin/components/AdminFaqEditorView.js +9 -3
- package/dist/features/admin/components/AdminFaqsView.js +4 -4
- package/dist/features/admin/components/AdminFeatureEditorView.js +7 -1
- package/dist/features/admin/components/AdminFeatureFlagsView.js +4 -1
- package/dist/features/admin/components/AdminFilterBar.js +4 -4
- package/dist/features/admin/components/AdminGroupedListingsView.js +65 -30
- package/dist/features/admin/components/AdminGuideHubView.js +4 -1
- package/dist/features/admin/components/AdminMediaView.js +4 -1
- package/dist/features/admin/components/AdminNavigationView.js +7 -4
- package/dist/features/admin/components/AdminNotificationsView.js +2 -2
- package/dist/features/admin/components/AdminOrderEditorView.js +2 -2
- package/dist/features/admin/components/AdminPageHeader.js +5 -2
- package/dist/features/admin/components/AdminPrizeDrawsView.js +5 -5
- package/dist/features/admin/components/AdminProductEditorView.js +12 -5
- package/dist/features/admin/components/AdminProductsView.js +4 -4
- package/dist/features/admin/components/AdminReviewsView.js +2 -2
- package/dist/features/admin/components/AdminScammerEditorView.js +6 -2
- package/dist/features/admin/components/AdminScammersView.js +3 -3
- package/dist/features/admin/components/AdminSectionsView.js +20 -22
- package/dist/features/admin/components/AdminSessionsManager.js +2 -1
- package/dist/features/admin/components/AdminSessionsView.js +2 -2
- package/dist/features/admin/components/AdminSidebar.js +11 -7
- package/dist/features/admin/components/AdminSiteConfigGuideView.js +2 -1
- package/dist/features/admin/components/AdminSiteSettingsView.js +5 -1
- package/dist/features/admin/components/AdminStoreAddressesView.js +2 -2
- package/dist/features/admin/components/AdminStoreEditorView.js +5 -5
- package/dist/features/admin/components/AdminSublistingCategoryEditorView.js +3 -3
- package/dist/features/admin/components/AdminSupportTicketDetailView.js +10 -3
- package/dist/features/admin/components/AdminSupportTicketsView.js +3 -3
- package/dist/features/admin/components/AdminTrustGuideView.js +3 -3
- package/dist/features/admin/components/AdminUsersGuideView.js +3 -3
- package/dist/features/admin/components/AdminViewCards.js +12 -6
- package/dist/features/admin/components/BrandQuickCreateForm.js +2 -2
- package/dist/features/admin/components/CategoryQuickCreateForm.js +2 -2
- package/dist/features/admin/components/DashboardStats.js +9 -3
- package/dist/features/admin/components/DataListingView.js +3 -3
- package/dist/features/admin/components/DataTable.js +11 -7
- package/dist/features/admin/components/DrawerFormFooter.js +2 -2
- package/dist/features/admin/components/QuickEditMenu.js +2 -1
- package/dist/features/admin/components/analytics/AdminAnalyticsCharts.js +5 -1
- package/dist/features/admin/hooks/useAdmin.d.ts +1 -1
- package/dist/features/admin/hooks/useAdminSectionsListing.d.ts +1 -1
- package/dist/features/admin/hooks/useChat.d.ts +1 -1
- package/dist/features/auctions/components/AuctionBidsTable.js +4 -1
- package/dist/features/auctions/components/AuctionDetailPageView.js +14 -6
- package/dist/features/auctions/components/CollapsibleBidHistory.js +5 -1
- package/dist/features/auctions/components/MarketplaceAuctionCard.js +9 -3
- package/dist/features/auctions/components/MarketplaceAuctionGrid.js +8 -2
- package/dist/features/auctions/components/PlaceBidFormClient.js +4 -1
- package/dist/features/auctions/hooks/useAuctions.d.ts +8 -8
- package/dist/features/auth/components/RegisterForm.js +2 -2
- package/dist/features/auth/components/VerifyEmailView.js +5 -2
- package/dist/features/auth/hooks/useAuth.d.ts +2 -2
- package/dist/features/before-after/components/BeforeAfterSlider.js +1 -1
- package/dist/features/blog/components/BlogFeaturedCard.js +8 -1
- package/dist/features/blog/components/BlogIndexListing.js +11 -5
- package/dist/features/blog/components/BlogListView.js +11 -3
- package/dist/features/blog/components/BlogPostView.js +10 -3
- package/dist/features/cart/components/CartDrawer.js +11 -3
- package/dist/features/cart/components/CartSummary.js +2 -2
- package/dist/features/cart/components/CheckoutOtpModal.js +2 -1
- package/dist/features/cart/hooks/useCart.d.ts +1 -1
- package/dist/features/cart/hooks/useCartQuery.d.ts +1 -1
- package/dist/features/cart/hooks/useCheckoutReadQueries.d.ts +2 -2
- package/dist/features/cart/hooks/useOrder.d.ts +2 -2
- package/dist/features/categories/components/BrandDetailPageView.js +5 -2
- package/dist/features/categories/components/BrandDetailTabs.js +5 -1
- package/dist/features/categories/components/BundleDetailView.js +6 -3
- package/dist/features/categories/components/BundleDynamicRuleEditor.js +3 -1
- package/dist/features/categories/components/BundleItemsPicker.js +10 -3
- package/dist/features/categories/components/CategoriesIndexListing.js +12 -6
- package/dist/features/categories/components/CategoryBundlesListing.js +5 -2
- package/dist/features/categories/components/CategoryDetailPageView.js +6 -2
- package/dist/features/categories/components/CategoryDetailTabs.js +5 -1
- package/dist/features/categories/components/CategoryForm.js +6 -3
- package/dist/features/categories/components/CategoryGrid.js +9 -2
- package/dist/features/categories/components/CategoryProductsListing.js +10 -4
- package/dist/features/categories/components/CategorySelectorCreate.js +3 -3
- package/dist/features/categories/components/CategorySortSelect.js +1 -1
- package/dist/features/categories/components/CategoryStoresListing.js +3 -3
- package/dist/features/categories/components/CategoryTableColumns.js +10 -6
- package/dist/features/categories/components/CategoryTree.js +1 -1
- package/dist/features/categories/hooks/useCategories.d.ts +3 -3
- package/dist/features/categories/hooks/useCategorySelector.d.ts +3 -3
- package/dist/features/categories/hooks/useCategoryTree.d.ts +1 -1
- package/dist/features/checkout/hooks/useCheckoutApi.d.ts +2 -2
- package/dist/features/classified/components/ClassifiedFilters.js +2 -2
- package/dist/features/classified/components/ClassifiedIndexListing.js +9 -3
- package/dist/features/collections/components/CollectionCard.js +2 -1
- package/dist/features/collections/hooks/useCollections.d.ts +2 -2
- package/dist/features/contact/components/ContactForm.js +4 -2
- package/dist/features/contact/components/ContactInfoSidebar.js +4 -1
- package/dist/features/copilot/components/AdminCopilotView.js +13 -5
- package/dist/features/digital-codes/components/DigitalCodesIndexListing.js +9 -3
- package/dist/features/events/components/AdminEventEditorView.js +62 -40
- package/dist/features/events/components/AdminEventEntriesView.js +9 -6
- package/dist/features/events/components/EventCard.js +7 -1
- package/dist/features/events/components/EventFormDrawer.js +2 -1
- package/dist/features/events/components/EventLeaderboard.js +4 -4
- package/dist/features/events/components/EventOfferCard.js +4 -1
- package/dist/features/events/components/EventParticipateView.js +3 -2
- package/dist/features/events/components/EventPollWidget.js +6 -5
- package/dist/features/events/components/EventRaffleEntryForm.js +5 -2
- package/dist/features/events/components/EventRaffleWinnerView.js +7 -1
- package/dist/features/events/components/EventRafflesSection.js +2 -2
- package/dist/features/events/components/EventSaleBanner.js +5 -2
- package/dist/features/events/components/EventsIndexListing.js +8 -2
- package/dist/features/events/components/EventsListView.js +4 -1
- package/dist/features/events/components/SpinWheelView.js +7 -2
- package/dist/features/events/hooks/useEvent.d.ts +3 -3
- package/dist/features/events/hooks/useEvents.d.ts +1 -1
- package/dist/features/events/schemas/firestore.d.ts +1 -0
- package/dist/features/events/types/index.d.ts +1 -0
- package/dist/features/faq/components/ContactCTA.js +4 -1
- package/dist/features/faq/components/FAQCategorySidebar.js +2 -2
- package/dist/features/faq/components/FAQHelpfulButtons.js +8 -5
- package/dist/features/faq/components/FAQPageContent.js +5 -5
- package/dist/features/faq/components/FAQSortDropdown.js +2 -2
- package/dist/features/faq/hooks/useFAQs.d.ts +1 -1
- package/dist/features/faq/hooks/useFaqList.d.ts +15 -15
- package/dist/features/filters/AsyncFacetSection.js +4 -2
- package/dist/features/filters/FilterFacetSection.js +14 -6
- package/dist/features/filters/RangeFilter.js +4 -2
- package/dist/features/filters/SwitchFilter.js +2 -1
- package/dist/features/forms/Checkbox.js +1 -1
- package/dist/features/forms/Radio.js +1 -1
- package/dist/features/forms/Slider.js +1 -1
- package/dist/features/homepage/components/AdSlot.js +4 -4
- package/dist/features/homepage/components/AdvertisementBanner.js +13 -4
- package/dist/features/homepage/components/AnnouncementBar.js +2 -1
- package/dist/features/homepage/components/BeforeAfterCard.js +8 -2
- package/dist/features/homepage/components/BrandsSection.js +6 -3
- package/dist/features/homepage/components/CTABannerSection.js +2 -2
- package/dist/features/homepage/components/CharacterHotspot.js +5 -2
- package/dist/features/homepage/components/CharacterHotspotForm.js +8 -4
- package/dist/features/homepage/components/CustomCardsSection.js +13 -7
- package/dist/features/homepage/components/CustomerReviewsSection.js +9 -3
- package/dist/features/homepage/components/FAQSection.js +7 -4
- package/dist/features/homepage/components/FeaturedBundlesSection.js +8 -2
- package/dist/features/homepage/components/FeaturedResultsSection.js +1 -1
- package/dist/features/homepage/components/GoogleReviewsSection.js +14 -8
- package/dist/features/homepage/components/HeroCarousel.js +1 -1
- package/dist/features/homepage/components/HomepageSkeleton.js +7 -1
- package/dist/features/homepage/components/HowItWorksInfoView.js +2 -2
- package/dist/features/homepage/components/HowItWorksSection.js +2 -2
- package/dist/features/homepage/components/NewsletterBanner.js +3 -2
- package/dist/features/homepage/components/NewsletterSection.js +5 -2
- package/dist/features/homepage/components/PromoGrid.js +4 -1
- package/dist/features/homepage/components/SectionCarousel.js +7 -4
- package/dist/features/homepage/components/SecurityHighlightsSection.js +3 -3
- package/dist/features/homepage/components/ShopByCategorySection.js +10 -4
- package/dist/features/homepage/components/SiteFeaturesSection.js +5 -2
- package/dist/features/homepage/components/SocialFeedSection.js +4 -4
- package/dist/features/homepage/components/SocialPostCard.js +6 -3
- package/dist/features/homepage/components/TrustFeaturesSection.js +5 -5
- package/dist/features/homepage/components/TrustIndicatorsSection.js +5 -2
- package/dist/features/homepage/components/WelcomeSection.js +1 -1
- package/dist/features/homepage/components/WhatsAppCommunitySection.js +3 -3
- package/dist/features/homepage/hooks/useBlogArticles.d.ts +1 -1
- package/dist/features/homepage/hooks/useFeaturedAuctions.d.ts +1 -1
- package/dist/features/homepage/hooks/useFeaturedPreOrders.d.ts +1 -1
- package/dist/features/homepage/hooks/useFeaturedProducts.d.ts +1 -1
- package/dist/features/homepage/hooks/useFeaturedStores.d.ts +1 -1
- package/dist/features/homepage/hooks/useHeroCarousel.d.ts +1 -1
- package/dist/features/homepage/hooks/useHomepageEvents.d.ts +1 -1
- package/dist/features/homepage/hooks/useHomepageReviews.d.ts +1 -1
- package/dist/features/homepage/hooks/useHomepageSections.d.ts +1 -1
- package/dist/features/homepage/hooks/useTopBrands.d.ts +1 -1
- package/dist/features/homepage/hooks/useTopCategories.d.ts +1 -1
- package/dist/features/layout/AppLayoutShell.js +2 -1
- package/dist/features/layout/BackToTop.js +1 -1
- package/dist/features/layout/BottomActions.js +4 -3
- package/dist/features/layout/BottomNavItem.js +1 -1
- package/dist/features/layout/BottomSheet.js +4 -1
- package/dist/features/layout/FooterLayout.js +1 -1
- package/dist/features/layout/NavbarLayout.js +4 -1
- package/dist/features/layout/SidebarLayout.js +5 -2
- package/dist/features/live/components/LiveItemFilters.js +2 -2
- package/dist/features/live/components/LiveItemsIndexListing.js +9 -3
- package/dist/features/loyalty/components/CoinsDisplay.js +4 -2
- package/dist/features/loyalty/hooks/useLoyaltyBalance.d.ts +1 -1
- package/dist/features/media/AvatarUpload.js +2 -2
- package/dist/features/media/MediaLightbox.js +3 -2
- package/dist/features/media/modals/VideoThumbnailSelector.js +4 -1
- package/dist/features/media/modals/VideoTrimModal.js +1 -1
- package/dist/features/media/upload/CameraCapture.js +1 -1
- package/dist/features/media/upload/ImageUpload.js +4 -1
- package/dist/features/media/upload/MediaUploadField.js +11 -2
- package/dist/features/media/upload/MediaUploadList.js +5 -1
- package/dist/features/orders/components/MarketplaceOrderCard.js +2 -2
- package/dist/features/orders/components/OrdersList.js +2 -1
- package/dist/features/orders/components/RefundHistoryTable.js +4 -1
- package/dist/features/orders/components/RefundRequestView.js +2 -1
- package/dist/features/orders/hooks/useOrders.d.ts +2 -2
- package/dist/features/payments/hooks/usePayments.d.ts +1 -1
- package/dist/features/pre-orders/components/MarketplacePreorderCard.js +5 -1
- package/dist/features/pre-orders/components/PreOrderActionsClient.js +3 -3
- package/dist/features/pre-orders/components/PreOrderBadge.js +2 -1
- package/dist/features/pre-orders/components/PreOrderDetailPageView.js +16 -7
- package/dist/features/pre-orders/components/PreOrdersIndexListing.js +32 -24
- package/dist/features/pre-orders/hooks/usePreOrders.d.ts +2 -2
- package/dist/features/products/columns/productTableColumns.js +9 -4
- package/dist/features/products/components/AuctionsIndexListing.js +9 -3
- package/dist/features/products/components/BidHistory.js +4 -4
- package/dist/features/products/components/CompareOverlay.js +10 -2
- package/dist/features/products/components/CustomFieldsEditor.js +2 -1
- package/dist/features/products/components/CustomSectionTabContent.js +2 -2
- package/dist/features/products/components/CustomSectionsEditor.js +3 -2
- package/dist/features/products/components/GroupSettingsPanel.js +34 -26
- package/dist/features/products/components/MakeOfferButton.js +6 -2
- package/dist/features/products/components/MakeOfferForm.js +2 -1
- package/dist/features/products/components/MarketplaceBundleCard.js +6 -3
- package/dist/features/products/components/MarketplacePrizeDrawCard.js +3 -2
- package/dist/features/products/components/PlaceBidForm.js +2 -1
- package/dist/features/products/components/PrizeDrawCollage.js +6 -2
- package/dist/features/products/components/PrizeDrawDetailPageView.js +6 -1
- package/dist/features/products/components/PrizeDrawItemsEditor.js +4 -2
- package/dist/features/products/components/PrizeDrawsIndexListing.js +6 -3
- package/dist/features/products/components/PrizeDrawsSection.js +2 -2
- package/dist/features/products/components/PrizeRevealModal.js +5 -1
- package/dist/features/products/components/ProductDetailPageView.js +32 -16
- package/dist/features/products/components/ProductFeatureBadges.js +9 -9
- package/dist/features/products/components/ProductForm.d.ts +11 -1
- package/dist/features/products/components/ProductForm.js +10 -5
- package/dist/features/products/components/ProductGalleryClient.js +8 -4
- package/dist/features/products/components/ProductGradingTab.js +4 -1
- package/dist/features/products/components/ProductGrid.js +35 -14
- package/dist/features/products/components/ProductInfo.js +2 -1
- package/dist/features/products/components/ProductTabs.js +2 -1
- package/dist/features/products/components/ProductTabsShell.js +5 -1
- package/dist/features/products/components/ProductsIndexListing.js +32 -24
- package/dist/features/products/components/ProductsIndexPageView.js +2 -2
- package/dist/features/products/components/RelatedProducts.js +3 -3
- package/dist/features/products/components/ShowGroupSection.js +10 -6
- package/dist/features/products/components/SublistingCarouselSection.js +7 -3
- package/dist/features/products/components/SublistingCategorySelect.d.ts +3 -1
- package/dist/features/products/components/SublistingCategorySelect.js +4 -37
- package/dist/features/products/constants/action-defs.js +3 -3
- package/dist/features/products/hooks/useProductDetail.d.ts +1 -1
- package/dist/features/products/hooks/useRelatedProducts.d.ts +1 -1
- package/dist/features/promotions/components/CouponCard.js +5 -3
- package/dist/features/promotions/components/CouponsIndexListing.js +7 -3
- package/dist/features/promotions/hooks/usePromotions.d.ts +2 -2
- package/dist/features/promotions/repository/coupons.repository.d.ts +8 -0
- package/dist/features/promotions/repository/coupons.repository.js +2 -0
- package/dist/features/reviews/components/ReviewDetailPageView.js +3 -3
- package/dist/features/reviews/components/ReviewDetailShell.js +15 -3
- package/dist/features/reviews/components/ReviewSummary.js +4 -2
- package/dist/features/reviews/components/ReviewsIndexListing.js +8 -2
- package/dist/features/reviews/components/ReviewsList.js +1 -1
- package/dist/features/reviews/hooks/useReviews.d.ts +2 -2
- package/dist/features/scams/components/ScamAwarenessModal.js +2 -2
- package/dist/features/scams/components/ScamProfileView.js +3 -3
- package/dist/features/scams/components/ScamRegistryView.js +6 -4
- package/dist/features/search/components/Search.js +9 -6
- package/dist/features/search/components/SearchFiltersRow.js +1 -1
- package/dist/features/search/components/SearchResultsSection.js +1 -1
- package/dist/features/search/hooks/useSearch.d.ts +2 -2
- package/dist/features/seller/components/CouponInlineSelect.d.ts +22 -0
- package/dist/features/seller/components/CouponInlineSelect.js +103 -0
- package/dist/features/seller/components/GroupInlineSelect.d.ts +23 -0
- package/dist/features/seller/components/GroupInlineSelect.js +80 -0
- package/dist/features/seller/components/PhysicalLocationModal.js +2 -1
- package/dist/features/seller/components/PrintCenterView.js +2 -1
- package/dist/features/seller/components/ProductInlineSelect.d.ts +24 -0
- package/dist/features/seller/components/ProductInlineSelect.js +42 -0
- package/dist/features/seller/components/QuickProductForm.js +4 -1
- package/dist/features/seller/components/SellerAddressesView.js +8 -3
- package/dist/features/seller/components/SellerAnalyticsAlertsView.js +6 -3
- package/dist/features/seller/components/SellerAnalyticsView.js +2 -2
- package/dist/features/seller/components/SellerBidsView.js +7 -7
- package/dist/features/seller/components/SellerBundlesView.js +2 -1
- package/dist/features/seller/components/SellerCouponEditorView.d.ts +2 -0
- package/dist/features/seller/components/SellerCouponEditorView.js +15 -3
- package/dist/features/seller/components/SellerCouponsView.js +1 -1
- package/dist/features/seller/components/SellerDashboardView.js +2 -2
- package/dist/features/seller/components/SellerDigitalCodesView.js +2 -2
- package/dist/features/seller/components/SellerGoogleReviewsView.js +2 -2
- package/dist/features/seller/components/SellerGroupedListingsView.js +5 -5
- package/dist/features/seller/components/SellerOrdersView.js +13 -10
- package/dist/features/seller/components/SellerPayoutMethodsView.js +5 -4
- package/dist/features/seller/components/SellerPayoutRequestView.js +5 -1
- package/dist/features/seller/components/SellerPayoutSettingsView.js +5 -2
- package/dist/features/seller/components/SellerPreOrdersView.js +6 -6
- package/dist/features/seller/components/SellerPrizeDrawsView.js +6 -6
- package/dist/features/seller/components/SellerProductShell.js +1 -1
- package/dist/features/seller/components/SellerProductsCards.js +4 -1
- package/dist/features/seller/components/SellerProductsView.js +5 -5
- package/dist/features/seller/components/SellerReviewsView.js +7 -3
- package/dist/features/seller/components/SellerShippingConfigsView.js +4 -4
- package/dist/features/seller/components/SellerShippingView.js +1 -1
- package/dist/features/seller/components/SellerSidebar.js +15 -8
- package/dist/features/seller/components/SellerStoreCategoriesView.js +1 -1
- package/dist/features/seller/components/SellerStorefrontView.js +2 -2
- package/dist/features/seller/components/SellerTemplatesView.js +7 -4
- package/dist/features/seller/components/SublistingInlineSelect.d.ts +19 -0
- package/dist/features/seller/components/SublistingInlineSelect.js +83 -0
- package/dist/features/seller/components/analytics/SellerTopProducts.js +1 -1
- package/dist/features/seller/components/index.d.ts +8 -0
- package/dist/features/seller/components/index.js +4 -0
- package/dist/features/seller/hooks/useSellerPayouts.d.ts +3 -3
- package/dist/features/seller/hooks/useSellerStore.d.ts +6 -6
- package/dist/features/seller/hooks/useSellerStorefront.d.ts +2 -2
- package/dist/features/shell/FormShell.js +10 -2
- package/dist/features/shell/QuickFormDrawer.js +5 -5
- package/dist/features/shell/StepForm.js +6 -6
- package/dist/features/site-settings/components/ActionPermissionsManager.js +8 -4
- package/dist/features/site-settings/components/NavPermissionsManager.js +7 -4
- package/dist/features/stores/components/InteractiveStoreCard.js +5 -1
- package/dist/features/stores/components/StoreAboutView.js +4 -1
- package/dist/features/stores/components/StoreAddressSelectorCreate.d.ts +2 -1
- package/dist/features/stores/components/StoreAddressSelectorCreate.js +5 -31
- package/dist/features/stores/components/StoreAuctionsListing.js +6 -3
- package/dist/features/stores/components/StoreGuideHubView.js +5 -2
- package/dist/features/stores/components/StoreHeader.js +8 -1
- package/dist/features/stores/components/StorePreOrdersListing.js +6 -3
- package/dist/features/stores/components/StoreProductsListing.js +6 -3
- package/dist/features/stores/components/StoreReviewsListing.js +8 -2
- package/dist/features/stores/components/StoresIndexListing.js +12 -6
- package/dist/features/stores/hooks/useStoreAddressSelector.d.ts +1 -1
- package/dist/features/stores/hooks/useStores.d.ts +6 -6
- package/dist/features/whatsapp-bot/components/SellerWhatsAppSettingsView.js +7 -1
- package/dist/features/whatsapp-bot/components/WhatsAppChatButton.js +2 -1
- package/dist/features/wishlist/components/WishlistPage.js +2 -1
- package/dist/features/wishlist/hooks/useUserWishlist.d.ts +15 -15
- package/dist/features/wishlist/hooks/useWishlist.d.ts +1 -1
- package/dist/features/wishlist/hooks/useWishlistWithGuest.d.ts +1 -1
- package/dist/index.d.ts +10 -0
- package/dist/index.js +13 -1
- package/dist/next/components/GlobalError.js +2 -2
- package/dist/next/routing/route-map.d.ts +2 -0
- package/dist/next/routing/route-map.js +1 -0
- package/dist/react/ErrorBoundary.js +2 -2
- package/dist/styles.css +2 -1
- package/dist/tailwind-utilities.css +1 -1
- package/dist/ui/DataTable.js +17 -16
- package/dist/ui/components/DateInput.js +2 -2
- package/dist/ui/components/DetailPageGallery.js +4 -1
- package/dist/ui/components/DetailPageTabs.js +6 -2
- package/dist/ui/components/ImageLightbox.js +5 -3
- package/dist/ui/components/Input.js +6 -3
- package/dist/ui/components/Layout.d.ts +4 -0
- package/dist/ui/components/Layout.js +1 -1
- package/dist/ui/components/Layout.style.css +1 -0
- package/dist/ui/components/ListingFilterDrawer.js +4 -1
- package/dist/ui/components/ListingLayout.js +9 -8
- package/dist/ui/components/ListingToolbar.js +5 -1
- package/dist/ui/components/PaginatedSelect.d.ts +1 -2
- package/dist/ui/components/PaginatedSelect.js +1 -2
- package/dist/ui/components/Radio.js +1 -1
- package/dist/ui/components/Select.js +2 -1
- package/dist/ui/components/Slider.js +1 -1
- package/dist/ui/components/VacationBanner.js +2 -1
- package/dist/ui/components/surface-tokens.d.ts +1 -0
- package/dist/ui/components/surface-tokens.js +1 -0
- package/package.json +11 -2
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { useState } from "react";
|
|
4
|
+
import { Div } from "../../../ui/components/Div";
|
|
5
|
+
const __O = {
|
|
6
|
+
xAuto: "overflow-x-auto",
|
|
7
|
+
};
|
|
4
8
|
const STATIC_TABS = [
|
|
5
9
|
{ id: "description", label: "Description" },
|
|
6
10
|
{ id: "specs", label: "Specifications" },
|
|
@@ -35,7 +39,7 @@ export function ProductTabsShell({ descriptionContent, specsContent, gradingCont
|
|
|
35
39
|
if (allTabs.length === 0)
|
|
36
40
|
return null;
|
|
37
41
|
const activeContent = allTabs.find((t) => t.id === activeId)?.content;
|
|
38
|
-
return (_jsxs(
|
|
42
|
+
return (_jsxs(Div, { className: `mt-8 ${className}`, children: [_jsx(Div, { className: `mb-6 flex gap-1 ${__O.xAuto} border-b border-zinc-200 dark:border-zinc-700 pb-px`, children: allTabs.map((t) => (_jsx("button", { type: "button", onClick: () => setActiveId(t.id), className: `flex-shrink-0 -mb-px pb-3 px-4 text-sm font-medium border-b-2 transition-colors ${activeId === t.id
|
|
39
43
|
? "border-[var(--appkit-color-primary,#6366f1)] text-[var(--appkit-color-primary,#6366f1)]"
|
|
40
44
|
: "border-transparent text-zinc-500 dark:text-zinc-400 hover:text-zinc-700 dark:hover:text-zinc-300"}`, children: t.label }, t.id))) }), _jsx("div", { children: activeContent })] }));
|
|
41
45
|
}
|
|
@@ -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 { Pagination, useToast, BulkActionBar, ListingToolbar, LoginRequiredModal, FilterDrawer } from "../../../ui";
|
|
8
|
+
import { Div, Pagination, useToast, BulkActionBar, ListingToolbar, LoginRequiredModal, FilterDrawer } 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";
|
|
@@ -23,6 +23,12 @@ import { TABLE_KEYS, VIEW_MODE } from "../../../constants/table-keys";
|
|
|
23
23
|
import { sortBy } from "../../../constants/sort";
|
|
24
24
|
import { PRODUCT_FIELDS } from "../../../constants/field-names";
|
|
25
25
|
import { useBottomActions } from "../../layout";
|
|
26
|
+
const __P = {
|
|
27
|
+
p3: "p-3",
|
|
28
|
+
};
|
|
29
|
+
const __O = {
|
|
30
|
+
hidden: "overflow-hidden",
|
|
31
|
+
};
|
|
26
32
|
const DEFAULT_SORT = sortBy(PRODUCT_FIELDS.CREATED_AT);
|
|
27
33
|
const FILTER_KEYS = [TABLE_KEYS.CATEGORY, TABLE_KEYS.CONDITION, TABLE_KEYS.MIN_PRICE, TABLE_KEYS.MAX_PRICE, TABLE_KEYS.BRAND, TABLE_KEYS.STORE_ID, TABLE_KEYS.FREE_SHIPPING, TABLE_KEYS.TAGS, TABLE_KEYS.FEATURES, TABLE_KEYS.IS_PART_OF_BUNDLE];
|
|
28
34
|
export function ProductsIndexListing({ initialData }) {
|
|
@@ -133,39 +139,41 @@ export function ProductsIndexListing({ initialData }) {
|
|
|
133
139
|
router.push(String(ROUTES.USER.CART));
|
|
134
140
|
});
|
|
135
141
|
}, [localCart, router, requireAuth]);
|
|
142
|
+
const handleBulkAddToCart = useCallback(() => {
|
|
143
|
+
const selected = products.filter((p) => selection.selectedIdSet.has(p.id));
|
|
144
|
+
selected.forEach((p) => {
|
|
145
|
+
const snapshot = { productTitle: p.title, productImage: p.mainImage, price: p.price, storeId: p.storeId, storeName: p.storeName };
|
|
146
|
+
localCart.add(p.id, 1, snapshot);
|
|
147
|
+
pushCartOp({ op: "add", productId: p.id, quantity: 1, ...snapshot });
|
|
148
|
+
});
|
|
149
|
+
showToast(`${selected.length} items added to cart`, "success");
|
|
150
|
+
selection.clearSelection();
|
|
151
|
+
}, [products, selection, localCart, showToast]);
|
|
152
|
+
const handleBulkAddToWishlist = useCallback(() => {
|
|
153
|
+
requireAuth(ACTION_ID.ADD_TO_WISHLIST, () => {
|
|
154
|
+
const selected = products.filter((p) => selection.selectedIdSet.has(p.id));
|
|
155
|
+
selected.forEach((p) => {
|
|
156
|
+
localWishlist.add(p.id, "product");
|
|
157
|
+
pushWishlistOp({ op: "add", itemId: p.id, type: "product" });
|
|
158
|
+
});
|
|
159
|
+
showToast(`${selected.length} items added to wishlist`, "success");
|
|
160
|
+
selection.clearSelection();
|
|
161
|
+
});
|
|
162
|
+
}, [products, selection, localWishlist, showToast, requireAuth]);
|
|
136
163
|
useBottomActions(selection.selectedCount > 0 ? { bulk: { selectedCount: selection.selectedCount, onClearSelection: selection.clearSelection, actions: [
|
|
137
164
|
{
|
|
138
165
|
id: ACTION_ID.ADD_TO_CART,
|
|
139
166
|
label: ACTION_META[ACTION_ID.ADD_TO_CART].label,
|
|
140
167
|
icon: _jsx(ShoppingCart, { className: "h-3.5 w-3.5" }),
|
|
141
168
|
variant: "primary",
|
|
142
|
-
onClick:
|
|
143
|
-
const selected = products.filter((p) => selection.selectedIdSet.has(p.id));
|
|
144
|
-
selected.forEach((p) => {
|
|
145
|
-
const snapshot = { productTitle: p.title, productImage: p.mainImage, price: p.price, storeId: p.storeId, storeName: p.storeName };
|
|
146
|
-
localCart.add(p.id, 1, snapshot);
|
|
147
|
-
pushCartOp({ op: "add", productId: p.id, quantity: 1, ...snapshot });
|
|
148
|
-
});
|
|
149
|
-
showToast(`${selected.length} items added to cart`, "success");
|
|
150
|
-
selection.clearSelection();
|
|
151
|
-
},
|
|
169
|
+
onClick: handleBulkAddToCart,
|
|
152
170
|
},
|
|
153
171
|
{
|
|
154
172
|
id: ACTION_ID.ADD_TO_WISHLIST,
|
|
155
173
|
label: ACTION_META[ACTION_ID.ADD_TO_WISHLIST].label,
|
|
156
174
|
icon: _jsx(Heart, { className: "h-3.5 w-3.5" }),
|
|
157
175
|
variant: "secondary",
|
|
158
|
-
onClick:
|
|
159
|
-
requireAuth(ACTION_ID.ADD_TO_WISHLIST, () => {
|
|
160
|
-
const selected = products.filter((p) => selection.selectedIdSet.has(p.id));
|
|
161
|
-
selected.forEach((p) => {
|
|
162
|
-
localWishlist.add(p.id, "product");
|
|
163
|
-
pushWishlistOp({ op: "add", itemId: p.id, type: "product" });
|
|
164
|
-
});
|
|
165
|
-
showToast(`${selected.length} items added to wishlist`, "success");
|
|
166
|
-
selection.clearSelection();
|
|
167
|
-
});
|
|
168
|
-
},
|
|
176
|
+
onClick: handleBulkAddToWishlist,
|
|
169
177
|
},
|
|
170
178
|
{
|
|
171
179
|
id: ACTION_ID.COMPARE,
|
|
@@ -179,7 +187,7 @@ export function ProductsIndexListing({ initialData }) {
|
|
|
179
187
|
},
|
|
180
188
|
},
|
|
181
189
|
] } } : {});
|
|
182
|
-
return (_jsxs(
|
|
190
|
+
return (_jsxs(Div, { className: "min-h-screen", children: [_jsx(ListingToolbar, { filterCount: filterActiveCount, onFiltersClick: openFilters, searchValue: searchInput, searchPlaceholder: "Search products...", onSearchChange: setSearchInput, onSearchCommit: commitSearch, onSearchKeyDown: handleSearchKeyDown, sortValue: table.get(TABLE_KEYS.SORT) || DEFAULT_SORT, sortOptions: PRODUCT_PUBLIC_SORT_OPTIONS, onSortChange: (v) => { table.set(TABLE_KEYS.SORT, v); }, view: view, onViewChange: handleViewToggle, onResetAll: resetAll, hasActiveState: hasActiveState, bulkMode: selection.isSelecting, bulkSelectedCount: selection.selectedCount, bulkTotalCount: products.length, onBulkSelectAll: selection.toggleAll, onBulkClear: selection.clearSelection, toggles: [
|
|
183
191
|
{ label: "Show sold", active: showSold, onChange: (next) => table.set(TABLE_KEYS.SHOW_SOLD, next ? "true" : "") },
|
|
184
192
|
] }), _jsx(BulkActionBar, { selectedCount: selection.selectedCount, onClearSelection: selection.clearSelection, actions: [
|
|
185
193
|
{
|
|
@@ -226,7 +234,7 @@ export function ProductsIndexListing({ initialData }) {
|
|
|
226
234
|
setCompareIds(ids);
|
|
227
235
|
},
|
|
228
236
|
},
|
|
229
|
-
] }), totalPages > 1 && (_jsx(
|
|
237
|
+
] }), totalPages > 1 && (_jsx(Div, { className: "sticky top-[calc(var(--header-height,0px)+44px)] z-10 flex justify-center bg-white/95 dark:bg-slate-900/95 backdrop-blur-sm border-b border-zinc-200 dark:border-slate-700 px-3 py-1.5", children: _jsx(Pagination, { currentPage: page, totalPages: totalPages, onPageChange: (p) => table.setPage(p) }) })), _jsx(Div, { className: "py-6", children: isLoading ? (_jsx(Div, { className: "grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 gap-4", children: Array.from({ length: 10 }).map((_, i) => (_jsxs(Div, { className: `rounded-xl border border-zinc-100 dark:border-slate-700 ${__O.hidden} animate-pulse`, children: [_jsx(Div, { className: "aspect-square bg-zinc-200 dark:bg-slate-700" }), _jsxs(Div, { className: `${__P.p3} space-y-2`, children: [_jsx(Div, { className: "h-3 bg-zinc-200 dark:bg-slate-700 rounded w-3/4" }), _jsx(Div, { className: "h-3 bg-zinc-200 dark:bg-slate-700 rounded w-1/2" }), _jsx(Div, { className: "h-4 bg-zinc-200 dark:bg-slate-700 rounded w-1/3" })] })] }, 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: () => {
|
|
230
238
|
setCompareIds([]);
|
|
231
239
|
selection.clearSelection();
|
|
232
240
|
}, 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 })] }));
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { productRepository } from "../../../repositories";
|
|
3
3
|
import { ROUTES } from "../../../constants";
|
|
4
|
-
import { Container, Heading, Main, Section, Text } from "../../../ui";
|
|
4
|
+
import { Container, Div, Heading, Main, Section, Text } from "../../../ui";
|
|
5
5
|
import { AdSlot } from "../../homepage/components/AdSlot";
|
|
6
6
|
import { parseListingSearchParams } from "../../../utils/listing-params";
|
|
7
7
|
import { ProductsIndexListing } from "./ProductsIndexListing";
|
|
@@ -59,5 +59,5 @@ export async function ProductsIndexPageView({ searchParams = {} }) {
|
|
|
59
59
|
})
|
|
60
60
|
.catch(() => null);
|
|
61
61
|
const products = result ?? null;
|
|
62
|
-
return (_jsxs(Main, { children: [_jsx(Section, { className: "pt-8 pb-4 border-b border-zinc-100 dark:border-slate-800", children: _jsxs(Container, { size: "xl", children: [_jsx(Heading, { level: 1, className: "text-3xl font-bold text-zinc-900 dark:text-zinc-100", children: "Products" }), _jsx(Text, { className: "mt-1 text-sm text-zinc-500 dark:text-zinc-400", children: "Discover amazing products and deals" }), _jsx(
|
|
62
|
+
return (_jsxs(Main, { children: [_jsx(Section, { className: "pt-8 pb-4 border-b border-zinc-100 dark:border-slate-800", children: _jsxs(Container, { size: "xl", children: [_jsx(Heading, { level: 1, className: "text-3xl font-bold text-zinc-900 dark:text-zinc-100", children: "Products" }), _jsx(Text, { className: "mt-1 text-sm text-zinc-500 dark:text-zinc-400", children: "Discover amazing products and deals" }), _jsx(Div, { className: "mt-3", children: _jsx("a", { href: ROUTES.PUBLIC.AUCTIONS, className: "inline-flex items-center gap-1.5 rounded-full border border-primary/30 bg-primary/10 px-4 py-1.5 text-xs font-medium text-primary-700 dark:text-primary-400 hover:bg-primary/15 transition-colors", children: "\uD83C\uDFF7\uFE0F Looking for unique deals? Browse Auctions \u2192" }) })] }) }), _jsxs(Container, { size: "xl", className: "px-4", children: [_jsx(AdSlot, { id: "listing-sidebar-top", className: "mb-4 mt-4" }), _jsx(ProductsIndexListing, { initialData: products }), _jsx(AdSlot, { id: "listing-sidebar-bottom", className: "mt-8" })] })] }));
|
|
63
63
|
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { Heading } from "../../../ui";
|
|
2
|
+
import { Div, Heading } from "../../../ui";
|
|
3
3
|
export function RelatedProducts({ isLoading = false, isEmpty = false, renderGrid, renderSkeleton, renderTitle, labels = {}, className = "", }) {
|
|
4
4
|
if (isLoading) {
|
|
5
5
|
if (renderSkeleton)
|
|
6
6
|
return _jsx(_Fragment, { children: renderSkeleton() });
|
|
7
|
-
return (_jsx(
|
|
7
|
+
return (_jsx(Div, { className: "grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 gap-4 animate-pulse", children: Array.from({ length: 4 }).map((_, i) => (_jsx(Div, { className: "aspect-square rounded-xl bg-zinc-100 dark:bg-zinc-800" }, i))) }));
|
|
8
8
|
}
|
|
9
9
|
if (isEmpty)
|
|
10
10
|
return null;
|
|
11
|
-
return (_jsxs(
|
|
11
|
+
return (_jsxs(Div, { className: `space-y-4 ${className}`, children: [renderTitle ? (renderTitle()) : labels.title ? (_jsx(Heading, { level: 2, className: "text-xl font-bold", variant: "none", children: labels.title })) : null, renderGrid?.()] }));
|
|
12
12
|
}
|
|
@@ -3,9 +3,13 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
3
3
|
import { useEffect, useState } from "react";
|
|
4
4
|
import Link from "next/link";
|
|
5
5
|
import { ROUTES } from "../../../next";
|
|
6
|
-
import { Row, Text, Modal, SideDrawer, Button } from "../../../ui";
|
|
6
|
+
import { Div, Row, Span, Table, Thead, Tbody, Tr, Th, Td, Text, Modal, SideDrawer, Button } from "../../../ui";
|
|
7
7
|
import { formatCurrency } from "../../../utils/number.formatter";
|
|
8
8
|
import { isPreOrderListing } from "../utils/listing-type";
|
|
9
|
+
const __O = {
|
|
10
|
+
hidden: "overflow-hidden",
|
|
11
|
+
xAuto: "overflow-x-auto",
|
|
12
|
+
};
|
|
9
13
|
function memberHref(m) {
|
|
10
14
|
const slug = m.slug ?? m.id;
|
|
11
15
|
if (isPreOrderListing(m))
|
|
@@ -20,15 +24,15 @@ function MemberThumb({ member, isCurrent }) {
|
|
|
20
24
|
? "border-[var(--appkit-color-primary,#6366f1)] ring-2 ring-[var(--appkit-color-primary,#6366f1)]/30"
|
|
21
25
|
: "border-zinc-200 dark:border-zinc-700 group-hover:border-[var(--appkit-color-primary,#6366f1)]"}`, children: [image ? (
|
|
22
26
|
// eslint-disable-next-line @next/next/no-img-element
|
|
23
|
-
_jsx("img", { src: image, alt: member.title, className: "w-full h-full object-cover", loading: "lazy" })) : (_jsx(
|
|
27
|
+
_jsx("img", { src: image, alt: member.title, className: "w-full h-full object-cover", loading: "lazy" })) : (_jsx(Div, { className: "w-full h-full bg-zinc-100 dark:bg-zinc-800 flex items-center justify-center text-zinc-400 text-xs", children: "\u00E2\u2014\u00AF" })), member.isGroupParent && (_jsx(Span, { className: "absolute bottom-0 right-0 bg-[var(--appkit-color-primary,#6366f1)] text-white text-[8px] leading-none px-1 py-0.5 rounded-tl", children: "Set" }))] }), _jsx(Text, { className: "text-[10px] text-center text-zinc-600 dark:text-zinc-400 leading-tight line-clamp-2 w-full", children: member.title }), _jsx(Text, { className: "text-[10px] font-semibold text-zinc-800 dark:text-zinc-200", children: price })] }));
|
|
24
28
|
}
|
|
25
29
|
function GroupTableRow({ member }) {
|
|
26
30
|
const href = memberHref(member);
|
|
27
31
|
const price = formatCurrency(member.price, member.currency ?? "INR");
|
|
28
32
|
const image = member.images?.[0] ?? "";
|
|
29
|
-
return (_jsxs(
|
|
33
|
+
return (_jsxs(Tr, { className: "border-b border-zinc-100 dark:border-zinc-800 last:border-0", children: [_jsx(Td, { className: "py-2 pr-3", children: _jsx(Div, { className: `w-10 h-10 rounded-full ${__O.hidden} border border-zinc-200 dark:border-zinc-700`, children: image ? (
|
|
30
34
|
// eslint-disable-next-line @next/next/no-img-element
|
|
31
|
-
_jsx("img", { src: image, alt: member.title, className: "w-full h-full object-cover", loading: "lazy" })) : (_jsx(
|
|
35
|
+
_jsx("img", { src: image, alt: member.title, className: "w-full h-full object-cover", loading: "lazy" })) : (_jsx(Div, { className: "w-full h-full bg-zinc-100 dark:bg-zinc-800" })) }) }), _jsxs(Td, { className: "py-2 pr-3", children: [_jsx(Text, { className: "text-sm text-zinc-800 dark:text-zinc-200 font-medium line-clamp-2", children: member.title }), member.isGroupParent && (_jsx(Span, { weight: "semibold", className: "text-[10px] text-[var(--appkit-color-primary,#6366f1)]", children: "Parent" }))] }), _jsx(Td, { className: "py-2 pr-3", children: _jsx(Text, { className: "text-sm text-zinc-700 dark:text-zinc-300", children: price }) }), _jsx(Td, { className: "py-2 pr-3", children: _jsx(Text, { className: "text-xs text-zinc-500 dark:text-zinc-400 capitalize", children: member.condition ?? "—" }) }), _jsx(Td, { className: "py-2", children: _jsx(Link, { href: href, className: "text-xs text-[var(--appkit-color-primary,#6366f1)] hover:underline", children: "View \u00E2\u2020\u2019" }) })] }));
|
|
32
36
|
}
|
|
33
37
|
export function ShowGroupSection({ groupId, currentSlug, isParent, groupTitle }) {
|
|
34
38
|
const [open, setOpen] = useState(false);
|
|
@@ -50,8 +54,8 @@ export function ShowGroupSection({ groupId, currentSlug, isParent, groupTitle })
|
|
|
50
54
|
const label = groupTitle ?? "Product group";
|
|
51
55
|
const parentLabel = isParent ? `Parts in this group: ${label}` : `Part of: ${label}`;
|
|
52
56
|
const useDrawer = members.length >= 5;
|
|
53
|
-
const tableContent = (_jsx(
|
|
54
|
-
return (_jsxs(_Fragment, { children: [_jsxs(
|
|
57
|
+
const tableContent = (_jsx(Div, { className: `${__O.xAuto}`, children: _jsxs(Table, { className: "w-full text-left min-w-[400px]", children: [_jsx(Thead, { children: _jsxs(Tr, { className: "border-b border-zinc-200 dark:border-zinc-700", children: [_jsx(Th, { className: "pb-2 pr-3 text-xs font-semibold text-zinc-500 dark:text-zinc-400", children: "Image" }), _jsx(Th, { className: "pb-2 pr-3 text-xs font-semibold text-zinc-500 dark:text-zinc-400", children: "Name" }), _jsx(Th, { className: "pb-2 pr-3 text-xs font-semibold text-zinc-500 dark:text-zinc-400", children: "Price" }), _jsx(Th, { className: "pb-2 pr-3 text-xs font-semibold text-zinc-500 dark:text-zinc-400", children: "Condition" }), _jsx(Th, { className: "pb-2 text-xs font-semibold text-zinc-500 dark:text-zinc-400" })] }) }), _jsx(Tbody, { children: members.map((m) => _jsx(GroupTableRow, { member: m }, m.id)) })] }) }));
|
|
58
|
+
return (_jsxs(_Fragment, { children: [_jsxs(Div, { className: `rounded-xl border border-zinc-200 dark:border-zinc-700 bg-zinc-50/60 dark:bg-zinc-800/40 ${__O.hidden}`, children: [_jsxs("button", { type: "button", onClick: () => setOpen((v) => !v), className: "w-full flex items-center justify-between px-4 py-3 text-left hover:bg-zinc-100/70 dark:hover:bg-zinc-800/70 transition-colors", "aria-expanded": open, children: [_jsxs(Row, { align: "center", gap: "xs", children: [_jsx(Span, { size: "xs", className: "text-zinc-400 dark:text-zinc-400 mr-1", children: open ? "â–¼" : "â–¶" }), _jsx(Text, { className: "text-sm font-medium text-zinc-800 dark:text-zinc-200", children: parentLabel }), _jsx(Span, { size: "xs", className: "ml-1 rounded-full bg-zinc-200 dark:bg-zinc-700 px-2 py-0.5 text-zinc-600 dark:text-zinc-400", children: members.length })] }), _jsx(Button, { type: "button", variant: "ghost", size: "sm", onClick: (e) => { e.stopPropagation(); setShowAll(true); }, className: "text-xs text-[var(--appkit-color-primary,#6366f1)] hover:underline ml-3 flex-shrink-0", children: "View whole group \u00E2\u2020\u2019" })] }), open && (_jsx(Div, { className: `px-4 pb-4 pt-1 ${__O.xAuto}`, children: _jsx(Div, { className: "flex gap-3 min-w-0", children: [...members]
|
|
55
59
|
.sort((a, b) => (b.isGroupParent ? 1 : 0) - (a.isGroupParent ? 1 : 0))
|
|
56
60
|
.map((m) => (_jsx(MemberThumb, { member: m, isCurrent: m.slug === currentSlug || m.id === currentSlug }, m.id))) }) }))] }), useDrawer ? (_jsx(SideDrawer, { isOpen: showAll, onClose: () => setShowAll(false), title: label, children: tableContent })) : (_jsx(Modal, { open: showAll, onClose: () => setShowAll(false), title: label, children: tableContent }))] }));
|
|
57
61
|
}
|
|
@@ -3,9 +3,13 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
3
3
|
import { useEffect, useState } from "react";
|
|
4
4
|
import Link from "next/link";
|
|
5
5
|
import { ROUTES } from "../../../next";
|
|
6
|
-
import { Row, Text } from "../../../ui";
|
|
6
|
+
import { Div, Row, Span, Text } from "../../../ui";
|
|
7
7
|
import { formatCurrency } from "../../../utils/number.formatter";
|
|
8
8
|
import { isAuctionListing, isPreOrderListing } from "../utils/listing-type";
|
|
9
|
+
const __O = {
|
|
10
|
+
hidden: "overflow-hidden",
|
|
11
|
+
xAuto: "overflow-x-auto",
|
|
12
|
+
};
|
|
9
13
|
function getHref(listing) {
|
|
10
14
|
const slug = listing.slug ?? listing.id;
|
|
11
15
|
if (isAuctionListing(listing))
|
|
@@ -22,7 +26,7 @@ function ListingThumb({ listing, isCurrent, }) {
|
|
|
22
26
|
? "border-[var(--appkit-color-primary,#6366f1)] ring-2 ring-[var(--appkit-color-primary,#6366f1)]/30"
|
|
23
27
|
: "border-zinc-200 dark:border-zinc-700 group-hover:border-[var(--appkit-color-primary,#6366f1)]"}`, children: image ? (
|
|
24
28
|
// eslint-disable-next-line @next/next/no-img-element
|
|
25
|
-
_jsx("img", { src: image, alt: listing.title, className: "w-full h-full object-cover", loading: "lazy" })) : (_jsx(
|
|
29
|
+
_jsx("img", { src: image, alt: listing.title, className: "w-full h-full object-cover", loading: "lazy" })) : (_jsx(Div, { className: "w-full h-full bg-zinc-100 dark:bg-zinc-800 flex items-center justify-center text-zinc-400 text-xs", children: "\u00E2\u2014\u00AF" })) }), _jsx(Text, { className: "text-[10px] text-center text-zinc-600 dark:text-zinc-400 leading-tight line-clamp-2 w-full", children: listing.title }), _jsx(Text, { className: "text-[10px] font-semibold text-zinc-800 dark:text-zinc-200", children: price })] }));
|
|
26
30
|
}
|
|
27
31
|
export function SublistingCarouselSection({ sublistingCategoryId, currentListingId }) {
|
|
28
32
|
const [open, setOpen] = useState(false);
|
|
@@ -50,5 +54,5 @@ export function SublistingCarouselSection({ sublistingCategoryId, currentListing
|
|
|
50
54
|
if (others.length === 0)
|
|
51
55
|
return null;
|
|
52
56
|
const label = category?.name ?? "More listings like this";
|
|
53
|
-
return (_jsxs(
|
|
57
|
+
return (_jsxs(Div, { className: `rounded-xl border border-zinc-200 dark:border-zinc-700 bg-zinc-50/60 dark:bg-zinc-800/40 ${__O.hidden}`, children: [_jsxs("button", { type: "button", onClick: () => setOpen((v) => !v), className: "w-full flex items-center justify-between px-4 py-3 text-left hover:bg-zinc-100/70 dark:hover:bg-zinc-800/70 transition-colors", "aria-expanded": open, children: [_jsxs(Row, { align: "center", gap: "xs", children: [_jsx(Span, { size: "xs", className: "text-zinc-400 dark:text-zinc-400 mr-1", children: open ? "â–¼" : "â–¶" }), _jsxs(Text, { className: "text-sm font-medium text-zinc-800 dark:text-zinc-200", children: ["More listings like this:", " ", _jsx(Span, { className: "text-[var(--appkit-color-primary,#6366f1)]", children: label })] }), _jsx(Span, { size: "xs", className: "ml-1 rounded-full bg-zinc-200 dark:bg-zinc-700 px-2 py-0.5 text-zinc-600 dark:text-zinc-400", children: listings.length })] }), category && (_jsx(Link, { href: String(ROUTES.PUBLIC.SUBLISTING_CATEGORY(category.slug)), onClick: (e) => e.stopPropagation(), className: "text-xs text-[var(--appkit-color-primary,#6366f1)] hover:underline ml-3 flex-shrink-0", children: "View all \u00E2\u2020\u2019" }))] }), open && (_jsx(Div, { className: `px-4 pb-4 pt-1 ${__O.xAuto}`, children: _jsx(Div, { className: "flex gap-3 min-w-0", children: listings.map((listing) => (_jsx(ListingThumb, { listing: listing, isCurrent: listing.id === currentListingId }, listing.id))) }) }))] }));
|
|
54
58
|
}
|
|
@@ -2,6 +2,8 @@ interface Props {
|
|
|
2
2
|
value: string;
|
|
3
3
|
onChange: (id: string) => void;
|
|
4
4
|
disabled?: boolean;
|
|
5
|
+
/** Allow creating a new sub-listing inline. Defaults to false. */
|
|
6
|
+
allowCreate?: boolean;
|
|
5
7
|
}
|
|
6
|
-
export declare function SublistingCategorySelect({ value, onChange, disabled }: Props): import("react/jsx-runtime").JSX.Element;
|
|
8
|
+
export declare function SublistingCategorySelect({ value, onChange, disabled, allowCreate, }: Props): import("react/jsx-runtime").JSX.Element;
|
|
7
9
|
export {};
|
|
@@ -1,40 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
export function SublistingCategorySelect({ value, onChange, disabled }) {
|
|
8
|
-
const [options, setOptions] = useState([]);
|
|
9
|
-
const [loading, setLoading] = useState(true);
|
|
10
|
-
useEffect(() => {
|
|
11
|
-
let cancelled = false;
|
|
12
|
-
apiClient
|
|
13
|
-
.get(`${ADMIN_ENDPOINTS.SUBLISTING_CATEGORIES}?pageSize=200&sorts=name`)
|
|
14
|
-
.then((res) => {
|
|
15
|
-
if (cancelled)
|
|
16
|
-
return;
|
|
17
|
-
const items = res?.data?.items ?? [];
|
|
18
|
-
const opts = [
|
|
19
|
-
{ value: "", label: "— None —" },
|
|
20
|
-
...items.map((item) => ({
|
|
21
|
-
value: String(item.id ?? ""),
|
|
22
|
-
label: item.itemCode
|
|
23
|
-
? `${item.name} (${item.itemCode})`
|
|
24
|
-
: String(item.name ?? ""),
|
|
25
|
-
})),
|
|
26
|
-
];
|
|
27
|
-
setOptions(opts);
|
|
28
|
-
})
|
|
29
|
-
.catch(() => {
|
|
30
|
-
if (!cancelled)
|
|
31
|
-
setOptions([{ value: "", label: "— None —" }]);
|
|
32
|
-
})
|
|
33
|
-
.finally(() => {
|
|
34
|
-
if (!cancelled)
|
|
35
|
-
setLoading(false);
|
|
36
|
-
});
|
|
37
|
-
return () => { cancelled = true; };
|
|
38
|
-
}, []);
|
|
39
|
-
return (_jsxs(Stack, { gap: "xs", children: [_jsx(Text, { className: "text-sm font-medium text-zinc-900 dark:text-zinc-100", children: "Sub-listing category" }), _jsx(Select, { options: loading ? [{ value: "", label: "Loading…" }] : options, value: value, onChange: (e) => onChange(e.target.value), disabled: disabled || loading, "aria-label": "Sub-listing category" }), _jsx(Text, { className: "text-xs text-zinc-400 dark:text-zinc-400", children: "Groups this listing with others for the same collectible (e.g. \u201CBase Set Charizard 108/120\u201D)." })] }));
|
|
3
|
+
import { Stack, Text } from "../../../ui";
|
|
4
|
+
import { SublistingInlineSelect } from "../../seller/components/SublistingInlineSelect";
|
|
5
|
+
export function SublistingCategorySelect({ value, onChange, disabled, allowCreate = false, }) {
|
|
6
|
+
return (_jsxs(Stack, { gap: "xs", children: [_jsx(Text, { className: "text-sm font-medium text-zinc-900 dark:text-zinc-100", children: "Sub-listing category" }), _jsx(SublistingInlineSelect, { value: value, onChange: onChange, disabled: disabled, allowCreate: allowCreate, placeholder: "\u2014 None \u2014" }), _jsx(Text, { className: "text-xs text-zinc-400 dark:text-zinc-400", children: "Groups this listing with others for the same collectible (e.g. \u201CBase Set Charizard 108/120\u201D)." })] }));
|
|
40
7
|
}
|
|
@@ -31,7 +31,7 @@ function regLabel(resource, id, fallback) {
|
|
|
31
31
|
}
|
|
32
32
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
33
33
|
// § 1 Product / listing actions
|
|
34
|
-
// Used by: detail pages,
|
|
34
|
+
// Used by: detail pages, bulk action bars, mobile bottom bars
|
|
35
35
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
36
36
|
export const ACTION_ID = {
|
|
37
37
|
// Standard product
|
|
@@ -138,13 +138,13 @@ export const DETAIL_ACTIONS = {
|
|
|
138
138
|
/** Pre-order: reserve, wishlist, share */
|
|
139
139
|
preorder: [ACTION_ID.RESERVE_NOW, ACTION_ID.ADD_TO_WISHLIST, ACTION_ID.SHARE],
|
|
140
140
|
};
|
|
141
|
-
// Mobile
|
|
141
|
+
// Mobile bottom bar — 1–2 primary CTAs only (limited horizontal space)
|
|
142
142
|
export const MOBILE_PRIMARY_ACTIONS = {
|
|
143
143
|
product: [ACTION_ID.BUY_NOW, ACTION_ID.ADD_TO_CART],
|
|
144
144
|
auction: [ACTION_ID.PLACE_BID, ACTION_ID.BUY_NOW_AUCTION],
|
|
145
145
|
preorder: [ACTION_ID.RESERVE_NOW],
|
|
146
146
|
};
|
|
147
|
-
// Listing page bulk actions — shown in
|
|
147
|
+
// Listing page bulk actions — shown in the bottom action bar when items are selected
|
|
148
148
|
export const LISTING_BULK_ACTIONS = {
|
|
149
149
|
products: [ACTION_ID.ADD_TO_CART, ACTION_ID.ADD_TO_WISHLIST, ACTION_ID.COMPARE],
|
|
150
150
|
auctions: [ACTION_ID.WATCH_AUCTION, ACTION_ID.UNWATCH_AUCTION, ACTION_ID.COMPARE],
|
|
@@ -10,6 +10,6 @@ export declare function useProductDetail<TProduct = ProductItem>(slug: string, o
|
|
|
10
10
|
product: TProduct | null;
|
|
11
11
|
isLoading: boolean;
|
|
12
12
|
error: Error | null;
|
|
13
|
-
refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<ProductItem | null
|
|
13
|
+
refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<NoInfer<ProductItem | null>, Error>>;
|
|
14
14
|
};
|
|
15
15
|
export {};
|
|
@@ -4,4 +4,4 @@ import type { ProductListResponse } from "../types";
|
|
|
4
4
|
* boolean translates to the canonical `listingType` clause; new callers can
|
|
5
5
|
* pass the union directly via the same parameter slot in a follow-up.
|
|
6
6
|
*/
|
|
7
|
-
export declare function useRelatedProducts(category: string, excludeId: string, limit?: number, isAuction?: boolean): import("@tanstack/react-query").UseQueryResult<ProductListResponse
|
|
7
|
+
export declare function useRelatedProducts(category: string, excludeId: string, limit?: number, isAuction?: boolean): import("@tanstack/react-query").UseQueryResult<NoInfer<ProductListResponse>, Error>;
|
|
@@ -4,6 +4,8 @@ import { useState } from "react";
|
|
|
4
4
|
import { Pencil, Trash2, ToggleLeft, ToggleRight } from "lucide-react";
|
|
5
5
|
import { BaseListingCard, ConfirmDeleteModal, Div, Row, Span, Text } from "../../../ui";
|
|
6
6
|
import { useLongPress } from "../../../react/hooks/useLongPress";
|
|
7
|
+
const CLS_TOGGLE_ON = "h-4 w-4 text-emerald-600 dark:text-emerald-400";
|
|
8
|
+
const CLS_DELETE_BTN = "rounded-lg p-1.5 text-zinc-500 dark:text-zinc-400 hover:bg-red-50 dark:hover:bg-red-950/40 hover:text-red-600 dark:hover:text-red-400 transition-colors disabled:opacity-50";
|
|
7
9
|
const TYPE_COLORS = {
|
|
8
10
|
percentage: { card: "bg-purple-50 border-purple-200 dark:bg-purple-950/30 dark:border-purple-800", code: "bg-purple-100 dark:bg-purple-900/40 text-purple-800 dark:text-purple-200 border-purple-300 dark:border-purple-700" },
|
|
9
11
|
fixed: { card: "bg-green-50 border-green-200 dark:bg-green-950/30 dark:border-green-800", code: "bg-green-100 dark:bg-green-900/40 text-green-800 dark:text-green-200 border-green-300 dark:border-green-700" },
|
|
@@ -159,7 +161,7 @@ export function CouponCard({ coupon, labels: labelsProp, onCopy, className = "",
|
|
|
159
161
|
};
|
|
160
162
|
return (_jsxs(Div, { className: `group relative flex h-full flex-col rounded-xl border-2 p-4 ${colors.card} ${isSelected ? "ring-2 ring-primary" : ""} ${!n.isActive ? "opacity-70" : ""} ${className}`, onMouseDown: onSelect && !isSelected ? longPress.onMouseDown : undefined, onMouseUp: onSelect && !isSelected ? longPress.onMouseUp : undefined, onMouseLeave: onSelect && !isSelected ? longPress.onMouseLeave : undefined, onTouchStart: onSelect && !isSelected ? longPress.onTouchStart : undefined, onTouchEnd: onSelect && !isSelected ? longPress.onTouchEnd : undefined, children: [onSelect && (_jsx(BaseListingCard.Checkbox, { selected: isSelected, onSelect: (e) => { e.preventDefault(); onSelect(n.id, !isSelected); }, label: isSelected ? "Deselect coupon" : "Select coupon", position: "top-2 right-2", className: selectable || isSelected ? "opacity-100" : "opacity-0 group-hover:opacity-100 transition-opacity" })), (hasAdminActions || n.scope) && (_jsxs(Row, { gap: "xs", className: "mb-2 flex-wrap", children: [_jsx(Span, { className: `inline-flex items-center rounded-full px-2 py-0.5 text-[10px] font-semibold uppercase tracking-wide ${n.isActive
|
|
161
163
|
? "bg-success-surface text-success"
|
|
162
|
-
: "bg-zinc-200 text-zinc-600 dark:bg-zinc-700 dark:text-zinc-300"}`, children: n.isActive ? labels.active : labels.inactive }), n.scope && (_jsx(Span, { className: "inline-flex items-center rounded-full bg-zinc-200/70 px-2 py-0.5 text-[10px]
|
|
163
|
-
? _jsx(ToggleRight, { className:
|
|
164
|
-
: _jsx(ToggleLeft, { className: "h-4 w-4" }) })), onDelete && (_jsx("button", { type: "button", onClick: () => setDeleteConfirmOpen(true), disabled: busy === "delete", title: labels.delete, "aria-label": labels.delete, className:
|
|
164
|
+
: "bg-zinc-200 text-zinc-600 dark:bg-zinc-700 dark:text-zinc-300"}`, children: n.isActive ? labels.active : labels.inactive }), n.scope && (_jsx(Span, { weight: "semibold", className: "inline-flex items-center rounded-full bg-zinc-200/70 px-2 py-0.5 text-[10px] uppercase tracking-wide text-zinc-700 dark:bg-zinc-700/60 dark:text-zinc-200", children: n.scope }))] })), _jsxs(Div, { className: "mb-3", children: [_jsx(Text, { className: "text-2xl font-extrabold tracking-tight leading-none", children: discountLabel }), n.name && (_jsx(Text, { className: "text-sm mt-0.5 font-medium opacity-80", children: n.name }))] }), n.description && (_jsx(Text, { className: "text-xs opacity-60 mb-3", children: n.description })), _jsxs(Div, { className: `flex items-center gap-2 rounded-lg border border-dashed px-3 py-2 ${colors.code}`, children: [_jsx(Span, { size: "sm", weight: "bold", className: "flex-1 font-mono tracking-widest uppercase select-all", children: n.code || "—" }), n.code && (_jsx("button", { type: "button", onClick: handleCopy, className: "shrink-0 rounded-md px-2.5 py-1 text-xs font-semibold transition-all hover:opacity-80 active:scale-95 bg-white/60 dark:bg-black/20 border border-current/20", "aria-label": "Copy coupon code", children: copied ? labels.copied : labels.copy }))] }), showClaim && n.code && n.isActive && (_jsx(Div, { className: "mt-2", children: _jsx("button", { type: "button", onClick: handleClaim, disabled: claiming, className: "w-full rounded-md px-3 py-1.5 text-xs font-semibold transition-all active:scale-95 bg-[var(--appkit-color-primary-700)] text-[var(--appkit-color-text-on-primary,#fff)] hover:bg-[var(--appkit-color-primary-800)] disabled:opacity-50", "aria-label": `Claim coupon ${n.code} and apply at checkout`, children: claiming ? labels.claiming : labels.claim }) })), _jsxs(Row, { wrap: true, gap: "sm", className: "text-xs opacity-60 mt-2", children: [n.minOrderAmount ? (_jsxs(Span, { children: [labels.minOrder, ": \u20B9", (n.minOrderAmount / 100).toFixed(0)] })) : null, expiry && (_jsxs(Span, { children: [labels.expires, ": ", expiry] })), n.usageLimit ? (_jsxs(Span, { children: [n.usageCount, "/", n.usageLimit, " ", labels.used] })) : n.usageCount > 0 ? (_jsxs(Span, { children: [n.usageCount, " ", labels.used] })) : null] }), hasAdminActions && (_jsxs(Row, { gap: "xs", justify: "end", className: "mt-auto pt-3", children: [onEdit && (_jsx("button", { type: "button", onClick: () => onEdit(n.id), title: labels.edit, "aria-label": labels.edit, className: "rounded-lg p-1.5 text-zinc-500 dark:text-zinc-400 hover:bg-white/60 dark:hover:bg-black/30 hover:text-zinc-800 dark:hover:text-zinc-200 transition-colors", children: _jsx(Pencil, { className: "h-4 w-4" }) })), onToggleActive && (_jsx("button", { type: "button", onClick: handleToggle, disabled: busy === "toggle", title: n.isActive ? labels.deactivate : labels.activate, "aria-label": n.isActive ? labels.deactivate : labels.activate, className: "rounded-lg p-1.5 text-zinc-500 dark:text-zinc-400 hover:bg-white/60 dark:hover:bg-black/30 transition-colors disabled:opacity-50", children: n.isActive
|
|
165
|
+
? _jsx(ToggleRight, { className: CLS_TOGGLE_ON })
|
|
166
|
+
: _jsx(ToggleLeft, { className: "h-4 w-4" }) })), onDelete && (_jsx("button", { type: "button", onClick: () => setDeleteConfirmOpen(true), disabled: busy === "delete", title: labels.delete, "aria-label": labels.delete, className: CLS_DELETE_BTN, children: _jsx(Trash2, { className: "h-4 w-4" }) }))] })), deleteConfirmOpen && (_jsx(ConfirmDeleteModal, { isOpen: true, title: "Delete Coupon", message: labels.deleteConfirm, onConfirm: handleDeleteConfirmed, onClose: () => setDeleteConfirmOpen(false), isDeleting: busy === "delete" }))] }));
|
|
165
167
|
}
|
|
@@ -3,13 +3,17 @@ 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 { ListingFilterDrawer, Pagination, SortDropdown, Div, Grid, Row, Span, Stack, Text, Heading } from "../../../ui";
|
|
6
|
+
import { Button, Label, ListingFilterDrawer, Pagination, SortDropdown, Div, Grid, Row, Span, Stack, Text, Heading } from "../../../ui";
|
|
7
7
|
import { usePromotions } from "../hooks/usePromotions";
|
|
8
8
|
import { CouponCard } from "./CouponCard";
|
|
9
9
|
import { TABLE_KEYS } from "../../../constants/table-keys";
|
|
10
10
|
import { COUPON_FIELDS } from "../../../constants/field-names";
|
|
11
11
|
import { sortBy } from "../../../constants/sort";
|
|
12
|
+
const __O = {
|
|
13
|
+
hidden: "overflow-hidden",
|
|
14
|
+
};
|
|
12
15
|
const DEFAULT_SORT = sortBy(COUPON_FIELDS.CREATED_AT);
|
|
16
|
+
const CLS_CHIP_BTN = "p-0 min-h-0 h-auto inline-flex";
|
|
13
17
|
const COUPON_SORT_OPTIONS = [
|
|
14
18
|
{ value: sortBy(COUPON_FIELDS.NAME, "ASC"), label: "Name A–Z" },
|
|
15
19
|
{ value: sortBy(COUPON_FIELDS.NAME), label: "Name Z–A" },
|
|
@@ -91,12 +95,12 @@ export function CouponsIndexListing({ initialCoupons, storeSlug, storeId, }) {
|
|
|
91
95
|
};
|
|
92
96
|
return (_jsxs(Div, { className: "min-h-[40vh]", children: [_jsxs(Div, { className: "sticky top-[var(--header-height,0px)] z-20 border-b border-zinc-200 dark:border-slate-700 bg-white/95 dark:bg-slate-900/95 backdrop-blur-sm py-2.5 px-4", children: [_jsxs(Row, { gap: "xs", className: "max-w-full", children: [_jsxs("button", { type: "button", onClick: openFilters, className: `flex shrink-0 items-center gap-2 rounded-lg border px-3.5 py-2 text-sm font-medium transition-colors ${hasActiveFilters
|
|
93
97
|
? "border-primary bg-primary-50 text-primary-700 dark:bg-primary-900/30 dark:text-primary-300"
|
|
94
|
-
: "border-zinc-300 dark:border-slate-600 text-zinc-700 dark:text-zinc-200 hover:bg-zinc-50 dark:hover:bg-slate-800"}`, children: [_jsx(SlidersHorizontal, { className: "h-4 w-4" }), _jsxs(Span, { className: "hidden sm:inline", children: ["Filters", hasActiveFilters ? " •" : ""] })] }), _jsxs(Row, { className:
|
|
98
|
+
: "border-zinc-300 dark:border-slate-600 text-zinc-700 dark:text-zinc-200 hover:bg-zinc-50 dark:hover:bg-slate-800"}`, 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} rounded-lg border border-zinc-300 dark:border-slate-600`, children: [_jsx("input", { 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-3 py-2 text-sm text-zinc-900 dark:text-zinc-100 placeholder-zinc-400 outline-none" }), searchInput && (_jsx("button", { type: "button", onClick: () => { setSearchInput(""); table.set(TABLE_KEYS.QUERY, ""); }, className: "p-2 text-zinc-400 hover:text-zinc-600 dark:hover:text-zinc-300", "aria-label": "Clear search", children: _jsx(X, { className: "h-3.5 w-3.5" }) })), _jsx("button", { type: "button", onClick: commitSearch, className: "flex shrink-0 items-center justify-center px-3 py-2 text-zinc-400 hover:text-primary dark:hover:text-primary-400 transition-colors", "aria-label": "Search", children: _jsx(Search, { className: "h-4 w-4" }) })] }), _jsxs(Row, { gap: "xs", className: "shrink-0 text-sm text-zinc-500 dark:text-zinc-400", 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, { size: "xs", weight: "medium", className: "flex items-center gap-1 rounded-full bg-primary-50 dark:bg-primary-900/30 text-primary-700 dark:text-primary-300 px-2.5 py-1", 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, { size: "xs", weight: "medium", className: "flex items-center gap-1 rounded-full bg-primary-50 dark:bg-primary-900/30 text-primary-700 dark:text-primary-300 px-2.5 py-1", 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, { size: "xs", weight: "medium", className: "flex items-center gap-1 rounded-full bg-primary-50 dark:bg-primary-900/30 text-primary-700 dark:text-primary-300 px-2.5 py-1", 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", { type: "button", onClick: clearFilters, className: "text-xs text-zinc-500 dark:text-zinc-400 hover:text-zinc-700 dark:hover:text-zinc-300 underline", children: "Clear all" })] }))] }), _jsxs(Div, { className: "py-6 px-4", children: [isLoading ? (_jsx(Grid, { gap: "sm", className: "md:grid-cols-2 lg:grid-cols-3", children: Array.from({ length: 6 }).map((_, i) => (_jsxs(Stack, { gap: "sm", rounded: "xl", padding: "md", className: "border-2 border-zinc-100 dark:border-slate-700 animate-pulse", children: [_jsx(Div, { className: "h-6 bg-zinc-200 dark:bg-slate-700 rounded w-2/3" }), _jsx(Div, { className: "h-4 bg-zinc-200 dark:bg-slate-700 rounded w-full" }), _jsx(Div, { className: "h-3 bg-zinc-200 dark:bg-slate-700 rounded w-1/2" })] }, i))) })) : displayCoupons.length === 0 ? (_jsx(Div, { className: "py-16 text-center", children: _jsx(Text, { className: "text-zinc-400 dark:text-zinc-400", 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: {
|
|
95
99
|
copy: "Copy",
|
|
96
100
|
copied: "Copied!",
|
|
97
101
|
expires: "Expires",
|
|
98
102
|
minOrder: "Min. order",
|
|
99
103
|
off: "OFF",
|
|
100
104
|
freeShipping: "Free Shipping",
|
|
101
|
-
} }, coupon.id))) })), totalPages > 1 && (_jsx(Row, { justify: "center", className: "mt-8", children: _jsx(Pagination, { currentPage: table.getNumber("page", 1), totalPages: totalPages, onPageChange: (p) => table.setPage(p) }) })), !isLoading && total > 0 && (_jsx(Div, { className: "mt-4 text-center", children: _jsxs(Text, { className: "text-xs text-zinc-400 dark:text-zinc-400", children: [total, " coupon", total !== 1 ? "s" : "", " available"] }) }))] }), _jsxs(ListingFilterDrawer, { open: filterOpen, onClose: () => setFilterOpen(false), onApply: applyFilters, onClear: clearPending, activeCount: activeFilterCount, children: [_jsxs(_Fragment, { children: [_jsx(Heading, { level: 6, className: "text-xs font-semibold uppercase tracking-wider text-zinc-500 dark:text-zinc-400 mb-3", children: "Discount Type" }), _jsxs(Stack, { gap: "xs", children: [COUPON_TYPES.map((t) => (_jsxs(
|
|
105
|
+
} }, coupon.id))) })), totalPages > 1 && (_jsx(Row, { justify: "center", className: "mt-8", children: _jsx(Pagination, { currentPage: table.getNumber("page", 1), totalPages: totalPages, onPageChange: (p) => table.setPage(p) }) })), !isLoading && total > 0 && (_jsx(Div, { className: "mt-4 text-center", children: _jsxs(Text, { className: "text-xs text-zinc-400 dark:text-zinc-400", children: [total, " coupon", total !== 1 ? "s" : "", " available"] }) }))] }), _jsxs(ListingFilterDrawer, { open: filterOpen, onClose: () => setFilterOpen(false), onApply: applyFilters, onClear: clearPending, activeCount: activeFilterCount, children: [_jsxs(_Fragment, { children: [_jsx(Heading, { level: 6, className: "text-xs font-semibold uppercase tracking-wider text-zinc-500 dark:text-zinc-400 mb-3", children: "Discount Type" }), _jsxs(Stack, { gap: "xs", children: [COUPON_TYPES.map((t) => (_jsxs(Label, { className: "flex items-center gap-2 cursor-pointer text-sm text-zinc-700 dark:text-zinc-300", children: [_jsx("input", { type: "radio", name: "coupon-type", value: t.value, checked: pendingTable.get(TABLE_KEYS.TYPE) === t.value, onChange: () => { pendingTable.set(TABLE_KEYS.TYPE, t.value); }, className: "accent-primary" }), t.label] }, t.value))), pendingTable.get(TABLE_KEYS.TYPE) && (_jsx("button", { type: "button", onClick: () => { pendingTable.set(TABLE_KEYS.TYPE, ""); }, className: "text-xs text-zinc-400 hover:text-zinc-600 dark:hover:text-zinc-300 underline", children: "Clear type" }))] })] }), _jsxs(_Fragment, { children: [_jsx(Heading, { level: 6, className: "text-xs font-semibold uppercase tracking-wider text-zinc-500 dark:text-zinc-400 mb-3", children: "Valid Date Range" }), _jsxs(Stack, { gap: "sm", children: [_jsxs(_Fragment, { children: [_jsx(Label, { className: "block text-xs text-zinc-500 dark:text-zinc-400 mb-1", children: "From date" }), _jsx("input", { type: "date", value: pendingTable.get(TABLE_KEYS.DATE_FROM) || "", onChange: (e) => { pendingTable.set(TABLE_KEYS.DATE_FROM, e.target.value); }, className: "w-full rounded-lg border border-zinc-300 dark:border-slate-600 bg-white dark:bg-slate-800 px-3 py-2 text-sm text-zinc-900 dark:text-zinc-100 outline-none focus:ring-2 focus:ring-primary" })] }), _jsxs(_Fragment, { children: [_jsx(Label, { className: "block text-xs text-zinc-500 dark:text-zinc-400 mb-1", children: "To date" }), _jsx("input", { type: "date", value: pendingTable.get(TABLE_KEYS.DATE_TO) || "", onChange: (e) => { pendingTable.set(TABLE_KEYS.DATE_TO, e.target.value); }, className: "w-full rounded-lg border border-zinc-300 dark:border-slate-600 bg-white dark:bg-slate-800 px-3 py-2 text-sm text-zinc-900 dark:text-zinc-100 outline-none focus:ring-2 focus:ring-primary" })] })] })] })] })] }));
|
|
102
106
|
}
|
|
@@ -9,13 +9,13 @@ export declare function usePromotions(params?: PromotionsListParams, opts?: {
|
|
|
9
9
|
hasMore: boolean;
|
|
10
10
|
isLoading: boolean;
|
|
11
11
|
error: string | null;
|
|
12
|
-
refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<PromotionsListResponse
|
|
12
|
+
refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<NoInfer<PromotionsListResponse>, Error>>;
|
|
13
13
|
};
|
|
14
14
|
export declare function useCoupon(code: string, opts?: {
|
|
15
15
|
enabled?: boolean;
|
|
16
16
|
endpoint?: string;
|
|
17
17
|
}): {
|
|
18
|
-
coupon: CouponItem | null;
|
|
18
|
+
coupon: NonNullable<NoInfer<CouponItem | null>> | null;
|
|
19
19
|
isLoading: boolean;
|
|
20
20
|
error: string | null;
|
|
21
21
|
};
|
|
@@ -202,6 +202,14 @@ export declare class CouponsRepository extends BaseRepository<CouponDocument> {
|
|
|
202
202
|
canFilter: boolean;
|
|
203
203
|
canSort: boolean;
|
|
204
204
|
};
|
|
205
|
+
storeId: {
|
|
206
|
+
canFilter: boolean;
|
|
207
|
+
canSort: boolean;
|
|
208
|
+
};
|
|
209
|
+
scope: {
|
|
210
|
+
canFilter: boolean;
|
|
211
|
+
canSort: boolean;
|
|
212
|
+
};
|
|
205
213
|
};
|
|
206
214
|
/**
|
|
207
215
|
* Paginated, Firestore-native coupon list.
|
|
@@ -505,6 +505,8 @@ CouponsRepository.SIEVE_FIELDS = {
|
|
|
505
505
|
canSort: true,
|
|
506
506
|
},
|
|
507
507
|
createdAt: { canFilter: true, canSort: true },
|
|
508
|
+
storeId: { canFilter: true, canSort: false },
|
|
509
|
+
scope: { canFilter: true, canSort: false },
|
|
508
510
|
};
|
|
509
511
|
// Export singleton instance
|
|
510
512
|
export const couponsRepository = new CouponsRepository();
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import Link from "next/link";
|
|
3
3
|
import { reviewRepository } from "../../../repositories";
|
|
4
|
-
import { Container, Heading, Main, Section, Text } from "../../../ui";
|
|
4
|
+
import { Container, Div, Heading, Main, Nav, Section, Span, Text } from "../../../ui";
|
|
5
5
|
import { ROUTES } from "../../../next";
|
|
6
6
|
import { ReviewDetailShell } from "./ReviewDetailShell";
|
|
7
7
|
export async function ReviewDetailPageView({ id }) {
|
|
@@ -10,7 +10,7 @@ export async function ReviewDetailPageView({ id }) {
|
|
|
10
10
|
// storeId === storeSlug for stores in this project (pure slug IDs)
|
|
11
11
|
const storeSlug = doc?.storeId ?? null;
|
|
12
12
|
if (!review || review.status !== "approved") {
|
|
13
|
-
return (_jsx(Main, { children: _jsx(Section, { className: "py-24", children: _jsx(Container, { size: "sm", children: _jsxs(
|
|
13
|
+
return (_jsx(Main, { children: _jsx(Section, { className: "py-24", children: _jsx(Container, { size: "sm", children: _jsxs(Div, { className: "text-center", children: [_jsx(Text, { className: "text-5xl mb-4", "aria-hidden": "true", children: "\uD83D\uDD0D" }), _jsx(Heading, { level: 1, className: "text-2xl font-bold text-neutral-900 dark:text-white mb-2", children: "Review not found" }), _jsx(Text, { className: "text-sm text-neutral-500 dark:text-zinc-400 mb-6", children: "This review may have been removed or is no longer available." }), _jsx(Link, { href: String(ROUTES.PUBLIC.REVIEWS), className: "inline-flex items-center gap-2 rounded-lg bg-primary px-5 py-2.5 text-sm font-medium text-white hover:bg-primary-600 transition-colors", children: "\u2190 Back to Reviews" })] }) }) }) }));
|
|
14
14
|
}
|
|
15
|
-
return (_jsxs(Main, { children: [_jsx(
|
|
15
|
+
return (_jsxs(Main, { children: [_jsx(Div, { className: "border-b border-neutral-100 dark:border-zinc-800 bg-neutral-50 dark:bg-zinc-950 py-2.5 px-4", children: _jsxs(Nav, { className: "mx-auto max-w-3xl flex items-center gap-1.5 text-xs text-zinc-400 dark:text-zinc-400", "aria-label": "Breadcrumb", children: [_jsx(Link, { href: String(ROUTES.HOME), className: "hover:text-primary transition-colors", children: "Home" }), _jsx(Span, { children: "/" }), _jsx(Link, { href: String(ROUTES.PUBLIC.REVIEWS), className: "hover:text-primary transition-colors", children: "Reviews" }), _jsx(Span, { children: "/" }), _jsx(Span, { className: "text-neutral-700 dark:text-zinc-300 truncate max-w-[200px]", children: review.title ?? review.id })] }) }), _jsx(ReviewDetailShell, { review: review, storeHref: storeSlug ? String(ROUTES.PUBLIC.STORE_DETAIL(storeSlug)) : null })] }));
|
|
16
16
|
}
|