@mohasinac/appkit 2.7.27 → 2.7.31
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 +29 -0
- package/dist/_internal/client/features/filters/filter-load-options.js +98 -0
- package/dist/_internal/client/features/layout/DashboardLayoutClient.js +1 -1
- package/dist/_internal/server/features/checkout/actions.js +42 -35
- package/dist/_internal/server/features/classified/adapters.d.ts +21 -0
- package/dist/_internal/server/features/classified/adapters.js +24 -0
- package/dist/_internal/server/features/classified/index.d.ts +3 -0
- package/dist/_internal/server/features/classified/index.js +3 -0
- package/dist/_internal/server/features/classified/metadata.d.ts +8 -0
- package/dist/_internal/server/features/classified/metadata.js +43 -0
- package/dist/_internal/server/features/classified/og.d.ts +30 -0
- package/dist/_internal/server/features/classified/og.js +76 -0
- package/dist/_internal/server/features/digital-code/adapters.d.ts +21 -0
- package/dist/_internal/server/features/digital-code/adapters.js +29 -0
- package/dist/_internal/server/features/digital-code/index.d.ts +3 -0
- package/dist/_internal/server/features/digital-code/index.js +3 -0
- package/dist/_internal/server/features/digital-code/metadata.d.ts +8 -0
- package/dist/_internal/server/features/digital-code/metadata.js +36 -0
- package/dist/_internal/server/features/digital-code/og.d.ts +27 -0
- package/dist/_internal/server/features/digital-code/og.js +77 -0
- package/dist/_internal/server/features/live/adapters.d.ts +21 -0
- package/dist/_internal/server/features/live/adapters.js +34 -0
- package/dist/_internal/server/features/live/index.d.ts +3 -0
- package/dist/_internal/server/features/live/index.js +3 -0
- package/dist/_internal/server/features/live/metadata.d.ts +8 -0
- package/dist/_internal/server/features/live/metadata.js +39 -0
- package/dist/_internal/server/features/live/og.d.ts +27 -0
- package/dist/_internal/server/features/live/og.js +72 -0
- package/dist/_internal/server/features/promotions/actions.js +4 -3
- package/dist/_internal/server/jobs/core/onOrderCreate.js +19 -16
- package/dist/_internal/server/jobs/core/onOrderStatusChange.js +25 -22
- package/dist/_internal/server/jobs/core/onProductWrite.js +48 -58
- package/dist/_internal/shared/actions/action-registry.js +504 -9
- package/dist/_internal/shared/features/blog/schema.d.ts +4 -4
- package/dist/_internal/shared/features/brands/schema.d.ts +5 -5
- package/dist/_internal/shared/features/cart/schema.d.ts +18 -18
- package/dist/_internal/shared/features/categories/bundle-copy.d.ts +1 -1
- package/dist/_internal/shared/features/categories/bundle-schemas.d.ts +38 -38
- package/dist/_internal/shared/features/events/schema.d.ts +8 -8
- package/dist/_internal/shared/features/orders/schema.d.ts +8 -8
- package/dist/_internal/shared/features/products/schema.d.ts +42 -42
- package/dist/_internal/shared/features/promotions/schema.d.ts +4 -4
- package/dist/_internal/shared/features/reviews/schema.d.ts +1 -1
- package/dist/_internal/shared/media/limits.js +4 -3
- package/dist/client.d.ts +4 -0
- package/dist/client.js +2 -0
- package/dist/configs/next.js +4 -0
- package/dist/constants/api-endpoints.d.ts +6 -0
- package/dist/constants/api-endpoints.js +2 -0
- package/dist/constants/field-names.d.ts +1 -0
- package/dist/constants/field-names.js +1 -0
- package/dist/constants/table-keys.d.ts +6 -0
- package/dist/constants/table-keys.js +9 -0
- package/dist/core/hooks/useSyncManager.js +9 -8
- package/dist/features/about/components/FeesView.js +10 -7
- package/dist/features/about/components/HelpPageView.js +10 -1
- package/dist/features/about/components/HowAuctionsWorkView.js +10 -1
- package/dist/features/about/components/HowCheckoutWorksView.js +10 -1
- package/dist/features/about/components/HowOffersWorkView.js +10 -1
- package/dist/features/about/components/HowOrdersWorkView.js +10 -1
- package/dist/features/about/components/HowPayoutsWorkView.js +10 -1
- package/dist/features/about/components/HowPreOrdersWorkView.js +10 -1
- package/dist/features/about/components/HowReviewsWorkView.js +10 -1
- package/dist/features/about/components/PublicProfileView.js +46 -16
- package/dist/features/about/components/SecurityPrivacyView.js +7 -1
- package/dist/features/account/components/AddressesIndexListing.js +2 -2
- package/dist/features/account/components/NotificationBell.js +27 -16
- package/dist/features/account/components/NotificationPreferencesPanel.d.ts +9 -0
- package/dist/features/account/components/NotificationPreferencesPanel.js +91 -0
- package/dist/features/account/components/UserSidebar.js +4 -4
- package/dist/features/account/components/UserSupportView.js +16 -6
- package/dist/features/account/components/index.d.ts +2 -0
- package/dist/features/account/components/index.js +1 -0
- package/dist/features/account/schemas/index.d.ts +4 -4
- package/dist/features/account/types/index.d.ts +34 -0
- package/dist/features/admin/actions/admin-actions.js +4 -3
- package/dist/features/admin/actions/notification-actions.d.ts +24 -22
- package/dist/features/admin/actions/notification-actions.js +122 -22
- package/dist/features/admin/components/AdminAdEditorView.js +29 -15
- package/dist/features/admin/components/AdminAddressEditorView.d.ts +7 -0
- package/dist/features/admin/components/AdminAddressEditorView.js +117 -0
- package/dist/features/admin/components/AdminAdsView.js +22 -28
- package/dist/features/admin/components/AdminAllEventEntriesView.js +6 -1
- package/dist/features/admin/components/AdminBidsView.js +10 -3
- package/dist/features/admin/components/AdminBlogEditorView.js +2 -2
- package/dist/features/admin/components/AdminBlogView.js +8 -3
- package/dist/features/admin/components/AdminBrandsView.js +7 -2
- package/dist/features/admin/components/AdminBundleEditorView.js +5 -2
- package/dist/features/admin/components/AdminCarouselEditorView.js +6 -3
- package/dist/features/admin/components/AdminCarouselView.js +13 -7
- package/dist/features/admin/components/AdminCategoriesView.js +8 -3
- package/dist/features/admin/components/AdminCategoryEditorView.js +12 -9
- package/dist/features/admin/components/AdminContactView.js +6 -1
- package/dist/features/admin/components/AdminCouponEditorView.js +8 -2
- package/dist/features/admin/components/AdminCouponsView.js +6 -1
- package/dist/features/admin/components/AdminEmployeeEditorView.js +12 -9
- package/dist/features/admin/components/AdminFaqEditorView.js +2 -2
- package/dist/features/admin/components/AdminFaqsView.js +7 -2
- package/dist/features/admin/components/AdminFeatureFlagsView.js +58 -13
- package/dist/features/admin/components/AdminFeaturesView.js +4 -3
- package/dist/features/admin/components/AdminMediaView.js +9 -8
- package/dist/features/admin/components/AdminNavigationView.js +10 -17
- package/dist/features/admin/components/AdminNewsletterView.js +6 -1
- package/dist/features/admin/components/AdminNotificationsView.js +11 -3
- package/dist/features/admin/components/AdminOrdersView.js +6 -1
- package/dist/features/admin/components/AdminPayoutsView.js +10 -3
- package/dist/features/admin/components/AdminPrizeDrawsView.js +10 -3
- package/dist/features/admin/components/AdminProductEditorView.d.ts +3 -1
- package/dist/features/admin/components/AdminProductEditorView.js +12 -9
- package/dist/features/admin/components/AdminProductsView.js +18 -12
- package/dist/features/admin/components/AdminReturnRequestsView.js +5 -4
- package/dist/features/admin/components/AdminReviewsView.js +36 -26
- package/dist/features/admin/components/AdminScammerEditorView.js +3 -2
- package/dist/features/admin/components/AdminScammersView.js +28 -26
- package/dist/features/admin/components/AdminSectionsView.js +112 -99
- package/dist/features/admin/components/AdminSessionsView.js +10 -3
- package/dist/features/admin/components/AdminSidebar.js +4 -4
- package/dist/features/admin/components/AdminSiteSettingsView.js +45 -4
- package/dist/features/admin/components/AdminStoresView.js +6 -1
- package/dist/features/admin/components/AdminSublistingCategoriesView.js +0 -1
- package/dist/features/admin/components/AdminSupportTicketDetailView.js +1 -1
- package/dist/features/admin/components/AdminSupportTicketsView.js +32 -34
- package/dist/features/admin/components/AdminTeamView.js +6 -1
- package/dist/features/admin/components/AdminUserEditorView.js +8 -15
- package/dist/features/admin/components/AdminUsersView.js +6 -1
- package/dist/features/admin/components/AdminViewCards.js +4 -3
- package/dist/features/admin/components/DashboardStats.js +2 -2
- package/dist/features/admin/components/DataTable.js +2 -2
- package/dist/features/admin/components/index.d.ts +2 -0
- package/dist/features/admin/components/index.js +1 -0
- package/dist/features/admin/components/sections/adminSectionsTypes.js +4 -3
- package/dist/features/admin/repository/chat.repository.js +8 -8
- package/dist/features/admin/repository/site-settings.repository.d.ts +1 -0
- package/dist/features/admin/repository/site-settings.repository.js +11 -9
- package/dist/features/admin/schemas/firestore.d.ts +38 -0
- package/dist/features/admin/schemas/firestore.js +15 -0
- package/dist/features/auctions/components/AuctionBidsTable.d.ts +13 -0
- package/dist/features/auctions/components/AuctionBidsTable.js +62 -0
- package/dist/features/auctions/components/AuctionDetailPageView.js +15 -21
- package/dist/features/auctions/components/AuctionFilters.d.ts +7 -1
- package/dist/features/auctions/components/AuctionFilters.js +3 -2
- package/dist/features/auctions/components/MarketplaceAuctionCard.js +18 -9
- package/dist/features/auctions/components/MarketplaceAuctionGrid.js +3 -2
- package/dist/features/auctions/components/index.d.ts +2 -1
- package/dist/features/auctions/components/index.js +1 -1
- package/dist/features/auctions/schemas/index.d.ts +14 -14
- package/dist/features/auth/actions/realtime-token-actions.js +19 -4
- package/dist/features/auth/components/RegisterForm.js +8 -4
- package/dist/features/auth/consent-otp.d.ts +2 -0
- package/dist/features/auth/consent-otp.js +8 -0
- package/dist/features/auth/schemas/firestore.d.ts +2 -0
- package/dist/features/auth/schemas/firestore.js +18 -25
- package/dist/features/auth/schemas/index.d.ts +2 -2
- package/dist/features/before-after/api/[id]/route.js +8 -6
- package/dist/features/before-after/schemas/index.d.ts +2 -2
- package/dist/features/blog/actions/blog-actions.d.ts +3 -3
- package/dist/features/blog/components/BlogIndexListing.js +21 -2
- package/dist/features/blog/components/BlogPostForm.js +11 -5
- package/dist/features/blog/components/BlogPostView.js +10 -2
- package/dist/features/blog/schemas/index.d.ts +18 -18
- package/dist/features/cart/components/CartDrawer.js +3 -2
- package/dist/features/cart/components/CartView.js +2 -1
- package/dist/features/cart/components/CheckoutView.js +2 -1
- package/dist/features/cart/repository/cart.repository.js +4 -3
- package/dist/features/cart/utils/pending-ops.d.ts +1 -1
- package/dist/features/categories/api/[id]/route.js +4 -3
- package/dist/features/categories/api/route.js +4 -3
- package/dist/features/categories/components/BrandDetailPageView.js +2 -2
- package/dist/features/categories/components/BrandDetailTabs.d.ts +5 -1
- package/dist/features/categories/components/BrandDetailTabs.js +30 -16
- package/dist/features/categories/components/BundleCollage.d.ts +8 -0
- package/dist/features/categories/components/BundleCollage.js +50 -0
- package/dist/features/categories/components/BundleDetailView.js +2 -10
- package/dist/features/categories/components/BundleItemsPicker.js +20 -13
- package/dist/features/categories/components/CategoriesIndexListing.js +28 -9
- package/dist/features/categories/components/CategoryDetailPageView.js +2 -2
- package/dist/features/categories/components/CategoryDetailTabs.d.ts +5 -1
- package/dist/features/categories/components/CategoryDetailTabs.js +31 -16
- package/dist/features/categories/components/CategoryProductsListing.js +52 -13
- package/dist/features/categories/components/index.d.ts +2 -0
- package/dist/features/categories/components/index.js +1 -0
- package/dist/features/categories/schemas/index.d.ts +6 -6
- package/dist/features/checkout/actions/checkout-actions.js +4 -3
- package/dist/features/checkout/hooks/usePaymentCheckout.js +31 -22
- package/dist/features/classified/components/ClassifiedFilters.d.ts +12 -0
- package/dist/features/classified/components/ClassifiedFilters.js +20 -0
- package/dist/features/classified/components/ClassifiedIndexListing.d.ts +4 -0
- package/dist/features/classified/components/ClassifiedIndexListing.js +110 -0
- package/dist/features/classified/components/ClassifiedListView.d.ts +6 -0
- package/dist/features/classified/components/ClassifiedListView.js +43 -0
- package/dist/features/classified/components/index.d.ts +6 -0
- package/dist/features/classified/components/index.js +3 -0
- package/dist/features/collections/api/[slug]/route.js +16 -12
- package/dist/features/collections/schemas/index.d.ts +5 -5
- package/dist/features/consultation/api/[id]/route.js +12 -9
- package/dist/features/consultation/components/ConsultationForm.js +3 -2
- package/dist/features/consultation/schemas/index.d.ts +6 -6
- package/dist/features/contact/email.js +77 -116
- package/dist/features/copilot/components/AdminCopilotView.js +12 -2
- package/dist/features/corporate/api/[id]/route.js +12 -9
- package/dist/features/corporate/components/CorporateInquiryForm.js +2 -1
- package/dist/features/digital-codes/components/DigitalCodeFilters.d.ts +12 -0
- package/dist/features/digital-codes/components/DigitalCodeFilters.js +17 -0
- package/dist/features/digital-codes/components/DigitalCodesIndexListing.d.ts +4 -0
- package/dist/features/digital-codes/components/DigitalCodesIndexListing.js +107 -0
- package/dist/features/digital-codes/components/DigitalCodesListView.d.ts +6 -0
- package/dist/features/digital-codes/components/DigitalCodesListView.js +37 -0
- package/dist/features/digital-codes/components/index.d.ts +6 -0
- package/dist/features/digital-codes/components/index.js +3 -0
- package/dist/features/events/actions/event-actions.js +4 -3
- package/dist/features/events/components/AdminEventEditorView.js +3 -2
- package/dist/features/events/components/AdminEventsView.js +4 -2
- package/dist/features/events/components/EventPollWidget.js +5 -5
- package/dist/features/events/components/EventsIndexListing.js +2 -2
- package/dist/features/events/repository/event-entry.repository.d.ts +1 -0
- package/dist/features/events/repository/event-entry.repository.js +5 -0
- package/dist/features/events/schemas/index.d.ts +20 -20
- package/dist/features/faq/actions/faq-actions.d.ts +8 -8
- package/dist/features/faq/components/ContactCTA.js +3 -1
- package/dist/features/faq/components/FAQAccordion.js +1 -1
- package/dist/features/faq/schemas/index.d.ts +4 -4
- package/dist/features/filters/AsyncFacetSection.d.ts +18 -0
- package/dist/features/filters/AsyncFacetSection.js +65 -0
- package/dist/features/filters/index.d.ts +2 -0
- package/dist/features/filters/index.js +1 -0
- package/dist/features/forms/Checkbox.js +2 -2
- package/dist/features/forms/Input.js +2 -2
- package/dist/features/forms/Radio.js +5 -5
- package/dist/features/forms/Select.js +2 -2
- package/dist/features/forms/Slider.js +2 -2
- package/dist/features/forms/Textarea.js +2 -2
- package/dist/features/homepage/api/[id]/route.js +4 -3
- package/dist/features/homepage/api/sections/[id]/route.js +12 -9
- package/dist/features/homepage/components/AdSlot.js +2 -1
- package/dist/features/homepage/components/AdvertisementBanner.js +5 -3
- package/dist/features/homepage/components/BrandsSection.js +2 -2
- package/dist/features/homepage/components/CTABannerSection.js +2 -2
- package/dist/features/homepage/components/CharacterHotspot.d.ts +2 -2
- package/dist/features/homepage/components/CharacterHotspot.js +119 -157
- package/dist/features/homepage/components/CharacterHotspotForm.js +25 -20
- package/dist/features/homepage/components/CustomCardsSection.js +8 -6
- package/dist/features/homepage/components/FeaturedProductsSection.js +2 -2
- package/dist/features/homepage/components/GoogleReviewsSection.js +3 -3
- package/dist/features/homepage/components/HeroBanner.js +5 -4
- package/dist/features/homepage/components/HeroCarousel.js +13 -26
- package/dist/features/homepage/components/HowItWorksSection.js +4 -2
- package/dist/features/homepage/components/SocialFeedSection.js +2 -2
- package/dist/features/homepage/components/SocialPostCard.js +3 -2
- package/dist/features/homepage/lib/social-feed-fetcher.js +6 -3
- package/dist/features/layout/AppLayoutShell.d.ts +8 -2
- package/dist/features/layout/AppLayoutShell.js +54 -78
- package/dist/features/layout/BottomActions.js +43 -48
- package/dist/features/live/components/LiveItemFilters.d.ts +12 -0
- package/dist/features/live/components/LiveItemFilters.js +24 -0
- package/dist/features/live/components/LiveItemsIndexListing.d.ts +4 -0
- package/dist/features/live/components/LiveItemsIndexListing.js +108 -0
- package/dist/features/live/components/LiveItemsListView.d.ts +6 -0
- package/dist/features/live/components/LiveItemsListView.js +43 -0
- package/dist/features/live/components/index.d.ts +6 -0
- package/dist/features/live/components/index.js +3 -0
- package/dist/features/media/MediaLightbox.js +8 -14
- package/dist/features/media/types/index.d.ts +2 -2
- package/dist/features/media/upload/CameraCapture.js +2 -2
- package/dist/features/media/upload/ImageUpload.js +4 -2
- package/dist/features/media/upload/MediaUploadField.js +24 -8
- package/dist/features/media/upload/MediaUploadList.js +1 -1
- package/dist/features/orders/actions/order-actions.js +4 -3
- package/dist/features/orders/components/MarketplaceOrderCard.js +2 -1
- package/dist/features/orders/components/OrderFilters.js +12 -9
- package/dist/features/orders/schemas/index.d.ts +6 -6
- package/dist/features/pre-orders/api/[id]/route.js +12 -9
- package/dist/features/pre-orders/components/MarketplacePreorderCard.js +5 -4
- package/dist/features/pre-orders/components/PreOrderDetailPageView.js +29 -22
- package/dist/features/pre-orders/components/PreOrderFilters.d.ts +7 -1
- package/dist/features/pre-orders/components/PreOrderFilters.js +3 -2
- package/dist/features/pre-orders/components/PreOrdersIndexListing.js +17 -52
- package/dist/features/pre-orders/components/PreorderCard.d.ts +0 -9
- package/dist/features/pre-orders/components/PreorderCard.js +2 -13
- package/dist/features/pre-orders/components/index.d.ts +1 -1
- package/dist/features/pre-orders/components/index.js +1 -1
- package/dist/features/pre-orders/schemas/index.d.ts +10 -10
- package/dist/features/products/api/[id]/route.js +9 -7
- package/dist/features/products/api/route.js +1 -1
- package/dist/features/products/columns/productTableColumns.js +3 -3
- package/dist/features/products/components/AuctionsIndexListing.js +15 -51
- package/dist/features/products/components/BidHistory.js +2 -2
- package/dist/features/products/components/CompareOverlay.d.ts +2 -0
- package/dist/features/products/components/CompareOverlay.js +3 -2
- package/dist/features/products/components/MakeOfferButton.js +20 -14
- package/dist/features/products/components/MarketplacePrizeDrawCard.js +2 -1
- package/dist/features/products/components/PrizeDrawCollage.d.ts +1 -15
- package/dist/features/products/components/PrizeDrawCollage.js +54 -14
- package/dist/features/products/components/PrizeDrawDetailPageView.js +2 -1
- package/dist/features/products/components/PrizeDrawEntryActions.js +2 -1
- package/dist/features/products/components/PrizeDrawItemsEditor.js +9 -7
- package/dist/features/products/components/PrizeDrawsIndexListing.js +18 -51
- package/dist/features/products/components/PrizeRevealModal.js +24 -14
- package/dist/features/products/components/ProductDetailPageView.js +2 -1
- package/dist/features/products/components/ProductFilters.d.ts +7 -1
- package/dist/features/products/components/ProductFilters.js +11 -8
- package/dist/features/products/components/ProductForm.js +18 -16
- package/dist/features/products/components/ProductGalleryClient.js +2 -1
- package/dist/features/products/components/ProductGrid.js +12 -15
- package/dist/features/products/components/ProductsIndexListing.js +16 -52
- package/dist/features/products/components/ProductsIndexPageView.js +2 -2
- package/dist/features/products/repository/products.repository.d.ts +4 -0
- package/dist/features/products/repository/products.repository.js +22 -3
- package/dist/features/products/schemas/firestore.d.ts +7 -1
- package/dist/features/products/schemas/index.d.ts +56 -56
- package/dist/features/products/schemas/product-features.validators.d.ts +14 -14
- package/dist/features/products/types/index.d.ts +4 -0
- package/dist/features/promotions/components/CouponsIndexListing.js +1 -1
- package/dist/features/promotions/schemas/index.d.ts +6 -6
- package/dist/features/reviews/actions/review-actions.js +6 -5
- package/dist/features/reviews/api/[id]/route.js +4 -3
- package/dist/features/reviews/components/ReviewDetailPageView.js +2 -2
- package/dist/features/reviews/components/ReviewDetailShell.js +6 -3
- package/dist/features/reviews/components/ReviewsIndexListing.js +2 -2
- package/dist/features/reviews/schemas/index.d.ts +6 -6
- package/dist/features/scams/components/ScamProfileView.js +19 -10
- package/dist/features/scams/components/ScamRegistryView.js +2 -1
- package/dist/features/search/components/Search.d.ts +1 -1
- package/dist/features/search/components/Search.js +56 -49
- package/dist/features/search/schemas/index.d.ts +5 -5
- package/dist/features/seller/actions/offer-actions.js +11 -9
- package/dist/features/seller/components/SellerAddressesView.js +6 -4
- package/dist/features/seller/components/SellerBidsView.js +2 -2
- package/dist/features/seller/components/SellerCouponsView.js +1 -1
- package/dist/features/seller/components/SellerOffersPanel.js +6 -1
- package/dist/features/seller/components/SellerOrdersView.js +1 -1
- package/dist/features/seller/components/SellerPayoutSettingsView.js +3 -3
- package/dist/features/seller/components/SellerPreOrdersView.js +5 -4
- package/dist/features/seller/components/SellerPrizeDrawsView.js +5 -4
- package/dist/features/seller/components/SellerProductShell.d.ts +19 -1
- package/dist/features/seller/components/SellerProductShell.js +75 -9
- package/dist/features/seller/components/SellerProductsView.js +10 -11
- package/dist/features/seller/components/SellerShippingView.js +3 -3
- package/dist/features/seller/components/SellerSidebar.js +10 -7
- package/dist/features/seller/components/SellerStorefrontView.js +3 -3
- package/dist/features/seller/schemas/index.d.ts +4 -4
- package/dist/features/shell/FormShell.js +2 -1
- package/dist/features/shell/QuickFormDrawer.js +4 -3
- package/dist/features/shell/StepForm.js +4 -3
- package/dist/features/stores/actions/store-query-actions.js +4 -3
- package/dist/features/stores/components/StoreAboutView.js +2 -1
- package/dist/features/stores/components/StoreAuctionsListing.js +43 -64
- package/dist/features/stores/components/StoreDetailLayoutView.js +18 -4
- package/dist/features/stores/components/StorePreOrdersListing.js +33 -57
- package/dist/features/stores/components/StoreProductsListing.js +16 -49
- package/dist/features/stores/components/StoresIndexListing.js +2 -2
- package/dist/features/stores/schemas/index.d.ts +2 -2
- package/dist/features/whatsapp-bot/components/SellerWhatsAppSettingsView.js +8 -7
- package/dist/features/wishlist/hooks/useGuestWishlist.d.ts +5 -5
- package/dist/features/wishlist/hooks/useWishlistWithGuest.d.ts +6 -6
- package/dist/features/wishlist/utils/guest-wishlist.d.ts +5 -5
- package/dist/index.d.ts +27 -3
- package/dist/index.js +1743 -1725
- package/dist/monitoring/server-logger.js +5 -9
- package/dist/next/api/apiHandler.js +56 -37
- package/dist/next/components/GlobalError.js +2 -1
- package/dist/next/routing/route-map.d.ts +41 -0
- package/dist/next/routing/route-map.js +17 -0
- package/dist/react/ErrorBoundary.js +2 -1
- package/dist/react/contexts/SessionContext.js +38 -28
- package/dist/react/hooks/useCamera.d.ts +1 -1
- package/dist/react/hooks/useCamera.js +8 -7
- package/dist/seed/products-auctions-seed-data.js +40 -40
- package/dist/seed/products-preorders-seed-data.js +16 -16
- package/dist/seed/products-prize-draws-seed-data.js +4 -4
- package/dist/seed/products-standard-seed-data.js +202 -202
- package/dist/seed/site-settings-seed-data.js +6 -0
- package/dist/server-entry.d.ts +3 -0
- package/dist/server-entry.js +3 -0
- package/dist/server.d.ts +12 -0
- package/dist/server.js +15 -0
- package/dist/tailwind-utilities.css +1 -1
- package/dist/ui/DataTable.js +28 -7
- package/dist/ui/components/Button.d.ts +8 -1
- package/dist/ui/components/Button.js +47 -8
- package/dist/ui/components/CollageLightbox.d.ts +18 -0
- package/dist/ui/components/CollageLightbox.js +41 -0
- package/dist/ui/components/Dropdown.js +7 -6
- package/dist/ui/components/ImageLightbox.d.ts +7 -1
- package/dist/ui/components/ImageLightbox.js +15 -5
- package/dist/ui/components/PageLoader.js +4 -3
- package/dist/ui/components/PaginatedMultiSelect.d.ts +28 -0
- package/dist/ui/components/PaginatedMultiSelect.js +141 -0
- package/dist/ui/components/PaginatedMultiSelect.style.css +272 -0
- package/dist/ui/components/Semantic.js +1 -1
- package/dist/ui/components/SideDrawer.js +17 -15
- package/dist/ui/components/index.style.css +1 -0
- package/dist/ui/index.d.ts +2 -0
- package/dist/ui/index.js +1 -0
- package/dist/utils/number.formatter.js +5 -13
- package/dist/utils/string.formatter.js +21 -18
- package/dist/validation/schemas.d.ts +2 -2
- package/package.json +1 -1
|
@@ -91,6 +91,7 @@ export declare const faqSchema: z.ZodObject<{
|
|
|
91
91
|
};
|
|
92
92
|
createdAt?: string | undefined;
|
|
93
93
|
updatedAt?: string | undefined;
|
|
94
|
+
tags?: string[] | undefined;
|
|
94
95
|
order?: number | undefined;
|
|
95
96
|
priority?: number | undefined;
|
|
96
97
|
stats?: {
|
|
@@ -99,7 +100,6 @@ export declare const faqSchema: z.ZodObject<{
|
|
|
99
100
|
notHelpful?: number | undefined;
|
|
100
101
|
} | undefined;
|
|
101
102
|
isActive?: boolean | undefined;
|
|
102
|
-
tags?: string[] | undefined;
|
|
103
103
|
seo?: {
|
|
104
104
|
slug?: string | undefined;
|
|
105
105
|
} | undefined;
|
|
@@ -117,6 +117,7 @@ export declare const faqSchema: z.ZodObject<{
|
|
|
117
117
|
};
|
|
118
118
|
createdAt?: string | undefined;
|
|
119
119
|
updatedAt?: string | undefined;
|
|
120
|
+
tags?: string[] | undefined;
|
|
120
121
|
order?: number | undefined;
|
|
121
122
|
priority?: number | undefined;
|
|
122
123
|
stats?: {
|
|
@@ -125,7 +126,6 @@ export declare const faqSchema: z.ZodObject<{
|
|
|
125
126
|
notHelpful?: number | undefined;
|
|
126
127
|
} | undefined;
|
|
127
128
|
isActive?: boolean | undefined;
|
|
128
|
-
tags?: string[] | undefined;
|
|
129
129
|
seo?: {
|
|
130
130
|
slug?: string | undefined;
|
|
131
131
|
} | undefined;
|
|
@@ -144,14 +144,14 @@ export declare const faqListParamsSchema: z.ZodObject<{
|
|
|
144
144
|
}, "strip", z.ZodTypeAny, {
|
|
145
145
|
perPage?: number | undefined;
|
|
146
146
|
q?: string | undefined;
|
|
147
|
-
page?: number | undefined;
|
|
148
147
|
category?: "orders_payment" | "shipping_delivery" | "returns_refunds" | "product_information" | "account_security" | "technical_support" | "general" | undefined;
|
|
148
|
+
page?: number | undefined;
|
|
149
149
|
homepage?: boolean | undefined;
|
|
150
150
|
}, {
|
|
151
151
|
perPage?: number | undefined;
|
|
152
152
|
q?: string | undefined;
|
|
153
|
-
page?: number | undefined;
|
|
154
153
|
category?: "orders_payment" | "shipping_delivery" | "returns_refunds" | "product_information" | "account_security" | "technical_support" | "general" | undefined;
|
|
154
|
+
page?: number | undefined;
|
|
155
155
|
homepage?: boolean | undefined;
|
|
156
156
|
}>;
|
|
157
157
|
export * from "./firestore";
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { FacetOption } from "./FilterFacetSection";
|
|
2
|
+
import type { AsyncPage } from "../../ui/components/DynamicSelect";
|
|
3
|
+
export interface AsyncFacetSectionProps {
|
|
4
|
+
title: string;
|
|
5
|
+
selected: string[];
|
|
6
|
+
onChange: (selected: string[]) => void;
|
|
7
|
+
loadOptions: (query: string, page: number) => Promise<AsyncPage<FacetOption>>;
|
|
8
|
+
selectionMode?: "single" | "multi";
|
|
9
|
+
defaultCollapsed?: boolean;
|
|
10
|
+
onClear?: () => void;
|
|
11
|
+
className?: string;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* AsyncFacetSection — collapsible filter section that loads options from the API
|
|
15
|
+
* with search + pagination. Replaces static `FilterFacetSection` for large datasets
|
|
16
|
+
* (>20 items). Uses the same accordion UX pattern for visual consistency.
|
|
17
|
+
*/
|
|
18
|
+
export declare function AsyncFacetSection({ title, selected, onChange, loadOptions, selectionMode, defaultCollapsed, onClear, className, }: AsyncFacetSectionProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useCallback, useEffect, useRef, useState } from "react";
|
|
4
|
+
import { Button, Div, Input, Row, Span, Text } from "../../ui";
|
|
5
|
+
import { cn } from "./filterUtils";
|
|
6
|
+
/**
|
|
7
|
+
* AsyncFacetSection — collapsible filter section that loads options from the API
|
|
8
|
+
* with search + pagination. Replaces static `FilterFacetSection` for large datasets
|
|
9
|
+
* (>20 items). Uses the same accordion UX pattern for visual consistency.
|
|
10
|
+
*/
|
|
11
|
+
export function AsyncFacetSection({ title, selected, onChange, loadOptions, selectionMode = "multi", defaultCollapsed = true, onClear, className = "", }) {
|
|
12
|
+
const [collapsed, setCollapsed] = useState(defaultCollapsed);
|
|
13
|
+
const [query, setQuery] = useState("");
|
|
14
|
+
const [options, setOptions] = useState([]);
|
|
15
|
+
const [page, setPage] = useState(1);
|
|
16
|
+
const [hasMore, setHasMore] = useState(false);
|
|
17
|
+
const [loading, setLoading] = useState(false);
|
|
18
|
+
// label cache so chips show labels even after options change
|
|
19
|
+
const labelMap = useRef(new Map());
|
|
20
|
+
const load = useCallback(async (search, nextPage, reset = false) => {
|
|
21
|
+
setLoading(true);
|
|
22
|
+
try {
|
|
23
|
+
const res = await loadOptions(search, nextPage);
|
|
24
|
+
setOptions((prev) => {
|
|
25
|
+
const merged = reset ? res.items : [...prev, ...res.items];
|
|
26
|
+
merged.forEach((o) => labelMap.current.set(o.value, o.label));
|
|
27
|
+
return merged;
|
|
28
|
+
});
|
|
29
|
+
setPage(nextPage);
|
|
30
|
+
setHasMore(res.hasMore);
|
|
31
|
+
}
|
|
32
|
+
finally {
|
|
33
|
+
setLoading(false);
|
|
34
|
+
}
|
|
35
|
+
}, [loadOptions]);
|
|
36
|
+
// Load whenever the section is expanded or query changes
|
|
37
|
+
useEffect(() => {
|
|
38
|
+
if (collapsed)
|
|
39
|
+
return;
|
|
40
|
+
void load(query, 1, true);
|
|
41
|
+
}, [collapsed, query, load]);
|
|
42
|
+
function handleQueryChange(val) {
|
|
43
|
+
setQuery(val);
|
|
44
|
+
if (collapsed)
|
|
45
|
+
setCollapsed(false);
|
|
46
|
+
}
|
|
47
|
+
function toggle(value) {
|
|
48
|
+
if (selectionMode === "single") {
|
|
49
|
+
onChange(selected.includes(value) ? [] : [value]);
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
onChange(selected.includes(value)
|
|
53
|
+
? selected.filter((v) => v !== value)
|
|
54
|
+
: [...selected, value]);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
const hasValue = selected.length > 0;
|
|
58
|
+
const selectedLabels = selected
|
|
59
|
+
.map((v) => labelMap.current.get(v) ?? v)
|
|
60
|
+
.slice(0, 3);
|
|
61
|
+
return (_jsxs(Div, { className: cn("p-4 border-b border-zinc-200 dark:border-slate-700 last:border-b-0", className), children: [_jsxs(Row, { gap: "xs", children: [_jsxs(Button, { type: "button", onClick: () => setCollapsed((c) => !c), variant: "ghost", size: "sm", className: "flex flex-1 items-center justify-between text-sm font-semibold text-zinc-900 dark:text-zinc-50 py-1 hover:opacity-80 transition-opacity", "aria-expanded": !collapsed, children: [_jsxs(Row, { as: Span, gap: "xs", children: [title, hasValue && (_jsx(Span, { className: "inline-flex items-center justify-center w-5 h-5 text-xs rounded-full bg-emerald-50 dark:bg-emerald-900/30 text-emerald-700 dark:text-emerald-300 ring-1 ring-emerald-600/20 dark:ring-emerald-400/20", children: selected.length }))] }), _jsx("svg", { className: cn("w-4 h-4 text-zinc-500 dark:text-zinc-400 transition-transform duration-200", collapsed ? "" : "rotate-180"), fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, "aria-hidden": "true", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M19 9l-7 7-7-7" }) })] }), onClear && hasValue && (_jsx(Button, { type: "button", onClick: onClear, variant: "ghost", size: "sm", className: "inline-flex items-center justify-center w-5 h-5 p-0 text-zinc-500 dark:text-zinc-400 hover:text-red-600 dark:hover:text-red-400 hover:bg-zinc-100 dark:hover:bg-slate-700 transition-colors rounded-full", "aria-label": "Clear filter", children: _jsx("svg", { className: "w-3 h-3", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2.5, "aria-hidden": "true", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M6 18L18 6M6 6l12 12" }) }) }))] }), collapsed && hasValue && (_jsxs(Div, { className: "mt-2 flex flex-wrap gap-1", children: [selectedLabels.map((label) => (_jsx(Span, { className: "inline-flex items-center px-2 py-0.5 rounded-full text-xs bg-zinc-100 dark:bg-slate-700 text-zinc-700 dark:text-zinc-300 border border-zinc-200 dark:border-slate-600", children: label }, label))), selected.length > 3 && (_jsxs(Span, { className: "inline-flex items-center px-2 py-0.5 rounded-full text-xs text-zinc-400 dark:text-zinc-500", children: ["+", selected.length - 3, " more"] }))] })), _jsx(Div, { className: "mt-2", children: _jsx(Input, { type: "search", placeholder: "Search\u2026", value: query, onChange: (e) => handleQueryChange(e.target.value), className: "w-full rounded-md border border-zinc-200 dark:border-slate-700 bg-white dark:bg-slate-800/60 px-2.5 py-1.5 text-xs text-zinc-900 dark:text-zinc-100 focus:outline-none focus:ring-2 focus:ring-primary-500/20" }) }), !collapsed && (_jsxs(Div, { className: "mt-3 space-y-1", children: [options.map((opt) => {
|
|
62
|
+
const isSelected = selected.includes(opt.value);
|
|
63
|
+
return (_jsxs(Row, { gap: "2.5", className: "py-1 cursor-pointer group", children: [_jsx("input", { type: selectionMode === "single" ? "radio" : "checkbox", checked: isSelected, onChange: () => toggle(opt.value), "aria-label": opt.label, className: "flex-shrink-0 w-4 h-4 rounded border-zinc-300 dark:border-slate-600 cursor-pointer text-primary-600 dark:text-secondary-500" }), _jsx(Span, { className: "flex-1 text-sm text-zinc-700 dark:text-zinc-300 group-hover:text-zinc-900 dark:group-hover:text-zinc-100 transition-colors truncate", children: opt.label }), opt.count !== undefined && (_jsx(Span, { className: "text-xs text-zinc-400 dark:text-zinc-500 tabular-nums flex-shrink-0", children: opt.count }))] }, opt.value));
|
|
64
|
+
}), options.length === 0 && !loading && (_jsx(Text, { className: "text-xs text-zinc-400 dark:text-zinc-500 py-1", children: "No results" })), loading && (_jsx(Text, { className: "text-xs text-zinc-400 dark:text-zinc-500 py-1 animate-pulse", children: "Loading\u2026" })), hasMore && !loading && (_jsx(Button, { type: "button", variant: "ghost", size: "sm", className: "w-full text-xs text-left text-zinc-400 dark:text-zinc-500 hover:text-zinc-600 dark:hover:text-zinc-300 py-1", onClick: () => void load(query, page + 1), children: "Load more\u2026" }))] }))] }));
|
|
65
|
+
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
export { FilterFacetSection } from "./FilterFacetSection";
|
|
2
2
|
export type { FilterFacetSectionProps, FacetOption, } from "./FilterFacetSection";
|
|
3
|
+
export { AsyncFacetSection } from "./AsyncFacetSection";
|
|
4
|
+
export type { AsyncFacetSectionProps } from "./AsyncFacetSection";
|
|
3
5
|
export { RangeFilter } from "./RangeFilter";
|
|
4
6
|
export type { RangeFilterProps } from "./RangeFilter";
|
|
5
7
|
export { SwitchFilter } from "./SwitchFilter";
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// Public API for @mohasinac/feat-filters
|
|
2
2
|
export { FilterFacetSection } from "./FilterFacetSection";
|
|
3
|
+
export { AsyncFacetSection } from "./AsyncFacetSection";
|
|
3
4
|
export { RangeFilter } from "./RangeFilter";
|
|
4
5
|
export { SwitchFilter } from "./SwitchFilter";
|
|
5
6
|
export { FilterPanel } from "./FilterPanel";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import React from "react";
|
|
4
|
-
import { Div, Span } from "../../ui";
|
|
4
|
+
import { Div, Span, Text } from "../../ui";
|
|
5
5
|
import { cn, ERROR_BASE } from "./utils";
|
|
6
6
|
export function Checkbox({ label, suffix, error, indeterminate, className = "", checked, ...props }) {
|
|
7
7
|
const inputRef = React.useRef(null);
|
|
@@ -12,5 +12,5 @@ export function Checkbox({ label, suffix, error, indeterminate, className = "",
|
|
|
12
12
|
}, [indeterminate]);
|
|
13
13
|
return (_jsxs(Div, { className: "w-full", children: [_jsxs("label", { className: "flex flex-row items-center gap-3 cursor-pointer group", children: [_jsxs(Div, { className: "relative flex items-center justify-center flex-shrink-0", children: [_jsx("input", { ref: inputRef, type: "checkbox", checked: checked, className: cn("peer w-5 h-5 rounded-md border-2 cursor-pointer", "transition-all duration-200 appearance-none", error
|
|
14
14
|
? "border-red-400 dark:border-red-500"
|
|
15
|
-
: "border-zinc-300 dark:border-slate-600", "checked:bg-primary-600 checked:border-primary-600", "dark:checked:bg-secondary-500 dark:checked:border-secondary-500", "hover:border-primary-400 dark:hover:border-secondary-400", "focus:outline-none focus:ring-2 focus:ring-primary-500/30 focus:ring-offset-1", "dark:focus:ring-secondary-400/30 dark:focus:ring-offset-slate-900", "disabled:opacity-50 disabled:cursor-not-allowed", className), ...props }), _jsx("svg", { className: "absolute w-3 h-3 text-white pointer-events-none opacity-0 peer-checked:opacity-100 transition-opacity duration-150", viewBox: "0 0 12 12", fill: "none", "aria-hidden": "true", children: indeterminate ? (_jsx("line", { x1: "2", y1: "6", x2: "10", y2: "6", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" })) : (_jsx("path", { d: "M2 6L5 9L10 3", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" })) })] }), (label || suffix) && (_jsxs(Span, { className: "flex items-center gap-2 text-sm text-zinc-700 dark:text-zinc-300 group-hover:text-zinc-900 dark:group-hover:text-zinc-100 transition-colors", children: [label, suffix] }))] }), error && (_jsx(
|
|
15
|
+
: "border-zinc-300 dark:border-slate-600", "checked:bg-primary-600 checked:border-primary-600", "dark:checked:bg-secondary-500 dark:checked:border-secondary-500", "hover:border-primary-400 dark:hover:border-secondary-400", "focus:outline-none focus:ring-2 focus:ring-primary-500/30 focus:ring-offset-1", "dark:focus:ring-secondary-400/30 dark:focus:ring-offset-slate-900", "disabled:opacity-50 disabled:cursor-not-allowed", className), ...props }), _jsx("svg", { className: "absolute w-3 h-3 text-white pointer-events-none opacity-0 peer-checked:opacity-100 transition-opacity duration-150", viewBox: "0 0 12 12", fill: "none", "aria-hidden": "true", children: indeterminate ? (_jsx("line", { x1: "2", y1: "6", x2: "10", y2: "6", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" })) : (_jsx("path", { d: "M2 6L5 9L10 3", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" })) })] }), (label || suffix) && (_jsxs(Span, { className: "flex items-center gap-2 text-sm text-zinc-700 dark:text-zinc-300 group-hover:text-zinc-900 dark:group-hover:text-zinc-100 transition-colors", children: [label, suffix] }))] }), error && (_jsx(Text, { className: cn(ERROR_BASE, "mt-1.5"), role: "alert", children: error }))] }));
|
|
16
16
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import React from "react";
|
|
3
|
-
import { Div, Span } from "../../ui";
|
|
3
|
+
import { Div, Span, Text } from "../../ui";
|
|
4
4
|
import { cn, INPUT_BASE, INPUT_ERROR, INPUT_SUCCESS, INPUT_DISABLED, INPUT_WITH_ICON, LABEL_BASE, HELPER_BASE, ERROR_BASE, } from "./utils";
|
|
5
5
|
export const Input = React.forwardRef(function Input({ label, error, helperText, icon, rightIcon, success, className = "", required, disabled, ...props }, ref) {
|
|
6
6
|
const stateClasses = error
|
|
@@ -18,6 +18,6 @@ export const Input = React.forwardRef(function Input({ label, error, helperText,
|
|
|
18
18
|
? `${props.id}-helper`
|
|
19
19
|
: undefined, ...props }), rightIcon && (_jsx(Div, { className: cn("absolute right-3 top-1/2 -translate-y-1/2 transition-colors duration-150", error
|
|
20
20
|
? "text-red-600 dark:text-red-400"
|
|
21
|
-
: "text-zinc-400 dark:text-zinc-500"), children: rightIcon }))] }), error && (_jsx(
|
|
21
|
+
: "text-zinc-400 dark:text-zinc-500"), children: rightIcon }))] }), error && (_jsx(Text, { id: `${props.id}-error`, className: ERROR_BASE, role: "alert", children: error })), !error && helperText && (_jsx(Text, { id: `${props.id}-helper`, className: HELPER_BASE, children: helperText }))] }));
|
|
22
22
|
});
|
|
23
23
|
Input.displayName = "Input";
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { Div, Span } from "../../ui";
|
|
2
|
+
import { Div, Span, Text } from "../../ui";
|
|
3
3
|
import { cn, LABEL_BASE, ERROR_BASE } from "./utils";
|
|
4
4
|
export function RadioGroup({ name, options, value, onChange, label, error, orientation = "vertical", variant = "toggle", }) {
|
|
5
5
|
if (variant === "classic") {
|
|
6
|
-
return (_jsxs(Div, { className: "w-full", children: [label && _jsx(
|
|
6
|
+
return (_jsxs(Div, { className: "w-full", children: [label && _jsx(Text, { className: LABEL_BASE, children: label }), _jsx(Div, { className: cn("flex gap-3", orientation === "vertical" ? "flex-col" : "flex-row flex-wrap"), children: options.map((option) => {
|
|
7
7
|
const isSelected = value === option.value;
|
|
8
8
|
return (_jsxs("label", { className: cn("flex items-center gap-2.5 cursor-pointer", option.disabled && "opacity-50 cursor-not-allowed"), children: [_jsx("input", { type: "radio", name: name, value: option.value, checked: isSelected, disabled: option.disabled, onChange: () => !option.disabled && onChange?.(option.value), className: "w-4 h-4 text-primary-600 dark:text-secondary-500 border-zinc-300 dark:border-slate-600 focus:ring-primary-500/30 dark:focus:ring-secondary-400/30" }), _jsx(Span, { className: "text-sm text-zinc-700 dark:text-zinc-300", children: option.label })] }, option.value));
|
|
9
|
-
}) }), error && (_jsx(
|
|
9
|
+
}) }), error && (_jsx(Text, { className: ERROR_BASE, role: "alert", children: error }))] }));
|
|
10
10
|
}
|
|
11
11
|
// Toggle variant — pill style
|
|
12
|
-
return (_jsxs(Div, { className: "w-full", children: [label && _jsx(
|
|
12
|
+
return (_jsxs(Div, { className: "w-full", children: [label && _jsx(Text, { className: LABEL_BASE, children: label }), _jsx(Div, { className: cn("flex gap-2", orientation === "vertical" ? "flex-col" : "flex-row flex-wrap"), role: "radiogroup", "aria-label": label, children: options.map((option) => {
|
|
13
13
|
const isSelected = value === option.value;
|
|
14
14
|
return (_jsxs("label", { className: cn("flex items-center justify-center px-4 py-2.5 rounded-xl border text-sm font-medium cursor-pointer transition-all duration-200", isSelected
|
|
15
15
|
? "bg-primary-600 dark:bg-secondary-500 border-primary-600 dark:border-secondary-500 text-white shadow-sm"
|
|
16
16
|
: "border-zinc-200 dark:border-slate-700 text-zinc-700 dark:text-zinc-300 hover:border-primary-400 dark:hover:border-secondary-400 hover:bg-primary-50/50 dark:hover:bg-secondary-900/20", option.disabled && "opacity-50 cursor-not-allowed"), children: [_jsx("input", { type: "radio", name: name, value: option.value, checked: isSelected, disabled: option.disabled, onChange: () => !option.disabled && onChange?.(option.value), className: "sr-only" }), option.label] }, option.value));
|
|
17
|
-
}) }), error && (_jsx(
|
|
17
|
+
}) }), error && (_jsx(Text, { className: ERROR_BASE, role: "alert", children: error }))] }));
|
|
18
18
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { Div, Span } from "../../ui";
|
|
2
|
+
import { Div, Span, Text } from "../../ui";
|
|
3
3
|
import { cn, INPUT_BASE, INPUT_ERROR, LABEL_BASE, HELPER_BASE, ERROR_BASE, } from "./utils";
|
|
4
4
|
export function Select({ label, error, helperText, options, placeholder, className = "", required, ...props }) {
|
|
5
5
|
return (_jsxs(Div, { className: "w-full", children: [label && (_jsxs("label", { className: LABEL_BASE, children: [label, required && (_jsx(Span, { className: "text-red-500 ml-1", "aria-hidden": "true", children: "*" }))] })), _jsxs(Div, { className: "relative group", children: [_jsxs("select", { className: cn(INPUT_BASE, "pr-10 appearance-none cursor-pointer", error ? INPUT_ERROR : "", className), "aria-invalid": error ? "true" : undefined, ...props, children: [placeholder && (_jsx("option", { value: "", disabled: true, children: placeholder })), options.map((option) => (_jsx("option", { value: option.value, children: option.label }, option.value)))] }), _jsx(Div, { className: "absolute right-3 top-1/2 -translate-y-1/2 pointer-events-none transition-colors duration-150", children: _jsx("svg", { className: cn("w-5 h-5 transition-transform duration-200", error
|
|
6
6
|
? "text-red-500 dark:text-red-400"
|
|
7
|
-
: "text-zinc-400 dark:text-zinc-500"), viewBox: "0 0 20 20", fill: "currentColor", "aria-hidden": "true", children: _jsx("path", { fillRule: "evenodd", d: "M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z", clipRule: "evenodd" }) }) })] }), error && (_jsx(
|
|
7
|
+
: "text-zinc-400 dark:text-zinc-500"), viewBox: "0 0 20 20", fill: "currentColor", "aria-hidden": "true", children: _jsx("path", { fillRule: "evenodd", d: "M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z", clipRule: "evenodd" }) }) })] }), error && (_jsx(Text, { className: ERROR_BASE, role: "alert", children: error })), !error && helperText && _jsx(Text, { className: HELPER_BASE, children: helperText })] }));
|
|
8
8
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import React from "react";
|
|
4
|
-
import { Div, Row, Span } from "../../ui";
|
|
4
|
+
import { Div, Row, Span, Text } from "../../ui";
|
|
5
5
|
import { cn, LABEL_BASE, ERROR_BASE } from "./utils";
|
|
6
6
|
/**
|
|
7
7
|
* Slider — single-thumb range slider.
|
|
@@ -18,5 +18,5 @@ export function Slider({ value: controlledValue, defaultValue = 0, min = 0, max
|
|
|
18
18
|
onChange?.(newVal);
|
|
19
19
|
};
|
|
20
20
|
const displayValue = formatValue ? formatValue(value) : String(value);
|
|
21
|
-
return (_jsxs(Div, { className: cn("w-full space-y-2", className), children: [(label || showValue) && (_jsxs(Row, { justify: "between", children: [label && (_jsx("label", { htmlFor: sliderId, className: LABEL_BASE, children: label })), showValue && (_jsx(Span, { className: "text-sm font-semibold tabular-nums text-zinc-900 dark:text-zinc-100", children: displayValue }))] })), _jsxs(Row, { className: "relative h-5", children: [_jsx(Div, { className: "absolute inset-y-0 flex items-center w-full", children: _jsx(Div, { className: "w-full h-1.5 rounded-full bg-zinc-200 dark:bg-slate-700", children: _jsx(Div, { className: "h-full rounded-full bg-primary-500 dark:bg-secondary-500 transition-all", style: { width: `${pct}%` } }) }) }), _jsx("input", { type: "range", id: sliderId, min: min, max: max, step: step, value: value, disabled: disabled, onChange: handleChange, className: cn("relative w-full appearance-none bg-transparent cursor-pointer", "focus:outline-none", "[&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:w-4 [&::-webkit-slider-thumb]:h-4", "[&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:bg-white", "[&::-webkit-slider-thumb]:border-2 [&::-webkit-slider-thumb]:border-primary-500 dark:[&::-webkit-slider-thumb]:border-secondary-500", "[&::-webkit-slider-thumb]:shadow-sm", "[&::-moz-range-thumb]:w-4 [&::-moz-range-thumb]:h-4", "[&::-moz-range-thumb]:rounded-full [&::-moz-range-thumb]:bg-white", "[&::-moz-range-thumb]:border-2 [&::-moz-range-thumb]:border-primary-500 dark:[&::-moz-range-thumb]:border-secondary-500", disabled && "opacity-50 cursor-not-allowed") })] }), _jsxs(Row, { justify: "between", className: "text-xs text-zinc-400 dark:text-zinc-500", children: [_jsx(Span, { children: formatValue ? formatValue(min) : min }), _jsx(Span, { children: formatValue ? formatValue(max) : max })] }), error && (_jsx(
|
|
21
|
+
return (_jsxs(Div, { className: cn("w-full space-y-2", className), children: [(label || showValue) && (_jsxs(Row, { justify: "between", children: [label && (_jsx("label", { htmlFor: sliderId, className: LABEL_BASE, children: label })), showValue && (_jsx(Span, { className: "text-sm font-semibold tabular-nums text-zinc-900 dark:text-zinc-100", children: displayValue }))] })), _jsxs(Row, { className: "relative h-5", children: [_jsx(Div, { className: "absolute inset-y-0 flex items-center w-full", children: _jsx(Div, { className: "w-full h-1.5 rounded-full bg-zinc-200 dark:bg-slate-700", children: _jsx(Div, { className: "h-full rounded-full bg-primary-500 dark:bg-secondary-500 transition-all", style: { width: `${pct}%` } }) }) }), _jsx("input", { type: "range", id: sliderId, min: min, max: max, step: step, value: value, disabled: disabled, onChange: handleChange, className: cn("relative w-full appearance-none bg-transparent cursor-pointer", "focus:outline-none", "[&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:w-4 [&::-webkit-slider-thumb]:h-4", "[&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:bg-white", "[&::-webkit-slider-thumb]:border-2 [&::-webkit-slider-thumb]:border-primary-500 dark:[&::-webkit-slider-thumb]:border-secondary-500", "[&::-webkit-slider-thumb]:shadow-sm", "[&::-moz-range-thumb]:w-4 [&::-moz-range-thumb]:h-4", "[&::-moz-range-thumb]:rounded-full [&::-moz-range-thumb]:bg-white", "[&::-moz-range-thumb]:border-2 [&::-moz-range-thumb]:border-primary-500 dark:[&::-moz-range-thumb]:border-secondary-500", disabled && "opacity-50 cursor-not-allowed") })] }), _jsxs(Row, { justify: "between", className: "text-xs text-zinc-400 dark:text-zinc-500", children: [_jsx(Span, { children: formatValue ? formatValue(min) : min }), _jsx(Span, { children: formatValue ? formatValue(max) : max })] }), error && (_jsx(Text, { className: ERROR_BASE, role: "alert", children: error }))] }));
|
|
22
22
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import React from "react";
|
|
3
|
-
import { Div, Span } from "../../ui";
|
|
3
|
+
import { Div, Span, Text } from "../../ui";
|
|
4
4
|
import { cn, INPUT_BASE, INPUT_ERROR, LABEL_BASE, HELPER_BASE, ERROR_BASE, } from "./utils";
|
|
5
5
|
export const Textarea = React.forwardRef(function Textarea({ label, error, helperText, showCharCount, className = "", required, maxLength, value, defaultValue, ...props }, ref) {
|
|
6
6
|
const charCount = typeof value === "string"
|
|
@@ -8,7 +8,7 @@ export const Textarea = React.forwardRef(function Textarea({ label, error, helpe
|
|
|
8
8
|
: typeof defaultValue === "string"
|
|
9
9
|
? defaultValue.length
|
|
10
10
|
: 0;
|
|
11
|
-
return (_jsxs(Div, { className: "w-full", children: [label && (_jsxs("label", { className: LABEL_BASE, children: [label, required && (_jsx(Span, { className: "text-red-500 ml-1", "aria-hidden": "true", children: "*" }))] })), _jsx("textarea", { ref: ref, className: cn(INPUT_BASE, "resize-y min-h-[80px]", error ? INPUT_ERROR : "", className), "aria-invalid": error ? "true" : undefined, maxLength: maxLength, value: value, defaultValue: defaultValue, ...props }), _jsxs(Div, { className: "flex items-center justify-between mt-1.5", children: [_jsxs(Div, { className: "flex-1", children: [error && (_jsx(
|
|
11
|
+
return (_jsxs(Div, { className: "w-full", children: [label && (_jsxs("label", { className: LABEL_BASE, children: [label, required && (_jsx(Span, { className: "text-red-500 ml-1", "aria-hidden": "true", children: "*" }))] })), _jsx("textarea", { ref: ref, className: cn(INPUT_BASE, "resize-y min-h-[80px]", error ? INPUT_ERROR : "", className), "aria-invalid": error ? "true" : undefined, maxLength: maxLength, value: value, defaultValue: defaultValue, ...props }), _jsxs(Div, { className: "flex items-center justify-between mt-1.5", children: [_jsxs(Div, { className: "flex-1", children: [error && (_jsx(Text, { className: ERROR_BASE, role: "alert", children: error })), !error && helperText && (_jsx(Text, { className: HELPER_BASE, children: helperText }))] }), showCharCount && maxLength && (_jsxs("p", { className: cn("text-xs tabular-nums ml-2 flex-shrink-0", charCount >= maxLength
|
|
12
12
|
? "text-red-500 dark:text-red-400"
|
|
13
13
|
: "text-zinc-400 dark:text-zinc-500"), children: [charCount, " / ", maxLength] }))] })] }));
|
|
14
14
|
});
|
|
@@ -12,6 +12,7 @@ import { NextResponse } from "next/server.js";
|
|
|
12
12
|
import { z } from "zod";
|
|
13
13
|
import { getProviders } from "../../../../contracts";
|
|
14
14
|
import { createRouteHandler } from "../../../../next";
|
|
15
|
+
const ERR_SECTION_NOT_FOUND = "Section not found";
|
|
15
16
|
// ---- GET /api/homepage-sections/[id] ----------------------------------------
|
|
16
17
|
export async function GET(_request, context) {
|
|
17
18
|
try {
|
|
@@ -23,7 +24,7 @@ export async function GET(_request, context) {
|
|
|
23
24
|
const repo = db.getRepository("homepageSections");
|
|
24
25
|
const section = await repo.findById(id);
|
|
25
26
|
if (!section) {
|
|
26
|
-
return NextResponse.json({ success: false, error:
|
|
27
|
+
return NextResponse.json({ success: false, error: ERR_SECTION_NOT_FOUND }, { status: 404 });
|
|
27
28
|
}
|
|
28
29
|
return NextResponse.json({ success: true, data: section });
|
|
29
30
|
}
|
|
@@ -71,7 +72,7 @@ export const homepageSectionItemPATCH = createRouteHandler({
|
|
|
71
72
|
const repo = db.getRepository("homepageSections");
|
|
72
73
|
const section = await repo.findById(id);
|
|
73
74
|
if (!section)
|
|
74
|
-
return NextResponse.json({ success: false, error:
|
|
75
|
+
return NextResponse.json({ success: false, error: ERR_SECTION_NOT_FOUND }, { status: 404 });
|
|
75
76
|
const updated = await repo.update(id, {
|
|
76
77
|
...body,
|
|
77
78
|
updatedAt: new Date().toISOString(),
|
|
@@ -93,7 +94,7 @@ export const homepageSectionItemDELETE = createRouteHandler({
|
|
|
93
94
|
const repo = db.getRepository("homepageSections");
|
|
94
95
|
const section = await repo.findById(id);
|
|
95
96
|
if (!section)
|
|
96
|
-
return NextResponse.json({ success: false, error:
|
|
97
|
+
return NextResponse.json({ success: false, error: ERR_SECTION_NOT_FOUND }, { status: 404 });
|
|
97
98
|
await repo.delete(id);
|
|
98
99
|
return NextResponse.json({ success: true });
|
|
99
100
|
},
|
|
@@ -10,15 +10,18 @@
|
|
|
10
10
|
*/
|
|
11
11
|
import { NextResponse } from "next/server.js";
|
|
12
12
|
import { getProviders } from "../../../../../contracts";
|
|
13
|
+
const ERR_SECTION_ID_REQUIRED = "Section ID is required";
|
|
14
|
+
const ERR_DB_NOT_CONFIGURED = "Database provider not configured";
|
|
15
|
+
const ERR_INTERNAL_SERVER_ERROR = "Internal server error";
|
|
13
16
|
export async function GET(request, { params }) {
|
|
14
17
|
try {
|
|
15
18
|
const { id } = await params;
|
|
16
19
|
if (!id) {
|
|
17
|
-
return NextResponse.json({ success: false, error:
|
|
20
|
+
return NextResponse.json({ success: false, error: ERR_SECTION_ID_REQUIRED }, { status: 400 });
|
|
18
21
|
}
|
|
19
22
|
const { db } = getProviders();
|
|
20
23
|
if (!db)
|
|
21
|
-
return NextResponse.json({ success: false, error:
|
|
24
|
+
return NextResponse.json({ success: false, error: ERR_DB_NOT_CONFIGURED }, { status: 503 });
|
|
22
25
|
const repo = db.getRepository("homepage_sections");
|
|
23
26
|
const section = await repo.findById(id);
|
|
24
27
|
if (!section) {
|
|
@@ -32,7 +35,7 @@ export async function GET(request, { params }) {
|
|
|
32
35
|
catch (error) {
|
|
33
36
|
return NextResponse.json({
|
|
34
37
|
success: false,
|
|
35
|
-
error: error instanceof Error ? error.message :
|
|
38
|
+
error: error instanceof Error ? error.message : ERR_INTERNAL_SERVER_ERROR,
|
|
36
39
|
}, { status: 500 });
|
|
37
40
|
}
|
|
38
41
|
}
|
|
@@ -40,12 +43,12 @@ export async function PATCH(request, { params }) {
|
|
|
40
43
|
try {
|
|
41
44
|
const { id } = await params;
|
|
42
45
|
if (!id) {
|
|
43
|
-
return NextResponse.json({ success: false, error:
|
|
46
|
+
return NextResponse.json({ success: false, error: ERR_SECTION_ID_REQUIRED }, { status: 400 });
|
|
44
47
|
}
|
|
45
48
|
const body = await request.json();
|
|
46
49
|
const { db } = getProviders();
|
|
47
50
|
if (!db)
|
|
48
|
-
return NextResponse.json({ success: false, error:
|
|
51
|
+
return NextResponse.json({ success: false, error: ERR_DB_NOT_CONFIGURED }, { status: 503 });
|
|
49
52
|
const repo = db.getRepository("homepage_sections");
|
|
50
53
|
const updated = await repo.update(id, body);
|
|
51
54
|
if (!updated) {
|
|
@@ -59,7 +62,7 @@ export async function PATCH(request, { params }) {
|
|
|
59
62
|
catch (error) {
|
|
60
63
|
return NextResponse.json({
|
|
61
64
|
success: false,
|
|
62
|
-
error: error instanceof Error ? error.message :
|
|
65
|
+
error: error instanceof Error ? error.message : ERR_INTERNAL_SERVER_ERROR,
|
|
63
66
|
}, { status: 500 });
|
|
64
67
|
}
|
|
65
68
|
}
|
|
@@ -67,11 +70,11 @@ export async function DELETE(request, { params }) {
|
|
|
67
70
|
try {
|
|
68
71
|
const { id } = await params;
|
|
69
72
|
if (!id) {
|
|
70
|
-
return NextResponse.json({ success: false, error:
|
|
73
|
+
return NextResponse.json({ success: false, error: ERR_SECTION_ID_REQUIRED }, { status: 400 });
|
|
71
74
|
}
|
|
72
75
|
const { db } = getProviders();
|
|
73
76
|
if (!db)
|
|
74
|
-
return NextResponse.json({ success: false, error:
|
|
77
|
+
return NextResponse.json({ success: false, error: ERR_DB_NOT_CONFIGURED }, { status: 503 });
|
|
75
78
|
const repo = db.getRepository("homepage_sections");
|
|
76
79
|
await repo.delete(id);
|
|
77
80
|
return NextResponse.json({
|
|
@@ -82,7 +85,7 @@ export async function DELETE(request, { params }) {
|
|
|
82
85
|
catch (error) {
|
|
83
86
|
return NextResponse.json({
|
|
84
87
|
success: false,
|
|
85
|
-
error: error instanceof Error ? error.message :
|
|
88
|
+
error: error instanceof Error ? error.message : ERR_INTERNAL_SERVER_ERROR,
|
|
86
89
|
}, { status: 500 });
|
|
87
90
|
}
|
|
88
91
|
}
|
|
@@ -3,6 +3,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
3
3
|
import { useEffect, useRef, useState } from "react";
|
|
4
4
|
import { getAdSlot, isAdSlotRenderable } from "../ad-registry";
|
|
5
5
|
import { useActiveAd } from "../hooks/useActiveAd";
|
|
6
|
+
import { Text } from "../../../ui";
|
|
6
7
|
// ---------------------------------------------------------------------------
|
|
7
8
|
// Sub-renderers
|
|
8
9
|
// ---------------------------------------------------------------------------
|
|
@@ -31,7 +32,7 @@ function ManualAdBanner({ ad }) {
|
|
|
31
32
|
const { creative } = ad;
|
|
32
33
|
if (!creative)
|
|
33
34
|
return null;
|
|
34
|
-
return (_jsxs("a", { href: creative.ctaHref || "#", target: creative.ctaHref ? "_blank" : undefined, rel: "noopener noreferrer", className: "flex items-center gap-3 w-full overflow-hidden rounded-lg bg-zinc-100 dark:bg-zinc-800 px-4 py-3 hover:bg-zinc-200 dark:hover:bg-zinc-700 transition-colors no-underline", children: [creative.imageUrl ? (_jsx("img", { src: creative.imageUrl, alt: creative.title || "Advertisement", className: "h-14 w-14 rounded object-cover flex-shrink-0", loading: "lazy" })) : null, _jsxs("div", { className: "flex-1 min-w-0", children: [creative.title ? (_jsx(
|
|
35
|
+
return (_jsxs("a", { href: creative.ctaHref || "#", target: creative.ctaHref ? "_blank" : undefined, rel: "noopener noreferrer", className: "flex items-center gap-3 w-full overflow-hidden rounded-lg bg-zinc-100 dark:bg-zinc-800 px-4 py-3 hover:bg-zinc-200 dark:hover:bg-zinc-700 transition-colors no-underline", children: [creative.imageUrl ? (_jsx("img", { src: creative.imageUrl, alt: creative.title || "Advertisement", className: "h-14 w-14 rounded object-cover flex-shrink-0", loading: "lazy" })) : null, _jsxs("div", { className: "flex-1 min-w-0", children: [creative.title ? (_jsx(Text, { className: "text-sm font-semibold text-zinc-900 dark:text-zinc-100 truncate", children: creative.title })) : null, creative.body ? (_jsx(Text, { className: "text-xs text-zinc-500 dark:text-zinc-400 truncate", children: creative.body })) : null] }), creative.ctaLabel ? (_jsx("span", { className: "flex-shrink-0 rounded-md bg-primary px-3 py-1.5 text-xs font-semibold text-white", children: creative.ctaLabel })) : null] }));
|
|
35
36
|
}
|
|
36
37
|
// ---------------------------------------------------------------------------
|
|
37
38
|
// Primary component
|
|
@@ -3,18 +3,20 @@ import { THEME_CONSTANTS } from "../../../tokens";
|
|
|
3
3
|
import { Button, Heading, Row, Section, Span, Text } from "../../../ui";
|
|
4
4
|
import { MediaImage } from "../../media/MediaImage";
|
|
5
5
|
import { ArrowRight, Sparkles } from "lucide-react";
|
|
6
|
+
// --- Constants ---------------------------------------------------------------
|
|
7
|
+
const CLS_CONTAINER = "w-full max-w-7xl mx-auto";
|
|
6
8
|
// --- Component ---------------------------------------------------------------
|
|
7
9
|
export function AdvertisementBanner({ title, subtitle, ctaLabel = "Shop now", onCtaClick, backgroundImage, backgroundColor, tagLabel, isLoading = false, compact = false, className = "", }) {
|
|
8
10
|
const wrapClass = "bg-gradient-to-br from-amber-50/40 to-orange-50/20 dark:from-amber-950/10 dark:to-orange-950/5";
|
|
9
11
|
if (isLoading) {
|
|
10
|
-
return (_jsx(Section, { className: `p-8 ${wrapClass} ${className}`, children: _jsx("div", { className:
|
|
12
|
+
return (_jsx(Section, { className: `p-8 ${wrapClass} ${className}`, children: _jsx("div", { className: CLS_CONTAINER, "data-section": "advertisementbanner-div-297", children: _jsx("div", { className: "h-72 bg-zinc-200 dark:bg-slate-700 rounded-2xl animate-pulse" }) }) }));
|
|
11
13
|
}
|
|
12
14
|
// -- Split layout: when a backgroundImage is provided --
|
|
13
15
|
if (backgroundImage) {
|
|
14
|
-
return (_jsx(Section, { className: `p-8 ${wrapClass} ${className}`, children: _jsx("div", { className:
|
|
16
|
+
return (_jsx(Section, { className: `p-8 ${wrapClass} ${className}`, children: _jsx("div", { className: CLS_CONTAINER, "data-section": "advertisementbanner-div-298", children: _jsx("div", { className: "relative overflow-hidden rounded-2xl bg-zinc-900 shadow-xl", "data-section": "advertisementbanner-div-299", children: _jsxs("div", { className: `${THEME_CONSTANTS.grid.cols2Md} min-h-[clamp(300px,40vh,420px)]`, "data-section": "advertisementbanner-div-300", children: [_jsxs("div", { className: `relative ${THEME_CONSTANTS.card.aspectBanner} order-last md:order-first min-h-0 min-h-[clamp(300px,40vh,420px)]`, "data-section": "advertisementbanner-div-301", children: [_jsx(MediaImage, { src: backgroundImage, alt: title, size: "banner", priority: true }), _jsx("div", { className: "hidden md:block absolute inset-y-0 right-0 w-24 bg-gradient-to-r from-transparent to-zinc-900/60 pointer-events-none" })] }), _jsxs("div", { className: "relative flex flex-col justify-center px-8 py-10 md:px-12 md:py-14", "data-section": "advertisementbanner-div-302", children: [_jsx("div", { className: "absolute top-0 right-0 w-32 h-32 opacity-10 pointer-events-none bg-[radial-gradient(circle,_white_1px,_transparent_1px)] bg-[length:12px_12px]", "aria-hidden": true }), tagLabel && (_jsxs("div", { className: "inline-flex items-center gap-1.5 self-start bg-white/10 text-white/80 text-xs font-semibold uppercase tracking-widest px-3 py-1 rounded-full mb-5 backdrop-blur-sm", "data-section": "advertisementbanner-div-303", children: [_jsx(Sparkles, { className: "w-3.5 h-3.5" }), tagLabel] })), _jsx(Heading, { level: 2, variant: "none", className: "text-3xl md:text-4xl lg:text-5xl font-extrabold text-white mb-4 leading-tight", children: title }), subtitle && (_jsx(Text, { variant: "none", className: "text-white/75 text-base md:text-lg mb-8 leading-relaxed", children: subtitle })), ctaLabel && onCtaClick && (_jsxs(Button, { variant: "secondary", size: "lg", onClick: onCtaClick, className: "self-start bg-white text-zinc-900 hover:bg-zinc-100 font-semibold shadow-lg gap-2", children: [ctaLabel, _jsx(ArrowRight, { className: "w-4 h-4" })] }))] })] }) }) }) }));
|
|
15
17
|
}
|
|
16
18
|
// -- Full-width gradient layout --
|
|
17
|
-
return (_jsx(Section, { className: `p-8 ${wrapClass} ${className}`, children: _jsx("div", { className:
|
|
19
|
+
return (_jsx(Section, { className: `p-8 ${wrapClass} ${className}`, children: _jsx("div", { className: CLS_CONTAINER, "data-section": "advertisementbanner-div-304", children: _jsxs("div", { className: [
|
|
18
20
|
"relative overflow-hidden rounded-2xl flex items-center",
|
|
19
21
|
compact
|
|
20
22
|
? "h-[clamp(112px,16vh,160px)]"
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
3
|
import { useState } from "react";
|
|
4
4
|
import Image from "next/image";
|
|
5
5
|
import Link from "next/link";
|
|
@@ -39,5 +39,5 @@ export function BrandsSection({ title = "Top Brands", subtitle, limit = 12, view
|
|
|
39
39
|
});
|
|
40
40
|
if (!isLoading && allBrands.length === 0)
|
|
41
41
|
return null;
|
|
42
|
-
return (_jsx(Section, { className: `py-12 px-4 ${themed.bgSecondary} ${className}`, children: _jsxs("div", { className: "mx-auto max-w-7xl", children: [_jsxs("div", { className: "mb-6 flex items-center justify-between", children: [_jsxs(
|
|
42
|
+
return (_jsx(Section, { className: `py-12 px-4 ${themed.bgSecondary} ${className}`, children: _jsxs("div", { className: "mx-auto max-w-7xl", children: [_jsxs("div", { className: "mb-6 flex items-center justify-between", children: [_jsxs(_Fragment, { children: [_jsx(Heading, { level: 2, className: `text-2xl font-bold md:text-3xl ${themed.textPrimary}`, children: title }), subtitle && (_jsx(Text, { variant: "secondary", className: "mt-1 text-sm", children: subtitle }))] }), !cta && viewMoreHref && (_jsx(Link, { href: viewMoreHref, className: "text-sm font-medium text-[var(--appkit-color-primary)] hover:underline", children: viewMoreLabel }))] }), showFeaturedChip && !isLoading && (_jsxs("div", { className: "mb-4 flex flex-wrap gap-2", children: [_jsx(BrandFilterChip, { label: "All", active: activeFilter === "all", onClick: () => setActiveFilter("all") }), _jsx(BrandFilterChip, { label: "Featured", active: activeFilter === "featured", onClick: () => setActiveFilter(activeFilter === "featured" ? "all" : "featured") })] })), isLoading ? (_jsx("div", { className: "flex gap-3 overflow-hidden", children: Array.from({ length: 8 }).map((_, i) => (_jsx("div", { className: "h-24 w-28 flex-none animate-pulse rounded-xl bg-zinc-200 dark:bg-slate-700" }, i))) })) : (_jsx(HorizontalScroller, { items: brands, renderItem: (brand) => _jsx(BrandLogo, { brand: brand }), keyExtractor: (brand) => brand.id, gap: 12, showArrows: true, showScrollbar: false })), cta && !isLoading && (_jsx("div", { className: "mt-6 text-center", children: _jsx(Link, { href: cta.href, className: CTA_CLASSES[cta.variant], children: cta.label }) }))] }) }));
|
|
43
43
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import Link from "next/link";
|
|
3
|
-
import { Section } from "../../../ui";
|
|
3
|
+
import { Heading, Section, Text } from "../../../ui";
|
|
4
4
|
export function CTABannerSection({ title = "Thousands of collectibles. One marketplace.", subtitle, primaryLabel = "Shop All Products →", primaryHref = "/products", secondaryLabel = "Browse Auctions →", secondaryHref = "/auctions", className = "", }) {
|
|
5
|
-
return (_jsx(Section, { className: `bg-gradient-to-r from-primary-600 to-primary-700 py-16 px-4 ${className}`, children: _jsxs("div", { className: "mx-auto max-w-3xl text-center", "data-section": "ctabannersection-div-313", children: [_jsx("span", { className: "mb-4 inline-block text-2xl", "aria-hidden": "true", children: "\u2728" }), _jsx(
|
|
5
|
+
return (_jsx(Section, { className: `bg-gradient-to-r from-primary-600 to-primary-700 py-16 px-4 ${className}`, children: _jsxs("div", { className: "mx-auto max-w-3xl text-center", "data-section": "ctabannersection-div-313", children: [_jsx("span", { className: "mb-4 inline-block text-2xl", "aria-hidden": "true", children: "\u2728" }), _jsx(Heading, { level: 2, className: "text-2xl font-bold text-white md:text-3xl lg:text-4xl", children: title }), subtitle && (_jsx(Text, { className: "mt-3 text-base text-white/80", children: subtitle })), _jsxs("div", { className: "mt-8 flex flex-wrap items-center justify-center gap-4", "data-section": "ctabannersection-div-314", children: [_jsx(Link, { href: primaryHref, className: "inline-flex items-center rounded-full bg-white px-8 py-3 text-sm font-semibold text-primary-700 shadow-sm transition-all hover:bg-zinc-50 hover:shadow-md focus:outline-none focus:ring-2 focus:ring-white focus:ring-offset-2 focus:ring-offset-primary-600", children: primaryLabel }), secondaryHref && (_jsx(Link, { href: secondaryHref, className: "inline-flex items-center rounded-full border-2 border-white/80 px-8 py-3 text-sm font-semibold text-white transition-all hover:bg-white/10 focus:outline-none focus:ring-2 focus:ring-white focus:ring-offset-2 focus:ring-offset-primary-600", children: secondaryLabel }))] })] }) }));
|
|
6
6
|
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import type { CharacterHotspotConfig, HotspotPin } from "../types";
|
|
1
|
+
import type { CharacterHotspotConfig, HotspotPin as HotspotPinData } from "../types";
|
|
2
2
|
export interface CharacterHotspotProps {
|
|
3
3
|
config?: CharacterHotspotConfig | null;
|
|
4
4
|
/**
|
|
5
5
|
* Override the default fallback hotspot pins shown when no config is supplied.
|
|
6
6
|
* Useful for non-collectibles storefronts.
|
|
7
7
|
*/
|
|
8
|
-
defaultHotspots?:
|
|
8
|
+
defaultHotspots?: HotspotPinData[];
|
|
9
9
|
/** Universe quick-browse links shown below the panorama. */
|
|
10
10
|
universeLinks?: {
|
|
11
11
|
label: string;
|