@mohasinac/appkit 2.8.2 → 2.8.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_internal/client/features/classified/ClassifiedDetailView.js +7 -1
- package/dist/_internal/client/features/digital-code/CodeRevealPanel.js +4 -1
- package/dist/_internal/client/features/digital-code/DigitalCodeDetailView.js +7 -1
- package/dist/_internal/client/features/layout/DashboardLayoutClient.js +3 -2
- package/dist/_internal/client/features/live/LiveItemDetailView.js +11 -2
- package/dist/_internal/client/scaffolds/AppShell.js +2 -1
- package/dist/_internal/client/scaffolds/DashboardScaffold.js +2 -1
- package/dist/_internal/server/features/checkout/actions.js +40 -39
- package/dist/_internal/shared/actions/action-registry.js +6 -0
- package/dist/_internal/shared/config/index.d.ts +1 -1
- package/dist/_internal/shared/config/schema.d.ts +0 -8
- package/dist/client-entry.d.ts +1 -1
- package/dist/client.d.ts +3 -1
- package/dist/client.js +3 -1
- package/dist/configs/next.js +12 -22
- package/dist/constants/api-endpoints.d.ts +6 -0
- package/dist/constants/api-endpoints.js +2 -0
- package/dist/features/about/components/AboutView.js +5 -2
- package/dist/features/about/components/FAQPageView.js +3 -3
- package/dist/features/about/components/FeesView.js +13 -5
- package/dist/features/about/components/HelpPageView.js +9 -5
- package/dist/features/about/components/HowAuctionsWorkView.js +9 -5
- package/dist/features/about/components/HowCheckoutWorksView.js +9 -5
- package/dist/features/about/components/HowOffersWorkView.js +10 -5
- package/dist/features/about/components/HowOrdersWorkView.js +10 -5
- package/dist/features/about/components/HowPayoutsWorkView.js +9 -5
- package/dist/features/about/components/HowPreOrdersWorkView.js +9 -5
- package/dist/features/about/components/HowReviewsWorkView.js +9 -5
- package/dist/features/about/components/PolicyPageView.js +3 -3
- package/dist/features/about/components/PublicProfileView.js +11 -4
- package/dist/features/about/components/SecurityPrivacyView.js +8 -4
- package/dist/features/about/components/ShippingPolicyView.js +3 -2
- package/dist/features/about/components/TrackOrderView.js +2 -2
- package/dist/features/about/components/UnauthorizedView.js +3 -3
- package/dist/features/account/components/AddressBook.js +1 -1
- package/dist/features/account/components/AddressForm.js +2 -2
- package/dist/features/account/components/AddressInlineSelect.d.ts +24 -0
- package/dist/features/account/components/AddressInlineSelect.js +78 -0
- package/dist/features/account/components/AddressSelectorCreate.d.ts +2 -1
- package/dist/features/account/components/AddressSelectorCreate.js +5 -32
- package/dist/features/account/components/AddressesIndexListing.js +3 -3
- package/dist/features/account/components/ChatWindow.js +2 -1
- package/dist/features/account/components/NotificationBell.js +13 -7
- package/dist/features/account/components/NotificationPreferencesPanel.js +4 -1
- package/dist/features/account/components/UserOffersPanel.js +2 -1
- package/dist/features/account/components/UserSidebar.js +11 -7
- package/dist/features/account/components/UserSupportView.js +13 -4
- package/dist/features/account/components/index.d.ts +2 -0
- package/dist/features/account/components/index.js +1 -0
- package/dist/features/addresses/repository/addresses.repository.d.ts +1 -0
- package/dist/features/addresses/repository/addresses.repository.js +13 -0
- package/dist/features/admin/components/AdminAdEditorView.js +8 -5
- package/dist/features/admin/components/AdminAddressEditorView.js +5 -5
- package/dist/features/admin/components/AdminAdsView.js +10 -7
- package/dist/features/admin/components/AdminAllEventEntriesView.js +5 -3
- package/dist/features/admin/components/AdminBidsView.js +6 -4
- package/dist/features/admin/components/AdminBlogEditorView.js +15 -9
- package/dist/features/admin/components/AdminBlogView.js +6 -4
- package/dist/features/admin/components/AdminBrandEditorView.js +10 -4
- package/dist/features/admin/components/AdminBrandsView.js +12 -10
- package/dist/features/admin/components/AdminBundleEditorView.js +4 -5
- package/dist/features/admin/components/AdminBundlesView.js +13 -11
- package/dist/features/admin/components/AdminCarouselEditorView.js +6 -3
- package/dist/features/admin/components/AdminCarouselView.js +6 -6
- package/dist/features/admin/components/AdminCartsView.js +6 -4
- package/dist/features/admin/components/AdminCatalogGuideView.js +2 -1
- package/dist/features/admin/components/AdminCategoriesView.js +12 -10
- package/dist/features/admin/components/AdminCategoryEditorView.js +11 -5
- package/dist/features/admin/components/AdminClassifiedView.js +4 -3
- package/dist/features/admin/components/AdminContactEditorView.js +8 -1
- package/dist/features/admin/components/AdminContactView.js +6 -4
- package/dist/features/admin/components/AdminCouponEditorView.js +23 -5
- package/dist/features/admin/components/AdminCouponsView.js +6 -4
- package/dist/features/admin/components/AdminDigitalCodesView.js +4 -3
- package/dist/features/admin/components/AdminEmployeeEditorView.js +7 -4
- package/dist/features/admin/components/AdminFaqEditorView.js +9 -3
- package/dist/features/admin/components/AdminFaqsView.js +9 -7
- package/dist/features/admin/components/AdminFeatureEditorView.js +7 -1
- package/dist/features/admin/components/AdminFeatureFlagsView.js +4 -1
- package/dist/features/admin/components/AdminFeaturesView.js +5 -4
- package/dist/features/admin/components/AdminFilterBar.js +4 -4
- package/dist/features/admin/components/AdminGroupedListingsView.js +66 -30
- package/dist/features/admin/components/AdminGuideHubView.js +4 -1
- package/dist/features/admin/components/AdminHistoryView.js +4 -3
- package/dist/features/admin/components/AdminLiveView.js +4 -3
- package/dist/features/admin/components/AdminMediaView.js +4 -1
- package/dist/features/admin/components/AdminNavigationView.js +7 -4
- package/dist/features/admin/components/AdminNewsletterView.js +5 -3
- package/dist/features/admin/components/AdminNotificationsView.js +8 -6
- package/dist/features/admin/components/AdminOrderEditorView.js +2 -2
- package/dist/features/admin/components/AdminOrdersView.js +6 -4
- package/dist/features/admin/components/AdminPageHeader.js +5 -2
- package/dist/features/admin/components/AdminPayoutsView.js +7 -5
- package/dist/features/admin/components/AdminPrizeDrawsView.js +11 -9
- package/dist/features/admin/components/AdminProductEditorView.js +12 -5
- package/dist/features/admin/components/AdminProductsView.js +11 -9
- package/dist/features/admin/components/AdminReturnRequestsView.js +4 -3
- package/dist/features/admin/components/AdminReviewsView.js +10 -8
- package/dist/features/admin/components/AdminScammerEditorView.js +6 -2
- package/dist/features/admin/components/AdminScammersView.js +11 -9
- package/dist/features/admin/components/AdminSectionsView.js +20 -22
- package/dist/features/admin/components/AdminSessionsManager.js +2 -1
- package/dist/features/admin/components/AdminSessionsView.js +8 -6
- package/dist/features/admin/components/AdminSidebar.js +11 -7
- package/dist/features/admin/components/AdminSiteConfigGuideView.js +2 -1
- package/dist/features/admin/components/AdminSiteSettingsView.js +5 -1
- package/dist/features/admin/components/AdminStoreAddressesView.js +4 -3
- package/dist/features/admin/components/AdminStoreEditorView.js +5 -5
- package/dist/features/admin/components/AdminStoresView.js +6 -4
- package/dist/features/admin/components/AdminSublistingCategoriesView.js +6 -5
- package/dist/features/admin/components/AdminSublistingCategoryEditorView.js +3 -3
- package/dist/features/admin/components/AdminSupportTicketDetailView.js +10 -3
- package/dist/features/admin/components/AdminSupportTicketsView.js +11 -9
- package/dist/features/admin/components/AdminTeamView.js +6 -4
- package/dist/features/admin/components/AdminTrustGuideView.js +3 -3
- package/dist/features/admin/components/AdminUsersGuideView.js +3 -3
- package/dist/features/admin/components/AdminUsersView.js +6 -4
- package/dist/features/admin/components/AdminViewCards.js +12 -6
- package/dist/features/admin/components/AdminWishlistsView.js +4 -3
- package/dist/features/admin/components/BrandQuickCreateForm.js +2 -2
- package/dist/features/admin/components/CategoryQuickCreateForm.js +2 -2
- package/dist/features/admin/components/DashboardStats.js +9 -3
- package/dist/features/admin/components/DataListingView.js +3 -3
- package/dist/features/admin/components/DataTable.js +11 -7
- package/dist/features/admin/components/DrawerFormFooter.js +2 -2
- package/dist/features/admin/components/QuickEditMenu.js +2 -1
- package/dist/features/admin/components/analytics/AdminAnalyticsCharts.js +5 -1
- package/dist/features/admin/constants/filter-tabs.d.ts +1 -1
- package/dist/features/admin/constants/filter-tabs.js +0 -11
- package/dist/features/admin/types/index.d.ts +1 -1
- package/dist/features/auctions/actions/bid-actions.js +4 -2
- package/dist/features/auctions/components/AuctionBidsTable.js +4 -1
- package/dist/features/auctions/components/AuctionDetailPageView.js +14 -6
- package/dist/features/auctions/components/AuctionsListView.js +7 -6
- package/dist/features/auctions/components/CollapsibleBidHistory.js +5 -1
- package/dist/features/auctions/components/MarketplaceAuctionCard.js +9 -3
- package/dist/features/auctions/components/MarketplaceAuctionGrid.js +8 -2
- package/dist/features/auctions/components/PlaceBidFormClient.js +4 -1
- package/dist/features/auth/components/RegisterForm.js +2 -2
- package/dist/features/auth/components/VerifyEmailView.js +5 -2
- package/dist/features/before-after/components/BeforeAfterSlider.js +1 -1
- package/dist/features/blog/actions/blog-actions.js +3 -2
- package/dist/features/blog/components/BlogFeaturedCard.js +8 -1
- package/dist/features/blog/components/BlogIndexListing.js +11 -5
- package/dist/features/blog/components/BlogListView.js +11 -3
- package/dist/features/blog/components/BlogPostView.js +10 -3
- package/dist/features/cart/components/CartDrawer.js +11 -3
- package/dist/features/cart/components/CartSummary.js +2 -2
- package/dist/features/cart/components/CheckoutOtpModal.js +2 -1
- package/dist/features/categories/components/BrandDetailPageView.js +15 -10
- package/dist/features/categories/components/BrandDetailTabs.js +5 -1
- package/dist/features/categories/components/BundleDetailView.js +6 -3
- package/dist/features/categories/components/BundleDynamicRuleEditor.js +3 -1
- package/dist/features/categories/components/BundleItemsPicker.js +10 -3
- package/dist/features/categories/components/CategoriesIndexListing.js +13 -7
- package/dist/features/categories/components/CategoriesIndexPageView.js +5 -4
- package/dist/features/categories/components/CategoryBundlesListing.js +10 -6
- package/dist/features/categories/components/CategoryDetailPageView.js +18 -12
- package/dist/features/categories/components/CategoryDetailTabs.js +5 -1
- package/dist/features/categories/components/CategoryFilters.d.ts +12 -12
- package/dist/features/categories/components/CategoryFilters.js +13 -12
- package/dist/features/categories/components/CategoryForm.js +6 -3
- package/dist/features/categories/components/CategoryGrid.js +9 -2
- package/dist/features/categories/components/CategoryProductsListing.js +10 -4
- package/dist/features/categories/components/CategorySelectorCreate.js +3 -3
- package/dist/features/categories/components/CategorySortSelect.js +1 -1
- package/dist/features/categories/components/CategoryStoresListing.js +3 -3
- package/dist/features/categories/components/CategoryTableColumns.js +10 -6
- package/dist/features/categories/components/CategoryTree.d.ts +1 -1
- package/dist/features/categories/components/CategoryTree.js +2 -2
- package/dist/features/categories/schemas/firestore.d.ts +2 -2
- package/dist/features/checkout/actions/checkout-actions.d.ts +1 -1
- package/dist/features/checkout/actions/checkout-actions.js +1 -1
- package/dist/features/classified/components/ClassifiedFilters.js +2 -2
- package/dist/features/classified/components/ClassifiedIndexListing.js +9 -3
- package/dist/features/classified/components/ClassifiedListView.js +6 -5
- package/dist/features/collections/components/CollectionCard.js +2 -1
- package/dist/features/contact/components/ContactForm.js +4 -2
- package/dist/features/contact/components/ContactInfoSidebar.js +4 -1
- package/dist/features/copilot/components/AdminCopilotView.js +13 -5
- package/dist/features/cron/jobs/auction-expiry.job.d.ts +2 -2
- package/dist/features/cron/jobs/auction-expiry.job.js +2 -1
- package/dist/features/cron/jobs/preorder-reminder.job.d.ts +1 -1
- package/dist/features/cron/jobs/preorder-reminder.job.js +2 -1
- package/dist/features/digital-codes/components/DigitalCodesIndexListing.js +9 -3
- package/dist/features/digital-codes/components/DigitalCodesListView.js +4 -3
- package/dist/features/events/actions/event-actions.js +6 -4
- package/dist/features/events/components/AdminEventEditorView.js +63 -41
- package/dist/features/events/components/AdminEventEntriesView.js +9 -6
- package/dist/features/events/components/AdminEventsView.js +7 -5
- package/dist/features/events/components/EventCard.js +7 -1
- package/dist/features/events/components/EventFilters.d.ts +4 -4
- package/dist/features/events/components/EventFilters.js +2 -2
- package/dist/features/events/components/EventFormDrawer.js +2 -1
- package/dist/features/events/components/EventLeaderboard.js +4 -4
- package/dist/features/events/components/EventOfferCard.js +4 -1
- package/dist/features/events/components/EventParticipateView.js +3 -2
- package/dist/features/events/components/EventPollWidget.js +6 -5
- package/dist/features/events/components/EventRaffleEntryForm.js +5 -2
- package/dist/features/events/components/EventRaffleWinnerView.js +7 -1
- package/dist/features/events/components/EventRafflesSection.js +6 -4
- package/dist/features/events/components/EventSaleBanner.js +5 -2
- package/dist/features/events/components/EventsIndexListing.js +8 -2
- package/dist/features/events/components/EventsListView.js +4 -1
- package/dist/features/events/components/SpinWheelView.js +7 -2
- package/dist/features/events/schemas/firestore.d.ts +1 -0
- package/dist/features/events/types/index.d.ts +1 -0
- package/dist/features/faq/actions/faq-actions.js +4 -2
- package/dist/features/faq/components/ContactCTA.js +4 -1
- package/dist/features/faq/components/FAQCategorySidebar.js +2 -2
- package/dist/features/faq/components/FAQHelpfulButtons.js +8 -5
- package/dist/features/faq/components/FAQPageContent.js +7 -6
- package/dist/features/faq/components/FAQSortDropdown.js +2 -2
- package/dist/features/filters/AsyncFacetSection.js +4 -2
- package/dist/features/filters/FilterFacetSection.js +14 -6
- package/dist/features/filters/RangeFilter.js +4 -2
- package/dist/features/filters/SwitchFilter.js +2 -1
- package/dist/features/forms/Checkbox.js +1 -1
- package/dist/features/forms/Radio.js +1 -1
- package/dist/features/forms/Slider.js +1 -1
- package/dist/features/homepage/components/AdSlot.js +4 -4
- package/dist/features/homepage/components/AdvertisementBanner.js +13 -4
- package/dist/features/homepage/components/AnnouncementBar.js +2 -1
- package/dist/features/homepage/components/BeforeAfterCard.js +8 -2
- package/dist/features/homepage/components/BrandsSection.js +6 -3
- package/dist/features/homepage/components/CTABannerSection.js +2 -2
- package/dist/features/homepage/components/CharacterHotspot.js +5 -2
- package/dist/features/homepage/components/CharacterHotspotForm.js +8 -4
- package/dist/features/homepage/components/CustomCardsSection.js +13 -7
- package/dist/features/homepage/components/CustomerReviewsSection.js +9 -3
- package/dist/features/homepage/components/FAQSection.js +7 -4
- package/dist/features/homepage/components/FeaturedBundlesSection.js +8 -2
- package/dist/features/homepage/components/FeaturedResultsSection.js +1 -1
- package/dist/features/homepage/components/GoogleReviewsSection.js +14 -8
- package/dist/features/homepage/components/HeroCarousel.js +1 -1
- package/dist/features/homepage/components/HomepageSkeleton.js +7 -1
- package/dist/features/homepage/components/HowItWorksInfoView.js +2 -2
- package/dist/features/homepage/components/HowItWorksSection.js +2 -2
- package/dist/features/homepage/components/MarketplaceHomepageView.js +4 -2
- package/dist/features/homepage/components/NewsletterBanner.js +3 -2
- package/dist/features/homepage/components/NewsletterSection.js +5 -2
- package/dist/features/homepage/components/PromoGrid.js +4 -1
- package/dist/features/homepage/components/SectionCarousel.js +7 -4
- package/dist/features/homepage/components/SecurityHighlightsSection.js +3 -3
- package/dist/features/homepage/components/ShopByCategorySection.js +10 -4
- package/dist/features/homepage/components/SiteFeaturesSection.js +5 -2
- package/dist/features/homepage/components/SocialFeedSection.js +4 -4
- package/dist/features/homepage/components/SocialPostCard.js +6 -3
- package/dist/features/homepage/components/TrustFeaturesSection.js +5 -5
- package/dist/features/homepage/components/TrustIndicatorsSection.js +5 -2
- package/dist/features/homepage/components/WelcomeSection.js +1 -1
- package/dist/features/homepage/components/WhatsAppCommunitySection.js +3 -3
- package/dist/features/layout/AppLayoutShell.js +2 -1
- package/dist/features/layout/BackToTop.js +1 -1
- package/dist/features/layout/BottomActions.js +4 -30
- package/dist/features/layout/BottomActionsContext.d.ts +0 -36
- package/dist/features/layout/BottomActionsContext.js +0 -36
- package/dist/features/layout/BottomNavItem.js +1 -1
- package/dist/features/layout/BottomSheet.js +4 -1
- package/dist/features/layout/FooterLayout.js +1 -1
- package/dist/features/layout/NavbarLayout.js +4 -1
- package/dist/features/layout/SidebarLayout.js +5 -2
- package/dist/features/live/components/LiveItemFilters.js +2 -2
- package/dist/features/live/components/LiveItemsIndexListing.js +9 -3
- package/dist/features/live/components/LiveItemsListView.js +6 -5
- package/dist/features/loyalty/components/CoinsDisplay.js +4 -2
- package/dist/features/media/AvatarUpload.js +2 -2
- package/dist/features/media/MediaLightbox.js +3 -2
- package/dist/features/media/modals/VideoThumbnailSelector.js +4 -1
- package/dist/features/media/modals/VideoTrimModal.js +1 -1
- package/dist/features/media/upload/CameraCapture.js +1 -1
- package/dist/features/media/upload/ImageUpload.js +4 -1
- package/dist/features/media/upload/MediaUploadField.js +11 -2
- package/dist/features/media/upload/MediaUploadList.js +5 -1
- package/dist/features/orders/components/MarketplaceOrderCard.js +2 -2
- package/dist/features/orders/components/OrdersList.js +2 -1
- package/dist/features/orders/components/RefundHistoryTable.js +4 -1
- package/dist/features/orders/components/RefundRequestView.js +2 -1
- package/dist/features/pre-orders/components/MarketplacePreorderCard.js +5 -1
- package/dist/features/pre-orders/components/PreOrderActionsClient.js +3 -3
- package/dist/features/pre-orders/components/PreOrderBadge.js +2 -1
- package/dist/features/pre-orders/components/PreOrderDetailPageView.js +16 -7
- package/dist/features/pre-orders/components/PreOrdersIndexListing.js +32 -24
- package/dist/features/pre-orders/components/PreOrdersListView.js +5 -4
- package/dist/features/products/actions/product-actions.js +17 -15
- package/dist/features/products/columns/index.d.ts +1 -1
- package/dist/features/products/columns/index.js +1 -1
- package/dist/features/products/columns/productTableColumns.js +9 -4
- package/dist/features/products/components/AuctionsIndexListing.js +9 -3
- package/dist/features/products/components/BidHistory.js +4 -4
- package/dist/features/products/components/CompareOverlay.js +10 -2
- package/dist/features/products/components/CustomFieldsEditor.js +2 -1
- package/dist/features/products/components/CustomSectionTabContent.js +2 -2
- package/dist/features/products/components/CustomSectionsEditor.js +3 -2
- package/dist/features/products/components/GroupSettingsPanel.js +34 -26
- package/dist/features/products/components/MakeOfferButton.js +6 -2
- package/dist/features/products/components/MakeOfferForm.js +2 -1
- package/dist/features/products/components/MarketplaceBundleCard.js +6 -3
- package/dist/features/products/components/MarketplacePrizeDrawCard.js +3 -2
- package/dist/features/products/components/PlaceBidForm.js +2 -1
- package/dist/features/products/components/PrizeDrawCollage.js +6 -16
- package/dist/features/products/components/PrizeDrawDetailPageView.js +6 -1
- package/dist/features/products/components/PrizeDrawItemsEditor.js +4 -2
- package/dist/features/products/components/PrizeDrawsIndexListing.js +6 -3
- package/dist/features/products/components/PrizeDrawsListingView.js +5 -4
- package/dist/features/products/components/PrizeDrawsSection.js +6 -4
- package/dist/features/products/components/PrizeRevealModal.js +5 -1
- package/dist/features/products/components/ProductDetailPageView.js +32 -16
- package/dist/features/products/components/ProductFeatureBadges.js +9 -9
- package/dist/features/products/components/ProductForm.d.ts +11 -1
- package/dist/features/products/components/ProductForm.js +10 -5
- package/dist/features/products/components/ProductGalleryClient.js +8 -4
- package/dist/features/products/components/ProductGradingTab.js +4 -1
- package/dist/features/products/components/ProductGrid.js +35 -14
- package/dist/features/products/components/ProductInfo.js +2 -1
- package/dist/features/products/components/ProductTabs.js +2 -1
- package/dist/features/products/components/ProductTabsShell.js +5 -1
- package/dist/features/products/components/ProductsIndexListing.js +32 -24
- package/dist/features/products/components/ProductsIndexPageView.js +2 -2
- package/dist/features/products/components/RelatedProducts.js +3 -3
- package/dist/features/products/components/ShowGroupSection.js +10 -6
- package/dist/features/products/components/SublistingCarouselSection.js +7 -3
- package/dist/features/products/components/SublistingCategorySelect.d.ts +3 -1
- package/dist/features/products/components/SublistingCategorySelect.js +4 -37
- package/dist/features/products/constants/action-defs.js +3 -3
- package/dist/features/products/constants/sieve.d.ts +2 -2
- package/dist/features/products/constants/sieve.js +2 -2
- package/dist/features/products/hooks/useRelatedProducts.js +5 -4
- package/dist/features/promotions/components/CouponCard.js +5 -3
- package/dist/features/promotions/components/CouponsIndexListing.js +7 -3
- package/dist/features/promotions/repository/coupons.repository.d.ts +8 -0
- package/dist/features/promotions/repository/coupons.repository.js +2 -0
- package/dist/features/reviews/actions/review-actions.js +2 -1
- package/dist/features/reviews/components/ReviewDetailPageView.js +3 -3
- package/dist/features/reviews/components/ReviewDetailShell.js +15 -3
- package/dist/features/reviews/components/ReviewSummary.js +4 -2
- package/dist/features/reviews/components/ReviewsIndexListing.js +8 -2
- package/dist/features/reviews/components/ReviewsIndexPageView.js +7 -6
- package/dist/features/reviews/components/ReviewsList.js +1 -1
- package/dist/features/scams/actions/scam-actions.js +3 -2
- package/dist/features/scams/components/ScamAwarenessModal.js +2 -2
- package/dist/features/scams/components/ScamProfileView.js +3 -3
- package/dist/features/scams/components/ScamRegistryView.js +11 -8
- package/dist/features/search/actions/search-actions.js +7 -6
- package/dist/features/search/components/Search.js +9 -6
- package/dist/features/search/components/SearchFiltersRow.js +1 -1
- package/dist/features/search/components/SearchResultsSection.js +1 -1
- package/dist/features/seller/components/CouponInlineSelect.d.ts +22 -0
- package/dist/features/seller/components/CouponInlineSelect.js +104 -0
- package/dist/features/seller/components/GroupInlineSelect.d.ts +23 -0
- package/dist/features/seller/components/GroupInlineSelect.js +80 -0
- package/dist/features/seller/components/PhysicalLocationModal.js +2 -1
- package/dist/features/seller/components/PrintCenterView.js +2 -1
- package/dist/features/seller/components/ProductInlineSelect.d.ts +24 -0
- package/dist/features/seller/components/ProductInlineSelect.js +42 -0
- package/dist/features/seller/components/QuickProductForm.js +4 -1
- package/dist/features/seller/components/SellerAddressesView.js +8 -3
- package/dist/features/seller/components/SellerAnalyticsAlertsView.js +6 -3
- package/dist/features/seller/components/SellerAnalyticsView.js +2 -2
- package/dist/features/seller/components/SellerAuctionsView.js +7 -5
- package/dist/features/seller/components/SellerBidsView.js +12 -10
- package/dist/features/seller/components/SellerBundlesView.js +9 -7
- package/dist/features/seller/components/SellerClassifiedView.js +6 -5
- package/dist/features/seller/components/SellerCouponEditorView.d.ts +2 -0
- package/dist/features/seller/components/SellerCouponEditorView.js +15 -3
- package/dist/features/seller/components/SellerCouponsView.js +7 -5
- package/dist/features/seller/components/SellerDashboardView.js +2 -2
- package/dist/features/seller/components/SellerDigitalCodesView.js +7 -6
- package/dist/features/seller/components/SellerGoogleReviewsView.js +2 -2
- package/dist/features/seller/components/SellerGroupedListingsView.js +10 -9
- package/dist/features/seller/components/SellerLiveView.js +6 -5
- package/dist/features/seller/components/SellerOffersView.js +6 -4
- package/dist/features/seller/components/SellerOrdersView.js +18 -13
- package/dist/features/seller/components/SellerPayoutMethodsView.js +8 -6
- package/dist/features/seller/components/SellerPayoutRequestView.js +5 -1
- package/dist/features/seller/components/SellerPayoutSettingsView.js +5 -2
- package/dist/features/seller/components/SellerPayoutsView.js +6 -4
- package/dist/features/seller/components/SellerPreOrdersView.js +12 -10
- package/dist/features/seller/components/SellerPrizeDrawsView.js +12 -10
- package/dist/features/seller/components/SellerProductShell.js +1 -1
- package/dist/features/seller/components/SellerProductsCards.js +4 -1
- package/dist/features/seller/components/SellerProductsView.js +14 -12
- package/dist/features/seller/components/SellerReviewsView.js +7 -3
- package/dist/features/seller/components/SellerShippingConfigsView.js +7 -6
- package/dist/features/seller/components/SellerShippingView.js +1 -1
- package/dist/features/seller/components/SellerSidebar.js +15 -8
- package/dist/features/seller/components/SellerStoreCategoriesView.js +5 -4
- package/dist/features/seller/components/SellerStorefrontView.js +2 -2
- package/dist/features/seller/components/SellerTemplatesView.js +11 -7
- package/dist/features/seller/components/SublistingInlineSelect.d.ts +19 -0
- package/dist/features/seller/components/SublistingInlineSelect.js +84 -0
- package/dist/features/seller/components/analytics/SellerTopProducts.js +1 -1
- package/dist/features/seller/components/index.d.ts +8 -0
- package/dist/features/seller/components/index.js +4 -0
- package/dist/features/shell/FormShell.js +10 -2
- package/dist/features/shell/QuickFormDrawer.js +5 -5
- package/dist/features/shell/StepForm.js +6 -6
- package/dist/features/site-settings/components/ActionPermissionsManager.js +8 -4
- package/dist/features/site-settings/components/NavPermissionsManager.js +7 -4
- package/dist/features/stores/actions/store-query-actions.js +3 -2
- package/dist/features/stores/components/InteractiveStoreCard.js +5 -1
- package/dist/features/stores/components/StoreAboutView.js +4 -1
- package/dist/features/stores/components/StoreAddressSelectorCreate.d.ts +2 -1
- package/dist/features/stores/components/StoreAddressSelectorCreate.js +5 -31
- package/dist/features/stores/components/StoreAuctionsListing.js +6 -3
- package/dist/features/stores/components/StoreAuctionsPageView.js +4 -2
- package/dist/features/stores/components/StoreDetailLayoutView.d.ts +1 -1
- package/dist/features/stores/components/StoreDetailLayoutView.js +7 -6
- package/dist/features/stores/components/StoreGuideHubView.js +5 -2
- package/dist/features/stores/components/StoreHeader.js +8 -1
- package/dist/features/stores/components/StorePreOrdersListing.js +6 -3
- package/dist/features/stores/components/StorePreOrdersPageView.js +4 -2
- package/dist/features/stores/components/StorePrizeDrawsPageView.js +4 -2
- package/dist/features/stores/components/StoreProductsListing.js +6 -3
- package/dist/features/stores/components/StoreProductsPageView.js +2 -1
- package/dist/features/stores/components/StoreProductsView.js +5 -4
- package/dist/features/stores/components/StoreReviewsListing.js +8 -2
- package/dist/features/stores/components/StoresIndexListing.js +16 -9
- package/dist/features/whatsapp-bot/components/SellerWhatsAppSettingsView.js +7 -1
- package/dist/features/whatsapp-bot/components/WhatsAppChatButton.js +2 -1
- package/dist/features/wishlist/components/WishlistPage.js +2 -1
- package/dist/features/wishlist/components/WishlistView.js +4 -3
- package/dist/index.d.ts +10 -0
- package/dist/index.js +13 -1
- package/dist/next/components/GlobalError.js +2 -2
- package/dist/next/routing/route-map.d.ts +2 -0
- package/dist/next/routing/route-map.js +1 -0
- package/dist/react/ErrorBoundary.js +2 -2
- package/dist/styles.css +2 -1
- package/dist/tailwind-utilities.css +1 -1
- package/dist/ui/DataTable.js +17 -16
- package/dist/ui/components/DateInput.js +2 -2
- package/dist/ui/components/DetailPageGallery.js +4 -1
- package/dist/ui/components/DetailPageTabs.js +6 -2
- package/dist/ui/components/ImageLightbox.js +5 -3
- package/dist/ui/components/Input.js +6 -3
- package/dist/ui/components/Layout.d.ts +4 -0
- package/dist/ui/components/Layout.js +1 -1
- package/dist/ui/components/Layout.style.css +1 -0
- package/dist/ui/components/ListingFilterDrawer.js +4 -1
- package/dist/ui/components/ListingLayout.js +9 -8
- package/dist/ui/components/ListingToolbar.js +5 -1
- package/dist/ui/components/PaginatedSelect.d.ts +1 -2
- package/dist/ui/components/PaginatedSelect.js +1 -2
- package/dist/ui/components/Radio.js +1 -1
- package/dist/ui/components/Select.js +2 -1
- package/dist/ui/components/Slider.js +1 -1
- package/dist/ui/components/VacationBanner.js +2 -1
- package/dist/ui/components/surface-tokens.d.ts +1 -0
- package/dist/ui/components/surface-tokens.js +1 -0
- package/package.json +11 -2
|
@@ -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, {
|
|
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, { size: "sm", weight: "semibold", className: "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-400", 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
|
}
|
|
@@ -3,7 +3,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
3
3
|
import { useEffect, useRef, useState } from "react";
|
|
4
4
|
import { getAdSlot, isAdSlotRenderable } from "../ad-registry";
|
|
5
5
|
import { useActiveAd } from "../hooks/useActiveAd";
|
|
6
|
-
import { Text } from "../../../ui";
|
|
6
|
+
import { Div, Span, Text } from "../../../ui";
|
|
7
7
|
// ---------------------------------------------------------------------------
|
|
8
8
|
// Sub-renderers
|
|
9
9
|
// ---------------------------------------------------------------------------
|
|
@@ -20,7 +20,7 @@ function AdsenseAd({ config }) {
|
|
|
20
20
|
// AdSense not loaded yet — no-op
|
|
21
21
|
}
|
|
22
22
|
}, []);
|
|
23
|
-
return (_jsx(
|
|
23
|
+
return (_jsx(Div, { ref: ref, children: _jsx("ins", { className: "adsbygoogle", style: { display: "block" }, "data-ad-client": config.adsenseClient ?? "", "data-ad-slot": config.adsenseSlot ?? "", "data-ad-format": config.adsenseFormat ?? "auto", "data-full-width-responsive": "true" }) }));
|
|
24
24
|
}
|
|
25
25
|
function ThirdPartyAd({ config }) {
|
|
26
26
|
if (config.thirdPartyUrl) {
|
|
@@ -32,7 +32,7 @@ function ManualAdBanner({ ad }) {
|
|
|
32
32
|
const { creative } = ad;
|
|
33
33
|
if (!creative)
|
|
34
34
|
return null;
|
|
35
|
-
return (_jsxs("a", { href: creative.ctaHref || "#", target: creative.ctaHref ? "_blank" : undefined, rel: "noopener noreferrer", className: "flex items-center gap-3 w-full overflow-hidden rounded-lg bg-zinc-100 dark:bg-zinc-800 px-4 py-3 hover:bg-zinc-200 dark:hover:bg-zinc-700 transition-colors no-underline", children: [creative.imageUrl ? (_jsx("img", { src: creative.imageUrl, alt: creative.title || "Advertisement", className: "h-14 w-14 rounded object-cover flex-shrink-0", loading: "lazy" })) : null, _jsxs(
|
|
35
|
+
return (_jsxs("a", { href: creative.ctaHref || "#", target: creative.ctaHref ? "_blank" : undefined, rel: "noopener noreferrer", className: "flex items-center gap-3 w-full overflow-hidden rounded-lg bg-zinc-100 dark:bg-zinc-800 px-4 py-3 hover:bg-zinc-200 dark:hover:bg-zinc-700 transition-colors no-underline", children: [creative.imageUrl ? (_jsx("img", { src: creative.imageUrl, alt: creative.title || "Advertisement", className: "h-14 w-14 rounded object-cover flex-shrink-0", loading: "lazy" })) : null, _jsxs(Div, { className: "flex-1 min-w-0", children: [creative.title ? (_jsx(Text, { className: "text-sm font-semibold text-zinc-900 dark:text-zinc-100 truncate", children: creative.title })) : null, creative.body ? (_jsx(Text, { className: "text-xs text-zinc-500 dark:text-zinc-400 truncate", children: creative.body })) : null] }), creative.ctaLabel ? (_jsx(Span, { size: "xs", weight: "semibold", className: "flex-shrink-0 rounded-md bg-primary px-3 py-1.5 text-white", children: creative.ctaLabel })) : null] }));
|
|
36
36
|
}
|
|
37
37
|
// ---------------------------------------------------------------------------
|
|
38
38
|
// Primary component
|
|
@@ -68,7 +68,7 @@ export function AdSlot({ id, manualContent, className = "" }) {
|
|
|
68
68
|
const content = renderProvider(config.provider, config, resolvedManualContent);
|
|
69
69
|
if (!content)
|
|
70
70
|
return null;
|
|
71
|
-
return (_jsx(
|
|
71
|
+
return (_jsx(Div, { className: className, "data-ad-slot-id": id, "aria-label": "Advertisement", children: content }));
|
|
72
72
|
}
|
|
73
73
|
// ---------------------------------------------------------------------------
|
|
74
74
|
// Provider dispatch
|
|
@@ -3,23 +3,32 @@ import { THEME_CONSTANTS } from "../../../tokens";
|
|
|
3
3
|
import { Button, Div, Grid, Heading, Row, Section, Span, Stack, Text } from "../../../ui";
|
|
4
4
|
import { MediaImage } from "../../media/MediaImage";
|
|
5
5
|
import { ArrowRight, Sparkles } from "lucide-react";
|
|
6
|
+
const __P = {
|
|
7
|
+
p8: "p-8",
|
|
8
|
+
};
|
|
9
|
+
const __O = {
|
|
10
|
+
hidden: "overflow-hidden",
|
|
11
|
+
};
|
|
12
|
+
const CLS_GRADIENT_BG = "absolute inset-0 bg-gradient-to-br from-indigo-600 via-purple-600 to-fuchsia-600";
|
|
13
|
+
const CLS_CTA_BTN_SM = "bg-white dark:bg-zinc-100 text-indigo-700 hover:bg-zinc-50 dark:hover:bg-zinc-200 font-semibold gap-1.5 flex-shrink-0";
|
|
14
|
+
const CLS_CTA_BTN_LG = "bg-white dark:bg-zinc-100 text-indigo-700 hover:bg-zinc-50 dark:hover:bg-zinc-200 font-semibold shadow-lg gap-2";
|
|
6
15
|
// --- Constants ---------------------------------------------------------------
|
|
7
16
|
const CLS_CONTAINER = "w-full max-w-7xl mx-auto";
|
|
8
17
|
// --- Component ---------------------------------------------------------------
|
|
9
18
|
export function AdvertisementBanner({ title, subtitle, ctaLabel = "Shop now", onCtaClick, backgroundImage, backgroundColor, tagLabel, isLoading = false, compact = false, className = "", }) {
|
|
10
19
|
const wrapClass = "bg-gradient-to-br from-amber-50/40 to-orange-50/20 dark:from-amber-950/10 dark:to-orange-950/5";
|
|
11
20
|
if (isLoading) {
|
|
12
|
-
return (_jsx(Section, { className:
|
|
21
|
+
return (_jsx(Section, { className: `${__P.p8} ${wrapClass} ${className}`, children: _jsx(Div, { className: CLS_CONTAINER, children: _jsx(Div, { className: "h-72 bg-zinc-200 dark:bg-slate-700 rounded-2xl animate-pulse" }) }) }));
|
|
13
22
|
}
|
|
14
23
|
// -- Split layout: when a backgroundImage is provided --
|
|
15
24
|
if (backgroundImage) {
|
|
16
|
-
return (_jsx(Section, { className:
|
|
25
|
+
return (_jsx(Section, { className: `${__P.p8} ${wrapClass} ${className}`, children: _jsx(Div, { className: CLS_CONTAINER, children: _jsx(Div, { className: `relative ${__O.hidden} rounded-2xl bg-zinc-900 shadow-xl`, children: _jsxs(Grid, { className: `${THEME_CONSTANTS.grid.cols2Md} min-h-[clamp(300px,40vh,420px)]`, children: [_jsxs(Div, { className: `relative ${THEME_CONSTANTS.card.aspectBanner} order-last md:order-first min-h-0 min-h-[clamp(300px,40vh,420px)]`, children: [_jsx(MediaImage, { src: backgroundImage, alt: title, size: "banner", priority: true }), _jsx(Div, { className: "hidden md:block absolute inset-y-0 right-0 w-24 bg-gradient-to-r from-transparent to-zinc-900/60 pointer-events-none" })] }), _jsxs(Stack, { className: "relative justify-center px-8 py-10 md:px-12 md:py-14", children: [_jsx(Div, { className: "absolute top-0 right-0 w-32 h-32 opacity-10 pointer-events-none bg-[radial-gradient(circle,_white_1px,_transparent_1px)] bg-[length:12px_12px]", "aria-hidden": true }), tagLabel && (_jsxs(Span, { size: "xs", weight: "semibold", className: "inline-flex items-center gap-1.5 self-start bg-white/10 text-white/80 uppercase tracking-widest px-3 py-1 rounded-full mb-5 backdrop-blur-sm", children: [_jsx(Sparkles, { className: "w-3.5 h-3.5" }), tagLabel] })), _jsx(Heading, { level: 2, variant: "none", className: "text-3xl md:text-4xl lg:text-5xl font-extrabold text-white mb-4 leading-tight", children: title }), subtitle && (_jsx(Text, { variant: "none", className: "text-white/75 text-base md:text-lg mb-8 leading-relaxed", children: subtitle })), ctaLabel && onCtaClick && (_jsxs(Button, { variant: "secondary", size: "lg", onClick: onCtaClick, className: "self-start bg-white text-zinc-900 hover:bg-zinc-100 dark:bg-zinc-100 dark:text-zinc-900 dark:hover:bg-zinc-200 font-semibold shadow-lg gap-2", children: [ctaLabel, _jsx(ArrowRight, { className: "w-4 h-4" })] }))] })] }) }) }) }));
|
|
17
26
|
}
|
|
18
27
|
// -- Full-width gradient layout --
|
|
19
|
-
return (_jsx(Section, { className:
|
|
28
|
+
return (_jsx(Section, { className: `${__P.p8} ${wrapClass} ${className}`, children: _jsx(Div, { className: CLS_CONTAINER, children: _jsxs(Row, { align: "center", className: [
|
|
20
29
|
"relative overflow-hidden rounded-2xl",
|
|
21
30
|
compact
|
|
22
31
|
? "h-[clamp(112px,16vh,160px)]"
|
|
23
32
|
: "min-h-[clamp(240px,34vh,360px)]",
|
|
24
|
-
].join(" "), style: backgroundColor ? { backgroundColor } : undefined, children: [!backgroundColor && (_jsx(Div, { className:
|
|
33
|
+
].join(" "), style: backgroundColor ? { backgroundColor } : undefined, children: [!backgroundColor && (_jsx(Div, { className: CLS_GRADIENT_BG, "aria-hidden": true })), _jsxs(Div, { className: `absolute inset-0 ${__O.hidden}`, "aria-hidden": true, children: [_jsx(Div, { className: "absolute -top-16 -left-16 w-64 h-64 rounded-full bg-primary/20 blur-3xl animate-pulse" }), _jsx(Div, { className: "absolute -bottom-16 right-0 w-80 h-80 rounded-full bg-cobalt/20 blur-3xl animate-pulse" })] }), compact ? (_jsxs(Row, { justify: "between", className: "relative z-10 w-full px-6 py-4 gap-4 flex-wrap", children: [_jsxs(Span, { className: "inline-flex items-center gap-2", children: [_jsx(Sparkles, { className: "w-4 h-4 text-white/80" }), _jsx(Span, { size: "sm", weight: "semibold", className: "text-white", children: title })] }), ctaLabel && onCtaClick && (_jsxs(Button, { variant: "secondary", size: "sm", onClick: onCtaClick, className: CLS_CTA_BTN_SM, children: [ctaLabel, _jsx(ArrowRight, { className: "w-3.5 h-3.5" })] }))] })) : (_jsxs(Div, { className: "relative z-10 w-full max-w-4xl mx-auto px-6 py-12 md:py-16 text-center", children: [tagLabel && (_jsxs(Span, { size: "xs", weight: "semibold", className: "inline-flex items-center gap-1.5 bg-white/15 text-white/90 uppercase tracking-widest px-4 py-1.5 rounded-full mb-5 backdrop-blur-sm shadow-sm", children: [_jsx(Sparkles, { className: "w-3.5 h-3.5" }), tagLabel] })), _jsx(Heading, { level: 2, variant: "none", className: "text-3xl md:text-5xl lg:text-6xl font-extrabold text-white mb-4 drop-shadow-lg leading-tight", children: title }), subtitle && (_jsx(Text, { variant: "none", className: "text-white text-base md:text-xl mb-10 max-w-2xl mx-auto", children: subtitle })), ctaLabel && onCtaClick && (_jsxs(Button, { variant: "secondary", size: "lg", onClick: onCtaClick, className: CLS_CTA_BTN_LG, children: [ctaLabel, _jsx(ArrowRight, { className: "w-4 h-4" })] }))] }))] }) }) }));
|
|
25
34
|
}
|
|
@@ -3,6 +3,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
3
3
|
import { useState, useEffect } from "react";
|
|
4
4
|
import { X } from "lucide-react";
|
|
5
5
|
import { useAuth } from "../../../react/contexts/SessionContext";
|
|
6
|
+
import { Div } from "../../../ui/components/Div";
|
|
6
7
|
const STORAGE_KEY = "letitrip:announcement-dismissed";
|
|
7
8
|
const ONE_WEEK_MS = 7 * 24 * 60 * 60 * 1000;
|
|
8
9
|
export function hashBannerMessage(msg) {
|
|
@@ -49,7 +50,7 @@ export function AnnouncementBar({ message, className = "", onDismiss }) {
|
|
|
49
50
|
}, [message, userAlreadyDismissed]);
|
|
50
51
|
if (dismissed)
|
|
51
52
|
return null;
|
|
52
|
-
return (_jsx(
|
|
53
|
+
return (_jsx(Div, { className: `relative left-1/2 right-1/2 w-screen -translate-x-1/2 bg-primary-700 transition-opacity duration-200 ${mounted ? "opacity-100" : "opacity-0"} ${className}`, role: "banner", children: _jsx(Div, { className: "container mx-auto max-w-[1920px] px-4 sm:px-6 lg:px-8", children: _jsxs(Div, { className: "relative flex items-center justify-center py-2 text-center text-sm font-medium text-white", children: [_jsx("span", { children: message }), _jsx("button", { type: "button", onClick: () => {
|
|
53
54
|
saveLocalDismissal(message);
|
|
54
55
|
onDismiss?.(bannerHash);
|
|
55
56
|
setDismissed(true);
|
|
@@ -3,6 +3,12 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
3
3
|
import { useRef, useState, useCallback, useEffect } from "react";
|
|
4
4
|
import Image from "next/image";
|
|
5
5
|
import { Div, Span, Text } from "../../../ui";
|
|
6
|
+
const __P = {
|
|
7
|
+
p4: "p-4",
|
|
8
|
+
};
|
|
9
|
+
const __O = {
|
|
10
|
+
hidden: "overflow-hidden",
|
|
11
|
+
};
|
|
6
12
|
export function BeforeAfterCard({ item, beforeLabel = "Before", afterLabel = "After", }) {
|
|
7
13
|
const containerRef = useRef(null);
|
|
8
14
|
const [position, setPosition] = useState(50);
|
|
@@ -38,7 +44,7 @@ export function BeforeAfterCard({ item, beforeLabel = "Before", afterLabel = "Af
|
|
|
38
44
|
window.removeEventListener("touchend", onUp);
|
|
39
45
|
};
|
|
40
46
|
}, [dragging, updatePosition]);
|
|
41
|
-
return (_jsxs(Div, { className:
|
|
47
|
+
return (_jsxs(Div, { className: `border-border ${__O.hidden} rounded-2xl border bg-card shadow-sm`, children: [_jsxs(Div, { ref: containerRef, className: "relative aspect-[4/3] cursor-col-resize overflow-hidden select-none", onMouseDown: (e) => {
|
|
42
48
|
setDragging(true);
|
|
43
49
|
updatePosition(e.clientX);
|
|
44
50
|
}, onTouchStart: (e) => {
|
|
@@ -49,5 +55,5 @@ export function BeforeAfterCard({ item, beforeLabel = "Before", afterLabel = "Af
|
|
|
49
55
|
setPosition((p) => Math.max(0, p - 2));
|
|
50
56
|
if (e.key === "ArrowRight")
|
|
51
57
|
setPosition((p) => Math.min(100, p + 2));
|
|
52
|
-
}, children: [_jsx(Image, { src: item.afterImage, alt: afterLabel, fill: true, sizes: "(max-width: 640px) 100vw, 50vw", className: "object-cover" }), _jsx(Div, { className: "absolute inset-0 overflow-hidden", style: { width: `${position}%` }, children: _jsx(Image, { src: item.beforeImage, alt: beforeLabel, fill: true, sizes: "(max-width: 640px) 100vw, 50vw", className: "object-cover" }) }), _jsx(Div, { className: "absolute top-0 bottom-0 z-10 w-0.5 bg-card shadow-md", style: { left: `${position}%` }, children: _jsx(Div, { className: "absolute top-1/2 left-1/2 flex h-8 w-8 -translate-x-1/2 -translate-y-1/2 items-center justify-center rounded-full bg-card shadow-lg", children: _jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: _jsx("path", { d: "M4 8L1 5M4 8L1 11M4 8H12M12 8L15 5M12 8L15 11", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) }) }) }), _jsx(Span, { className: "absolute top-3 left-3 z-10 rounded-full bg-black/50 px-2.5 py-0.5 text-
|
|
58
|
+
}, children: [_jsx(Image, { src: item.afterImage, alt: afterLabel, fill: true, sizes: "(max-width: 640px) 100vw, 50vw", className: "object-cover" }), _jsx(Div, { className: "absolute inset-0 overflow-hidden", style: { width: `${position}%` }, children: _jsx(Image, { src: item.beforeImage, alt: beforeLabel, fill: true, sizes: "(max-width: 640px) 100vw, 50vw", className: "object-cover" }) }), _jsx(Div, { className: "absolute top-0 bottom-0 z-10 w-0.5 bg-card shadow-md", style: { left: `${position}%` }, children: _jsx(Div, { className: "absolute top-1/2 left-1/2 flex h-8 w-8 -translate-x-1/2 -translate-y-1/2 items-center justify-center rounded-full bg-card shadow-lg", children: _jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: _jsx("path", { d: "M4 8L1 5M4 8L1 11M4 8H12M12 8L15 5M12 8L15 11", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) }) }) }), _jsx(Span, { size: "xs", weight: "medium", className: "absolute top-3 left-3 z-10 rounded-full bg-black/50 px-2.5 py-0.5 text-white", children: beforeLabel }), _jsx(Span, { size: "xs", weight: "medium", className: "absolute top-3 right-3 z-10 rounded-full bg-black/50 px-2.5 py-0.5 text-white", children: afterLabel })] }), _jsx(Div, { className: `${__P.p4}`, children: _jsx(Text, { className: "text-foreground text-sm font-medium", children: item.caption }) })] }));
|
|
53
59
|
}
|
|
@@ -4,9 +4,12 @@ import { useState } from "react";
|
|
|
4
4
|
import Image from "next/image";
|
|
5
5
|
import Link from "next/link";
|
|
6
6
|
import { THEME_CONSTANTS } from "../../../tokens";
|
|
7
|
-
import { Heading, HorizontalScroller, Section, Text } from "../../../ui";
|
|
7
|
+
import { Div, Heading, HorizontalScroller, Section, Text } from "../../../ui";
|
|
8
8
|
import { ROUTES } from "../../../next";
|
|
9
9
|
import { useTopBrands } from "../hooks/useTopBrands";
|
|
10
|
+
const __O = {
|
|
11
|
+
hidden: "overflow-hidden",
|
|
12
|
+
};
|
|
10
13
|
const CTA_CLASSES = {
|
|
11
14
|
filled: "rounded-lg bg-[var(--appkit-color-primary)] px-5 py-2 text-sm font-semibold text-white hover:opacity-90",
|
|
12
15
|
outline: "rounded-lg border border-[var(--appkit-color-primary)] px-5 py-2 text-sm font-semibold text-[var(--appkit-color-primary)] hover:bg-[var(--appkit-color-primary)]/10",
|
|
@@ -24,7 +27,7 @@ function BrandLogo({ brand }) {
|
|
|
24
27
|
const iconSrc = brand.display?.icon;
|
|
25
28
|
const coverImage = brand.display?.coverImage;
|
|
26
29
|
const initial = brand.name[0]?.toUpperCase() ?? "?";
|
|
27
|
-
return (_jsxs(Link, { href: ROUTES.PUBLIC.CATEGORY_DETAIL(brand.slug), className: "flex h-32 w-36 flex-col items-center justify-center gap-2 rounded-xl border border-zinc-200 bg-white p-3 shadow-sm transition-all hover:border-primary-300 hover:shadow-md dark:border-slate-700 dark:bg-slate-900 md:h-40", children: [iconSrc || coverImage ? (_jsx(Image, { src: iconSrc ?? coverImage, alt: brand.name, width: 64, height: 64, className: "h-16 w-16 rounded object-contain" })) : (_jsx(
|
|
30
|
+
return (_jsxs(Link, { href: ROUTES.PUBLIC.CATEGORY_DETAIL(brand.slug), className: "flex h-32 w-36 flex-col items-center justify-center gap-2 rounded-xl border border-zinc-200 bg-white p-3 shadow-sm transition-all hover:border-primary-300 hover:shadow-md dark:border-slate-700 dark:bg-slate-900 md:h-40", children: [iconSrc || coverImage ? (_jsx(Image, { src: iconSrc ?? coverImage, alt: brand.name, width: 64, height: 64, className: "h-16 w-16 rounded object-contain" })) : (_jsx(Div, { className: "flex h-16 w-16 items-center justify-center rounded-lg bg-primary-100 text-sm font-bold text-primary-700 dark:bg-primary-900 dark:text-primary-300", children: initial })), _jsx(Text, { className: "w-full truncate text-center text-xs font-medium text-zinc-700 dark:text-zinc-300", children: brand.name })] }));
|
|
28
31
|
}
|
|
29
32
|
export function BrandsSection({ title = "Top Brands", subtitle, limit = 12, viewMoreHref, viewMoreLabel = "All brands →", className = "", initialItems, cta, filters, }) {
|
|
30
33
|
const { themed } = THEME_CONSTANTS;
|
|
@@ -39,5 +42,5 @@ export function BrandsSection({ title = "Top Brands", subtitle, limit = 12, view
|
|
|
39
42
|
});
|
|
40
43
|
if (!isLoading && allBrands.length === 0)
|
|
41
44
|
return null;
|
|
42
|
-
return (_jsx(Section, { className: `py-12 px-4 ${themed.bgSecondary} ${className}`, children: _jsxs(
|
|
45
|
+
return (_jsx(Section, { className: `py-12 px-4 ${themed.bgSecondary} ${className}`, children: _jsxs(Div, { className: "mx-auto max-w-7xl", children: [_jsxs(Div, { className: "mb-6 flex items-center justify-between", children: [_jsxs(_Fragment, { children: [_jsx(Heading, { level: 2, className: `text-2xl font-bold md:text-3xl ${themed.textPrimary}`, children: title }), subtitle && (_jsx(Text, { variant: "secondary", className: "mt-1 text-sm", children: subtitle }))] }), !cta && viewMoreHref && (_jsx(Link, { href: viewMoreHref, className: "text-sm font-medium text-[var(--appkit-color-primary)] hover:underline", children: viewMoreLabel }))] }), showFeaturedChip && !isLoading && (_jsxs(Div, { className: "mb-4 flex flex-wrap gap-2", children: [_jsx(BrandFilterChip, { label: "All", active: activeFilter === "all", onClick: () => setActiveFilter("all") }), _jsx(BrandFilterChip, { label: "Featured", active: activeFilter === "featured", onClick: () => setActiveFilter(activeFilter === "featured" ? "all" : "featured") })] })), isLoading ? (_jsx(Div, { className: `flex gap-3 ${__O.hidden}`, children: Array.from({ length: 8 }).map((_, i) => (_jsx(Div, { className: "h-32 w-36 flex-none animate-pulse rounded-xl bg-zinc-200 dark:bg-slate-700 md:h-40" }, i))) })) : (_jsx(HorizontalScroller, { items: brands, renderItem: (brand) => _jsx(BrandLogo, { brand: brand }), keyExtractor: (brand) => brand.id, gap: 12, showArrows: true, showScrollbar: false, loop: true })), cta && !isLoading && (_jsx(Div, { className: "mt-6 text-center", children: _jsx(Link, { href: cta.href, className: CTA_CLASSES[cta.variant], children: cta.label }) }))] }) }));
|
|
43
46
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import Link from "next/link";
|
|
3
|
-
import { Heading, Section, Text } from "../../../ui";
|
|
3
|
+
import { Div, Heading, Section, Span, Text } from "../../../ui";
|
|
4
4
|
export function CTABannerSection({ title = "Thousands of collectibles. One marketplace.", subtitle, primaryLabel = "Shop All Products →", primaryHref = "/products", secondaryLabel = "Browse Auctions →", secondaryHref = "/auctions", className = "", }) {
|
|
5
|
-
return (_jsx(Section, { className: `bg-gradient-to-r from-primary-600 to-primary-700 py-16 px-4 ${className}`, children: _jsxs(
|
|
5
|
+
return (_jsx(Section, { className: `bg-gradient-to-r from-primary-600 to-primary-700 py-16 px-4 ${className}`, children: _jsxs(Div, { className: "mx-auto max-w-3xl text-center", children: [_jsx(Span, { className: "mb-4 inline-block text-2xl", "aria-hidden": "true", children: "\u2728" }), _jsx(Heading, { level: 2, className: "text-2xl font-bold text-white md:text-3xl lg:text-4xl", children: title }), subtitle && (_jsx(Text, { className: "mt-3 text-base text-white/80", children: subtitle })), _jsxs(Div, { className: "mt-8 flex flex-wrap items-center justify-center gap-4", children: [_jsx(Link, { href: primaryHref, className: "inline-flex items-center rounded-full bg-white px-8 py-3 text-sm font-semibold text-primary-700 shadow-sm transition-all hover:bg-zinc-50 hover:shadow-md focus:outline-none focus:ring-2 focus:ring-white focus:ring-offset-2 focus:ring-offset-primary-600", children: primaryLabel }), secondaryHref && (_jsx(Link, { href: secondaryHref, className: "inline-flex items-center rounded-full border-2 border-white/80 px-8 py-3 text-sm font-semibold text-white transition-all hover:bg-white/10 focus:outline-none focus:ring-2 focus:ring-white focus:ring-offset-2 focus:ring-offset-primary-600", children: secondaryLabel }))] })] }) }));
|
|
6
6
|
}
|
|
@@ -6,6 +6,9 @@ import Link from "next/link";
|
|
|
6
6
|
import { THEME_CONSTANTS } from "../../../tokens";
|
|
7
7
|
import { useMediaQuery } from "../../../react";
|
|
8
8
|
import { Button, Div, Heading, Row, Section, Span, Text } from "../../../ui";
|
|
9
|
+
const __O = {
|
|
10
|
+
hidden: "overflow-hidden",
|
|
11
|
+
};
|
|
9
12
|
/* -- Fallback when no Firestore config is saved yet --------------------------
|
|
10
13
|
Consumers can override the full config via the `config` prop.
|
|
11
14
|
----------------------------------------------------------------- */
|
|
@@ -206,7 +209,7 @@ function HotspotHeaderOverlay({ heading, subheading, shopAllHref, }) {
|
|
|
206
209
|
}, children: "SHOP ALL \u2192" })] }) }));
|
|
207
210
|
}
|
|
208
211
|
function HotspotImageLayer({ panoramicImage, panoramicAlt, }) {
|
|
209
|
-
return (_jsxs(Div, { className:
|
|
212
|
+
return (_jsxs(Div, { className: `absolute inset-0 ${__O.hidden}`, children: [_jsx(Image, { src: panoramicImage, alt: panoramicAlt, fill: true, className: "object-cover object-top", sizes: "100vw", priority: false }), _jsx(Div, { className: "absolute inset-0", style: {
|
|
210
213
|
background: "linear-gradient(to right, rgba(10,10,18,0.72) 0%, rgba(10,10,18,0.30) 50%, rgba(10,10,18,0.72) 100%)",
|
|
211
214
|
} }), _jsx(Div, { className: "absolute inset-0", style: {
|
|
212
215
|
background: "linear-gradient(to bottom, rgba(10,10,18,0.25) 0%, transparent 40%, rgba(10,10,18,0.65) 100%)",
|
|
@@ -289,7 +292,7 @@ function UniverseBrowseRow({ universeLinks, }) {
|
|
|
289
292
|
}, onMouseLeave: (e) => {
|
|
290
293
|
e.currentTarget.style.borderColor = "rgba(255,255,255,0.08)";
|
|
291
294
|
e.currentTarget.style.background = "rgba(255,255,255,0.04)";
|
|
292
|
-
}, children: [_jsx(Span, {
|
|
295
|
+
}, children: [_jsx(Span, { size: "base", "aria-hidden": "true", className: "select-none", children: icon }), _jsx(Span, { size: "xs", className: "font-black uppercase tracking-wide", style: { fontFamily: FONT_BANGERS, letterSpacing: "0.1em", color: "#E2E8F0" }, children: label }), _jsx(Span, { size: "xs", className: "ml-auto", style: { color: "#475569", transition: "color 0.15s" }, children: "\u2192" })] }, label))) }));
|
|
293
296
|
}
|
|
294
297
|
function CharacterHotspotInner({ panoramicImage, panoramicAlt, hotspots, universeLinks, shopAllHref, heading, subheading, }) {
|
|
295
298
|
const [activeId, setActiveId] = useState(null);
|
|
@@ -9,6 +9,10 @@ function randomId() {
|
|
|
9
9
|
const CLS_STEP = "space-y-4 rounded-lg border-2 p-6";
|
|
10
10
|
const CLS_IMG_WRAP = "relative w-full overflow-hidden rounded-lg";
|
|
11
11
|
const CLS_INPUT = "rounded border-2 px-3 py-2 text-sm outline-none";
|
|
12
|
+
const CLS_ERROR_BANNER = "rounded border border-red-200 bg-red-50 px-4 py-2 text-sm font-bold text-red-600";
|
|
13
|
+
const CLS_SUCCESS_BANNER = "rounded border border-green-200 bg-green-50 px-4 py-2 text-sm font-bold text-green-700";
|
|
14
|
+
const CLS_SUCCESS_TEXT = "text-xs font-medium text-green-700";
|
|
15
|
+
const CLS_DELETE_PIN = "shrink-0 rounded p-1 text-xs text-red-500 hover:bg-red-50";
|
|
12
16
|
const STY_BORDER_INK = "2px solid var(--border-ink)";
|
|
13
17
|
const STY_CENTERED = "translate(-50%, -50%)";
|
|
14
18
|
export function CharacterHotspotForm({ initial, onUploadImage, onSave, onAfterSave, }) {
|
|
@@ -110,7 +114,7 @@ export function CharacterHotspotForm({ initial, onUploadImage, onSave, onAfterSa
|
|
|
110
114
|
{ key: "review", label: "Review & Save" },
|
|
111
115
|
];
|
|
112
116
|
const stepIndex = STEPS.findIndex((s) => s.key === step);
|
|
113
|
-
return (_jsxs(Div, { className: "mx-auto max-w-3xl space-y-6", children: [error && (_jsx(Text, { className:
|
|
117
|
+
return (_jsxs(Div, { className: "mx-auto max-w-3xl space-y-6", children: [error && (_jsx(Text, { className: CLS_ERROR_BANNER, children: error })), success && (_jsx(Text, { className: CLS_SUCCESS_BANNER, children: "Saved to database successfully!" })), _jsx(Div, { className: "flex items-start", children: STEPS.map((s, i) => (_jsxs(Div, { className: "flex flex-1 flex-col items-center", children: [_jsxs(Div, { className: "flex w-full items-center", children: [i > 0 && (_jsx(Div, { className: "h-0.5 flex-1", style: {
|
|
114
118
|
background: i <= stepIndex
|
|
115
119
|
? "var(--color-black)"
|
|
116
120
|
: "var(--border-ink)",
|
|
@@ -130,10 +134,10 @@ export function CharacterHotspotForm({ initial, onUploadImage, onSave, onAfterSa
|
|
|
130
134
|
background: i < stepIndex
|
|
131
135
|
? "var(--color-black)"
|
|
132
136
|
: "var(--border-ink)",
|
|
133
|
-
} }))] }), _jsx(Span, { className: "mt-1 text-center text-[10px]
|
|
137
|
+
} }))] }), _jsx(Span, { weight: "medium", className: "mt-1 text-center text-[10px]", style: { color: "var(--color-muted)" }, children: s.label })] }, s.key))) }), step === "image" && (_jsxs(Div, { className: CLS_STEP, style: {
|
|
134
138
|
borderColor: "var(--border-ink)",
|
|
135
139
|
background: "var(--surface-elevated)",
|
|
136
|
-
}, children: [_jsx(Heading, { level: 2, className: "text-lg font-bold", children: "Upload Background Image" }), _jsx(Text, { className: "text-sm", style: { color: "var(--color-muted)" }, children: "Choose a wide panoramic image that shows all the characters. You will place pins on it in the next step." }), _jsxs(Label, { className: "flex cursor-pointer flex-col items-center justify-center gap-2 rounded-lg border-2 border-dashed p-8 transition-colors hover:opacity-80", style: { borderColor: "var(--border-ink)" }, children: [_jsx(Span, { className: "text-3xl", children: "\uD83D\uDDBC" }), _jsx(Span, {
|
|
140
|
+
}, children: [_jsx(Heading, { level: 2, className: "text-lg font-bold", children: "Upload Background Image" }), _jsx(Text, { className: "text-sm", style: { color: "var(--color-muted)" }, children: "Choose a wide panoramic image that shows all the characters. You will place pins on it in the next step." }), _jsxs(Label, { className: "flex cursor-pointer flex-col items-center justify-center gap-2 rounded-lg border-2 border-dashed p-8 transition-colors hover:opacity-80", style: { borderColor: "var(--border-ink)" }, children: [_jsx(Span, { className: "text-3xl", children: "\uD83D\uDDBC" }), _jsx(Span, { weight: "medium", children: uploading ? "Uploading…" : "Click to choose image" }), _jsx(Span, { size: "xs", style: { color: "var(--color-muted)" }, children: "JPG, PNG, WebP \u2014 wide landscape images work best" }), _jsx(Input, { type: "file", accept: "image/*", className: "hidden", onChange: handleImageUpload, disabled: uploading })] }), imageUrl && (_jsxs(Div, { className: "space-y-1", children: [_jsx(Div, { className: CLS_IMG_WRAP, style: { paddingTop: "37.5%" }, children: _jsx(Image, { src: imageUrl, alt: imageAlt, fill: true, className: "object-cover", sizes: "680px" }) }), _jsx(Text, { className: CLS_SUCCESS_TEXT, children: "\u2713 Image uploaded" })] })), _jsxs(Div, { className: "flex flex-col gap-1", children: [_jsx(Label, { className: "text-sm font-bold", children: "Image Alt Text" }), _jsx(Input, { type: "text", value: imageAlt, onChange: (e) => setImageAlt(e.target.value), placeholder: "DC, Marvel and Anime characters", className: CLS_INPUT, style: {
|
|
137
141
|
borderColor: "var(--border-ink)",
|
|
138
142
|
background: "var(--surface-elevated)",
|
|
139
143
|
color: "var(--color-black)",
|
|
@@ -293,7 +297,7 @@ export function CharacterHotspotForm({ initial, onUploadImage, onSave, onAfterSa
|
|
|
293
297
|
background: pin.accent || "#E8001C",
|
|
294
298
|
border: "2px solid white",
|
|
295
299
|
boxShadow: "0 2px 6px rgba(0,0,0,0.55)",
|
|
296
|
-
}, children: "+" }), pin.name && (_jsx(Div, { className: "pointer-events-none absolute left-8 top-1/2 -translate-y-1/2 whitespace-nowrap rounded px-1.5 py-0.5 text-[9px] font-bold text-white", style: { background: "#0D0D0D" }, children: pin.name }))] }, pin.id)))] }), pins.length > 0 ? (_jsx(Ul, { className: "divide-y rounded-lg border", style: { borderColor: "var(--border-ink)" }, children: pins.map((pin, i) => (_jsx(Li, { className: "px-4 py-3", children: _jsxs(Row, { gap: "sm", children: [_jsx(Span, { className: "flex h-6 w-6 shrink-0 items-center justify-center rounded-full text-xs font-bold text-white", style: { background: pin.accent || "#E8001C" }, children: i + 1 }), _jsxs(Div, { className: "min-w-0 flex-1", children: [_jsx(Text, { className: "truncate text-sm font-bold", children: pin.name || (_jsx(Span, { className: "italic", style: { color: "var(--color-muted)" }, children: "Unnamed" })) }), _jsxs(Text, { className: "text-xs", style: { color: "var(--color-muted)" }, children: [pin.universe, " \u00B7 ", pin.xPct.toFixed(0), "%,", " ", pin.yPct.toFixed(0), "%"] })] }), _jsx(Button, { type: "button", onClick: () => deletePin(pin.id), variant: "ghost", className:
|
|
300
|
+
}, children: "+" }), pin.name && (_jsx(Div, { className: "pointer-events-none absolute left-8 top-1/2 -translate-y-1/2 whitespace-nowrap rounded px-1.5 py-0.5 text-[9px] font-bold text-white", style: { background: "#0D0D0D" }, children: pin.name }))] }, pin.id)))] }), pins.length > 0 ? (_jsx(Ul, { className: "divide-y rounded-lg border", style: { borderColor: "var(--border-ink)" }, children: pins.map((pin, i) => (_jsx(Li, { className: "px-4 py-3", children: _jsxs(Row, { gap: "sm", children: [_jsx(Span, { className: "flex h-6 w-6 shrink-0 items-center justify-center rounded-full text-xs font-bold text-white", style: { background: pin.accent || "#E8001C" }, children: i + 1 }), _jsxs(Div, { className: "min-w-0 flex-1", children: [_jsx(Text, { className: "truncate text-sm font-bold", children: pin.name || (_jsx(Span, { className: "italic", style: { color: "var(--color-muted)" }, children: "Unnamed" })) }), _jsxs(Text, { className: "text-xs", style: { color: "var(--color-muted)" }, children: [pin.universe, " \u00B7 ", pin.xPct.toFixed(0), "%,", " ", pin.yPct.toFixed(0), "%"] })] }), _jsx(Button, { type: "button", onClick: () => deletePin(pin.id), variant: "ghost", className: CLS_DELETE_PIN, title: "Remove pin", children: "\u2715" })] }) }, pin.id))) })) : (_jsx(Div, { className: "rounded-lg border-2 border-dashed p-8 text-center text-sm", style: {
|
|
297
301
|
borderColor: "var(--border-ink)",
|
|
298
302
|
color: "var(--color-muted)",
|
|
299
303
|
}, children: "No pins yet \u2014 add some using the button below." })), _jsxs("details", { className: "rounded-lg border p-3", style: { borderColor: "var(--border-ink)" }, children: [_jsx("summary", { className: "cursor-pointer text-sm font-medium", children: "Image Settings" }), _jsxs(Div, { className: "mt-3 space-y-3", children: [_jsxs(Label, { className: "inline-flex cursor-pointer items-center gap-2 rounded border-2 border-dashed px-3 py-1.5 text-sm font-medium transition-colors hover:opacity-80", style: { borderColor: "var(--border-ink)" }, children: [uploading ? "Uploading…" : "Replace Image", _jsx(Input, { type: "file", accept: "image/*", className: "hidden", onChange: handleImageUpload, disabled: uploading })] }), _jsxs(Div, { className: "flex flex-col gap-1", children: [_jsx(Label, { className: "text-sm font-bold", children: "Image Alt Text" }), _jsx(Input, { type: "text", value: imageAlt, onChange: (e) => setImageAlt(e.target.value), className: CLS_INPUT, style: {
|
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { Heading, HorizontalScroller, Section, Text } from "../../../ui";
|
|
2
|
+
import { Div, Heading, HorizontalScroller, Section, Text } from "../../../ui";
|
|
3
3
|
import { THEME_CONSTANTS } from "../../../tokens";
|
|
4
4
|
import { SectionCarousel } from "./SectionCarousel";
|
|
5
5
|
import { MediaImage } from "../../media/MediaImage";
|
|
6
|
+
const __P = {
|
|
7
|
+
p4: "p-4",
|
|
8
|
+
};
|
|
9
|
+
const __O = {
|
|
10
|
+
hidden: "overflow-hidden",
|
|
11
|
+
};
|
|
6
12
|
// --- Constants ---------------------------------------------------------------
|
|
7
13
|
const CLS_CONTAINER = "w-full max-w-7xl mx-auto px-4";
|
|
8
14
|
// --- Helpers -----------------------------------------------------------------
|
|
@@ -41,14 +47,14 @@ function CardItem({ card }) {
|
|
|
41
47
|
cardStyle.backgroundColor = card.backgroundColor;
|
|
42
48
|
if (card.textColor)
|
|
43
49
|
cardStyle.color = card.textColor;
|
|
44
|
-
return (_jsxs(
|
|
50
|
+
return (_jsxs(Div, { className: `flex flex-col overflow-hidden ${radiusClass} ${shadowClass} bg-[var(--appkit-color-surface)]`, style: cardStyle, children: [card.image && (_jsx(Div, { className: `relative w-full aspect-video ${__O.hidden}`, children: _jsx(MediaImage, { src: card.image, alt: card.imageAlt ?? "", size: "card" }) })), _jsxs(Div, { className: `flex flex-col gap-2 ${__P.p4} flex-1`, children: [card.eyebrow && (_jsx(Text, { className: "text-xs font-semibold uppercase tracking-widest opacity-70", children: card.eyebrow })), card.title && (_jsx(Text, { className: "text-base font-bold leading-snug", children: card.title })), card.body && (_jsx(Text, { className: "text-sm opacity-80 leading-relaxed flex-1", children: card.body })), card.buttons && card.buttons.length > 0 && (_jsx(Div, { className: "flex flex-wrap gap-2 mt-2", children: card.buttons.map((btn, i) => (_jsx("a", { href: btn.href, target: btn.target ?? "_self", rel: btn.target === "_blank" ? "noopener noreferrer" : undefined, className: VARIANT_CLASS[btn.variant] ?? VARIANT_CLASS.primary, children: btn.label }, i))) })), card.formEmbed && (_jsx("iframe", { src: card.formEmbed, sandbox: "allow-forms allow-scripts", loading: "lazy", className: "w-full mt-3 border-0 rounded-md", style: { minHeight: "200px" }, title: "Embedded form" }))] })] }));
|
|
45
51
|
}
|
|
46
52
|
// --- Section Header ----------------------------------------------------------
|
|
47
53
|
function SectionHeader({ title }) {
|
|
48
54
|
const { themed } = THEME_CONSTANTS;
|
|
49
55
|
if (!title)
|
|
50
56
|
return null;
|
|
51
|
-
return (_jsx(
|
|
57
|
+
return (_jsx(Div, { className: "mb-6", children: _jsx(Heading, { level: 2, className: themed.textPrimary, children: title }) }));
|
|
52
58
|
}
|
|
53
59
|
export function CustomCardsSection(config) {
|
|
54
60
|
const { title, layout, columns = 3, cards, autoScroll, scrollIntervalMs } = config;
|
|
@@ -57,11 +63,11 @@ export function CustomCardsSection(config) {
|
|
|
57
63
|
return null;
|
|
58
64
|
// autoScroll: wrap all cards in SectionCarousel (client carousel)
|
|
59
65
|
if (autoScroll) {
|
|
60
|
-
return (_jsx(Section, { className: `py-12 ${themed.bgPrimary}`, children: _jsx(
|
|
66
|
+
return (_jsx(Section, { className: `py-12 ${themed.bgPrimary}`, children: _jsx(Div, { className: CLS_CONTAINER, children: _jsx(SectionCarousel, { title: title ?? "", items: cards, renderItem: (card) => _jsx(CardItem, { card: card }), keyExtractor: (card) => card.id, autoScroll: true, autoScrollInterval: scrollIntervalMs ?? 3500, perView: { base: 1, sm: 2, md: columns } }) }) }));
|
|
61
67
|
}
|
|
62
68
|
// Row layout: horizontal scroller
|
|
63
69
|
if (layout === "row") {
|
|
64
|
-
return (_jsx(Section, { className: `py-12 ${themed.bgPrimary}`, children: _jsxs(
|
|
70
|
+
return (_jsx(Section, { className: `py-12 ${themed.bgPrimary}`, children: _jsxs(Div, { className: CLS_CONTAINER, children: [_jsx(SectionHeader, { title: title }), _jsx(HorizontalScroller, { gap: 16, showArrows: true, snapToItems: true, loop: true, children: cards.map((card) => (_jsx(Div, { className: "w-72 flex-shrink-0", children: _jsx(CardItem, { card: card }) }, card.id))) })] }) }));
|
|
65
71
|
}
|
|
66
72
|
// Masonry layout: CSS columns
|
|
67
73
|
if (layout === "masonry") {
|
|
@@ -70,9 +76,9 @@ export function CustomCardsSection(config) {
|
|
|
70
76
|
.split(" ")
|
|
71
77
|
.map((c) => c.replace("grid-cols-", "columns-"))
|
|
72
78
|
.join(" ");
|
|
73
|
-
return (_jsx(Section, { className: `py-12 ${themed.bgPrimary}`, children: _jsxs(
|
|
79
|
+
return (_jsx(Section, { className: `py-12 ${themed.bgPrimary}`, children: _jsxs(Div, { className: CLS_CONTAINER, children: [_jsx(SectionHeader, { title: title }), _jsx(Div, { className: `${masonryClass} gap-4 space-y-4`, children: cards.map((card) => (_jsx(Div, { className: "break-inside-avoid", children: _jsx(CardItem, { card: card }) }, card.id))) })] }) }));
|
|
74
80
|
}
|
|
75
81
|
// Grid layout (default)
|
|
76
82
|
const colsClass = COLS_CLASS[columns] ?? COLS_CLASS[3];
|
|
77
|
-
return (_jsx(Section, { className: `py-12 ${themed.bgPrimary}`, children: _jsxs(
|
|
83
|
+
return (_jsx(Section, { className: `py-12 ${themed.bgPrimary}`, children: _jsxs(Div, { className: CLS_CONTAINER, children: [_jsx(SectionHeader, { title: title }), _jsx(Div, { className: `grid ${colsClass} gap-4`, children: cards.map((card) => (_jsx(CardItem, { card: card }, card.id))) })] }) }));
|
|
78
84
|
}
|
|
@@ -1,13 +1,19 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { THEME_CONSTANTS } from "../../../tokens";
|
|
3
|
-
import { Heading, HorizontalScroller, Section, Text, TextLink, } from "../../../ui";
|
|
3
|
+
import { Div, Heading, HorizontalScroller, Section, Text, TextLink, } from "../../../ui";
|
|
4
|
+
const __P = {
|
|
5
|
+
p8: "p-8",
|
|
6
|
+
};
|
|
7
|
+
const __O = {
|
|
8
|
+
hidden: "overflow-hidden",
|
|
9
|
+
};
|
|
4
10
|
// --- Section -----------------------------------------------------------------
|
|
5
11
|
export function CustomerReviewsSection({ title, subtitle, items, renderItem, viewMoreHref, viewMoreLabel = "See all reviews", isLoading = false, keyExtractor, className = "", }) {
|
|
6
12
|
const { themed, skeleton } = THEME_CONSTANTS;
|
|
7
13
|
if (isLoading) {
|
|
8
|
-
return (_jsx(Section, { className:
|
|
14
|
+
return (_jsx(Section, { className: `${__P.p8} ${themed.bgPrimary} ${className}`, children: _jsxs(Div, { className: "w-full max-w-7xl mx-auto", children: [_jsx(Div, { className: `h-8 ${skeleton.base} mb-8 max-w-xs mx-auto` }), _jsx(Div, { className: `flex gap-6 ${__O.hidden}`, children: [...Array(3)].map((_, i) => (_jsx(Div, { className: `${skeleton.card} h-[clamp(180px,26vh,260px)] min-w-[clamp(150px,18vw,260px)] max-w-[clamp(240px,36vw,380px)] flex-none` }, i))) })] }) }));
|
|
9
15
|
}
|
|
10
16
|
if (items.length === 0)
|
|
11
17
|
return null;
|
|
12
|
-
return (_jsx(Section, { className: `py-12 ${themed.bgPrimary} ${className}`, children: _jsxs(
|
|
18
|
+
return (_jsx(Section, { className: `py-12 ${themed.bgPrimary} ${className}`, children: _jsxs(Div, { className: "w-full max-w-7xl mx-auto px-4 md:px-8", children: [_jsxs(Div, { className: "text-center mb-10", children: [_jsx(Heading, { level: 2, className: `text-3xl md:text-4xl font-bold ${themed.textPrimary} mb-3`, children: title }), subtitle && (_jsx(Text, { className: `text-base ${themed.textSecondary}`, children: subtitle }))] }), _jsx(HorizontalScroller, { items: items, renderItem: (item) => renderItem(item), perView: THEME_CONSTANTS.carousel.perView.reviews, gap: 24, autoScroll: true, autoScrollInterval: 4500, pauseOnHover: true, snapToItems: true, showArrows: true, keyExtractor: keyExtractor, loop: true }), viewMoreHref && (_jsx(Div, { className: "text-center mt-8", children: _jsx(TextLink, { href: viewMoreHref, className: "text-sm font-medium text-primary hover:text-primary/80", children: viewMoreLabel }) }))] }) }));
|
|
13
19
|
}
|
|
@@ -2,8 +2,11 @@
|
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { useState, useMemo } from "react";
|
|
4
4
|
import { THEME_CONSTANTS } from "../../../tokens";
|
|
5
|
-
import { Button, Heading, RichText, Section, Span, Text, TextLink } from "../../../ui";
|
|
5
|
+
import { Button, Div, Heading, RichText, Section, Span, Text, TextLink } from "../../../ui";
|
|
6
6
|
import { ChevronDown } from "lucide-react";
|
|
7
|
+
const __O = {
|
|
8
|
+
hidden: "overflow-hidden",
|
|
9
|
+
};
|
|
7
10
|
// --- Constants ----------------------------------------------------------------
|
|
8
11
|
const CATEGORY_LABELS = {
|
|
9
12
|
general: "General",
|
|
@@ -63,8 +66,8 @@ export function FAQSection({ title, subtitle, items, tabs: tabsProp, showCategor
|
|
|
63
66
|
return items;
|
|
64
67
|
return items.filter((i) => (i.category ?? "general") === activeTab);
|
|
65
68
|
}, [items, showTabs, activeTab]);
|
|
66
|
-
return (_jsx(Section, { className: `py-16 px-4 sm:px-8 ${themed.bgSecondary} ${className}`, children: _jsxs(
|
|
69
|
+
return (_jsx(Section, { className: `py-16 px-4 sm:px-8 ${themed.bgSecondary} ${className}`, children: _jsxs(Div, { className: "w-full max-w-4xl mx-auto", children: [_jsxs(Div, { className: "text-center mb-10", children: [_jsx(Heading, { level: 2, variant: "none", className: "bg-gradient-to-r from-primary to-cobalt bg-clip-text text-transparent text-3xl md:text-4xl font-bold mb-3", children: title }), subtitle && (_jsx(Text, { className: `text-base max-w-xl mx-auto ${themed.textSecondary}`, children: subtitle }))] }), showTabs && (_jsxs(Div, { className: `${flex.center} flex-wrap gap-2 mb-8`, children: [_jsx(Button, { variant: activeTab === "all" ? "primary" : "ghost", size: "sm", onClick: () => setActiveTab("all"), className: "rounded-full", children: "All" }), derivedTabs.map((tab) => (_jsx(Button, { variant: activeTab === tab.value ? "primary" : "ghost", size: "sm", onClick: () => setActiveTab(tab.value), className: "rounded-full", children: tab.label }, tab.value)))] })), _jsxs(Div, { className: "space-y-2", children: [visibleItems.length === 0 && (_jsx(Text, { className: `text-center py-12 ${themed.textSecondary}`, children: "No FAQs in this category yet." })), visibleItems.map((faq) => {
|
|
67
70
|
const isOpen = openIds.has(faq.id);
|
|
68
|
-
return (_jsxs("div", { className: `${themed.bgPrimary} rounded-xl overflow-hidden border transition-all duration-200 ${isOpen ? "border-primary/40 shadow-sm" : `${themed.border}`}`,
|
|
69
|
-
})] }), viewMoreHref && (_jsx(
|
|
71
|
+
return (_jsxs("div", { className: `${themed.bgPrimary} rounded-xl overflow-hidden border transition-all duration-200 ${isOpen ? "border-primary/40 shadow-sm" : `${themed.border}`}`, children: [_jsxs(Button, { variant: "ghost", className: `w-full text-left px-5 py-4 ${flex.between} gap-4 hover:${themed.bgTertiary} transition-colors rounded-none`, onClick: () => toggle(faq.id), "aria-expanded": isOpen, children: [_jsx(Span, { size: "sm", weight: "medium", className: `flex-1 leading-snug ${isOpen ? "text-primary" : themed.textPrimary}`, children: faq.question }), _jsx(ChevronDown, { className: `w-4 h-4 flex-shrink-0 transition-transform duration-250 ${isOpen ? "rotate-180 text-primary" : themed.textSecondary}` })] }), _jsx(Div, { className: `grid transition-all duration-300 ease-out ${isOpen ? "grid-rows-[1fr] opacity-100" : "grid-rows-[0fr] opacity-0"}`, children: _jsx(Div, { className: `${__O.hidden}`, children: _jsx(Div, { className: "px-5 pb-5 pt-0", children: isHtml(faq.answer) ? (_jsx(RichText, { html: faq.answer, proseClass: "prose prose-sm max-w-none dark:prose-invert" })) : (_jsx(Text, { className: `text-sm leading-relaxed ${themed.textSecondary}`, children: faq.answer })) }) }) })] }, faq.id));
|
|
72
|
+
})] }), viewMoreHref && (_jsx(Div, { className: "text-center mt-10", children: _jsxs(TextLink, { href: viewMoreHref, className: "inline-flex items-center gap-2 px-6 py-2.5 rounded-full text-sm font-medium bg-primary/10 text-primary hover:bg-primary/20 dark:bg-primary/15 transition-colors", children: [viewMoreLabel, hasMore && moreCount > 0 && (_jsxs(Span, { size: "xs", className: "bg-primary text-white px-2 py-0.5 rounded-full", children: ["+", moreCount] }))] }) }))] }) }));
|
|
70
73
|
}
|
|
@@ -5,6 +5,12 @@ import { ROUTES } from "../../../next/routing/route-map";
|
|
|
5
5
|
import { formatCurrency } from "../../../utils/number.formatter";
|
|
6
6
|
import { BUNDLE_COPY, BUNDLE_STOCK_VARIANT, } from "../../../_internal/shared/features/categories/bundle-copy";
|
|
7
7
|
import { BundleBuyNowCta } from "../../categories/components/BundleBuyNowCta";
|
|
8
|
+
const __P = {
|
|
9
|
+
p3: "p-3",
|
|
10
|
+
};
|
|
11
|
+
const __O = {
|
|
12
|
+
hidden: "overflow-hidden",
|
|
13
|
+
};
|
|
8
14
|
const PLACEHOLDER_EMOJI = "📦";
|
|
9
15
|
export function FeaturedBundlesSection({ title = BUNDLE_COPY.featuredDefaultTitle, description, initialItems = [], className = "", onBuyNow, }) {
|
|
10
16
|
const items = initialItems.filter((c) => c.categoryType === "bundle");
|
|
@@ -15,9 +21,9 @@ function FeaturedBundleCard({ bundle, onBuyNow }) {
|
|
|
15
21
|
const memberCount = bundle.bundleProductIds?.length ?? 0;
|
|
16
22
|
const cover = bundle.display?.coverImage;
|
|
17
23
|
const href = String(ROUTES.PUBLIC.BUNDLE_DETAIL?.(bundle.slug) ?? "#");
|
|
18
|
-
return (_jsxs(Stack, { gap: "none", className: "rounded-xl border border-zinc-200 bg-white dark:border-zinc-800 dark:bg-zinc-900", children: [_jsxs(Link, { href: href, className: "group block p-3 hover:no-underline", children: [_jsx(Div, { className:
|
|
24
|
+
return (_jsxs(Stack, { gap: "none", className: "rounded-xl border border-zinc-200 bg-white dark:border-zinc-800 dark:bg-zinc-900", children: [_jsxs(Link, { href: href, className: "group block p-3 hover:no-underline", children: [_jsx(Div, { className: `mb-2 aspect-square ${__O.hidden} rounded-lg bg-zinc-100 dark:bg-zinc-800`, children: cover ? (
|
|
19
25
|
// eslint-disable-next-line @next/next/no-img-element, lir/no-raw-media-elements
|
|
20
26
|
_jsx("img", { src: cover, alt: bundle.name, className: "h-full w-full object-cover transition-transform group-hover:scale-105", loading: "lazy" })) : (_jsx(Div, { className: "flex h-full w-full items-center justify-center text-3xl", children: PLACEHOLDER_EMOJI })) }), _jsx(Text, { className: "line-clamp-2 text-sm font-semibold", children: bundle.name }), _jsxs(Row, { gap: "sm", align: "center", className: "mt-1 flex-wrap", children: [_jsx(Text, { size: "sm", weight: "bold", children: bundle.bundlePriceInPaise
|
|
21
27
|
? formatCurrency(bundle.bundlePriceInPaise / 100, "INR")
|
|
22
|
-
: BUNDLE_COPY.featured.priceFallback }), _jsxs(Text, { size: "xs", color: "muted", children: ["\u00B7 ", BUNDLE_COPY.featured.itemCount(memberCount)] }), stock !== "in_stock" && (_jsx(Badge, { variant: BUNDLE_STOCK_VARIANT[stock], children: BUNDLE_COPY.stockBadge.listVariantOutOfStock }))] })] }), onBuyNow && (_jsx(Div, { className:
|
|
28
|
+
: BUNDLE_COPY.featured.priceFallback }), _jsxs(Text, { size: "xs", color: "muted", children: ["\u00B7 ", BUNDLE_COPY.featured.itemCount(memberCount)] }), stock !== "in_stock" && (_jsx(Badge, { variant: BUNDLE_STOCK_VARIANT[stock], children: BUNDLE_COPY.stockBadge.listVariantOutOfStock }))] })] }), onBuyNow && (_jsx(Div, { className: `border-t border-zinc-100 ${__P.p3} pt-2 dark:border-zinc-800`, children: _jsx(BundleBuyNowCta, { bundleSlug: bundle.slug, outOfStock: stock === "out_of_stock", onBuyNow: onBuyNow, compact: true }) }))] }));
|
|
23
29
|
}
|
|
@@ -8,7 +8,7 @@ export function FeaturedResultsSection({ title, subtitle, pillLabel, ornamentLab
|
|
|
8
8
|
const pillCls = "inline-flex items-center gap-2 rounded-full border border-primary-500/30 bg-primary-500/10 px-5 py-1.5 text-xs font-medium uppercase tracking-[0.2em] text-primary-700 backdrop-blur-sm dark:text-primary-400";
|
|
9
9
|
if (!items.length)
|
|
10
10
|
return null;
|
|
11
|
-
return (_jsxs(Section, { className: `px-4 py-16 md:py-20 ${className}`, children: [_jsxs(Div, { className: "mb-12 text-center", children: [pillLabel && (_jsxs(Span, { className: pillCls, children: [_jsx(Span, { className: "inline-block h-1.5 w-1.5 rounded-full bg-primary-500", "aria-hidden": "true" }), pillLabel] })), _jsx(Heading, { level: 2, className: "mt-3 font-display text-4xl text-zinc-900 dark:text-white", children: title }), _jsxs(Div, { className: `mt-3 ${flex.center} gap-2 text-zinc-400 dark:text-zinc-400`, "aria-hidden": "true", children: [_jsx(Span, { className: "h-px w-6 bg-current" }), _jsx(Span, {
|
|
11
|
+
return (_jsxs(Section, { className: `px-4 py-16 md:py-20 ${className}`, children: [_jsxs(Div, { className: "mb-12 text-center", children: [pillLabel && (_jsxs(Span, { className: pillCls, children: [_jsx(Span, { className: "inline-block h-1.5 w-1.5 rounded-full bg-primary-500", "aria-hidden": "true" }), pillLabel] })), _jsx(Heading, { level: 2, className: "mt-3 font-display text-4xl text-zinc-900 dark:text-white", children: title }), _jsxs(Div, { className: `mt-3 ${flex.center} gap-2 text-zinc-400 dark:text-zinc-400`, "aria-hidden": "true", children: [_jsx(Span, { className: "h-px w-6 bg-current" }), _jsx(Span, { size: "xs", children: ornamentLabel }), _jsx(Span, { className: "h-px w-6 bg-current" })] }), subtitle && (_jsx(Text, { className: "mx-auto mt-4 max-w-md text-sm text-zinc-500 dark:text-zinc-400", children: subtitle }))] }), _jsx(Div, { className: "mx-auto max-w-7xl", children: _jsx(HorizontalScroller, { items: items, renderItem: (item, i) => (_jsx(Div, { className: "w-full sm:w-auto", children: _jsx(BeforeAfterCard, { item: {
|
|
12
12
|
id: item.id ?? `result-${i}`,
|
|
13
13
|
beforeImage: item.beforeImage,
|
|
14
14
|
afterImage: item.afterImage,
|
|
@@ -1,15 +1,21 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
-
import { Heading, Section, Text } from "../../../ui";
|
|
2
|
+
import { Div, Heading, Section, Span, Text } from "../../../ui";
|
|
3
3
|
import { THEME_CONSTANTS } from "../../../tokens";
|
|
4
4
|
import { siteSettingsRepository } from "../../admin/repository/site-settings.repository";
|
|
5
5
|
import { fetchGoogleReviews } from "../lib/google-reviews-fetcher";
|
|
6
|
+
const __P = {
|
|
7
|
+
p4: "p-4",
|
|
8
|
+
};
|
|
9
|
+
const CLS_STAR_ON = "text-yellow-400";
|
|
10
|
+
const CLS_STAR_OFF = "text-zinc-300 dark:text-zinc-600";
|
|
11
|
+
const CLS_GMAPS_LINK = "shrink-0 text-sm font-medium text-blue-600 dark:text-blue-400 hover:underline";
|
|
6
12
|
// --- Star Rating -------------------------------------------------------------
|
|
7
13
|
function StarRating({ rating }) {
|
|
8
|
-
return (_jsx(
|
|
14
|
+
return (_jsx(Div, { className: "flex items-center gap-0.5", "aria-label": `${rating} out of 5 stars`, children: [1, 2, 3, 4, 5].map((star) => (_jsx("svg", { className: `w-4 h-4 ${star <= rating ? CLS_STAR_ON : CLS_STAR_OFF}`, viewBox: "0 0 20 20", fill: "currentColor", "aria-hidden": "true", children: _jsx("path", { d: "M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z" }) }, star))) }));
|
|
9
15
|
}
|
|
10
16
|
// --- Google Logo Badge -------------------------------------------------------
|
|
11
17
|
function GoogleBadge() {
|
|
12
|
-
return (_jsxs("
|
|
18
|
+
return (_jsxs(Span, { size: "xs", className: "inline-flex items-center gap-1 text-zinc-500 dark:text-zinc-400", children: [_jsxs("svg", { className: "w-3.5 h-3.5", viewBox: "0 0 24 24", "aria-hidden": "true", children: [_jsx("path", { fill: "#4285F4", d: "M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z" }), _jsx("path", { fill: "#34A853", d: "M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z" }), _jsx("path", { fill: "#FBBC05", d: "M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z" }), _jsx("path", { fill: "#EA4335", d: "M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z" })] }), "Posted on Google"] }));
|
|
13
19
|
}
|
|
14
20
|
// --- Review Card -------------------------------------------------------------
|
|
15
21
|
function ReviewCard({ review, showRating, showDate, }) {
|
|
@@ -20,14 +26,14 @@ function ReviewCard({ review, showRating, showDate, }) {
|
|
|
20
26
|
day: "numeric",
|
|
21
27
|
})
|
|
22
28
|
: null;
|
|
23
|
-
return (_jsxs(
|
|
29
|
+
return (_jsxs(Div, { className: `flex flex-col gap-3 ${__P.p4} rounded-xl bg-[var(--appkit-color-surface)] shadow-sm border border-[var(--appkit-color-border)]`, children: [_jsxs(Div, { className: "flex items-center gap-3", children: [review.authorPhotoUrl ? (_jsx("img", { src: review.authorPhotoUrl, alt: review.authorName, className: "w-9 h-9 rounded-full object-cover flex-shrink-0", loading: "lazy", referrerPolicy: "no-referrer" })) : (_jsx(Div, { className: "w-9 h-9 rounded-full bg-[var(--appkit-color-primary)] flex items-center justify-center flex-shrink-0", children: _jsx(Span, { size: "sm", weight: "bold", className: "text-white", children: review.authorName.charAt(0).toUpperCase() }) })), _jsxs(Div, { className: "min-w-0", children: [_jsx(Text, { className: "text-sm font-semibold truncate", children: review.authorName }), dateStr && (_jsx(Text, { className: "text-xs text-zinc-500 dark:text-zinc-400", children: dateStr }))] })] }), showRating && _jsx(StarRating, { rating: review.rating }), review.text && (_jsx(Text, { className: "text-sm leading-relaxed text-zinc-700 dark:text-zinc-300 line-clamp-4", children: review.text })), _jsx(GoogleBadge, {})] }));
|
|
24
30
|
}
|
|
25
31
|
// --- Empty / Not Configured States -------------------------------------------
|
|
26
32
|
function NotConfiguredState() {
|
|
27
|
-
return (_jsxs(
|
|
33
|
+
return (_jsxs(Div, { className: "flex flex-col items-center justify-center py-16 text-zinc-400 text-sm", children: [_jsxs("svg", { className: "w-10 h-10 mb-3", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.5", children: [_jsx("circle", { cx: "12", cy: "12", r: "10" }), _jsx("path", { d: "M12 8v4m0 4h.01" })] }), "Google Reviews not configured. Add your Google Maps API key in Site Settings."] }));
|
|
28
34
|
}
|
|
29
35
|
function EmptyState() {
|
|
30
|
-
return (_jsxs(
|
|
36
|
+
return (_jsxs(Div, { className: "flex flex-col items-center justify-center py-16 text-zinc-400 text-sm", children: [_jsx("svg", { className: "w-10 h-10 mb-3", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.5", children: _jsx("path", { d: "M8 10h.01M12 10h.01M16 10h.01M9 16H5a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v8a2 2 0 01-2 2h-5l-5 5v-5z" }) }), "No reviews yet."] }));
|
|
31
37
|
}
|
|
32
38
|
export async function GoogleReviewsSection(config) {
|
|
33
39
|
const { placeId: configPlaceId, maxReviews = 6, minRating = 0, layout = "grid", showRating = true, showDate = true, linkToGoogleMaps = true, googleMapsUrl, } = config;
|
|
@@ -38,7 +44,7 @@ export async function GoogleReviewsSection(config) {
|
|
|
38
44
|
.catch(() => ({}));
|
|
39
45
|
const apiKey = credentials.googleMapsApiKey ?? "";
|
|
40
46
|
if (!apiKey) {
|
|
41
|
-
return (_jsx(Section, { className: `py-12 ${themed.bgPrimary}`, children: _jsx(
|
|
47
|
+
return (_jsx(Section, { className: `py-12 ${themed.bgPrimary}`, children: _jsx(Div, { className: "w-full max-w-7xl mx-auto px-4", children: _jsx(NotConfiguredState, {}) }) }));
|
|
42
48
|
}
|
|
43
49
|
const placeId = configPlaceId || credentials.googlePlaceId || "";
|
|
44
50
|
if (!placeId) {
|
|
@@ -61,5 +67,5 @@ export async function GoogleReviewsSection(config) {
|
|
|
61
67
|
: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4";
|
|
62
68
|
const cardClass = layout === "carousel" ? "flex-shrink-0 w-72 snap-start" : "";
|
|
63
69
|
const mapsHref = googleMapsUrl || (placeId ? `https://search.google.com/local/reviews?placeid=${placeId}` : "");
|
|
64
|
-
return (_jsx(Section, { className: `py-12 ${themed.bgPrimary}`, children: _jsxs(
|
|
70
|
+
return (_jsx(Section, { className: `py-12 ${themed.bgPrimary}`, children: _jsxs(Div, { className: "w-full max-w-7xl mx-auto px-4", children: [_jsxs(Div, { className: "mb-8 flex items-end justify-between gap-4", children: [_jsxs(_Fragment, { children: [_jsx(Heading, { level: 2, children: "What Our Customers Say" }), aggregateRating > 0 && (_jsxs(Div, { className: "flex items-center gap-2 mt-1", children: [_jsx(StarRating, { rating: Math.round(aggregateRating) }), _jsxs(Text, { size: "sm", variant: "muted", children: [aggregateRating.toFixed(1), " \u00B7 ", totalRatings.toLocaleString(), " reviews"] })] }))] }), linkToGoogleMaps && mapsHref && (_jsx("a", { href: mapsHref, target: "_blank", rel: "noopener noreferrer", className: CLS_GMAPS_LINK, children: "View on Google \u2192" }))] }), reviews.length === 0 ? (_jsx(EmptyState, {})) : (_jsx(Div, { className: gridClass, children: reviews.map((review, i) => (_jsx(Div, { className: cardClass, children: _jsx(ReviewCard, { review: review, showRating: showRating, showDate: showDate }) }, `${review.authorName}-${i}`))) }))] }) }));
|
|
65
71
|
}
|