@mohasinac/appkit 2.7.26 → 2.7.30
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 +2 -2
- package/dist/_internal/client/features/digital-code/CodeRevealPanel.js +2 -2
- 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 +310 -8
- 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 +2 -0
- package/dist/client.js +1 -0
- package/dist/configs/next.js +4 -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 +44 -14
- 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/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 +2 -2
- 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/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/AdminProductsView.js +18 -12
- package/dist/features/admin/components/AdminReviewsView.js +33 -24
- 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/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/AuctionDetailPageView.js +13 -19
- 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 +0 -1
- package/dist/features/auctions/components/index.js +0 -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/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.js +2 -2
- 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.js +2 -2
- 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 +8 -0
- package/dist/features/classified/components/ClassifiedFilters.js +19 -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 +8 -0
- package/dist/features/digital-codes/components/DigitalCodeFilters.js +16 -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/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/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 +55 -84
- package/dist/features/layout/BottomActions.js +43 -48
- package/dist/features/layout/NavbarWithSettings.d.ts +6 -0
- package/dist/features/layout/NavbarWithSettings.js +11 -0
- package/dist/features/live/components/LiveItemFilters.d.ts +8 -0
- package/dist/features/live/components/LiveItemFilters.js +23 -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 +27 -20
- 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 +2 -2
- package/dist/features/products/components/AuctionsIndexListing.js +15 -51
- package/dist/features/products/components/BidHistory.js +2 -2
- 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.js +8 -6
- package/dist/features/products/components/ProductForm.js +12 -10
- package/dist/features/products/components/ProductGalleryClient.js +2 -1
- package/dist/features/products/components/ProductGrid.js +11 -14
- package/dist/features/products/components/ProductsIndexListing.js +16 -52
- package/dist/features/products/components/ProductsIndexPageView.js +2 -2
- 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/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 +2 -2
- 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 +21 -3
- package/dist/index.js +1737 -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 +27 -0
- package/dist/next/routing/route-map.js +10 -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/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 +2 -2
|
@@ -9,6 +9,12 @@ import { useAdminSectionsListing } from "../hooks/useAdminSectionsListing";
|
|
|
9
9
|
import { DataTable } from "./DataTable";
|
|
10
10
|
import { SECTION_TYPE_OPTIONS, SUPPORTED_TYPED_BUILDERS, RESOURCE_SORT_OPTIONS, FAQ_CATEGORY_OPTIONS, DEFAULT_PRODUCTS_BUILDER, DEFAULT_AUCTIONS_BUILDER, DEFAULT_STATS_BUILDER, DEFAULT_PRE_ORDERS_BUILDER, DEFAULT_STORES_BUILDER, DEFAULT_EVENTS_BUILDER, DEFAULT_SOCIAL_FEED_BUILDER, DEFAULT_WELCOME_BUILDER, DEFAULT_TRUST_INDICATORS_BUILDER, DEFAULT_CATEGORIES_BUILDER, DEFAULT_BRANDS_BUILDER, DEFAULT_BANNER_BUILDER, DEFAULT_FEATURES_BUILDER, DEFAULT_REVIEWS_BUILDER, DEFAULT_WHATSAPP_BUILDER, DEFAULT_FAQ_BUILDER, DEFAULT_BLOG_BUILDER, DEFAULT_NEWSLETTER_BUILDER, DEFAULT_CAROUSEL_BUILDER, DEFAULT_CUSTOM_CARDS_BUILDER, DEFAULT_GOOGLE_REVIEWS_BUILDER, DEFAULT_FEATURED_BUNDLES_BUILDER, DEFAULT_PRIZE_DRAWS_BUILDER, DEFAULT_EVENT_RAFFLES_BUILDER, DEFAULT_COLLECTION_CARDS_BUILDER, } from "./sections/adminSectionsTypes";
|
|
11
11
|
import { toStringValue, buildProductsConfig, buildAuctionsConfig, buildStatsConfig, buildPreOrdersConfig, buildStoresConfig, buildEventsConfig, buildSocialFeedConfig, buildWelcomeConfig, buildTrustIndicatorsConfig, buildCategoriesConfig, buildBrandsConfig, buildBannerConfig, buildFeaturesConfig, buildReviewsConfig, buildWhatsAppConfig, buildFAQConfig, buildBlogConfig, buildNewsletterConfig, buildCarouselConfig, buildCustomCardsConfig, buildGoogleReviewsConfig, buildFeaturedBundlesConfig, buildPrizeDrawsConfig, buildEventRafflesConfig, buildCollectionCardsConfig, parseProductsBuilder, parseAuctionsBuilder, parseStatsBuilder, parsePreOrdersBuilder, parseStoresBuilder, parseEventsBuilder, parseSocialFeedBuilder, parseWelcomeBuilder, parseTrustIndicatorsBuilder, parseCategoriesBuilder, parseBrandsBuilder, parseBannerBuilder, parseFeaturesBuilder, parseReviewsBuilder, parseWhatsAppBuilder, parseFAQBuilder, parseBlogBuilder, parseNewsletterBuilder, parseCarouselBuilder, parseCustomCardsBuilder, parseGoogleReviewsBuilder, parseFeaturedBundlesBuilder, parsePrizeDrawsBuilder, parseEventRafflesBuilder, parseCollectionCardsBuilder, } from "./sections/adminSectionsBuildParse";
|
|
12
|
+
const CLS_SECTION_PANEL = "rounded-xl border border-zinc-200 dark:border-zinc-700 bg-white dark:bg-zinc-900 p-4 space-y-3";
|
|
13
|
+
const LBL_FILTER_BY_CATEGORY = "Filter by category";
|
|
14
|
+
const LBL_MAX_ITEMS = "Max items";
|
|
15
|
+
const LBL_AUTOMATIC = "Automatic";
|
|
16
|
+
const LBL_MANUAL_IDS = "Manual IDs";
|
|
17
|
+
const LBL_SCROLL_INTERVAL = "Scroll interval (ms)";
|
|
12
18
|
export function AdminSectionsView({ children }) {
|
|
13
19
|
const hasChildren = React.Children.count(children) > 0;
|
|
14
20
|
const queryClient = useQueryClient();
|
|
@@ -465,6 +471,12 @@ export function AdminSectionsView({ children }) {
|
|
|
465
471
|
return normalizeOrder(next);
|
|
466
472
|
});
|
|
467
473
|
}
|
|
474
|
+
function handleReorderDrop(targetIndex) {
|
|
475
|
+
if (dragIndex !== null) {
|
|
476
|
+
moveItemToIndex(dragIndex, targetIndex);
|
|
477
|
+
}
|
|
478
|
+
setDragIndex(null);
|
|
479
|
+
}
|
|
468
480
|
function reindexDraft() {
|
|
469
481
|
applyReorderChange((prev) => normalizeOrder(prev));
|
|
470
482
|
}
|
|
@@ -479,8 +491,14 @@ export function AdminSectionsView({ children }) {
|
|
|
479
491
|
setReorderUndoStack(rest);
|
|
480
492
|
setReorderDraft(cloneReorderItems(latest));
|
|
481
493
|
}
|
|
494
|
+
function renderProductsCategorySelectors() {
|
|
495
|
+
return (_jsxs(Div, { className: "space-y-2", children: [_jsx(Text, { className: "text-xs font-semibold uppercase tracking-wide text-zinc-500 dark:text-zinc-400", children: "Category selectors" }), categoriesQuery.isLoading ? (_jsx(Text, { className: "text-sm text-zinc-500 dark:text-zinc-400", children: "Loading categories..." })) : categoryOptions.length === 0 ? (_jsx(Text, { className: "text-sm text-zinc-500 dark:text-zinc-400", children: "No categories available." })) : (_jsx(Div, { className: "grid grid-cols-1 gap-2 sm:grid-cols-2", children: categoryOptions.map((category) => (_jsx(Checkbox, { checked: productsBuilder.selectedCategoryIds.includes(category.id), label: category.name, onChange: (event) => setProductsBuilder((prev) => ({
|
|
496
|
+
...prev,
|
|
497
|
+
selectedCategoryIds: toggleCategorySelection(prev.selectedCategoryIds, category.id, event.target.checked),
|
|
498
|
+
})) }, category.id))) }))] }));
|
|
499
|
+
}
|
|
482
500
|
function renderProductsBuilder() {
|
|
483
|
-
return (_jsxs(Div, { className:
|
|
501
|
+
return (_jsxs(Div, { className: CLS_SECTION_PANEL, children: [_jsx(Text, { className: "text-sm font-semibold text-zinc-800 dark:text-zinc-200", children: "Products Carousel Builder" }), _jsx(Input, { label: "Section title", value: productsBuilder.title, onChange: (event) => setProductsBuilder((prev) => ({ ...prev, title: event.target.value })) }), _jsx(Input, { label: "Subtitle", value: productsBuilder.subtitle, onChange: (event) => setProductsBuilder((prev) => ({ ...prev, subtitle: event.target.value })) }), _jsx(Input, { label: "Max products", type: "number", min: 1, max: 50, value: String(productsBuilder.maxItems), onChange: (event) => setProductsBuilder((prev) => ({
|
|
484
502
|
...prev,
|
|
485
503
|
maxItems: Math.max(1, Number(event.target.value) || 1),
|
|
486
504
|
})) }), _jsx(Select, { label: "Status filter", value: productsBuilder.status, onValueChange: (value) => setProductsBuilder((prev) => ({
|
|
@@ -490,16 +508,13 @@ export function AdminSectionsView({ children }) {
|
|
|
490
508
|
{ label: "All", value: "all" },
|
|
491
509
|
{ label: "Published", value: "published" },
|
|
492
510
|
{ label: "Draft", value: "draft" },
|
|
493
|
-
] }), _jsx(Select, { label: "Sort by", value: productsBuilder.sortBy, onValueChange: (value) => setProductsBuilder((prev) => ({ ...prev, sortBy: value })), options: [...RESOURCE_SORT_OPTIONS] }), _jsx(Input, { label:
|
|
511
|
+
] }), _jsx(Select, { label: "Sort by", value: productsBuilder.sortBy, onValueChange: (value) => setProductsBuilder((prev) => ({ ...prev, sortBy: value })), options: [...RESOURCE_SORT_OPTIONS] }), _jsx(Input, { label: LBL_FILTER_BY_CATEGORY, value: productsBuilder.filterByCategory, onChange: (e) => setProductsBuilder((prev) => ({ ...prev, filterByCategory: e.target.value })), placeholder: "category-pokemon-cards" }), _jsx(Select, { label: LBL_MAX_ITEMS, value: String(productsBuilder.maxCount), onValueChange: (v) => setProductsBuilder((prev) => ({ ...prev, maxCount: Number(v) })), options: [{ label: "5", value: "5" }, { label: "10", value: "10" }, { label: "20", value: "20" }] }), _jsx(Checkbox, { checked: productsBuilder.loop, label: "Loop carousel", onChange: (e) => setProductsBuilder((prev) => ({ ...prev, loop: e.target.checked })) }), _jsx(Select, { label: "Resource mode", value: productsBuilder.resourceMode, onValueChange: (value) => setProductsBuilder((prev) => ({
|
|
494
512
|
...prev,
|
|
495
513
|
resourceMode: value,
|
|
496
514
|
})), options: [
|
|
497
|
-
{ label:
|
|
498
|
-
{ label:
|
|
499
|
-
] }),
|
|
500
|
-
...prev,
|
|
501
|
-
selectedCategoryIds: toggleCategorySelection(prev.selectedCategoryIds, category.id, event.target.checked),
|
|
502
|
-
})) }, category.id))) }))] }), productsBuilder.resourceMode === "manual" ? (_jsx(Textarea, { label: "Manual product resource IDs (comma-separated)", value: productsBuilder.manualResourceIds, onChange: (event) => setProductsBuilder((prev) => ({
|
|
515
|
+
{ label: LBL_AUTOMATIC, value: "automatic" },
|
|
516
|
+
{ label: LBL_MANUAL_IDS, value: "manual" },
|
|
517
|
+
] }), renderProductsCategorySelectors(), productsBuilder.resourceMode === "manual" ? (_jsx(Textarea, { label: "Manual product resource IDs (comma-separated)", value: productsBuilder.manualResourceIds, onChange: (event) => setProductsBuilder((prev) => ({
|
|
503
518
|
...prev,
|
|
504
519
|
manualResourceIds: event.target.value,
|
|
505
520
|
})), rows: 3 })) : null, _jsx(Checkbox, { checked: productsBuilder.featuredOnly, label: "Featured only", onChange: (event) => setProductsBuilder((prev) => ({
|
|
@@ -511,13 +526,19 @@ export function AdminSectionsView({ children }) {
|
|
|
511
526
|
})) }), _jsx(Checkbox, { checked: productsBuilder.autoScroll, label: "Auto-scroll", onChange: (event) => setProductsBuilder((prev) => ({
|
|
512
527
|
...prev,
|
|
513
528
|
autoScroll: event.target.checked,
|
|
514
|
-
})) }), _jsx(Input, { label:
|
|
529
|
+
})) }), _jsx(Input, { label: LBL_SCROLL_INTERVAL, type: "number", min: 1000, step: 500, value: String(productsBuilder.scrollInterval), onChange: (event) => setProductsBuilder((prev) => ({
|
|
515
530
|
...prev,
|
|
516
531
|
scrollInterval: Math.max(1000, Number(event.target.value) || 1000),
|
|
517
532
|
})) })] }));
|
|
518
533
|
}
|
|
534
|
+
function renderAuctionsCategorySelectors() {
|
|
535
|
+
return (_jsxs(Div, { className: "space-y-2", children: [_jsx(Text, { className: "text-xs font-semibold uppercase tracking-wide text-zinc-500 dark:text-zinc-400", children: "Category selectors" }), categoriesQuery.isLoading ? (_jsx(Text, { className: "text-sm text-zinc-500 dark:text-zinc-400", children: "Loading categories..." })) : categoryOptions.length === 0 ? (_jsx(Text, { className: "text-sm text-zinc-500 dark:text-zinc-400", children: "No categories available." })) : (_jsx(Div, { className: "grid grid-cols-1 gap-2 sm:grid-cols-2", children: categoryOptions.map((category) => (_jsx(Checkbox, { checked: auctionsBuilder.selectedCategoryIds.includes(category.id), label: category.name, onChange: (event) => setAuctionsBuilder((prev) => ({
|
|
536
|
+
...prev,
|
|
537
|
+
selectedCategoryIds: toggleCategorySelection(prev.selectedCategoryIds, category.id, event.target.checked),
|
|
538
|
+
})) }, category.id))) }))] }));
|
|
539
|
+
}
|
|
519
540
|
function renderAuctionsBuilder() {
|
|
520
|
-
return (_jsxs(Div, { className:
|
|
541
|
+
return (_jsxs(Div, { className: CLS_SECTION_PANEL, children: [_jsx(Text, { className: "text-sm font-semibold text-zinc-800 dark:text-zinc-200", children: "Auctions Carousel Builder" }), _jsx(Input, { label: "Section title", value: auctionsBuilder.title, onChange: (event) => setAuctionsBuilder((prev) => ({ ...prev, title: event.target.value })) }), _jsx(Input, { label: "Subtitle", value: auctionsBuilder.subtitle, onChange: (event) => setAuctionsBuilder((prev) => ({ ...prev, subtitle: event.target.value })) }), _jsx(Input, { label: "Max auctions", type: "number", min: 1, max: 50, value: String(auctionsBuilder.maxItems), onChange: (event) => setAuctionsBuilder((prev) => ({
|
|
521
542
|
...prev,
|
|
522
543
|
maxItems: Math.max(1, Number(event.target.value) || 1),
|
|
523
544
|
})) }), _jsx(Select, { label: "Status filter", value: auctionsBuilder.status, onValueChange: (value) => setAuctionsBuilder((prev) => ({
|
|
@@ -528,28 +549,25 @@ export function AdminSectionsView({ children }) {
|
|
|
528
549
|
{ label: "Active", value: "active" },
|
|
529
550
|
{ label: "Scheduled", value: "scheduled" },
|
|
530
551
|
{ label: "Ended", value: "ended" },
|
|
531
|
-
] }), _jsx(Select, { label: "Sort by", value: auctionsBuilder.sortBy, onValueChange: (value) => setAuctionsBuilder((prev) => ({ ...prev, sortBy: value })), options: [...RESOURCE_SORT_OPTIONS] }), _jsx(Input, { label:
|
|
552
|
+
] }), _jsx(Select, { label: "Sort by", value: auctionsBuilder.sortBy, onValueChange: (value) => setAuctionsBuilder((prev) => ({ ...prev, sortBy: value })), options: [...RESOURCE_SORT_OPTIONS] }), _jsx(Input, { label: LBL_FILTER_BY_CATEGORY, value: auctionsBuilder.filterByCategory, onChange: (e) => setAuctionsBuilder((prev) => ({ ...prev, filterByCategory: e.target.value })), placeholder: "category-pokemon-cards" }), _jsx(Select, { label: LBL_MAX_ITEMS, value: String(auctionsBuilder.maxCount), onValueChange: (v) => setAuctionsBuilder((prev) => ({ ...prev, maxCount: Number(v) })), options: [{ label: "5", value: "5" }, { label: "10", value: "10" }, { label: "20", value: "20" }] }), _jsx(Checkbox, { checked: auctionsBuilder.loop, label: "Loop carousel", onChange: (e) => setAuctionsBuilder((prev) => ({ ...prev, loop: e.target.checked })) }), _jsx(Select, { label: "Resource mode", value: auctionsBuilder.resourceMode, onValueChange: (value) => setAuctionsBuilder((prev) => ({
|
|
532
553
|
...prev,
|
|
533
554
|
resourceMode: value,
|
|
534
555
|
})), options: [
|
|
535
|
-
{ label:
|
|
536
|
-
{ label:
|
|
537
|
-
] }),
|
|
538
|
-
...prev,
|
|
539
|
-
selectedCategoryIds: toggleCategorySelection(prev.selectedCategoryIds, category.id, event.target.checked),
|
|
540
|
-
})) }, category.id))) }))] }), auctionsBuilder.resourceMode === "manual" ? (_jsx(Textarea, { label: "Manual auction resource IDs (comma-separated)", value: auctionsBuilder.manualResourceIds, onChange: (event) => setAuctionsBuilder((prev) => ({
|
|
556
|
+
{ label: LBL_AUTOMATIC, value: "automatic" },
|
|
557
|
+
{ label: LBL_MANUAL_IDS, value: "manual" },
|
|
558
|
+
] }), renderAuctionsCategorySelectors(), auctionsBuilder.resourceMode === "manual" ? (_jsx(Textarea, { label: "Manual auction resource IDs (comma-separated)", value: auctionsBuilder.manualResourceIds, onChange: (event) => setAuctionsBuilder((prev) => ({
|
|
541
559
|
...prev,
|
|
542
560
|
manualResourceIds: event.target.value,
|
|
543
561
|
})), rows: 3 })) : null, _jsx(Checkbox, { checked: auctionsBuilder.autoScroll, label: "Auto-scroll", onChange: (event) => setAuctionsBuilder((prev) => ({
|
|
544
562
|
...prev,
|
|
545
563
|
autoScroll: event.target.checked,
|
|
546
|
-
})) }), _jsx(Input, { label:
|
|
564
|
+
})) }), _jsx(Input, { label: LBL_SCROLL_INTERVAL, type: "number", min: 1000, step: 500, value: String(auctionsBuilder.scrollInterval), onChange: (event) => setAuctionsBuilder((prev) => ({
|
|
547
565
|
...prev,
|
|
548
566
|
scrollInterval: Math.max(1000, Number(event.target.value) || 1000),
|
|
549
567
|
})) })] }));
|
|
550
568
|
}
|
|
551
569
|
function renderStatsBuilder() {
|
|
552
|
-
return (_jsxs(Div, { className:
|
|
570
|
+
return (_jsxs(Div, { className: CLS_SECTION_PANEL, children: [_jsx(Text, { className: "text-sm font-semibold text-zinc-800 dark:text-zinc-200", children: "Stats Section Builder" }), _jsx(Input, { label: "Section title", value: statsBuilder.title, onChange: (event) => setStatsBuilder((prev) => ({ ...prev, title: event.target.value })), helperText: "Optional internal title for stats configuration." }), statsBuilder.stats.map((stat, index) => (_jsxs(Div, { className: "space-y-3 rounded-md border border-zinc-200 p-3 dark:border-slate-700", children: [_jsxs(Text, { className: "text-xs font-semibold uppercase tracking-wide text-zinc-500 dark:text-zinc-400", children: ["Stat ", index + 1] }), _jsx(Input, { label: "Key", value: stat.key, onChange: (event) => setStatsBuilder((prev) => {
|
|
553
571
|
const next = [...prev.stats];
|
|
554
572
|
next[index] = { ...next[index], key: event.target.value };
|
|
555
573
|
return { ...prev, stats: next };
|
|
@@ -567,7 +585,7 @@ export function AdminSectionsView({ children }) {
|
|
|
567
585
|
return (_jsxs(Div, { className: "space-y-2", children: [_jsx(Text, { className: "text-xs font-semibold uppercase tracking-wide text-zinc-500 dark:text-zinc-400", children: "Category selectors" }), categoriesQuery.isLoading ? (_jsx(Text, { className: "text-sm text-zinc-500 dark:text-zinc-400", children: "Loading categories..." })) : categoryOptions.length === 0 ? (_jsx(Text, { className: "text-sm text-zinc-500 dark:text-zinc-400", children: "No categories available." })) : (_jsx(Div, { className: "grid grid-cols-1 gap-2 sm:grid-cols-2", children: categoryOptions.map((category) => (_jsx(Checkbox, { checked: selectedIds.includes(category.id), label: category.name, onChange: (event) => onToggle(category.id, event.target.checked) }, category.id))) }))] }));
|
|
568
586
|
}
|
|
569
587
|
function renderPreOrdersBuilder() {
|
|
570
|
-
return (_jsxs(Div, { className:
|
|
588
|
+
return (_jsxs(Div, { className: CLS_SECTION_PANEL, children: [_jsx(Text, { className: "text-sm font-semibold text-zinc-800 dark:text-zinc-200", children: "Pre-Orders Carousel Builder" }), _jsx(Input, { label: "Section title", value: preOrdersBuilder.title, onChange: (event) => setPreOrdersBuilder((prev) => ({ ...prev, title: event.target.value })) }), _jsx(Input, { label: "Subtitle", value: preOrdersBuilder.subtitle, onChange: (event) => setPreOrdersBuilder((prev) => ({ ...prev, subtitle: event.target.value })) }), _jsx(Input, { label: "Max pre-orders", type: "number", min: 1, max: 50, value: String(preOrdersBuilder.maxItems), onChange: (event) => setPreOrdersBuilder((prev) => ({
|
|
571
589
|
...prev,
|
|
572
590
|
maxItems: Math.max(1, Number(event.target.value) || 1),
|
|
573
591
|
})) }), _jsx(Select, { label: "Status filter", value: preOrdersBuilder.status, onValueChange: (value) => setPreOrdersBuilder((prev) => ({
|
|
@@ -578,12 +596,12 @@ export function AdminSectionsView({ children }) {
|
|
|
578
596
|
{ label: "Active", value: "active" },
|
|
579
597
|
{ label: "Upcoming", value: "upcoming" },
|
|
580
598
|
{ label: "Closed", value: "closed" },
|
|
581
|
-
] }), _jsx(Select, { label: "Sort by", value: preOrdersBuilder.sortBy, onValueChange: (value) => setPreOrdersBuilder((prev) => ({ ...prev, sortBy: value })), options: [...RESOURCE_SORT_OPTIONS] }), _jsx(Input, { label:
|
|
599
|
+
] }), _jsx(Select, { label: "Sort by", value: preOrdersBuilder.sortBy, onValueChange: (value) => setPreOrdersBuilder((prev) => ({ ...prev, sortBy: value })), options: [...RESOURCE_SORT_OPTIONS] }), _jsx(Input, { label: LBL_FILTER_BY_CATEGORY, value: preOrdersBuilder.filterByCategory, onChange: (e) => setPreOrdersBuilder((prev) => ({ ...prev, filterByCategory: e.target.value })), placeholder: "category-beyblade-tops" }), _jsx(Select, { label: LBL_MAX_ITEMS, value: String(preOrdersBuilder.maxCount), onValueChange: (v) => setPreOrdersBuilder((prev) => ({ ...prev, maxCount: Number(v) })), options: [{ label: "5", value: "5" }, { label: "10", value: "10" }, { label: "20", value: "20" }] }), _jsx(Checkbox, { checked: preOrdersBuilder.loop, label: "Loop carousel", onChange: (e) => setPreOrdersBuilder((prev) => ({ ...prev, loop: e.target.checked })) }), _jsx(Select, { label: "Resource mode", value: preOrdersBuilder.resourceMode, onValueChange: (value) => setPreOrdersBuilder((prev) => ({
|
|
582
600
|
...prev,
|
|
583
601
|
resourceMode: value,
|
|
584
602
|
})), options: [
|
|
585
|
-
{ label:
|
|
586
|
-
{ label:
|
|
603
|
+
{ label: LBL_AUTOMATIC, value: "automatic" },
|
|
604
|
+
{ label: LBL_MANUAL_IDS, value: "manual" },
|
|
587
605
|
] }), renderCategorySelector(preOrdersBuilder.selectedCategoryIds, (categoryId, checked) => {
|
|
588
606
|
setPreOrdersBuilder((prev) => ({
|
|
589
607
|
...prev,
|
|
@@ -595,13 +613,13 @@ export function AdminSectionsView({ children }) {
|
|
|
595
613
|
})), rows: 3 })) : null, _jsx(Checkbox, { checked: preOrdersBuilder.autoScroll, label: "Auto-scroll", onChange: (event) => setPreOrdersBuilder((prev) => ({
|
|
596
614
|
...prev,
|
|
597
615
|
autoScroll: event.target.checked,
|
|
598
|
-
})) }), _jsx(Input, { label:
|
|
616
|
+
})) }), _jsx(Input, { label: LBL_SCROLL_INTERVAL, type: "number", min: 1000, step: 500, value: String(preOrdersBuilder.scrollInterval), onChange: (event) => setPreOrdersBuilder((prev) => ({
|
|
599
617
|
...prev,
|
|
600
618
|
scrollInterval: Math.max(1000, Number(event.target.value) || 1000),
|
|
601
619
|
})) })] }));
|
|
602
620
|
}
|
|
603
621
|
function renderStoresBuilder() {
|
|
604
|
-
return (_jsxs(Div, { className:
|
|
622
|
+
return (_jsxs(Div, { className: CLS_SECTION_PANEL, children: [_jsx(Text, { className: "text-sm font-semibold text-zinc-800 dark:text-zinc-200", children: "Stores Section Builder" }), _jsx(Input, { label: "Section title", value: storesBuilder.title, onChange: (event) => setStoresBuilder((prev) => ({ ...prev, title: event.target.value })) }), _jsx(Input, { label: "Subtitle", value: storesBuilder.subtitle, onChange: (event) => setStoresBuilder((prev) => ({ ...prev, subtitle: event.target.value })) }), _jsx(Input, { label: "Max stores", type: "number", min: 1, max: 30, value: String(storesBuilder.maxItems), onChange: (event) => setStoresBuilder((prev) => ({
|
|
605
623
|
...prev,
|
|
606
624
|
maxItems: Math.max(1, Number(event.target.value) || 1),
|
|
607
625
|
})) }), _jsx(Select, { label: "Status filter", value: storesBuilder.status, onValueChange: (value) => setStoresBuilder((prev) => ({
|
|
@@ -612,12 +630,12 @@ export function AdminSectionsView({ children }) {
|
|
|
612
630
|
{ label: "Active", value: "active" },
|
|
613
631
|
{ label: "Pending", value: "pending" },
|
|
614
632
|
{ label: "Disabled", value: "disabled" },
|
|
615
|
-
] }), _jsx(Select, { label: "Sort by", value: storesBuilder.sortBy, onValueChange: (value) => setStoresBuilder((prev) => ({ ...prev, sortBy: value })), options: [...RESOURCE_SORT_OPTIONS] }), _jsx(Input, { label:
|
|
633
|
+
] }), _jsx(Select, { label: "Sort by", value: storesBuilder.sortBy, onValueChange: (value) => setStoresBuilder((prev) => ({ ...prev, sortBy: value })), options: [...RESOURCE_SORT_OPTIONS] }), _jsx(Input, { label: LBL_FILTER_BY_CATEGORY, value: storesBuilder.filterByCategory, onChange: (e) => setStoresBuilder((prev) => ({ ...prev, filterByCategory: e.target.value })), placeholder: "category-pokemon-cards" }), _jsx(Select, { label: LBL_MAX_ITEMS, value: String(storesBuilder.maxCount), onValueChange: (v) => setStoresBuilder((prev) => ({ ...prev, maxCount: Number(v) })), options: [{ label: "5", value: "5" }, { label: "10", value: "10" }, { label: "20", value: "20" }] }), _jsx(Checkbox, { checked: storesBuilder.loop, label: "Loop carousel", onChange: (e) => setStoresBuilder((prev) => ({ ...prev, loop: e.target.checked })) }), _jsx(Select, { label: "Resource mode", value: storesBuilder.resourceMode, onValueChange: (value) => setStoresBuilder((prev) => ({
|
|
616
634
|
...prev,
|
|
617
635
|
resourceMode: value,
|
|
618
636
|
})), options: [
|
|
619
|
-
{ label:
|
|
620
|
-
{ label:
|
|
637
|
+
{ label: LBL_AUTOMATIC, value: "automatic" },
|
|
638
|
+
{ label: LBL_MANUAL_IDS, value: "manual" },
|
|
621
639
|
] }), renderCategorySelector(storesBuilder.selectedCategoryIds, (categoryId, checked) => {
|
|
622
640
|
setStoresBuilder((prev) => ({
|
|
623
641
|
...prev,
|
|
@@ -632,13 +650,13 @@ export function AdminSectionsView({ children }) {
|
|
|
632
650
|
})) }), _jsx(Checkbox, { checked: storesBuilder.autoScroll, label: "Auto-scroll", onChange: (event) => setStoresBuilder((prev) => ({
|
|
633
651
|
...prev,
|
|
634
652
|
autoScroll: event.target.checked,
|
|
635
|
-
})) }), _jsx(Input, { label:
|
|
653
|
+
})) }), _jsx(Input, { label: LBL_SCROLL_INTERVAL, type: "number", min: 1000, step: 500, value: String(storesBuilder.scrollInterval), onChange: (event) => setStoresBuilder((prev) => ({
|
|
636
654
|
...prev,
|
|
637
655
|
scrollInterval: Math.max(1000, Number(event.target.value) || 1000),
|
|
638
656
|
})) })] }));
|
|
639
657
|
}
|
|
640
658
|
function renderEventsBuilder() {
|
|
641
|
-
return (_jsxs(Div, { className:
|
|
659
|
+
return (_jsxs(Div, { className: CLS_SECTION_PANEL, children: [_jsx(Text, { className: "text-sm font-semibold text-zinc-800 dark:text-zinc-200", children: "Events Section Builder" }), _jsx(Input, { label: "Section title", value: eventsBuilder.title, onChange: (event) => setEventsBuilder((prev) => ({ ...prev, title: event.target.value })) }), _jsx(Input, { label: "Subtitle", value: eventsBuilder.subtitle, onChange: (event) => setEventsBuilder((prev) => ({ ...prev, subtitle: event.target.value })) }), _jsx(Input, { label: "Max events", type: "number", min: 1, max: 30, value: String(eventsBuilder.maxItems), onChange: (event) => setEventsBuilder((prev) => ({
|
|
642
660
|
...prev,
|
|
643
661
|
maxItems: Math.max(1, Number(event.target.value) || 1),
|
|
644
662
|
})) }), _jsx(Select, { label: "Status filter", value: eventsBuilder.status, onValueChange: (value) => setEventsBuilder((prev) => ({
|
|
@@ -649,12 +667,12 @@ export function AdminSectionsView({ children }) {
|
|
|
649
667
|
{ label: "Active", value: "active" },
|
|
650
668
|
{ label: "Upcoming", value: "upcoming" },
|
|
651
669
|
{ label: "Ended", value: "ended" },
|
|
652
|
-
] }), _jsx(Select, { label: "Sort by", value: eventsBuilder.sortBy, onValueChange: (value) => setEventsBuilder((prev) => ({ ...prev, sortBy: value })), options: [...RESOURCE_SORT_OPTIONS] }), _jsx(Input, { label:
|
|
670
|
+
] }), _jsx(Select, { label: "Sort by", value: eventsBuilder.sortBy, onValueChange: (value) => setEventsBuilder((prev) => ({ ...prev, sortBy: value })), options: [...RESOURCE_SORT_OPTIONS] }), _jsx(Input, { label: LBL_FILTER_BY_CATEGORY, value: eventsBuilder.filterByCategory, onChange: (e) => setEventsBuilder((prev) => ({ ...prev, filterByCategory: e.target.value })), placeholder: "category-events" }), _jsx(Select, { label: LBL_MAX_ITEMS, value: String(eventsBuilder.maxCount), onValueChange: (v) => setEventsBuilder((prev) => ({ ...prev, maxCount: Number(v) })), options: [{ label: "5", value: "5" }, { label: "10", value: "10" }, { label: "20", value: "20" }] }), _jsx(Checkbox, { checked: eventsBuilder.loop, label: "Loop carousel", onChange: (e) => setEventsBuilder((prev) => ({ ...prev, loop: e.target.checked })) }), _jsx(Select, { label: "Resource mode", value: eventsBuilder.resourceMode, onValueChange: (value) => setEventsBuilder((prev) => ({
|
|
653
671
|
...prev,
|
|
654
672
|
resourceMode: value,
|
|
655
673
|
})), options: [
|
|
656
|
-
{ label:
|
|
657
|
-
{ label:
|
|
674
|
+
{ label: LBL_AUTOMATIC, value: "automatic" },
|
|
675
|
+
{ label: LBL_MANUAL_IDS, value: "manual" },
|
|
658
676
|
] }), renderCategorySelector(eventsBuilder.selectedCategoryIds, (categoryId, checked) => {
|
|
659
677
|
setEventsBuilder((prev) => ({
|
|
660
678
|
...prev,
|
|
@@ -669,13 +687,13 @@ export function AdminSectionsView({ children }) {
|
|
|
669
687
|
})) }), _jsx(Checkbox, { checked: eventsBuilder.autoScroll, label: "Auto-scroll", onChange: (event) => setEventsBuilder((prev) => ({
|
|
670
688
|
...prev,
|
|
671
689
|
autoScroll: event.target.checked,
|
|
672
|
-
})) }), _jsx(Input, { label:
|
|
690
|
+
})) }), _jsx(Input, { label: LBL_SCROLL_INTERVAL, type: "number", min: 1000, step: 500, value: String(eventsBuilder.scrollInterval), onChange: (event) => setEventsBuilder((prev) => ({
|
|
673
691
|
...prev,
|
|
674
692
|
scrollInterval: Math.max(1000, Number(event.target.value) || 1000),
|
|
675
693
|
})) })] }));
|
|
676
694
|
}
|
|
677
695
|
function renderFAQBuilder() {
|
|
678
|
-
return (_jsxs(Div, { className:
|
|
696
|
+
return (_jsxs(Div, { className: CLS_SECTION_PANEL, children: [_jsx(Text, { className: "text-sm font-semibold text-zinc-800 dark:text-zinc-200", children: "FAQ Section Builder" }), _jsx(Input, { label: "Section title", value: faqBuilder.title, onChange: (e) => setFaqBuilder((prev) => ({ ...prev, title: e.target.value })) }), _jsx(Input, { label: "Subtitle", value: faqBuilder.subtitle, onChange: (e) => setFaqBuilder((prev) => ({ ...prev, subtitle: e.target.value })) }), _jsx(Input, { label: "Display count", type: "number", min: 1, max: 20, value: String(faqBuilder.displayCount), onChange: (e) => setFaqBuilder((prev) => ({ ...prev, displayCount: Math.min(20, Math.max(1, Number(e.target.value) || 1)) })) }), _jsx(Checkbox, { checked: faqBuilder.showOnHomepage, label: "Show on homepage", onChange: (e) => setFaqBuilder((prev) => ({ ...prev, showOnHomepage: e.target.checked })) }), _jsx(Checkbox, { checked: faqBuilder.expandedByDefault, label: "Expanded by default", onChange: (e) => setFaqBuilder((prev) => ({ ...prev, expandedByDefault: e.target.checked })) }), _jsx(Checkbox, { checked: faqBuilder.linkToFullPage, label: "Link to full FAQ page", onChange: (e) => setFaqBuilder((prev) => ({ ...prev, linkToFullPage: e.target.checked })) }), _jsxs(Div, { className: "space-y-2", children: [_jsx(Text, { className: "text-xs font-semibold uppercase tracking-wide text-zinc-500 dark:text-zinc-400", children: "Categories" }), _jsx(Div, { className: "grid grid-cols-2 gap-2", children: FAQ_CATEGORY_OPTIONS.map((opt) => (_jsx(Checkbox, { checked: faqBuilder.categories.includes(opt.value), label: opt.label, onChange: (e) => setFaqBuilder((prev) => ({
|
|
679
697
|
...prev,
|
|
680
698
|
categories: e.target.checked
|
|
681
699
|
? [...prev.categories, opt.value]
|
|
@@ -683,40 +701,40 @@ export function AdminSectionsView({ children }) {
|
|
|
683
701
|
})) }, opt.value))) })] })] }));
|
|
684
702
|
}
|
|
685
703
|
function renderBlogBuilder() {
|
|
686
|
-
return (_jsxs(Div, { className:
|
|
704
|
+
return (_jsxs(Div, { className: CLS_SECTION_PANEL, children: [_jsx(Text, { className: "text-sm font-semibold text-zinc-800 dark:text-zinc-200", children: "Blog Articles Builder" }), _jsx(Input, { label: "Section title", value: blogBuilder.title, onChange: (e) => setBlogBuilder((prev) => ({ ...prev, title: e.target.value })) }), _jsx(Select, { label: "Max articles", value: String(blogBuilder.maxArticles), onValueChange: (v) => setBlogBuilder((prev) => ({ ...prev, maxArticles: Number(v) })), options: [{ label: "3", value: "3" }, { label: "4", value: "4" }, { label: "6", value: "6" }] }), _jsx(Checkbox, { checked: blogBuilder.showReadTime, label: "Show read time", onChange: (e) => setBlogBuilder((prev) => ({ ...prev, showReadTime: e.target.checked })) }), _jsx(Checkbox, { checked: blogBuilder.showAuthor, label: "Show author", onChange: (e) => setBlogBuilder((prev) => ({ ...prev, showAuthor: e.target.checked })) }), _jsx(Checkbox, { checked: blogBuilder.showThumbnails, label: "Show thumbnails", onChange: (e) => setBlogBuilder((prev) => ({ ...prev, showThumbnails: e.target.checked })) })] }));
|
|
687
705
|
}
|
|
688
706
|
function renderNewsletterBuilder() {
|
|
689
|
-
return (_jsxs(Div, { className:
|
|
707
|
+
return (_jsxs(Div, { className: CLS_SECTION_PANEL, children: [_jsx(Text, { className: "text-sm font-semibold text-zinc-800 dark:text-zinc-200", children: "Newsletter Section Builder" }), _jsx(Input, { label: "Title", value: newsletterBuilder.title, onChange: (e) => setNewsletterBuilder((prev) => ({ ...prev, title: e.target.value })) }), _jsx(Textarea, { label: "Description", value: newsletterBuilder.description, onChange: (e) => setNewsletterBuilder((prev) => ({ ...prev, description: e.target.value })), rows: 2 }), _jsx(Input, { label: "Email placeholder", value: newsletterBuilder.placeholder, onChange: (e) => setNewsletterBuilder((prev) => ({ ...prev, placeholder: e.target.value })) }), _jsx(Input, { label: "Button text", value: newsletterBuilder.buttonText, onChange: (e) => setNewsletterBuilder((prev) => ({ ...prev, buttonText: e.target.value })) }), _jsx(Input, { label: "Privacy text", value: newsletterBuilder.privacyText, onChange: (e) => setNewsletterBuilder((prev) => ({ ...prev, privacyText: e.target.value })) }), _jsx(Input, { label: "Privacy link", value: newsletterBuilder.privacyLink, onChange: (e) => setNewsletterBuilder((prev) => ({ ...prev, privacyLink: e.target.value })), placeholder: "/privacy" })] }));
|
|
690
708
|
}
|
|
691
709
|
function renderBannerBuilder() {
|
|
692
|
-
return (_jsxs(Div, { className:
|
|
710
|
+
return (_jsxs(Div, { className: CLS_SECTION_PANEL, children: [_jsx(Text, { className: "text-sm font-semibold text-zinc-800 dark:text-zinc-200", children: "Banner Section Builder" }), _jsx(Select, { label: "Height", value: bannerBuilder.height, onValueChange: (v) => setBannerBuilder((prev) => ({ ...prev, height: v })), options: [{ label: "Small (200px)", value: "sm" }, { label: "Medium (300px)", value: "md" }, { label: "Large (400px)", value: "lg" }, { label: "Extra Large (500px)", value: "xl" }] }), _jsx(Input, { label: "Background image URL", type: "url", value: bannerBuilder.backgroundImage, onChange: (e) => setBannerBuilder((prev) => ({ ...prev, backgroundImage: e.target.value })), placeholder: "https://..." }), _jsx(Input, { label: "Background color (CSS token)", value: bannerBuilder.backgroundColor, onChange: (e) => setBannerBuilder((prev) => ({ ...prev, backgroundColor: e.target.value })), placeholder: "var(--appkit-color-primary)" }), _jsx(Input, { label: "Gradient from (CSS token)", value: bannerBuilder.gradientFrom, onChange: (e) => setBannerBuilder((prev) => ({ ...prev, gradientFrom: e.target.value })), placeholder: "var(--appkit-color-primary)" }), _jsx(Input, { label: "Gradient to (CSS token)", value: bannerBuilder.gradientTo, onChange: (e) => setBannerBuilder((prev) => ({ ...prev, gradientTo: e.target.value })), placeholder: "var(--appkit-color-secondary)" }), _jsx(Input, { label: "Content title", value: bannerBuilder.contentTitle, onChange: (e) => setBannerBuilder((prev) => ({ ...prev, contentTitle: e.target.value })) }), _jsx(Input, { label: "Content subtitle", value: bannerBuilder.contentSubtitle, onChange: (e) => setBannerBuilder((prev) => ({ ...prev, contentSubtitle: e.target.value })) }), _jsx(Textarea, { label: "Content description", value: bannerBuilder.contentDescription, onChange: (e) => setBannerBuilder((prev) => ({ ...prev, contentDescription: e.target.value })), rows: 2 }), _jsxs(Div, { className: "space-y-2", children: [_jsx(Text, { className: "text-xs font-semibold uppercase tracking-wide text-zinc-500 dark:text-zinc-400", children: "Buttons (max 3)" }), bannerBuilder.buttons.map((btn, index) => (_jsxs(Div, { className: "space-y-2 rounded-md border border-zinc-200 p-2 dark:border-slate-700", children: [_jsxs(Div, { className: "flex items-center justify-between", children: [_jsxs(Text, { className: "text-xs text-zinc-500", children: ["Button ", index + 1] }), _jsx(Button, { type: "button", variant: "ghost", size: "sm", onClick: () => setBannerBuilder((prev) => ({ ...prev, buttons: prev.buttons.filter((_, i) => i !== index) })), children: "Remove" })] }), _jsx(Input, { label: "Text", value: btn.text, onChange: (e) => setBannerBuilder((prev) => { const next = [...prev.buttons]; next[index] = { ...next[index], text: e.target.value }; return { ...prev, buttons: next }; }) }), _jsx(Input, { label: "Link", value: btn.link, onChange: (e) => setBannerBuilder((prev) => { const next = [...prev.buttons]; next[index] = { ...next[index], link: e.target.value }; return { ...prev, buttons: next }; }) }), _jsx(Select, { label: "Variant", value: btn.variant, onValueChange: (v) => setBannerBuilder((prev) => { const next = [...prev.buttons]; next[index] = { ...next[index], variant: v }; return { ...prev, buttons: next }; }), options: [{ label: "Primary", value: "primary" }, { label: "Secondary", value: "secondary" }, { label: "Outline", value: "outline" }] })] }, `banner-btn-${index}`))), bannerBuilder.buttons.length < 3 ? (_jsx(Button, { type: "button", variant: "outline", size: "sm", onClick: () => setBannerBuilder((prev) => ({ ...prev, buttons: [...prev.buttons, { text: "", link: "", variant: "primary" }] })), children: "+ Add button" })) : null] }), _jsx(Checkbox, { checked: bannerBuilder.clickable, label: "Make entire banner clickable", onChange: (e) => setBannerBuilder((prev) => ({ ...prev, clickable: e.target.checked })) }), bannerBuilder.clickable ? (_jsx(Input, { label: "Click link", value: bannerBuilder.clickLink, onChange: (e) => setBannerBuilder((prev) => ({ ...prev, clickLink: e.target.value })), placeholder: "/products" })) : null] }));
|
|
693
711
|
}
|
|
694
712
|
function renderFeaturesBuilder() {
|
|
695
|
-
return (_jsxs(Div, { className:
|
|
713
|
+
return (_jsxs(Div, { className: CLS_SECTION_PANEL, children: [_jsx(Text, { className: "text-sm font-semibold text-zinc-800 dark:text-zinc-200", children: "Features Section Builder" }), _jsx(Input, { label: "Section title", value: featuresBuilder.title, onChange: (e) => setFeaturesBuilder((prev) => ({ ...prev, title: e.target.value })) }), _jsxs(Div, { className: "space-y-2", children: [_jsx(Text, { className: "text-xs font-semibold uppercase tracking-wide text-zinc-500 dark:text-zinc-400", children: "Feature items" }), featuresBuilder.features.map((feature, index) => (_jsxs(Div, { className: "flex items-center gap-2", children: [_jsx(Input, { value: feature, onChange: (e) => setFeaturesBuilder((prev) => { const next = [...prev.features]; next[index] = e.target.value; return { ...prev, features: next }; }), className: "flex-1" }), _jsx(Button, { type: "button", variant: "ghost", size: "sm", onClick: () => setFeaturesBuilder((prev) => ({ ...prev, features: prev.features.filter((_, i) => i !== index) })), children: "\u2715" })] }, `feat-${index}`))), _jsx(Button, { type: "button", variant: "outline", size: "sm", onClick: () => setFeaturesBuilder((prev) => ({ ...prev, features: [...prev.features, ""] })), children: "+ Add feature" })] })] }));
|
|
696
714
|
}
|
|
697
715
|
function renderReviewsBuilder() {
|
|
698
|
-
return (_jsxs(Div, { className:
|
|
716
|
+
return (_jsxs(Div, { className: CLS_SECTION_PANEL, children: [_jsx(Text, { className: "text-sm font-semibold text-zinc-800 dark:text-zinc-200", children: "Reviews Section Builder" }), _jsx(Input, { label: "Section title", value: reviewsBuilder.title, onChange: (e) => setReviewsBuilder((prev) => ({ ...prev, title: e.target.value })) }), _jsx(Select, { label: "Reviews source", value: reviewsBuilder.source, onValueChange: (v) => setReviewsBuilder((prev) => ({ ...prev, source: v })), options: [
|
|
699
717
|
{ label: "Platform reviews (LetItRip)", value: "platform" },
|
|
700
718
|
{ label: "Google Business Reviews", value: "google" },
|
|
701
|
-
] }), reviewsBuilder.source === "google" ? (_jsx(Input, { label: "Google Place ID", value: reviewsBuilder.placeId, onChange: (e) => setReviewsBuilder((prev) => ({ ...prev, placeId: e.target.value })), placeholder: "ChIJ...", helperText: "Find your Place ID at maps.google.com/placesinventory" })) : null, _jsx(Select, { label: "Max reviews", value: String(reviewsBuilder.maxReviews), onValueChange: (v) => setReviewsBuilder((prev) => ({ ...prev, maxReviews: Number(v) })), options: [{ label: "5", value: "5" }, { label: "10", value: "10" }, { label: "20", value: "20" }] }), _jsx(Select, { label: "Items per view", value: String(reviewsBuilder.itemsPerView), onValueChange: (v) => setReviewsBuilder((prev) => ({ ...prev, itemsPerView: Number(v) })), options: [{ label: "1", value: "1" }, { label: "2", value: "2" }, { label: "3", value: "3" }] }), _jsx(Checkbox, { checked: reviewsBuilder.autoScroll, label: "Auto-scroll", onChange: (e) => setReviewsBuilder((prev) => ({ ...prev, autoScroll: e.target.checked })) }), _jsx(Input, { label:
|
|
719
|
+
] }), reviewsBuilder.source === "google" ? (_jsx(Input, { label: "Google Place ID", value: reviewsBuilder.placeId, onChange: (e) => setReviewsBuilder((prev) => ({ ...prev, placeId: e.target.value })), placeholder: "ChIJ...", helperText: "Find your Place ID at maps.google.com/placesinventory" })) : null, _jsx(Select, { label: "Max reviews", value: String(reviewsBuilder.maxReviews), onValueChange: (v) => setReviewsBuilder((prev) => ({ ...prev, maxReviews: Number(v) })), options: [{ label: "5", value: "5" }, { label: "10", value: "10" }, { label: "20", value: "20" }] }), _jsx(Select, { label: "Items per view", value: String(reviewsBuilder.itemsPerView), onValueChange: (v) => setReviewsBuilder((prev) => ({ ...prev, itemsPerView: Number(v) })), options: [{ label: "1", value: "1" }, { label: "2", value: "2" }, { label: "3", value: "3" }] }), _jsx(Checkbox, { checked: reviewsBuilder.autoScroll, label: "Auto-scroll", onChange: (e) => setReviewsBuilder((prev) => ({ ...prev, autoScroll: e.target.checked })) }), _jsx(Input, { label: LBL_SCROLL_INTERVAL, type: "number", min: 1000, step: 500, value: String(reviewsBuilder.scrollInterval), onChange: (e) => setReviewsBuilder((prev) => ({ ...prev, scrollInterval: Math.max(1000, Number(e.target.value) || 1000) })) })] }));
|
|
702
720
|
}
|
|
703
721
|
function renderWhatsAppBuilder() {
|
|
704
|
-
return (_jsxs(Div, { className:
|
|
722
|
+
return (_jsxs(Div, { className: CLS_SECTION_PANEL, children: [_jsx(Text, { className: "text-sm font-semibold text-zinc-800 dark:text-zinc-200", children: "WhatsApp Community Builder" }), _jsx(Input, { label: "Title", value: whatsappBuilder.title, onChange: (e) => setWhatsappBuilder((prev) => ({ ...prev, title: e.target.value })) }), _jsx(Textarea, { label: "Description", value: whatsappBuilder.description, onChange: (e) => setWhatsappBuilder((prev) => ({ ...prev, description: e.target.value })), rows: 2 }), _jsx(Input, { label: "WhatsApp group link", type: "url", value: whatsappBuilder.groupLink, onChange: (e) => setWhatsappBuilder((prev) => ({ ...prev, groupLink: e.target.value })), placeholder: "https://chat.whatsapp.com/..." }), _jsx(Input, { label: "Member count", type: "number", min: 0, value: String(whatsappBuilder.memberCount), onChange: (e) => setWhatsappBuilder((prev) => ({ ...prev, memberCount: Math.max(0, Number(e.target.value) || 0) })) }), _jsxs(Div, { className: "space-y-2", children: [_jsx(Text, { className: "text-xs font-semibold uppercase tracking-wide text-zinc-500 dark:text-zinc-400", children: "Benefits" }), whatsappBuilder.benefits.map((benefit, index) => (_jsxs(Div, { className: "flex items-center gap-2", children: [_jsx(Input, { value: benefit, onChange: (e) => setWhatsappBuilder((prev) => { const next = [...prev.benefits]; next[index] = e.target.value; return { ...prev, benefits: next }; }), className: "flex-1" }), _jsx(Button, { type: "button", variant: "ghost", size: "sm", onClick: () => setWhatsappBuilder((prev) => ({ ...prev, benefits: prev.benefits.filter((_, i) => i !== index) })), children: "\u2715" })] }, `wb-${index}`))), _jsx(Button, { type: "button", variant: "outline", size: "sm", onClick: () => setWhatsappBuilder((prev) => ({ ...prev, benefits: [...prev.benefits, ""] })), children: "+ Add benefit" })] }), _jsx(Input, { label: "Button text", value: whatsappBuilder.buttonText, onChange: (e) => setWhatsappBuilder((prev) => ({ ...prev, buttonText: e.target.value })) }), _jsx(Input, { label: "Testimonial (optional)", value: whatsappBuilder.testimonial, onChange: (e) => setWhatsappBuilder((prev) => ({ ...prev, testimonial: e.target.value })) })] }));
|
|
705
723
|
}
|
|
706
724
|
function renderWelcomeBuilder() {
|
|
707
|
-
return (_jsxs(Div, { className:
|
|
725
|
+
return (_jsxs(Div, { className: CLS_SECTION_PANEL, children: [_jsx(Text, { className: "text-sm font-semibold text-zinc-800 dark:text-zinc-200", children: "Welcome Section Builder" }), _jsx(Input, { label: "Headline (h1)", value: welcomeBuilder.h1, onChange: (e) => setWelcomeBuilder((prev) => ({ ...prev, h1: e.target.value })) }), _jsx(Input, { label: "Subtitle", value: welcomeBuilder.subtitle, onChange: (e) => setWelcomeBuilder((prev) => ({ ...prev, subtitle: e.target.value })) }), _jsx(Textarea, { label: "Description", value: welcomeBuilder.description, onChange: (e) => setWelcomeBuilder((prev) => ({ ...prev, description: e.target.value })), rows: 3 }), _jsx(Checkbox, { checked: welcomeBuilder.showCTA, label: "Show CTA button", onChange: (e) => setWelcomeBuilder((prev) => ({ ...prev, showCTA: e.target.checked })) }), welcomeBuilder.showCTA ? (_jsxs(_Fragment, { children: [_jsx(Input, { label: "CTA text", value: welcomeBuilder.ctaText, onChange: (e) => setWelcomeBuilder((prev) => ({ ...prev, ctaText: e.target.value })) }), _jsx(Input, { label: "CTA link", value: welcomeBuilder.ctaLink, onChange: (e) => setWelcomeBuilder((prev) => ({ ...prev, ctaLink: e.target.value })), placeholder: "/products" })] })) : null] }));
|
|
708
726
|
}
|
|
709
727
|
function renderTrustIndicatorsBuilder() {
|
|
710
|
-
return (_jsxs(Div, { className:
|
|
728
|
+
return (_jsxs(Div, { className: CLS_SECTION_PANEL, children: [_jsx(Text, { className: "text-sm font-semibold text-zinc-800 dark:text-zinc-200", children: "Trust Indicators Builder" }), _jsx(Input, { label: "Section title", value: trustIndicatorsBuilder.title, onChange: (e) => setTrustIndicatorsBuilder((prev) => ({ ...prev, title: e.target.value })) }), trustIndicatorsBuilder.indicators.map((ind, index) => (_jsxs(Div, { className: "space-y-2 rounded-md border border-zinc-200 p-3 dark:border-slate-700", children: [_jsxs(Div, { className: "flex items-center justify-between", children: [_jsxs(Text, { className: "text-xs font-semibold uppercase tracking-wide text-zinc-500 dark:text-zinc-400", children: ["Indicator ", index + 1] }), _jsx(Button, { type: "button", variant: "ghost", size: "sm", onClick: () => setTrustIndicatorsBuilder((prev) => ({ ...prev, indicators: prev.indicators.filter((_, i) => i !== index) })), children: "Remove" })] }), _jsx(Input, { label: "Icon (emoji or text)", value: ind.icon, onChange: (e) => setTrustIndicatorsBuilder((prev) => { const next = [...prev.indicators]; next[index] = { ...next[index], icon: e.target.value }; return { ...prev, indicators: next }; }) }), _jsx(Input, { label: "Title", value: ind.title, onChange: (e) => setTrustIndicatorsBuilder((prev) => { const next = [...prev.indicators]; next[index] = { ...next[index], title: e.target.value }; return { ...prev, indicators: next }; }) }), _jsx(Input, { label: "Description", value: ind.description, onChange: (e) => setTrustIndicatorsBuilder((prev) => { const next = [...prev.indicators]; next[index] = { ...next[index], description: e.target.value }; return { ...prev, indicators: next }; }) })] }, ind.id))), _jsx(Button, { type: "button", variant: "outline", size: "sm", onClick: () => setTrustIndicatorsBuilder((prev) => ({ ...prev, indicators: [...prev.indicators, { id: `ti-${Date.now()}`, icon: "✨", title: "", description: "" }] })), children: "+ Add indicator" })] }));
|
|
711
729
|
}
|
|
712
730
|
function renderCategoriesBuilder() {
|
|
713
|
-
return (_jsxs(Div, { className:
|
|
731
|
+
return (_jsxs(Div, { className: CLS_SECTION_PANEL, children: [_jsx(Text, { className: "text-sm font-semibold text-zinc-800 dark:text-zinc-200", children: "Categories Section Builder" }), _jsx(Input, { label: "Section title", value: categoriesBuilder.title, onChange: (e) => setCategoriesBuilder((prev) => ({ ...prev, title: e.target.value })) }), _jsx(Input, { label: "Max categories (4\u201312)", type: "number", min: 4, max: 12, value: String(categoriesBuilder.maxCategories), onChange: (e) => setCategoriesBuilder((prev) => ({ ...prev, maxCategories: Math.min(12, Math.max(4, Number(e.target.value) || 4)) })) }), _jsx(Checkbox, { checked: categoriesBuilder.autoScroll, label: "Auto-scroll", onChange: (e) => setCategoriesBuilder((prev) => ({ ...prev, autoScroll: e.target.checked })) }), _jsx(Input, { label: LBL_SCROLL_INTERVAL, type: "number", min: 1000, step: 500, value: String(categoriesBuilder.scrollInterval), onChange: (e) => setCategoriesBuilder((prev) => ({ ...prev, scrollInterval: Math.max(1000, Number(e.target.value) || 1000) })) })] }));
|
|
714
732
|
}
|
|
715
733
|
function renderBrandsBuilder() {
|
|
716
|
-
return (_jsxs(Div, { className:
|
|
734
|
+
return (_jsxs(Div, { className: CLS_SECTION_PANEL, children: [_jsx(Text, { className: "text-sm font-semibold text-zinc-800 dark:text-zinc-200", children: "Brands Section Builder" }), _jsx(Input, { label: "Section title", value: brandsBuilder.title, onChange: (e) => setBrandsBuilder((prev) => ({ ...prev, title: e.target.value })) }), _jsx(Input, { label: "Subtitle", value: brandsBuilder.subtitle, onChange: (e) => setBrandsBuilder((prev) => ({ ...prev, subtitle: e.target.value })) }), _jsx(Input, { label: "Max brands", type: "number", min: 1, max: 30, value: String(brandsBuilder.maxBrands), onChange: (e) => setBrandsBuilder((prev) => ({ ...prev, maxBrands: Math.max(1, Number(e.target.value) || 1) })) }), _jsx(Checkbox, { checked: brandsBuilder.autoScroll, label: "Auto-scroll", onChange: (e) => setBrandsBuilder((prev) => ({ ...prev, autoScroll: e.target.checked })) }), _jsx(Input, { label: LBL_SCROLL_INTERVAL, type: "number", min: 1000, step: 500, value: String(brandsBuilder.scrollInterval), onChange: (e) => setBrandsBuilder((prev) => ({ ...prev, scrollInterval: Math.max(1000, Number(e.target.value) || 1000) })) })] }));
|
|
717
735
|
}
|
|
718
736
|
function renderCarouselBuilder() {
|
|
719
|
-
return (_jsxs(Div, { className:
|
|
737
|
+
return (_jsxs(Div, { className: CLS_SECTION_PANEL, children: [_jsx(Text, { className: "text-sm font-semibold text-zinc-800 dark:text-zinc-200", children: "Carousel Section Builder" }), _jsx(Input, { label: "Section title", value: carouselBuilder.title, onChange: (e) => setCarouselBuilder((prev) => ({ ...prev, title: e.target.value })), placeholder: "Hero Carousel" }), _jsx(Select, { label: "Slide height", value: carouselBuilder.height, onValueChange: (value) => setCarouselBuilder((prev) => ({ ...prev, height: value })), options: [
|
|
720
738
|
{ label: "Viewport (100vh)", value: "viewport" },
|
|
721
739
|
{ label: "Tall (80vh)", value: "tall" },
|
|
722
740
|
{ label: "Medium (60vh)", value: "medium" },
|
|
@@ -760,7 +778,16 @@ export function AdminSectionsView({ children }) {
|
|
|
760
778
|
return { ...prev, cards: next };
|
|
761
779
|
});
|
|
762
780
|
}
|
|
763
|
-
|
|
781
|
+
function renderCardFields(card, index) {
|
|
782
|
+
return (_jsxs(Div, { className: "space-y-3 rounded-md border border-zinc-200 p-3 dark:border-slate-700", children: [_jsxs(Div, { className: "flex items-center justify-between", children: [_jsxs(Text, { className: "text-xs font-semibold uppercase tracking-wide text-zinc-500 dark:text-zinc-400", children: ["Card ", index + 1] }), _jsx(Button, { type: "button", variant: "outline", size: "sm", onClick: () => removeCard(index), children: "Remove" })] }), _jsx(Input, { label: "ID / slug", value: card.id, onChange: (e) => updateCard(index, { id: e.target.value }), placeholder: "card-1" }), _jsx(Input, { label: "Image URL", value: card.image, onChange: (e) => updateCard(index, { image: e.target.value }), placeholder: "https://..." }), _jsx(Input, { label: "Image alt text", value: card.imageAlt, onChange: (e) => updateCard(index, { imageAlt: e.target.value }) }), _jsx(Input, { label: "Eyebrow (small label above title)", value: card.eyebrow, onChange: (e) => updateCard(index, { eyebrow: e.target.value }) }), _jsx(Input, { label: "Title", value: card.title, onChange: (e) => updateCard(index, { title: e.target.value }) }), _jsx(Input, { label: "Body / description", value: card.body, onChange: (e) => updateCard(index, { body: e.target.value }) }), _jsx(Input, { label: "Link (href)", value: card.link, onChange: (e) => updateCard(index, { link: e.target.value }), placeholder: "/categories/..." }), _jsx(Input, { label: "Background colour", value: card.backgroundColor, onChange: (e) => updateCard(index, { backgroundColor: e.target.value }), placeholder: "#ffffff or var(--appkit-color-primary)" }), _jsx(Input, { label: "Text colour", value: card.textColor, onChange: (e) => updateCard(index, { textColor: e.target.value }), placeholder: "#000000" }), _jsx(Select, { label: "Border radius", value: card.borderRadius, onValueChange: (value) => updateCard(index, { borderRadius: value }), options: [
|
|
783
|
+
{ label: "None", value: "none" }, { label: "Small", value: "sm" }, { label: "Medium", value: "md" },
|
|
784
|
+
{ label: "Large", value: "lg" }, { label: "XL", value: "xl" }, { label: "Full (pill)", value: "full" },
|
|
785
|
+
] }), _jsx(Select, { label: "Shadow level", value: card.shadowLevel, onValueChange: (value) => updateCard(index, { shadowLevel: value }), options: [
|
|
786
|
+
{ label: "None", value: "none" }, { label: "Small", value: "sm" },
|
|
787
|
+
{ label: "Medium", value: "md" }, { label: "Large", value: "lg" },
|
|
788
|
+
] })] }, `custom-card-${index}`));
|
|
789
|
+
}
|
|
790
|
+
return (_jsxs(Div, { className: CLS_SECTION_PANEL, children: [_jsx(Text, { className: "text-sm font-semibold text-zinc-800 dark:text-zinc-200", children: "Custom Cards Builder" }), _jsx(Input, { label: "Section title", value: customCardsBuilder.title, onChange: (e) => setCustomCardsBuilder((prev) => ({ ...prev, title: e.target.value })) }), _jsx(Select, { label: "Layout", value: customCardsBuilder.layout, onValueChange: (value) => setCustomCardsBuilder((prev) => ({ ...prev, layout: value })), options: [
|
|
764
791
|
{ label: "Grid", value: "grid" },
|
|
765
792
|
{ label: "Row (horizontal scroll)", value: "row" },
|
|
766
793
|
{ label: "Masonry", value: "masonry" },
|
|
@@ -769,25 +796,13 @@ export function AdminSectionsView({ children }) {
|
|
|
769
796
|
{ label: "2 columns", value: "2" },
|
|
770
797
|
{ label: "3 columns", value: "3" },
|
|
771
798
|
{ label: "4 columns", value: "4" },
|
|
772
|
-
] }), _jsx(Checkbox, { checked: customCardsBuilder.autoScroll, label: "Auto-scroll", onChange: (e) => setCustomCardsBuilder((prev) => ({ ...prev, autoScroll: e.target.checked })) }), _jsx(Input, { label:
|
|
799
|
+
] }), _jsx(Checkbox, { checked: customCardsBuilder.autoScroll, label: "Auto-scroll", onChange: (e) => setCustomCardsBuilder((prev) => ({ ...prev, autoScroll: e.target.checked })) }), _jsx(Input, { label: LBL_SCROLL_INTERVAL, type: "number", min: 1000, step: 500, value: String(customCardsBuilder.scrollIntervalMs), onChange: (e) => setCustomCardsBuilder((prev) => ({
|
|
773
800
|
...prev,
|
|
774
801
|
scrollIntervalMs: Math.max(1000, Number(e.target.value) || 4000),
|
|
775
|
-
})) }), _jsxs(Div, { className: "space-y-3", children: [_jsxs(Div, { className: "flex items-center justify-between", children: [_jsxs(Text, { className: "text-xs font-semibold uppercase tracking-wide text-zinc-500 dark:text-zinc-400", children: ["Cards (", customCardsBuilder.cards.length, ")"] }), _jsx(Button, { type: "button", variant: "outline", size: "sm", onClick: addCard, children: "Add card" })] }), customCardsBuilder.cards.map((card, index) => (
|
|
776
|
-
{ label: "None", value: "none" },
|
|
777
|
-
{ label: "Small", value: "sm" },
|
|
778
|
-
{ label: "Medium", value: "md" },
|
|
779
|
-
{ label: "Large", value: "lg" },
|
|
780
|
-
{ label: "XL", value: "xl" },
|
|
781
|
-
{ label: "Full (pill)", value: "full" },
|
|
782
|
-
] }), _jsx(Select, { label: "Shadow level", value: card.shadowLevel, onValueChange: (value) => updateCard(index, { shadowLevel: value }), options: [
|
|
783
|
-
{ label: "None", value: "none" },
|
|
784
|
-
{ label: "Small", value: "sm" },
|
|
785
|
-
{ label: "Medium", value: "md" },
|
|
786
|
-
{ label: "Large", value: "lg" },
|
|
787
|
-
] })] }, `custom-card-${index}`))), customCardsBuilder.cards.length === 0 ? (_jsx(Text, { className: "text-sm text-zinc-500 dark:text-zinc-400", children: "No cards added yet. Click \"Add card\" to start." })) : null] })] }));
|
|
802
|
+
})) }), _jsxs(Div, { className: "space-y-3", children: [_jsxs(Div, { className: "flex items-center justify-between", children: [_jsxs(Text, { className: "text-xs font-semibold uppercase tracking-wide text-zinc-500 dark:text-zinc-400", children: ["Cards (", customCardsBuilder.cards.length, ")"] }), _jsx(Button, { type: "button", variant: "outline", size: "sm", onClick: addCard, children: "Add card" })] }), customCardsBuilder.cards.map((card, index) => renderCardFields(card, index)), customCardsBuilder.cards.length === 0 ? (_jsx(Text, { className: "text-sm text-zinc-500 dark:text-zinc-400", children: "No cards added yet. Click \"Add card\" to start." })) : null] })] }));
|
|
788
803
|
}
|
|
789
804
|
function renderGoogleReviewsBuilder() {
|
|
790
|
-
return (_jsxs(Div, { className:
|
|
805
|
+
return (_jsxs(Div, { className: CLS_SECTION_PANEL, children: [_jsx(Text, { className: "text-sm font-semibold text-zinc-800 dark:text-zinc-200", children: "Google Reviews Builder" }), _jsx(Input, { label: "Google Place ID", value: googleReviewsBuilder.placeId, onChange: (e) => setGoogleReviewsBuilder((prev) => ({ ...prev, placeId: e.target.value })), placeholder: "ChIJ...", helperText: "Find your Place ID at developers.google.com/maps/documentation/places/web-service/place-id" }), _jsx(Input, { label: "Max reviews to show", type: "number", min: 1, max: 20, value: String(googleReviewsBuilder.maxReviews), onChange: (e) => setGoogleReviewsBuilder((prev) => ({
|
|
791
806
|
...prev,
|
|
792
807
|
maxReviews: Math.max(1, Math.min(20, Number(e.target.value) || 6)),
|
|
793
808
|
})) }), _jsx(Select, { label: "Minimum star rating to show", value: String(googleReviewsBuilder.minRating), onValueChange: (value) => setGoogleReviewsBuilder((prev) => ({ ...prev, minRating: Number(value) })), options: [
|
|
@@ -801,17 +816,17 @@ export function AdminSectionsView({ children }) {
|
|
|
801
816
|
] }), _jsx(Checkbox, { checked: googleReviewsBuilder.showRating, label: "Show star rating on each review", onChange: (e) => setGoogleReviewsBuilder((prev) => ({ ...prev, showRating: e.target.checked })) }), _jsx(Checkbox, { checked: googleReviewsBuilder.showDate, label: "Show review date", onChange: (e) => setGoogleReviewsBuilder((prev) => ({ ...prev, showDate: e.target.checked })) }), _jsx(Checkbox, { checked: googleReviewsBuilder.linkToGoogleMaps, label: "Link to Google Maps listing", onChange: (e) => setGoogleReviewsBuilder((prev) => ({ ...prev, linkToGoogleMaps: e.target.checked })) }), googleReviewsBuilder.linkToGoogleMaps ? (_jsx(Input, { label: "Google Maps URL", value: googleReviewsBuilder.googleMapsUrl, onChange: (e) => setGoogleReviewsBuilder((prev) => ({ ...prev, googleMapsUrl: e.target.value })), placeholder: "https://maps.google.com/..." })) : null] }));
|
|
802
817
|
}
|
|
803
818
|
function renderFeaturedBundlesBuilder() {
|
|
804
|
-
return (_jsxs(Div, { className:
|
|
819
|
+
return (_jsxs(Div, { className: CLS_SECTION_PANEL, children: [_jsx(Text, { className: "text-sm font-semibold text-zinc-800 dark:text-zinc-200", children: "Featured Bundles Builder" }), _jsx(Input, { label: "Section title", value: featuredBundlesBuilder.title, onChange: (e) => setFeaturedBundlesBuilder((prev) => ({ ...prev, title: e.target.value })), placeholder: "Curated Bundles" }), _jsx(Input, { label: "Subtitle", value: featuredBundlesBuilder.subtitle, onChange: (e) => setFeaturedBundlesBuilder((prev) => ({ ...prev, subtitle: e.target.value })), placeholder: "Everything you need in one deal" }), _jsx(Input, { label: "Max items", type: "number", min: 1, max: 12, value: String(featuredBundlesBuilder.maxItems), onChange: (e) => setFeaturedBundlesBuilder((prev) => ({
|
|
805
820
|
...prev,
|
|
806
821
|
maxItems: Math.max(1, Math.min(12, Number(e.target.value) || 8)),
|
|
807
|
-
})) }), _jsx(Input, { label: "Filter by store (storeId)", value: featuredBundlesBuilder.storeId, onChange: (e) => setFeaturedBundlesBuilder((prev) => ({ ...prev, storeId: e.target.value })), placeholder: "store-pokemon-palace", helperText: "Leave blank to show bundles from all stores." }), _jsx(Input, { label:
|
|
822
|
+
})) }), _jsx(Input, { label: "Filter by store (storeId)", value: featuredBundlesBuilder.storeId, onChange: (e) => setFeaturedBundlesBuilder((prev) => ({ ...prev, storeId: e.target.value })), placeholder: "store-pokemon-palace", helperText: "Leave blank to show bundles from all stores." }), _jsx(Input, { label: LBL_FILTER_BY_CATEGORY, value: featuredBundlesBuilder.categorySlug, onChange: (e) => setFeaturedBundlesBuilder((prev) => ({ ...prev, categorySlug: e.target.value })), placeholder: "category-trading-cards", helperText: "Leave blank to show bundles from all categories." }), _jsx(Select, { label: "Sort by", value: featuredBundlesBuilder.sortBy, onValueChange: (value) => setFeaturedBundlesBuilder((prev) => ({ ...prev, sortBy: value })), options: [
|
|
808
823
|
{ label: "Newest first", value: "newest" },
|
|
809
824
|
{ label: "Biggest savings", value: "savings-desc" },
|
|
810
825
|
{ label: "Price: low → high", value: "price-asc" },
|
|
811
826
|
] }), _jsx(Checkbox, { checked: featuredBundlesBuilder.showSavingsBadge, label: "Show savings % badge on each bundle", onChange: (e) => setFeaturedBundlesBuilder((prev) => ({ ...prev, showSavingsBadge: e.target.checked })) }), _jsx(Text, { className: "text-xs text-zinc-500 dark:text-zinc-400", children: "The bundles collection lands later in the bundle / prize-draw work; until then this section renders an empty state." })] }));
|
|
812
827
|
}
|
|
813
828
|
function renderPrizeDrawsBuilder() {
|
|
814
|
-
return (_jsxs(Div, { className:
|
|
829
|
+
return (_jsxs(Div, { className: CLS_SECTION_PANEL, children: [_jsx(Text, { className: "text-sm font-semibold text-zinc-800 dark:text-zinc-200", children: "Prize Draws Builder" }), _jsx(Input, { label: "Section title", value: prizeDrawsBuilder.title, onChange: (e) => setPrizeDrawsBuilder((prev) => ({ ...prev, title: e.target.value })), placeholder: "Prize Draws" }), _jsx(Input, { label: "Subtitle", value: prizeDrawsBuilder.subtitle, onChange: (e) => setPrizeDrawsBuilder((prev) => ({ ...prev, subtitle: e.target.value })), placeholder: "Enter for a chance to win rare collectibles" }), _jsx(Input, { label: "Max items", type: "number", min: 1, max: 12, value: String(prizeDrawsBuilder.maxItems), onChange: (e) => setPrizeDrawsBuilder((prev) => ({
|
|
815
830
|
...prev,
|
|
816
831
|
maxItems: Math.max(1, Math.min(12, Number(e.target.value) || 6)),
|
|
817
832
|
})) }), _jsx(Input, { label: "Filter by store (storeId)", value: prizeDrawsBuilder.storeId, onChange: (e) => setPrizeDrawsBuilder((prev) => ({ ...prev, storeId: e.target.value })), placeholder: "Leave blank for all stores" }), _jsx(Select, { label: "Reveal status", value: prizeDrawsBuilder.revealStatus, onValueChange: (value) => setPrizeDrawsBuilder((prev) => ({ ...prev, revealStatus: value })), options: [
|
|
@@ -821,7 +836,7 @@ export function AdminSectionsView({ children }) {
|
|
|
821
836
|
] }), _jsx(Checkbox, { checked: prizeDrawsBuilder.showCountdown, label: "Show countdown to reveal window", onChange: (e) => setPrizeDrawsBuilder((prev) => ({ ...prev, showCountdown: e.target.checked })) }), _jsx(Checkbox, { checked: prizeDrawsBuilder.showEntriesRemaining, label: "Show entries-remaining bar", onChange: (e) => setPrizeDrawsBuilder((prev) => ({ ...prev, showEntriesRemaining: e.target.checked })) }), _jsx(Text, { className: "text-xs text-zinc-500 dark:text-zinc-400", children: "Prize-draw listing type is added with the prize-draw feature; until then this section renders an empty state." })] }));
|
|
822
837
|
}
|
|
823
838
|
function renderEventRafflesBuilder() {
|
|
824
|
-
return (_jsxs(Div, { className:
|
|
839
|
+
return (_jsxs(Div, { className: CLS_SECTION_PANEL, children: [_jsx(Text, { className: "text-sm font-semibold text-zinc-800 dark:text-zinc-200", children: "Event Raffles Builder" }), _jsx(Input, { label: "Section title", value: eventRafflesBuilder.title, onChange: (e) => setEventRafflesBuilder((prev) => ({ ...prev, title: e.target.value })), placeholder: "Live Raffles & Spin Wheels" }), _jsx(Input, { label: "Subtitle", value: eventRafflesBuilder.subtitle, onChange: (e) => setEventRafflesBuilder((prev) => ({ ...prev, subtitle: e.target.value })), placeholder: "Participate in community events and win prizes" }), _jsx(Input, { label: "Max items", type: "number", min: 1, max: 8, value: String(eventRafflesBuilder.maxItems), onChange: (e) => setEventRafflesBuilder((prev) => ({
|
|
825
840
|
...prev,
|
|
826
841
|
maxItems: Math.max(1, Math.min(8, Number(e.target.value) || 4)),
|
|
827
842
|
})) }), _jsx(Select, { label: "Raffle type", value: eventRafflesBuilder.raffleType, onValueChange: (value) => setEventRafflesBuilder((prev) => ({ ...prev, raffleType: value })), options: [
|
|
@@ -830,21 +845,36 @@ export function AdminSectionsView({ children }) {
|
|
|
830
845
|
{ label: "Spin wheel only", value: "spin_wheel" },
|
|
831
846
|
] }), _jsx(Checkbox, { checked: eventRafflesBuilder.showEntryCount, label: "Show entry count on each event", onChange: (e) => setEventRafflesBuilder((prev) => ({ ...prev, showEntryCount: e.target.checked })) }), _jsx(Checkbox, { checked: eventRafflesBuilder.showCountdown, label: "Show countdown to event start/end", onChange: (e) => setEventRafflesBuilder((prev) => ({ ...prev, showCountdown: e.target.checked })) }), _jsx(Text, { className: "text-xs text-zinc-500 dark:text-zinc-400", children: "The hasRaffle flag on events ships with the raffle feature; until then this section renders an empty state." })] }));
|
|
832
847
|
}
|
|
848
|
+
const COLLECTION_CARD_TYPE_OPTIONS = [
|
|
849
|
+
{ label: "Products", value: "products" },
|
|
850
|
+
{ label: "Auctions", value: "auctions" },
|
|
851
|
+
{ label: "Pre-orders", value: "pre-orders" },
|
|
852
|
+
{ label: "Stores", value: "stores" },
|
|
853
|
+
{ label: "Events", value: "events" },
|
|
854
|
+
{ label: "Blog posts", value: "blog-posts" },
|
|
855
|
+
{ label: "Reviews", value: "reviews" },
|
|
856
|
+
{ label: "Brands", value: "brands" },
|
|
857
|
+
{ label: "Categories", value: "categories" },
|
|
858
|
+
];
|
|
859
|
+
function renderCollectionEntry(entry, idx) {
|
|
860
|
+
return (_jsxs(Div, { className: "space-y-2 rounded-lg border border-zinc-200 p-3 dark:border-slate-700", children: [_jsx(Select, { label: `Collection ${idx + 1} type`, value: entry.type, onValueChange: (value) => setCollectionCardsBuilder((prev) => ({
|
|
861
|
+
...prev,
|
|
862
|
+
collections: prev.collections.map((c, i) => i === idx ? { ...c, type: value } : c),
|
|
863
|
+
})), options: COLLECTION_CARD_TYPE_OPTIONS }), _jsx(Input, { label: "Display label (optional)", value: entry.label, onChange: (e) => setCollectionCardsBuilder((prev) => ({
|
|
864
|
+
...prev,
|
|
865
|
+
collections: prev.collections.map((c, i) => (i === idx ? { ...c, label: e.target.value } : c)),
|
|
866
|
+
})), placeholder: "Leave blank to use the type name" }), _jsx(Input, { label: "Items in this collection", type: "number", min: 1, max: 20, value: String(entry.limit), onChange: (e) => setCollectionCardsBuilder((prev) => ({
|
|
867
|
+
...prev,
|
|
868
|
+
collections: prev.collections.map((c, i) => i === idx ? { ...c, limit: Math.max(1, Math.min(20, Number(e.target.value) || 4)) } : c),
|
|
869
|
+
})) }), _jsx(Button, { type: "button", variant: "secondary", onClick: () => setCollectionCardsBuilder((prev) => ({
|
|
870
|
+
...prev,
|
|
871
|
+
collections: prev.collections.filter((_, i) => i !== idx),
|
|
872
|
+
})), children: "Remove" })] }, `collection-${idx}`));
|
|
873
|
+
}
|
|
833
874
|
function renderCollectionCardsBuilder() {
|
|
834
|
-
const COLLECTION_TYPE_OPTIONS = [
|
|
835
|
-
{ label: "Products", value: "products" },
|
|
836
|
-
{ label: "Auctions", value: "auctions" },
|
|
837
|
-
{ label: "Pre-orders", value: "pre-orders" },
|
|
838
|
-
{ label: "Stores", value: "stores" },
|
|
839
|
-
{ label: "Events", value: "events" },
|
|
840
|
-
{ label: "Blog posts", value: "blog-posts" },
|
|
841
|
-
{ label: "Reviews", value: "reviews" },
|
|
842
|
-
{ label: "Brands", value: "brands" },
|
|
843
|
-
{ label: "Categories", value: "categories" },
|
|
844
|
-
];
|
|
845
875
|
const entries = collectionCardsBuilder.collections;
|
|
846
876
|
const canAdd = entries.length < 3;
|
|
847
|
-
return (_jsxs(Div, { className:
|
|
877
|
+
return (_jsxs(Div, { className: CLS_SECTION_PANEL, children: [_jsx(Text, { className: "text-sm font-semibold text-zinc-800 dark:text-zinc-200", children: "Collection Cards Builder" }), _jsx(Input, { label: "Section title", value: collectionCardsBuilder.title, onChange: (e) => setCollectionCardsBuilder((prev) => ({ ...prev, title: e.target.value })), placeholder: "Featured Collections" }), _jsx(Input, { label: "Subtitle", value: collectionCardsBuilder.subtitle, onChange: (e) => setCollectionCardsBuilder((prev) => ({ ...prev, subtitle: e.target.value })), placeholder: "Hand-picked across the marketplace" }), _jsx(Select, { label: "Layout", value: collectionCardsBuilder.layout, onValueChange: (value) => setCollectionCardsBuilder((prev) => ({ ...prev, layout: value })), options: [
|
|
848
878
|
{ label: "Carousel", value: "carousel" },
|
|
849
879
|
{ label: "Grid", value: "grid" },
|
|
850
880
|
{ label: "Mixed row", value: "mixed-row" },
|
|
@@ -858,19 +888,7 @@ export function AdminSectionsView({ children }) {
|
|
|
858
888
|
] }), _jsx(Input, { label: "Max total items", type: "number", min: 4, max: 20, value: String(collectionCardsBuilder.maxItems), onChange: (e) => setCollectionCardsBuilder((prev) => ({
|
|
859
889
|
...prev,
|
|
860
890
|
maxItems: Math.max(4, Math.min(20, Number(e.target.value) || 12)),
|
|
861
|
-
})) }), _jsx(Checkbox, { checked: collectionCardsBuilder.showCollectionTabs, label: "Show collection tabs (filter chips)", onChange: (e) => setCollectionCardsBuilder((prev) => ({ ...prev, showCollectionTabs: e.target.checked })) }), _jsxs(Div, { className: "space-y-3", children: [_jsxs(Text, { className: "text-sm font-semibold text-zinc-800 dark:text-zinc-200", children: ["Collections (", entries.length, "/3)"] }), entries.map((entry, idx) => (
|
|
862
|
-
...prev,
|
|
863
|
-
collections: prev.collections.map((c, i) => i === idx ? { ...c, type: value } : c),
|
|
864
|
-
})), options: COLLECTION_TYPE_OPTIONS }), _jsx(Input, { label: "Display label (optional)", value: entry.label, onChange: (e) => setCollectionCardsBuilder((prev) => ({
|
|
865
|
-
...prev,
|
|
866
|
-
collections: prev.collections.map((c, i) => (i === idx ? { ...c, label: e.target.value } : c)),
|
|
867
|
-
})), placeholder: "Leave blank to use the type name" }), _jsx(Input, { label: "Items in this collection", type: "number", min: 1, max: 20, value: String(entry.limit), onChange: (e) => setCollectionCardsBuilder((prev) => ({
|
|
868
|
-
...prev,
|
|
869
|
-
collections: prev.collections.map((c, i) => i === idx ? { ...c, limit: Math.max(1, Math.min(20, Number(e.target.value) || 4)) } : c),
|
|
870
|
-
})) }), _jsx(Button, { type: "button", variant: "secondary", onClick: () => setCollectionCardsBuilder((prev) => ({
|
|
871
|
-
...prev,
|
|
872
|
-
collections: prev.collections.filter((_, i) => i !== idx),
|
|
873
|
-
})), children: "Remove" })] }, `collection-${idx}`))), canAdd ? (_jsx(Button, { type: "button", variant: "secondary", onClick: () => setCollectionCardsBuilder((prev) => ({
|
|
891
|
+
})) }), _jsx(Checkbox, { checked: collectionCardsBuilder.showCollectionTabs, label: "Show collection tabs (filter chips)", onChange: (e) => setCollectionCardsBuilder((prev) => ({ ...prev, showCollectionTabs: e.target.checked })) }), _jsxs(Div, { className: "space-y-3", children: [_jsxs(Text, { className: "text-sm font-semibold text-zinc-800 dark:text-zinc-200", children: ["Collections (", entries.length, "/3)"] }), entries.map((entry, idx) => renderCollectionEntry(entry, idx)), canAdd ? (_jsx(Button, { type: "button", variant: "secondary", onClick: () => setCollectionCardsBuilder((prev) => ({
|
|
874
892
|
...prev,
|
|
875
893
|
collections: [
|
|
876
894
|
...prev.collections,
|
|
@@ -879,7 +897,7 @@ export function AdminSectionsView({ children }) {
|
|
|
879
897
|
})), children: "+ Add collection" })) : (_jsx(Text, { className: "text-xs text-zinc-500 dark:text-zinc-400", children: "Maximum of 3 collections per section." }))] }), _jsx(Text, { className: "text-xs text-zinc-500 dark:text-zinc-400", children: "Data fetching wires into the per-resource repositories \u2014 the section renders an empty state until the wiring lands." })] }));
|
|
880
898
|
}
|
|
881
899
|
function renderSocialFeedBuilder() {
|
|
882
|
-
return (_jsxs(Div, { className:
|
|
900
|
+
return (_jsxs(Div, { className: CLS_SECTION_PANEL, children: [_jsx(Text, { className: "text-sm font-semibold text-zinc-800 dark:text-zinc-200", children: "Social Feed Builder" }), _jsx(Input, { label: "Section title", value: socialFeedBuilder.title, onChange: (e) => setSocialFeedBuilder((prev) => ({ ...prev, title: e.target.value })), placeholder: "LetItRip on Instagram" }), _jsx(Input, { label: "Subtitle", value: socialFeedBuilder.subtitle, onChange: (e) => setSocialFeedBuilder((prev) => ({ ...prev, subtitle: e.target.value })), placeholder: "Follow us for daily collection showcases" }), _jsx(Select, { label: "Platform", value: socialFeedBuilder.platform, onValueChange: (v) => setSocialFeedBuilder((prev) => ({ ...prev, platform: v })), options: [
|
|
883
901
|
{ label: "Instagram", value: "instagram" },
|
|
884
902
|
{ label: "Facebook", value: "facebook" },
|
|
885
903
|
{ label: "TikTok", value: "tiktok" },
|
|
@@ -942,12 +960,7 @@ export function AdminSectionsView({ children }) {
|
|
|
942
960
|
}, [sections]);
|
|
943
961
|
const hasReorderChanges = reorderDraft.some((item) => sectionOrderMap.get(item.id) !== item.order);
|
|
944
962
|
const canUndoReorderChanges = reorderUndoStack.length > 0;
|
|
945
|
-
return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "py-4 px-3 sm:px-4", children: [_jsxs(Div, { className: "mb-4 flex items-center justify-between gap-3", children: [_jsxs(Div, { children: [_jsx(Text, { className: "text-base font-semibold text-zinc-900 dark:text-zinc-100", children: "Homepage Sections" }), _jsx(Text, { className: "text-sm text-zinc-500 dark:text-zinc-400", children: "Manage homepage sections and their display order" })] }), _jsxs(Div, { className: "flex items-center gap-2", children: [_jsx(Button, { type: "button", variant: "outline", size: "sm", onClick: () => setSeedResetOpen(true), children: "Reset seed data" }), _jsx(Button, { type: "button", variant: "primary", size: "sm", onClick: () => setIsModalOpen(true), children: "Manage Sections" })] })] }), errorMessage && (_jsx("div", { className: "mb-4 rounded-xl border border-red-200 bg-red-50 px-4 py-3 text-sm text-red-700 dark:border-red-900/60 dark:bg-red-950/40 dark:text-red-200", children: errorMessage })), _jsx(DataTable, { rows: rows, isLoading: isLoading, emptyLabel: "No sections found" })] }), _jsxs(Div, { className: "mt-4 space-y-3 rounded-xl border border-zinc-200 bg-white p-4 dark:border-slate-700 dark:bg-slate-900", children: [_jsxs(Div, { className: "flex items-center justify-between gap-3", children: [_jsx(Text, { className: "text-sm font-semibold text-zinc-900 dark:text-zinc-100", children: "Reorder Sections" }), _jsxs(Div, { className: "flex items-center gap-2", children: [_jsx(Button, { type: "button", variant: "outline", size: "sm", onClick: reindexDraft, disabled: reorderSections.isPending || reorderDraft.length === 0, children: "Reindex 1..N" }), _jsx(Button, { type: "button", variant: "outline", size: "sm", onClick: undoReorderChange, disabled: reorderSections.isPending || !canUndoReorderChanges, children: "Undo unsaved" }), _jsx(Button, { type: "button", variant: "outline", size: "sm", onClick: resetToServerOrder, disabled: reorderSections.isPending || !hasReorderChanges, children: "Reset to server" }), _jsx(Button, { type: "button", variant: "primary", size: "sm", onClick: () => reorderSections.mutate(), disabled: !hasReorderChanges || reorderSections.isPending, children: reorderSections.isPending ? "Saving order..." : "Save order" })] })] }), reorderDraft.length === 0 ? (_jsx(Text, { className: "text-sm text-zinc-500 dark:text-zinc-400", children: "No sections to reorder." })) : (_jsx(Div, { className: "space-y-2", children: reorderDraft.map((item, index) => (_jsxs(Div, { className: "grid grid-cols-[auto_1fr_auto_auto_auto] items-center gap-2 rounded-md border border-zinc-200 p-2 dark:border-slate-700", draggable: true, onDragStart: () => setDragIndex(index), onDragOver: (event) => event.preventDefault(), onDrop: () => {
|
|
946
|
-
if (dragIndex !== null) {
|
|
947
|
-
moveItemToIndex(dragIndex, index);
|
|
948
|
-
}
|
|
949
|
-
setDragIndex(null);
|
|
950
|
-
}, onDragEnd: () => setDragIndex(null), children: [_jsx(Text, { className: "text-sm font-semibold text-zinc-500 dark:text-zinc-400", children: "\u2261" }), _jsxs(Text, { className: "text-sm text-zinc-800 dark:text-zinc-200", children: [item.type, " #", item.order] }), _jsx(Input, { type: "number", min: 1, max: reorderDraft.length, value: String(item.order), onChange: (event) => updateReorderItemOrder(index, Number(event.target.value) || 1), className: "w-24" }), _jsx(Button, { type: "button", variant: "outline", size: "sm", onClick: () => moveReorderItem(index, -1), disabled: index === 0, children: "Up" }), _jsx(Button, { type: "button", variant: "outline", size: "sm", onClick: () => moveReorderItem(index, 1), disabled: index === reorderDraft.length - 1, children: "Down" })] }, `reorder-${item.id}`))) }))] }), _jsx(ConfirmDeleteModal, { isOpen: seedResetOpen, onClose: () => setSeedResetOpen(false), onConfirm: () => resetSeed.mutate(), title: "Reset homepage sections seed data?", message: "This will reload the 19 default homepage sections from seed data. Any manual changes made in Firestore will be overwritten.", confirmText: "Reset seed", cancelText: "Cancel", isDeleting: resetSeed.isPending, variant: "danger" }), _jsx(Modal, { isOpen: isModalOpen, onClose: () => setIsModalOpen(false), title: "Manage Homepage Section", size: "lg", children: _jsxs(Form, { className: "space-y-4", onSubmit: (event) => {
|
|
963
|
+
return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "py-4 px-3 sm:px-4", children: [_jsxs(Div, { className: "mb-4 flex items-center justify-between gap-3", children: [_jsxs(Div, { children: [_jsx(Text, { className: "text-base font-semibold text-zinc-900 dark:text-zinc-100", children: "Homepage Sections" }), _jsx(Text, { className: "text-sm text-zinc-500 dark:text-zinc-400", children: "Manage homepage sections and their display order" })] }), _jsxs(Div, { className: "flex items-center gap-2", children: [_jsx(Button, { type: "button", variant: "outline", size: "sm", onClick: () => setSeedResetOpen(true), children: "Reset seed data" }), _jsx(Button, { type: "button", variant: "primary", size: "sm", onClick: () => setIsModalOpen(true), children: "Manage Sections" })] })] }), errorMessage && (_jsx("div", { className: "mb-4 rounded-xl border border-red-200 bg-red-50 px-4 py-3 text-sm text-red-700 dark:border-red-900/60 dark:bg-red-950/40 dark:text-red-200", children: errorMessage })), _jsx(DataTable, { rows: rows, isLoading: isLoading, emptyLabel: "No sections found" })] }), _jsxs(Div, { className: "mt-4 space-y-3 rounded-xl border border-zinc-200 bg-white p-4 dark:border-slate-700 dark:bg-slate-900", children: [_jsxs(Div, { className: "flex items-center justify-between gap-3", children: [_jsx(Text, { className: "text-sm font-semibold text-zinc-900 dark:text-zinc-100", children: "Reorder Sections" }), _jsxs(Div, { className: "flex items-center gap-2", children: [_jsx(Button, { type: "button", variant: "outline", size: "sm", onClick: reindexDraft, disabled: reorderSections.isPending || reorderDraft.length === 0, children: "Reindex 1..N" }), _jsx(Button, { type: "button", variant: "outline", size: "sm", onClick: undoReorderChange, disabled: reorderSections.isPending || !canUndoReorderChanges, children: "Undo unsaved" }), _jsx(Button, { type: "button", variant: "outline", size: "sm", onClick: resetToServerOrder, disabled: reorderSections.isPending || !hasReorderChanges, children: "Reset to server" }), _jsx(Button, { type: "button", variant: "primary", size: "sm", onClick: () => reorderSections.mutate(), disabled: !hasReorderChanges || reorderSections.isPending, children: reorderSections.isPending ? "Saving order..." : "Save order" })] })] }), reorderDraft.length === 0 ? (_jsx(Text, { className: "text-sm text-zinc-500 dark:text-zinc-400", children: "No sections to reorder." })) : (_jsx(Div, { className: "space-y-2", children: reorderDraft.map((item, index) => (_jsxs(Div, { className: "grid grid-cols-[auto_1fr_auto_auto_auto] items-center gap-2 rounded-md border border-zinc-200 p-2 dark:border-slate-700", draggable: true, onDragStart: () => setDragIndex(index), onDragOver: (event) => event.preventDefault(), onDrop: () => handleReorderDrop(index), onDragEnd: () => setDragIndex(null), children: [_jsx(Text, { className: "text-sm font-semibold text-zinc-500 dark:text-zinc-400", children: "\u2261" }), _jsxs(Text, { className: "text-sm text-zinc-800 dark:text-zinc-200", children: [item.type, " #", item.order] }), _jsx(Input, { type: "number", min: 1, max: reorderDraft.length, value: String(item.order), onChange: (event) => updateReorderItemOrder(index, Number(event.target.value) || 1), className: "w-24" }), _jsx(Button, { type: "button", variant: "outline", size: "sm", onClick: () => moveReorderItem(index, -1), disabled: index === 0, children: "Up" }), _jsx(Button, { type: "button", variant: "outline", size: "sm", onClick: () => moveReorderItem(index, 1), disabled: index === reorderDraft.length - 1, children: "Down" })] }, `reorder-${item.id}`))) }))] }), _jsx(ConfirmDeleteModal, { isOpen: seedResetOpen, onClose: () => setSeedResetOpen(false), onConfirm: () => resetSeed.mutate(), title: "Reset homepage sections seed data?", message: "This will reload the 19 default homepage sections from seed data. Any manual changes made in Firestore will be overwritten.", confirmText: "Reset seed", cancelText: "Cancel", isDeleting: resetSeed.isPending, variant: "danger" }), _jsx(Modal, { isOpen: isModalOpen, onClose: () => setIsModalOpen(false), title: "Manage Homepage Section", size: "lg", children: _jsxs(Form, { className: "space-y-4", onSubmit: (event) => {
|
|
951
964
|
event.preventDefault();
|
|
952
965
|
saveSection.mutate();
|
|
953
966
|
}, children: [_jsx(Select, { label: "Mode", value: mode, onValueChange: (value) => setMode(value), options: [
|