@mohasinac/appkit 2.7.27 → 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/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 +54 -78
- package/dist/features/layout/BottomActions.js +43 -48
- 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 +1 -1
|
@@ -90,14 +90,14 @@ export declare const eventItemSchema: z.ZodObject<{
|
|
|
90
90
|
}, "strip", z.ZodTypeAny, {
|
|
91
91
|
type: "video" | "image" | "file";
|
|
92
92
|
url: string;
|
|
93
|
-
source?: "
|
|
93
|
+
source?: "upload" | "youtube" | "external" | undefined;
|
|
94
94
|
alt?: string | undefined;
|
|
95
95
|
thumbnailUrl?: string | undefined;
|
|
96
96
|
youtubeId?: string | undefined;
|
|
97
97
|
}, {
|
|
98
98
|
type: "video" | "image" | "file";
|
|
99
99
|
url: string;
|
|
100
|
-
source?: "
|
|
100
|
+
source?: "upload" | "youtube" | "external" | undefined;
|
|
101
101
|
alt?: string | undefined;
|
|
102
102
|
thumbnailUrl?: string | undefined;
|
|
103
103
|
youtubeId?: string | undefined;
|
|
@@ -107,7 +107,7 @@ export declare const eventItemSchema: z.ZodObject<{
|
|
|
107
107
|
}, string>]>>>, {
|
|
108
108
|
type: "video" | "image" | "file";
|
|
109
109
|
url: string;
|
|
110
|
-
source?: "
|
|
110
|
+
source?: "upload" | "youtube" | "external" | undefined;
|
|
111
111
|
alt?: string | undefined;
|
|
112
112
|
thumbnailUrl?: string | undefined;
|
|
113
113
|
youtubeId?: string | undefined;
|
|
@@ -117,7 +117,7 @@ export declare const eventItemSchema: z.ZodObject<{
|
|
|
117
117
|
} | null, string | {
|
|
118
118
|
type: "video" | "image" | "file";
|
|
119
119
|
url: string;
|
|
120
|
-
source?: "
|
|
120
|
+
source?: "upload" | "youtube" | "external" | undefined;
|
|
121
121
|
alt?: string | undefined;
|
|
122
122
|
thumbnailUrl?: string | undefined;
|
|
123
123
|
youtubeId?: string | undefined;
|
|
@@ -133,14 +133,14 @@ export declare const eventItemSchema: z.ZodObject<{
|
|
|
133
133
|
}, "strip", z.ZodTypeAny, {
|
|
134
134
|
type: "video" | "image" | "file";
|
|
135
135
|
url: string;
|
|
136
|
-
source?: "
|
|
136
|
+
source?: "upload" | "youtube" | "external" | undefined;
|
|
137
137
|
alt?: string | undefined;
|
|
138
138
|
thumbnailUrl?: string | undefined;
|
|
139
139
|
youtubeId?: string | undefined;
|
|
140
140
|
}, {
|
|
141
141
|
type: "video" | "image" | "file";
|
|
142
142
|
url: string;
|
|
143
|
-
source?: "
|
|
143
|
+
source?: "upload" | "youtube" | "external" | undefined;
|
|
144
144
|
alt?: string | undefined;
|
|
145
145
|
thumbnailUrl?: string | undefined;
|
|
146
146
|
youtubeId?: string | undefined;
|
|
@@ -155,14 +155,14 @@ export declare const eventItemSchema: z.ZodObject<{
|
|
|
155
155
|
}, "strip", z.ZodTypeAny, {
|
|
156
156
|
type: "video" | "image" | "file";
|
|
157
157
|
url: string;
|
|
158
|
-
source?: "
|
|
158
|
+
source?: "upload" | "youtube" | "external" | undefined;
|
|
159
159
|
alt?: string | undefined;
|
|
160
160
|
thumbnailUrl?: string | undefined;
|
|
161
161
|
youtubeId?: string | undefined;
|
|
162
162
|
}, {
|
|
163
163
|
type: "video" | "image" | "file";
|
|
164
164
|
url: string;
|
|
165
|
-
source?: "
|
|
165
|
+
source?: "upload" | "youtube" | "external" | undefined;
|
|
166
166
|
alt?: string | undefined;
|
|
167
167
|
thumbnailUrl?: string | undefined;
|
|
168
168
|
youtubeId?: string | undefined;
|
|
@@ -177,14 +177,14 @@ export declare const eventItemSchema: z.ZodObject<{
|
|
|
177
177
|
}, "strip", z.ZodTypeAny, {
|
|
178
178
|
type: "video" | "image" | "file";
|
|
179
179
|
url: string;
|
|
180
|
-
source?: "
|
|
180
|
+
source?: "upload" | "youtube" | "external" | undefined;
|
|
181
181
|
alt?: string | undefined;
|
|
182
182
|
thumbnailUrl?: string | undefined;
|
|
183
183
|
youtubeId?: string | undefined;
|
|
184
184
|
}, {
|
|
185
185
|
type: "video" | "image" | "file";
|
|
186
186
|
url: string;
|
|
187
|
-
source?: "
|
|
187
|
+
source?: "upload" | "youtube" | "external" | undefined;
|
|
188
188
|
alt?: string | undefined;
|
|
189
189
|
thumbnailUrl?: string | undefined;
|
|
190
190
|
youtubeId?: string | undefined;
|
|
@@ -269,17 +269,17 @@ export declare const eventItemSchema: z.ZodObject<{
|
|
|
269
269
|
status: "draft" | "ended" | "active" | "paused";
|
|
270
270
|
type: "offer" | "feedback" | "sale" | "poll" | "survey";
|
|
271
271
|
title: string;
|
|
272
|
+
description: string;
|
|
272
273
|
stats: {
|
|
273
274
|
totalEntries: number;
|
|
274
275
|
approvedEntries: number;
|
|
275
276
|
flaggedEntries: number;
|
|
276
277
|
};
|
|
277
|
-
description: string;
|
|
278
278
|
createdBy: string;
|
|
279
279
|
coverImage: {
|
|
280
280
|
type: "video" | "image" | "file";
|
|
281
281
|
url: string;
|
|
282
|
-
source?: "
|
|
282
|
+
source?: "upload" | "youtube" | "external" | undefined;
|
|
283
283
|
alt?: string | undefined;
|
|
284
284
|
thumbnailUrl?: string | undefined;
|
|
285
285
|
youtubeId?: string | undefined;
|
|
@@ -292,7 +292,7 @@ export declare const eventItemSchema: z.ZodObject<{
|
|
|
292
292
|
additionalImages: {
|
|
293
293
|
type: "video" | "image" | "file";
|
|
294
294
|
url: string;
|
|
295
|
-
source?: "
|
|
295
|
+
source?: "upload" | "youtube" | "external" | undefined;
|
|
296
296
|
alt?: string | undefined;
|
|
297
297
|
thumbnailUrl?: string | undefined;
|
|
298
298
|
youtubeId?: string | undefined;
|
|
@@ -300,7 +300,7 @@ export declare const eventItemSchema: z.ZodObject<{
|
|
|
300
300
|
eventImages: {
|
|
301
301
|
type: "video" | "image" | "file";
|
|
302
302
|
url: string;
|
|
303
|
-
source?: "
|
|
303
|
+
source?: "upload" | "youtube" | "external" | undefined;
|
|
304
304
|
alt?: string | undefined;
|
|
305
305
|
thumbnailUrl?: string | undefined;
|
|
306
306
|
youtubeId?: string | undefined;
|
|
@@ -308,7 +308,7 @@ export declare const eventItemSchema: z.ZodObject<{
|
|
|
308
308
|
winnerImages: {
|
|
309
309
|
type: "video" | "image" | "file";
|
|
310
310
|
url: string;
|
|
311
|
-
source?: "
|
|
311
|
+
source?: "upload" | "youtube" | "external" | undefined;
|
|
312
312
|
alt?: string | undefined;
|
|
313
313
|
thumbnailUrl?: string | undefined;
|
|
314
314
|
youtubeId?: string | undefined;
|
|
@@ -340,19 +340,19 @@ export declare const eventItemSchema: z.ZodObject<{
|
|
|
340
340
|
status: "draft" | "ended" | "active" | "paused";
|
|
341
341
|
type: "offer" | "feedback" | "sale" | "poll" | "survey";
|
|
342
342
|
title: string;
|
|
343
|
+
description: string;
|
|
343
344
|
stats: {
|
|
344
345
|
totalEntries: number;
|
|
345
346
|
approvedEntries: number;
|
|
346
347
|
flaggedEntries: number;
|
|
347
348
|
};
|
|
348
|
-
description: string;
|
|
349
349
|
createdBy: string;
|
|
350
350
|
startsAt: string;
|
|
351
351
|
endsAt: string;
|
|
352
352
|
coverImage?: string | {
|
|
353
353
|
type: "video" | "image" | "file";
|
|
354
354
|
url: string;
|
|
355
|
-
source?: "
|
|
355
|
+
source?: "upload" | "youtube" | "external" | undefined;
|
|
356
356
|
alt?: string | undefined;
|
|
357
357
|
thumbnailUrl?: string | undefined;
|
|
358
358
|
youtubeId?: string | undefined;
|
|
@@ -360,7 +360,7 @@ export declare const eventItemSchema: z.ZodObject<{
|
|
|
360
360
|
additionalImages?: {
|
|
361
361
|
type: "video" | "image" | "file";
|
|
362
362
|
url: string;
|
|
363
|
-
source?: "
|
|
363
|
+
source?: "upload" | "youtube" | "external" | undefined;
|
|
364
364
|
alt?: string | undefined;
|
|
365
365
|
thumbnailUrl?: string | undefined;
|
|
366
366
|
youtubeId?: string | undefined;
|
|
@@ -369,7 +369,7 @@ export declare const eventItemSchema: z.ZodObject<{
|
|
|
369
369
|
eventImages?: {
|
|
370
370
|
type: "video" | "image" | "file";
|
|
371
371
|
url: string;
|
|
372
|
-
source?: "
|
|
372
|
+
source?: "upload" | "youtube" | "external" | undefined;
|
|
373
373
|
alt?: string | undefined;
|
|
374
374
|
thumbnailUrl?: string | undefined;
|
|
375
375
|
youtubeId?: string | undefined;
|
|
@@ -377,7 +377,7 @@ export declare const eventItemSchema: z.ZodObject<{
|
|
|
377
377
|
winnerImages?: {
|
|
378
378
|
type: "video" | "image" | "file";
|
|
379
379
|
url: string;
|
|
380
|
-
source?: "
|
|
380
|
+
source?: "upload" | "youtube" | "external" | undefined;
|
|
381
381
|
alt?: string | undefined;
|
|
382
382
|
thumbnailUrl?: string | undefined;
|
|
383
383
|
youtubeId?: string | undefined;
|
|
@@ -26,10 +26,10 @@ export declare const faqCreateSchema: z.ZodEffects<z.ZodObject<{
|
|
|
26
26
|
variables: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
27
27
|
template: z.ZodOptional<z.ZodString>;
|
|
28
28
|
}, "strip", z.ZodTypeAny, {
|
|
29
|
+
category: string;
|
|
29
30
|
order: number;
|
|
30
31
|
priority: number;
|
|
31
32
|
isActive: boolean;
|
|
32
|
-
category: string;
|
|
33
33
|
question: string;
|
|
34
34
|
showInFooter: boolean;
|
|
35
35
|
showOnHomepage: boolean;
|
|
@@ -51,10 +51,10 @@ export declare const faqCreateSchema: z.ZodEffects<z.ZodObject<{
|
|
|
51
51
|
format?: "html" | "plain" | "markdown" | undefined;
|
|
52
52
|
};
|
|
53
53
|
template?: string | undefined;
|
|
54
|
+
tags?: string[] | undefined;
|
|
54
55
|
order?: number | undefined;
|
|
55
56
|
priority?: number | undefined;
|
|
56
57
|
isActive?: boolean | undefined;
|
|
57
|
-
tags?: string[] | undefined;
|
|
58
58
|
variables?: Record<string, string> | undefined;
|
|
59
59
|
showInFooter?: boolean | undefined;
|
|
60
60
|
showOnHomepage?: boolean | undefined;
|
|
@@ -62,10 +62,10 @@ export declare const faqCreateSchema: z.ZodEffects<z.ZodObject<{
|
|
|
62
62
|
relatedFAQs?: string[] | undefined;
|
|
63
63
|
useSiteSettings?: boolean | undefined;
|
|
64
64
|
}>, {
|
|
65
|
+
category: string;
|
|
65
66
|
order: number;
|
|
66
67
|
priority: number;
|
|
67
68
|
isActive: boolean;
|
|
68
|
-
category: string;
|
|
69
69
|
question: string;
|
|
70
70
|
showInFooter: boolean;
|
|
71
71
|
showOnHomepage: boolean;
|
|
@@ -87,10 +87,10 @@ export declare const faqCreateSchema: z.ZodEffects<z.ZodObject<{
|
|
|
87
87
|
format?: "html" | "plain" | "markdown" | undefined;
|
|
88
88
|
};
|
|
89
89
|
template?: string | undefined;
|
|
90
|
+
tags?: string[] | undefined;
|
|
90
91
|
order?: number | undefined;
|
|
91
92
|
priority?: number | undefined;
|
|
92
93
|
isActive?: boolean | undefined;
|
|
93
|
-
tags?: string[] | undefined;
|
|
94
94
|
variables?: Record<string, string> | undefined;
|
|
95
95
|
showInFooter?: boolean | undefined;
|
|
96
96
|
showOnHomepage?: boolean | undefined;
|
|
@@ -124,11 +124,11 @@ export declare const faqUpdateSchema: z.ZodObject<{
|
|
|
124
124
|
template: z.ZodOptional<z.ZodOptional<z.ZodString>>;
|
|
125
125
|
}, "strip", z.ZodTypeAny, {
|
|
126
126
|
template?: string | undefined;
|
|
127
|
+
category?: string | undefined;
|
|
128
|
+
tags?: string[] | undefined;
|
|
127
129
|
order?: number | undefined;
|
|
128
130
|
priority?: number | undefined;
|
|
129
131
|
isActive?: boolean | undefined;
|
|
130
|
-
category?: string | undefined;
|
|
131
|
-
tags?: string[] | undefined;
|
|
132
132
|
variables?: Record<string, string> | undefined;
|
|
133
133
|
question?: string | undefined;
|
|
134
134
|
showInFooter?: boolean | undefined;
|
|
@@ -142,11 +142,11 @@ export declare const faqUpdateSchema: z.ZodObject<{
|
|
|
142
142
|
useSiteSettings?: boolean | undefined;
|
|
143
143
|
}, {
|
|
144
144
|
template?: string | undefined;
|
|
145
|
+
category?: string | undefined;
|
|
146
|
+
tags?: string[] | undefined;
|
|
145
147
|
order?: number | undefined;
|
|
146
148
|
priority?: number | undefined;
|
|
147
149
|
isActive?: boolean | undefined;
|
|
148
|
-
category?: string | undefined;
|
|
149
|
-
tags?: string[] | undefined;
|
|
150
150
|
variables?: Record<string, string> | undefined;
|
|
151
151
|
question?: string | undefined;
|
|
152
152
|
showInFooter?: boolean | undefined;
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { Card, Div, Heading, Span, Text, TextLink } from "../../../ui";
|
|
3
|
+
const CLS_CONTACT_CARD = "flex items-center gap-3 rounded-lg border border-zinc-100 dark:border-zinc-700 bg-zinc-50 dark:bg-zinc-800 px-4 py-3 hover:border-primary/40 transition-colors";
|
|
4
|
+
const CLS_CONTACT_LABEL = "text-xs text-zinc-500 dark:text-zinc-400";
|
|
3
5
|
export function ContactCTA({ email, phone, contactHref, labels, }) {
|
|
4
|
-
return (_jsxs(Card, { variant: "outlined", padding: "lg", className: "text-center dark:bg-slate-800/60", children: [_jsx(Div, { className: "mb-6 flex justify-center", children: _jsx(Div, { className: "rounded-full bg-primary/10 p-8", children: _jsx("svg", { className: "h-12 w-12 text-primary", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" }) }) }) }), _jsx(Heading, { level: 2, className: "mb-3 text-2xl font-semibold", children: labels?.title ?? "Need More Help?" }), _jsx(Text, { className: "mx-auto mb-6 max-w-2xl text-zinc-600 dark:text-zinc-300", children: labels?.description ?? "Our support team is here to help you." }), _jsxs(Div, { className: "mb-8 grid grid-cols-1 gap-4 md:grid-cols-3", children: [_jsxs(TextLink, { href: `mailto:${email}`, variant: "none", className:
|
|
6
|
+
return (_jsxs(Card, { variant: "outlined", padding: "lg", className: "text-center dark:bg-slate-800/60", children: [_jsx(Div, { className: "mb-6 flex justify-center", children: _jsx(Div, { className: "rounded-full bg-primary/10 p-8", children: _jsx("svg", { className: "h-12 w-12 text-primary", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" }) }) }) }), _jsx(Heading, { level: 2, className: "mb-3 text-2xl font-semibold", children: labels?.title ?? "Need More Help?" }), _jsx(Text, { className: "mx-auto mb-6 max-w-2xl text-zinc-600 dark:text-zinc-300", children: labels?.description ?? "Our support team is here to help you." }), _jsxs(Div, { className: "mb-8 grid grid-cols-1 gap-4 md:grid-cols-3", children: [_jsxs(TextLink, { href: `mailto:${email}`, variant: "none", className: CLS_CONTACT_CARD, children: [_jsx(Text, { className: CLS_CONTACT_LABEL, children: labels?.emailUs ?? "Email Us" }), _jsx(Text, { className: "text-xs text-zinc-500 dark:text-zinc-400", children: email })] }), _jsxs(TextLink, { href: `tel:${phone}`, variant: "none", className: CLS_CONTACT_CARD, children: [_jsx(Text, { className: CLS_CONTACT_LABEL, children: labels?.callUs ?? "Call Us" }), _jsx(Text, { className: "text-xs text-zinc-500 dark:text-zinc-400", children: phone })] }), _jsxs(TextLink, { href: contactHref, className: CLS_CONTACT_CARD, children: [_jsx(Text, { className: CLS_CONTACT_LABEL, children: labels?.contactForm ?? "Contact Form" }), _jsx(Text, { className: "text-xs text-zinc-500 dark:text-zinc-400", children: labels?.submitRequest ?? "Submit a request" })] })] }), _jsxs(TextLink, { href: contactHref, className: "inline-flex items-center gap-2 rounded-xl bg-primary p-6 font-medium text-white transition-colors hover:bg-primary/90", children: [_jsx(Span, { children: labels?.contactTeam ?? "Contact Team" }), _jsx("svg", { className: "h-5 w-5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 5l7 7-7 7" }) })] })] }));
|
|
5
7
|
}
|
|
@@ -3,7 +3,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
3
3
|
import { useState } from "react";
|
|
4
4
|
import { Button, Div, RichText, Row, Span, Text } from "../../../ui";
|
|
5
5
|
function FAQAccordionItem({ faq, isOpen, onToggle, renderExpandedFooter, }) {
|
|
6
|
-
return (_jsxs(Div, { className: "border-b border-neutral-200 dark:border-slate-700 last:border-0", children: [_jsxs(Button, { onClick: onToggle, "aria-expanded": isOpen, className: "flex w-full items-center justify-between gap-4 py-4 text-left text-sm font-medium text-neutral-900 dark:text-zinc-100 transition hover:text-primary", children: [_jsx(Span, { children: faq.question }), _jsx(Span, { className: `flex-shrink-0 transition-transform ${isOpen ? "rotate-180" : ""}`, children: _jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: _jsx("path", { d: "M4 6l4 4 4-4", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) }) })] }), isOpen && (_jsxs(Div, { className: "pb-4 text-sm text-neutral-600 dark:text-zinc-300", children: [faq.tags && faq.tags.length > 0 && (_jsx(Row, { wrap: true, gap: "sm", className: "mb-3", children: faq.tags.map((tag) => (_jsx(Span, { className: "rounded-md bg-neutral-100 dark:bg-slate-700 px-2 py-1 text-xs text-neutral-600 dark:text-zinc-300", children: tag }, tag))) })), faq.answer.format === "html" ? (_jsx(RichText, { html: faq.answer.text, className: "prose-sm" })) : (_jsx(Text, { className: "whitespace-pre-line", children: faq.answer.text })), renderExpandedFooter?.(faq)] }))] }));
|
|
6
|
+
return (_jsxs(Div, { className: "border-b border-neutral-200 dark:border-slate-700 last:border-0", children: [_jsxs(Button, { variant: "ghost", onClick: onToggle, "aria-expanded": isOpen, className: "flex w-full items-center justify-between gap-4 py-4 text-left text-sm font-medium text-neutral-900 dark:text-zinc-100 transition hover:text-primary", children: [_jsx(Span, { children: faq.question }), _jsx(Span, { className: `flex-shrink-0 transition-transform ${isOpen ? "rotate-180" : ""}`, children: _jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: _jsx("path", { d: "M4 6l4 4 4-4", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) }) })] }), isOpen && (_jsxs(Div, { className: "pb-4 text-sm text-neutral-600 dark:text-zinc-300", children: [faq.tags && faq.tags.length > 0 && (_jsx(Row, { wrap: true, gap: "sm", className: "mb-3", children: faq.tags.map((tag) => (_jsx(Span, { className: "rounded-md bg-neutral-100 dark:bg-slate-700 px-2 py-1 text-xs text-neutral-600 dark:text-zinc-300", children: tag }, tag))) })), faq.answer.format === "html" ? (_jsx(RichText, { html: faq.answer.text, className: "prose-sm" })) : (_jsx(Text, { className: "whitespace-pre-line", children: faq.answer.text })), renderExpandedFooter?.(faq)] }))] }));
|
|
7
7
|
}
|
|
8
8
|
export function FAQAccordion({ faqs, className = "", renderExpandedFooter, labels, }) {
|
|
9
9
|
const [openId, setOpenId] = useState(null);
|
|
@@ -91,6 +91,7 @@ export declare const faqSchema: z.ZodObject<{
|
|
|
91
91
|
};
|
|
92
92
|
createdAt?: string | undefined;
|
|
93
93
|
updatedAt?: string | undefined;
|
|
94
|
+
tags?: string[] | undefined;
|
|
94
95
|
order?: number | undefined;
|
|
95
96
|
priority?: number | undefined;
|
|
96
97
|
stats?: {
|
|
@@ -99,7 +100,6 @@ export declare const faqSchema: z.ZodObject<{
|
|
|
99
100
|
notHelpful?: number | undefined;
|
|
100
101
|
} | undefined;
|
|
101
102
|
isActive?: boolean | undefined;
|
|
102
|
-
tags?: string[] | undefined;
|
|
103
103
|
seo?: {
|
|
104
104
|
slug?: string | undefined;
|
|
105
105
|
} | undefined;
|
|
@@ -117,6 +117,7 @@ export declare const faqSchema: z.ZodObject<{
|
|
|
117
117
|
};
|
|
118
118
|
createdAt?: string | undefined;
|
|
119
119
|
updatedAt?: string | undefined;
|
|
120
|
+
tags?: string[] | undefined;
|
|
120
121
|
order?: number | undefined;
|
|
121
122
|
priority?: number | undefined;
|
|
122
123
|
stats?: {
|
|
@@ -125,7 +126,6 @@ export declare const faqSchema: z.ZodObject<{
|
|
|
125
126
|
notHelpful?: number | undefined;
|
|
126
127
|
} | undefined;
|
|
127
128
|
isActive?: boolean | undefined;
|
|
128
|
-
tags?: string[] | undefined;
|
|
129
129
|
seo?: {
|
|
130
130
|
slug?: string | undefined;
|
|
131
131
|
} | undefined;
|
|
@@ -144,14 +144,14 @@ export declare const faqListParamsSchema: z.ZodObject<{
|
|
|
144
144
|
}, "strip", z.ZodTypeAny, {
|
|
145
145
|
perPage?: number | undefined;
|
|
146
146
|
q?: string | undefined;
|
|
147
|
-
page?: number | undefined;
|
|
148
147
|
category?: "orders_payment" | "shipping_delivery" | "returns_refunds" | "product_information" | "account_security" | "technical_support" | "general" | undefined;
|
|
148
|
+
page?: number | undefined;
|
|
149
149
|
homepage?: boolean | undefined;
|
|
150
150
|
}, {
|
|
151
151
|
perPage?: number | undefined;
|
|
152
152
|
q?: string | undefined;
|
|
153
|
-
page?: number | undefined;
|
|
154
153
|
category?: "orders_payment" | "shipping_delivery" | "returns_refunds" | "product_information" | "account_security" | "technical_support" | "general" | undefined;
|
|
154
|
+
page?: number | undefined;
|
|
155
155
|
homepage?: boolean | undefined;
|
|
156
156
|
}>;
|
|
157
157
|
export * from "./firestore";
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { FacetOption } from "./FilterFacetSection";
|
|
2
|
+
import type { AsyncPage } from "../../ui/components/DynamicSelect";
|
|
3
|
+
export interface AsyncFacetSectionProps {
|
|
4
|
+
title: string;
|
|
5
|
+
selected: string[];
|
|
6
|
+
onChange: (selected: string[]) => void;
|
|
7
|
+
loadOptions: (query: string, page: number) => Promise<AsyncPage<FacetOption>>;
|
|
8
|
+
selectionMode?: "single" | "multi";
|
|
9
|
+
defaultCollapsed?: boolean;
|
|
10
|
+
onClear?: () => void;
|
|
11
|
+
className?: string;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* AsyncFacetSection — collapsible filter section that loads options from the API
|
|
15
|
+
* with search + pagination. Replaces static `FilterFacetSection` for large datasets
|
|
16
|
+
* (>20 items). Uses the same accordion UX pattern for visual consistency.
|
|
17
|
+
*/
|
|
18
|
+
export declare function AsyncFacetSection({ title, selected, onChange, loadOptions, selectionMode, defaultCollapsed, onClear, className, }: AsyncFacetSectionProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useCallback, useEffect, useRef, useState } from "react";
|
|
4
|
+
import { Button, Div, Input, Row, Span, Text } from "../../ui";
|
|
5
|
+
import { cn } from "./filterUtils";
|
|
6
|
+
/**
|
|
7
|
+
* AsyncFacetSection — collapsible filter section that loads options from the API
|
|
8
|
+
* with search + pagination. Replaces static `FilterFacetSection` for large datasets
|
|
9
|
+
* (>20 items). Uses the same accordion UX pattern for visual consistency.
|
|
10
|
+
*/
|
|
11
|
+
export function AsyncFacetSection({ title, selected, onChange, loadOptions, selectionMode = "multi", defaultCollapsed = true, onClear, className = "", }) {
|
|
12
|
+
const [collapsed, setCollapsed] = useState(defaultCollapsed);
|
|
13
|
+
const [query, setQuery] = useState("");
|
|
14
|
+
const [options, setOptions] = useState([]);
|
|
15
|
+
const [page, setPage] = useState(1);
|
|
16
|
+
const [hasMore, setHasMore] = useState(false);
|
|
17
|
+
const [loading, setLoading] = useState(false);
|
|
18
|
+
// label cache so chips show labels even after options change
|
|
19
|
+
const labelMap = useRef(new Map());
|
|
20
|
+
const load = useCallback(async (search, nextPage, reset = false) => {
|
|
21
|
+
setLoading(true);
|
|
22
|
+
try {
|
|
23
|
+
const res = await loadOptions(search, nextPage);
|
|
24
|
+
setOptions((prev) => {
|
|
25
|
+
const merged = reset ? res.items : [...prev, ...res.items];
|
|
26
|
+
merged.forEach((o) => labelMap.current.set(o.value, o.label));
|
|
27
|
+
return merged;
|
|
28
|
+
});
|
|
29
|
+
setPage(nextPage);
|
|
30
|
+
setHasMore(res.hasMore);
|
|
31
|
+
}
|
|
32
|
+
finally {
|
|
33
|
+
setLoading(false);
|
|
34
|
+
}
|
|
35
|
+
}, [loadOptions]);
|
|
36
|
+
// Load whenever the section is expanded or query changes
|
|
37
|
+
useEffect(() => {
|
|
38
|
+
if (collapsed)
|
|
39
|
+
return;
|
|
40
|
+
void load(query, 1, true);
|
|
41
|
+
}, [collapsed, query, load]);
|
|
42
|
+
function handleQueryChange(val) {
|
|
43
|
+
setQuery(val);
|
|
44
|
+
if (collapsed)
|
|
45
|
+
setCollapsed(false);
|
|
46
|
+
}
|
|
47
|
+
function toggle(value) {
|
|
48
|
+
if (selectionMode === "single") {
|
|
49
|
+
onChange(selected.includes(value) ? [] : [value]);
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
onChange(selected.includes(value)
|
|
53
|
+
? selected.filter((v) => v !== value)
|
|
54
|
+
: [...selected, value]);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
const hasValue = selected.length > 0;
|
|
58
|
+
const selectedLabels = selected
|
|
59
|
+
.map((v) => labelMap.current.get(v) ?? v)
|
|
60
|
+
.slice(0, 3);
|
|
61
|
+
return (_jsxs(Div, { className: cn("p-4 border-b border-zinc-200 dark:border-slate-700 last:border-b-0", className), children: [_jsxs(Row, { gap: "xs", children: [_jsxs(Button, { type: "button", onClick: () => setCollapsed((c) => !c), variant: "ghost", size: "sm", className: "flex flex-1 items-center justify-between text-sm font-semibold text-zinc-900 dark:text-zinc-50 py-1 hover:opacity-80 transition-opacity", "aria-expanded": !collapsed, children: [_jsxs(Row, { as: Span, gap: "xs", children: [title, hasValue && (_jsx(Span, { className: "inline-flex items-center justify-center w-5 h-5 text-xs rounded-full bg-emerald-50 dark:bg-emerald-900/30 text-emerald-700 dark:text-emerald-300 ring-1 ring-emerald-600/20 dark:ring-emerald-400/20", children: selected.length }))] }), _jsx("svg", { className: cn("w-4 h-4 text-zinc-500 dark:text-zinc-400 transition-transform duration-200", collapsed ? "" : "rotate-180"), fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, "aria-hidden": "true", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M19 9l-7 7-7-7" }) })] }), onClear && hasValue && (_jsx(Button, { type: "button", onClick: onClear, variant: "ghost", size: "sm", className: "inline-flex items-center justify-center w-5 h-5 p-0 text-zinc-500 dark:text-zinc-400 hover:text-red-600 dark:hover:text-red-400 hover:bg-zinc-100 dark:hover:bg-slate-700 transition-colors rounded-full", "aria-label": "Clear filter", children: _jsx("svg", { className: "w-3 h-3", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2.5, "aria-hidden": "true", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M6 18L18 6M6 6l12 12" }) }) }))] }), collapsed && hasValue && (_jsxs(Div, { className: "mt-2 flex flex-wrap gap-1", children: [selectedLabels.map((label) => (_jsx(Span, { className: "inline-flex items-center px-2 py-0.5 rounded-full text-xs bg-zinc-100 dark:bg-slate-700 text-zinc-700 dark:text-zinc-300 border border-zinc-200 dark:border-slate-600", children: label }, label))), selected.length > 3 && (_jsxs(Span, { className: "inline-flex items-center px-2 py-0.5 rounded-full text-xs text-zinc-400 dark:text-zinc-500", children: ["+", selected.length - 3, " more"] }))] })), _jsx(Div, { className: "mt-2", children: _jsx(Input, { type: "search", placeholder: "Search\u2026", value: query, onChange: (e) => handleQueryChange(e.target.value), className: "w-full rounded-md border border-zinc-200 dark:border-slate-700 bg-white dark:bg-slate-800/60 px-2.5 py-1.5 text-xs text-zinc-900 dark:text-zinc-100 focus:outline-none focus:ring-2 focus:ring-primary-500/20" }) }), !collapsed && (_jsxs(Div, { className: "mt-3 space-y-1", children: [options.map((opt) => {
|
|
62
|
+
const isSelected = selected.includes(opt.value);
|
|
63
|
+
return (_jsxs(Row, { gap: "2.5", className: "py-1 cursor-pointer group", children: [_jsx("input", { type: selectionMode === "single" ? "radio" : "checkbox", checked: isSelected, onChange: () => toggle(opt.value), "aria-label": opt.label, className: "flex-shrink-0 w-4 h-4 rounded border-zinc-300 dark:border-slate-600 cursor-pointer text-primary-600 dark:text-secondary-500" }), _jsx(Span, { className: "flex-1 text-sm text-zinc-700 dark:text-zinc-300 group-hover:text-zinc-900 dark:group-hover:text-zinc-100 transition-colors truncate", children: opt.label }), opt.count !== undefined && (_jsx(Span, { className: "text-xs text-zinc-400 dark:text-zinc-500 tabular-nums flex-shrink-0", children: opt.count }))] }, opt.value));
|
|
64
|
+
}), options.length === 0 && !loading && (_jsx(Text, { className: "text-xs text-zinc-400 dark:text-zinc-500 py-1", children: "No results" })), loading && (_jsx(Text, { className: "text-xs text-zinc-400 dark:text-zinc-500 py-1 animate-pulse", children: "Loading\u2026" })), hasMore && !loading && (_jsx(Button, { type: "button", variant: "ghost", size: "sm", className: "w-full text-xs text-left text-zinc-400 dark:text-zinc-500 hover:text-zinc-600 dark:hover:text-zinc-300 py-1", onClick: () => void load(query, page + 1), children: "Load more\u2026" }))] }))] }));
|
|
65
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import React from "react";
|
|
4
|
-
import { Div, Span } from "../../ui";
|
|
4
|
+
import { Div, Span, Text } from "../../ui";
|
|
5
5
|
import { cn, ERROR_BASE } from "./utils";
|
|
6
6
|
export function Checkbox({ label, suffix, error, indeterminate, className = "", checked, ...props }) {
|
|
7
7
|
const inputRef = React.useRef(null);
|
|
@@ -12,5 +12,5 @@ export function Checkbox({ label, suffix, error, indeterminate, className = "",
|
|
|
12
12
|
}, [indeterminate]);
|
|
13
13
|
return (_jsxs(Div, { className: "w-full", children: [_jsxs("label", { className: "flex flex-row items-center gap-3 cursor-pointer group", children: [_jsxs(Div, { className: "relative flex items-center justify-center flex-shrink-0", children: [_jsx("input", { ref: inputRef, type: "checkbox", checked: checked, className: cn("peer w-5 h-5 rounded-md border-2 cursor-pointer", "transition-all duration-200 appearance-none", error
|
|
14
14
|
? "border-red-400 dark:border-red-500"
|
|
15
|
-
: "border-zinc-300 dark:border-slate-600", "checked:bg-primary-600 checked:border-primary-600", "dark:checked:bg-secondary-500 dark:checked:border-secondary-500", "hover:border-primary-400 dark:hover:border-secondary-400", "focus:outline-none focus:ring-2 focus:ring-primary-500/30 focus:ring-offset-1", "dark:focus:ring-secondary-400/30 dark:focus:ring-offset-slate-900", "disabled:opacity-50 disabled:cursor-not-allowed", className), ...props }), _jsx("svg", { className: "absolute w-3 h-3 text-white pointer-events-none opacity-0 peer-checked:opacity-100 transition-opacity duration-150", viewBox: "0 0 12 12", fill: "none", "aria-hidden": "true", children: indeterminate ? (_jsx("line", { x1: "2", y1: "6", x2: "10", y2: "6", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" })) : (_jsx("path", { d: "M2 6L5 9L10 3", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" })) })] }), (label || suffix) && (_jsxs(Span, { className: "flex items-center gap-2 text-sm text-zinc-700 dark:text-zinc-300 group-hover:text-zinc-900 dark:group-hover:text-zinc-100 transition-colors", children: [label, suffix] }))] }), error && (_jsx(
|
|
15
|
+
: "border-zinc-300 dark:border-slate-600", "checked:bg-primary-600 checked:border-primary-600", "dark:checked:bg-secondary-500 dark:checked:border-secondary-500", "hover:border-primary-400 dark:hover:border-secondary-400", "focus:outline-none focus:ring-2 focus:ring-primary-500/30 focus:ring-offset-1", "dark:focus:ring-secondary-400/30 dark:focus:ring-offset-slate-900", "disabled:opacity-50 disabled:cursor-not-allowed", className), ...props }), _jsx("svg", { className: "absolute w-3 h-3 text-white pointer-events-none opacity-0 peer-checked:opacity-100 transition-opacity duration-150", viewBox: "0 0 12 12", fill: "none", "aria-hidden": "true", children: indeterminate ? (_jsx("line", { x1: "2", y1: "6", x2: "10", y2: "6", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" })) : (_jsx("path", { d: "M2 6L5 9L10 3", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" })) })] }), (label || suffix) && (_jsxs(Span, { className: "flex items-center gap-2 text-sm text-zinc-700 dark:text-zinc-300 group-hover:text-zinc-900 dark:group-hover:text-zinc-100 transition-colors", children: [label, suffix] }))] }), error && (_jsx(Text, { className: cn(ERROR_BASE, "mt-1.5"), role: "alert", children: error }))] }));
|
|
16
16
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import React from "react";
|
|
3
|
-
import { Div, Span } from "../../ui";
|
|
3
|
+
import { Div, Span, Text } from "../../ui";
|
|
4
4
|
import { cn, INPUT_BASE, INPUT_ERROR, INPUT_SUCCESS, INPUT_DISABLED, INPUT_WITH_ICON, LABEL_BASE, HELPER_BASE, ERROR_BASE, } from "./utils";
|
|
5
5
|
export const Input = React.forwardRef(function Input({ label, error, helperText, icon, rightIcon, success, className = "", required, disabled, ...props }, ref) {
|
|
6
6
|
const stateClasses = error
|
|
@@ -18,6 +18,6 @@ export const Input = React.forwardRef(function Input({ label, error, helperText,
|
|
|
18
18
|
? `${props.id}-helper`
|
|
19
19
|
: undefined, ...props }), rightIcon && (_jsx(Div, { className: cn("absolute right-3 top-1/2 -translate-y-1/2 transition-colors duration-150", error
|
|
20
20
|
? "text-red-600 dark:text-red-400"
|
|
21
|
-
: "text-zinc-400 dark:text-zinc-500"), children: rightIcon }))] }), error && (_jsx(
|
|
21
|
+
: "text-zinc-400 dark:text-zinc-500"), children: rightIcon }))] }), error && (_jsx(Text, { id: `${props.id}-error`, className: ERROR_BASE, role: "alert", children: error })), !error && helperText && (_jsx(Text, { id: `${props.id}-helper`, className: HELPER_BASE, children: helperText }))] }));
|
|
22
22
|
});
|
|
23
23
|
Input.displayName = "Input";
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { Div, Span } from "../../ui";
|
|
2
|
+
import { Div, Span, Text } from "../../ui";
|
|
3
3
|
import { cn, LABEL_BASE, ERROR_BASE } from "./utils";
|
|
4
4
|
export function RadioGroup({ name, options, value, onChange, label, error, orientation = "vertical", variant = "toggle", }) {
|
|
5
5
|
if (variant === "classic") {
|
|
6
|
-
return (_jsxs(Div, { className: "w-full", children: [label && _jsx(
|
|
6
|
+
return (_jsxs(Div, { className: "w-full", children: [label && _jsx(Text, { className: LABEL_BASE, children: label }), _jsx(Div, { className: cn("flex gap-3", orientation === "vertical" ? "flex-col" : "flex-row flex-wrap"), children: options.map((option) => {
|
|
7
7
|
const isSelected = value === option.value;
|
|
8
8
|
return (_jsxs("label", { className: cn("flex items-center gap-2.5 cursor-pointer", option.disabled && "opacity-50 cursor-not-allowed"), children: [_jsx("input", { type: "radio", name: name, value: option.value, checked: isSelected, disabled: option.disabled, onChange: () => !option.disabled && onChange?.(option.value), className: "w-4 h-4 text-primary-600 dark:text-secondary-500 border-zinc-300 dark:border-slate-600 focus:ring-primary-500/30 dark:focus:ring-secondary-400/30" }), _jsx(Span, { className: "text-sm text-zinc-700 dark:text-zinc-300", children: option.label })] }, option.value));
|
|
9
|
-
}) }), error && (_jsx(
|
|
9
|
+
}) }), error && (_jsx(Text, { className: ERROR_BASE, role: "alert", children: error }))] }));
|
|
10
10
|
}
|
|
11
11
|
// Toggle variant — pill style
|
|
12
|
-
return (_jsxs(Div, { className: "w-full", children: [label && _jsx(
|
|
12
|
+
return (_jsxs(Div, { className: "w-full", children: [label && _jsx(Text, { className: LABEL_BASE, children: label }), _jsx(Div, { className: cn("flex gap-2", orientation === "vertical" ? "flex-col" : "flex-row flex-wrap"), role: "radiogroup", "aria-label": label, children: options.map((option) => {
|
|
13
13
|
const isSelected = value === option.value;
|
|
14
14
|
return (_jsxs("label", { className: cn("flex items-center justify-center px-4 py-2.5 rounded-xl border text-sm font-medium cursor-pointer transition-all duration-200", isSelected
|
|
15
15
|
? "bg-primary-600 dark:bg-secondary-500 border-primary-600 dark:border-secondary-500 text-white shadow-sm"
|
|
16
16
|
: "border-zinc-200 dark:border-slate-700 text-zinc-700 dark:text-zinc-300 hover:border-primary-400 dark:hover:border-secondary-400 hover:bg-primary-50/50 dark:hover:bg-secondary-900/20", option.disabled && "opacity-50 cursor-not-allowed"), children: [_jsx("input", { type: "radio", name: name, value: option.value, checked: isSelected, disabled: option.disabled, onChange: () => !option.disabled && onChange?.(option.value), className: "sr-only" }), option.label] }, option.value));
|
|
17
|
-
}) }), error && (_jsx(
|
|
17
|
+
}) }), error && (_jsx(Text, { className: ERROR_BASE, role: "alert", children: error }))] }));
|
|
18
18
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { Div, Span } from "../../ui";
|
|
2
|
+
import { Div, Span, Text } from "../../ui";
|
|
3
3
|
import { cn, INPUT_BASE, INPUT_ERROR, LABEL_BASE, HELPER_BASE, ERROR_BASE, } from "./utils";
|
|
4
4
|
export function Select({ label, error, helperText, options, placeholder, className = "", required, ...props }) {
|
|
5
5
|
return (_jsxs(Div, { className: "w-full", children: [label && (_jsxs("label", { className: LABEL_BASE, children: [label, required && (_jsx(Span, { className: "text-red-500 ml-1", "aria-hidden": "true", children: "*" }))] })), _jsxs(Div, { className: "relative group", children: [_jsxs("select", { className: cn(INPUT_BASE, "pr-10 appearance-none cursor-pointer", error ? INPUT_ERROR : "", className), "aria-invalid": error ? "true" : undefined, ...props, children: [placeholder && (_jsx("option", { value: "", disabled: true, children: placeholder })), options.map((option) => (_jsx("option", { value: option.value, children: option.label }, option.value)))] }), _jsx(Div, { className: "absolute right-3 top-1/2 -translate-y-1/2 pointer-events-none transition-colors duration-150", children: _jsx("svg", { className: cn("w-5 h-5 transition-transform duration-200", error
|
|
6
6
|
? "text-red-500 dark:text-red-400"
|
|
7
|
-
: "text-zinc-400 dark:text-zinc-500"), viewBox: "0 0 20 20", fill: "currentColor", "aria-hidden": "true", children: _jsx("path", { fillRule: "evenodd", d: "M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z", clipRule: "evenodd" }) }) })] }), error && (_jsx(
|
|
7
|
+
: "text-zinc-400 dark:text-zinc-500"), viewBox: "0 0 20 20", fill: "currentColor", "aria-hidden": "true", children: _jsx("path", { fillRule: "evenodd", d: "M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z", clipRule: "evenodd" }) }) })] }), error && (_jsx(Text, { className: ERROR_BASE, role: "alert", children: error })), !error && helperText && _jsx(Text, { className: HELPER_BASE, children: helperText })] }));
|
|
8
8
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import React from "react";
|
|
4
|
-
import { Div, Row, Span } from "../../ui";
|
|
4
|
+
import { Div, Row, Span, Text } from "../../ui";
|
|
5
5
|
import { cn, LABEL_BASE, ERROR_BASE } from "./utils";
|
|
6
6
|
/**
|
|
7
7
|
* Slider — single-thumb range slider.
|
|
@@ -18,5 +18,5 @@ export function Slider({ value: controlledValue, defaultValue = 0, min = 0, max
|
|
|
18
18
|
onChange?.(newVal);
|
|
19
19
|
};
|
|
20
20
|
const displayValue = formatValue ? formatValue(value) : String(value);
|
|
21
|
-
return (_jsxs(Div, { className: cn("w-full space-y-2", className), children: [(label || showValue) && (_jsxs(Row, { justify: "between", children: [label && (_jsx("label", { htmlFor: sliderId, className: LABEL_BASE, children: label })), showValue && (_jsx(Span, { className: "text-sm font-semibold tabular-nums text-zinc-900 dark:text-zinc-100", children: displayValue }))] })), _jsxs(Row, { className: "relative h-5", children: [_jsx(Div, { className: "absolute inset-y-0 flex items-center w-full", children: _jsx(Div, { className: "w-full h-1.5 rounded-full bg-zinc-200 dark:bg-slate-700", children: _jsx(Div, { className: "h-full rounded-full bg-primary-500 dark:bg-secondary-500 transition-all", style: { width: `${pct}%` } }) }) }), _jsx("input", { type: "range", id: sliderId, min: min, max: max, step: step, value: value, disabled: disabled, onChange: handleChange, className: cn("relative w-full appearance-none bg-transparent cursor-pointer", "focus:outline-none", "[&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:w-4 [&::-webkit-slider-thumb]:h-4", "[&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:bg-white", "[&::-webkit-slider-thumb]:border-2 [&::-webkit-slider-thumb]:border-primary-500 dark:[&::-webkit-slider-thumb]:border-secondary-500", "[&::-webkit-slider-thumb]:shadow-sm", "[&::-moz-range-thumb]:w-4 [&::-moz-range-thumb]:h-4", "[&::-moz-range-thumb]:rounded-full [&::-moz-range-thumb]:bg-white", "[&::-moz-range-thumb]:border-2 [&::-moz-range-thumb]:border-primary-500 dark:[&::-moz-range-thumb]:border-secondary-500", disabled && "opacity-50 cursor-not-allowed") })] }), _jsxs(Row, { justify: "between", className: "text-xs text-zinc-400 dark:text-zinc-500", children: [_jsx(Span, { children: formatValue ? formatValue(min) : min }), _jsx(Span, { children: formatValue ? formatValue(max) : max })] }), error && (_jsx(
|
|
21
|
+
return (_jsxs(Div, { className: cn("w-full space-y-2", className), children: [(label || showValue) && (_jsxs(Row, { justify: "between", children: [label && (_jsx("label", { htmlFor: sliderId, className: LABEL_BASE, children: label })), showValue && (_jsx(Span, { className: "text-sm font-semibold tabular-nums text-zinc-900 dark:text-zinc-100", children: displayValue }))] })), _jsxs(Row, { className: "relative h-5", children: [_jsx(Div, { className: "absolute inset-y-0 flex items-center w-full", children: _jsx(Div, { className: "w-full h-1.5 rounded-full bg-zinc-200 dark:bg-slate-700", children: _jsx(Div, { className: "h-full rounded-full bg-primary-500 dark:bg-secondary-500 transition-all", style: { width: `${pct}%` } }) }) }), _jsx("input", { type: "range", id: sliderId, min: min, max: max, step: step, value: value, disabled: disabled, onChange: handleChange, className: cn("relative w-full appearance-none bg-transparent cursor-pointer", "focus:outline-none", "[&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:w-4 [&::-webkit-slider-thumb]:h-4", "[&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:bg-white", "[&::-webkit-slider-thumb]:border-2 [&::-webkit-slider-thumb]:border-primary-500 dark:[&::-webkit-slider-thumb]:border-secondary-500", "[&::-webkit-slider-thumb]:shadow-sm", "[&::-moz-range-thumb]:w-4 [&::-moz-range-thumb]:h-4", "[&::-moz-range-thumb]:rounded-full [&::-moz-range-thumb]:bg-white", "[&::-moz-range-thumb]:border-2 [&::-moz-range-thumb]:border-primary-500 dark:[&::-moz-range-thumb]:border-secondary-500", disabled && "opacity-50 cursor-not-allowed") })] }), _jsxs(Row, { justify: "between", className: "text-xs text-zinc-400 dark:text-zinc-500", children: [_jsx(Span, { children: formatValue ? formatValue(min) : min }), _jsx(Span, { children: formatValue ? formatValue(max) : max })] }), error && (_jsx(Text, { className: ERROR_BASE, role: "alert", children: error }))] }));
|
|
22
22
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import React from "react";
|
|
3
|
-
import { Div, Span } from "../../ui";
|
|
3
|
+
import { Div, Span, Text } from "../../ui";
|
|
4
4
|
import { cn, INPUT_BASE, INPUT_ERROR, LABEL_BASE, HELPER_BASE, ERROR_BASE, } from "./utils";
|
|
5
5
|
export const Textarea = React.forwardRef(function Textarea({ label, error, helperText, showCharCount, className = "", required, maxLength, value, defaultValue, ...props }, ref) {
|
|
6
6
|
const charCount = typeof value === "string"
|
|
@@ -8,7 +8,7 @@ export const Textarea = React.forwardRef(function Textarea({ label, error, helpe
|
|
|
8
8
|
: typeof defaultValue === "string"
|
|
9
9
|
? defaultValue.length
|
|
10
10
|
: 0;
|
|
11
|
-
return (_jsxs(Div, { className: "w-full", children: [label && (_jsxs("label", { className: LABEL_BASE, children: [label, required && (_jsx(Span, { className: "text-red-500 ml-1", "aria-hidden": "true", children: "*" }))] })), _jsx("textarea", { ref: ref, className: cn(INPUT_BASE, "resize-y min-h-[80px]", error ? INPUT_ERROR : "", className), "aria-invalid": error ? "true" : undefined, maxLength: maxLength, value: value, defaultValue: defaultValue, ...props }), _jsxs(Div, { className: "flex items-center justify-between mt-1.5", children: [_jsxs(Div, { className: "flex-1", children: [error && (_jsx(
|
|
11
|
+
return (_jsxs(Div, { className: "w-full", children: [label && (_jsxs("label", { className: LABEL_BASE, children: [label, required && (_jsx(Span, { className: "text-red-500 ml-1", "aria-hidden": "true", children: "*" }))] })), _jsx("textarea", { ref: ref, className: cn(INPUT_BASE, "resize-y min-h-[80px]", error ? INPUT_ERROR : "", className), "aria-invalid": error ? "true" : undefined, maxLength: maxLength, value: value, defaultValue: defaultValue, ...props }), _jsxs(Div, { className: "flex items-center justify-between mt-1.5", children: [_jsxs(Div, { className: "flex-1", children: [error && (_jsx(Text, { className: ERROR_BASE, role: "alert", children: error })), !error && helperText && (_jsx(Text, { className: HELPER_BASE, children: helperText }))] }), showCharCount && maxLength && (_jsxs("p", { className: cn("text-xs tabular-nums ml-2 flex-shrink-0", charCount >= maxLength
|
|
12
12
|
? "text-red-500 dark:text-red-400"
|
|
13
13
|
: "text-zinc-400 dark:text-zinc-500"), children: [charCount, " / ", maxLength] }))] })] }));
|
|
14
14
|
});
|
|
@@ -12,6 +12,7 @@ import { NextResponse } from "next/server.js";
|
|
|
12
12
|
import { z } from "zod";
|
|
13
13
|
import { getProviders } from "../../../../contracts";
|
|
14
14
|
import { createRouteHandler } from "../../../../next";
|
|
15
|
+
const ERR_SECTION_NOT_FOUND = "Section not found";
|
|
15
16
|
// ---- GET /api/homepage-sections/[id] ----------------------------------------
|
|
16
17
|
export async function GET(_request, context) {
|
|
17
18
|
try {
|
|
@@ -23,7 +24,7 @@ export async function GET(_request, context) {
|
|
|
23
24
|
const repo = db.getRepository("homepageSections");
|
|
24
25
|
const section = await repo.findById(id);
|
|
25
26
|
if (!section) {
|
|
26
|
-
return NextResponse.json({ success: false, error:
|
|
27
|
+
return NextResponse.json({ success: false, error: ERR_SECTION_NOT_FOUND }, { status: 404 });
|
|
27
28
|
}
|
|
28
29
|
return NextResponse.json({ success: true, data: section });
|
|
29
30
|
}
|
|
@@ -71,7 +72,7 @@ export const homepageSectionItemPATCH = createRouteHandler({
|
|
|
71
72
|
const repo = db.getRepository("homepageSections");
|
|
72
73
|
const section = await repo.findById(id);
|
|
73
74
|
if (!section)
|
|
74
|
-
return NextResponse.json({ success: false, error:
|
|
75
|
+
return NextResponse.json({ success: false, error: ERR_SECTION_NOT_FOUND }, { status: 404 });
|
|
75
76
|
const updated = await repo.update(id, {
|
|
76
77
|
...body,
|
|
77
78
|
updatedAt: new Date().toISOString(),
|
|
@@ -93,7 +94,7 @@ export const homepageSectionItemDELETE = createRouteHandler({
|
|
|
93
94
|
const repo = db.getRepository("homepageSections");
|
|
94
95
|
const section = await repo.findById(id);
|
|
95
96
|
if (!section)
|
|
96
|
-
return NextResponse.json({ success: false, error:
|
|
97
|
+
return NextResponse.json({ success: false, error: ERR_SECTION_NOT_FOUND }, { status: 404 });
|
|
97
98
|
await repo.delete(id);
|
|
98
99
|
return NextResponse.json({ success: true });
|
|
99
100
|
},
|