@mohasinac/appkit 3.0.3 → 3.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_internal/client/features/filters/filter-load-options.js +11 -1
- package/dist/_internal/client/features/layout/filterNavItems.js +0 -1
- package/dist/_internal/client/features/layout/index.js +0 -1
- package/dist/_internal/client/features/maintenance/views/MaintenanceDashboardView.js +0 -1
- package/dist/_internal/client/features/maintenance/views/ServerErrorDetailView.js +0 -1
- package/dist/_internal/server/features/auctions/data.d.ts +2 -4
- package/dist/_internal/server/features/auctions/data.js +3 -9
- package/dist/_internal/server/features/checkout/actions.js +9 -9
- package/dist/_internal/server/features/classified/adapters.d.ts +2 -15
- package/dist/_internal/server/features/classified/adapters.js +2 -17
- package/dist/_internal/server/features/classified/data.d.ts +1 -6
- package/dist/_internal/server/features/classified/data.js +2 -10
- package/dist/_internal/server/features/digital-code/adapters.d.ts +2 -15
- package/dist/_internal/server/features/digital-code/adapters.js +2 -17
- package/dist/_internal/server/features/digital-code/data.d.ts +1 -6
- package/dist/_internal/server/features/digital-code/data.js +2 -10
- package/dist/_internal/server/features/live/adapters.d.ts +2 -15
- package/dist/_internal/server/features/live/adapters.js +2 -17
- package/dist/_internal/server/features/live/data.d.ts +1 -6
- package/dist/_internal/server/features/live/data.js +2 -10
- package/dist/_internal/server/features/pre-orders/data.d.ts +2 -4
- package/dist/_internal/server/features/pre-orders/data.js +3 -9
- package/dist/_internal/server/features/prize-draws/actions.d.ts +2 -0
- package/dist/_internal/server/features/prize-draws/actions.js +22 -0
- package/dist/_internal/server/features/prize-draws/data.d.ts +1 -17
- package/dist/_internal/server/features/prize-draws/data.js +2 -20
- package/dist/_internal/server/features/prize-draws/index.d.ts +3 -1
- package/dist/_internal/server/features/prize-draws/index.js +2 -0
- package/dist/_internal/server/features/prize-draws/service.d.ts +3 -0
- package/dist/_internal/server/features/prize-draws/service.js +19 -0
- package/dist/_internal/server/features/shared/listing-adapters.d.ts +19 -0
- package/dist/_internal/server/features/shared/listing-adapters.js +20 -0
- package/dist/_internal/server/features/shared/listing-data-factory.d.ts +9 -0
- package/dist/_internal/server/features/shared/listing-data-factory.js +33 -0
- package/dist/_internal/server/features/stores/data.d.ts +3 -14
- package/dist/_internal/server/features/stores/data.js +6 -44
- package/dist/_internal/server/jobs/core/cleanupRtdbEvents.js +1 -1
- package/dist/_internal/shared/features/cart/schema.d.ts +8 -8
- package/dist/_internal/shared/features/cart/schema.js +3 -0
- package/dist/_internal/shared/listing-types/_registry.js +2 -0
- package/dist/_internal/shared/listing-types/action-tracker.js +1 -1
- package/dist/_internal/shared/listing-types/auction/schema.d.ts +3 -1
- package/dist/_internal/shared/listing-types/auction/schema.js +7 -1
- package/dist/_internal/shared/listing-types/classified/schema.d.ts +2 -1
- package/dist/_internal/shared/listing-types/classified/schema.js +3 -1
- package/dist/_internal/shared/listing-types/digital-code/schema.d.ts +3 -1
- package/dist/_internal/shared/listing-types/digital-code/schema.js +7 -1
- package/dist/_internal/shared/listing-types/live/schema.d.ts +2 -1
- package/dist/_internal/shared/listing-types/live/schema.js +3 -1
- package/dist/_internal/shared/listing-types/pre-order/schema.d.ts +3 -1
- package/dist/_internal/shared/listing-types/pre-order/schema.js +7 -1
- package/dist/_internal/shared/listing-types/prize-draw/schema.d.ts +3 -1
- package/dist/_internal/shared/listing-types/prize-draw/schema.js +13 -1
- package/dist/_internal/shared/listing-types/standard/schema.d.ts +2 -1
- package/dist/_internal/shared/listing-types/standard/schema.js +4 -1
- package/dist/_internal/shared/types/base-document.d.ts +15 -0
- package/dist/_internal/shared/types/base-document.js +1 -0
- package/dist/_internal/shared/types/index.d.ts +2 -0
- package/dist/_internal/shared/types/index.js +1 -0
- package/dist/client/api/ApiError.d.ts +10 -4
- package/dist/client/api/surface-error.js +0 -1
- package/dist/client.d.ts +8 -4
- package/dist/client.js +4 -2
- package/dist/constants/api-endpoints.d.ts +12 -0
- package/dist/constants/api-endpoints.js +4 -0
- package/dist/core/hooks/useSyncManager.js +4 -4
- package/dist/features/_guide-cls.d.ts +1 -1
- package/dist/features/_guide-cls.js +1 -1
- package/dist/features/about/components/AboutView.js +1 -4
- package/dist/features/about/components/FAQPageView.js +1 -1
- package/dist/features/about/components/FeesView.js +1 -1
- package/dist/features/about/components/HelpPageView.js +1 -1
- package/dist/features/about/components/HowOrdersWorkView.js +1 -1
- package/dist/features/about/components/PublicProfileView.js +6 -6
- package/dist/features/about/components/TrackOrderView.js +1 -1
- package/dist/features/account/components/AddressBook.js +1 -1
- package/dist/features/account/components/AddressForm.js +10 -2
- package/dist/features/account/components/AddressesIndexListing.js +1 -1
- package/dist/features/account/components/BuyerAccountGuideView.js +1 -1
- package/dist/features/account/components/BuyerAuctionsGuideView.js +1 -1
- package/dist/features/account/components/BuyerOrdersGuideView.js +1 -1
- package/dist/features/account/components/BuyerShoppingGuideView.js +1 -1
- package/dist/features/account/components/ChatWindow.js +1 -1
- package/dist/features/account/components/MessagesView.js +1 -1
- package/dist/features/account/components/NotificationBell.js +25 -10
- package/dist/features/account/components/NotificationPreferencesPanel.js +2 -2
- package/dist/features/account/components/UserOffersPanel.js +1 -0
- package/dist/features/account/components/UserSidebar.js +1 -6
- package/dist/features/account/components/UserSupportView.js +1 -1
- package/dist/features/addresses/schemas/firestore.d.ts +2 -4
- package/dist/features/admin/components/AdminAnalyticsGuideView.js +2 -2
- package/dist/features/admin/components/AdminBlogEditorView.js +1 -1
- package/dist/features/admin/components/AdminBundlesView.js +1 -1
- package/dist/features/admin/components/AdminCarouselEditorView.js +1 -1
- package/dist/features/admin/components/AdminCatalogGuideView.js +2 -2
- package/dist/features/admin/components/AdminContentGuideView.js +2 -2
- package/dist/features/admin/components/AdminEmployeeEditorView.js +2 -2
- package/dist/features/admin/components/AdminFulfillmentView.d.ts +6 -0
- package/dist/features/admin/components/AdminFulfillmentView.js +107 -0
- package/dist/features/admin/components/AdminGuideHubView.js +1 -5
- package/dist/features/admin/components/AdminMediaView.js +1 -1
- package/dist/features/admin/components/AdminNavigationView.js +1 -1
- package/dist/features/admin/components/AdminOrdersGuideView.js +3 -3
- package/dist/features/admin/components/AdminPayoutsView.js +1 -4
- package/dist/features/admin/components/AdminProductEditorView.js +21 -9
- package/dist/features/admin/components/AdminProductsView.js +3 -0
- package/dist/features/admin/components/AdminSidebar.js +1 -6
- package/dist/features/admin/components/AdminSiteConfigGuideView.js +1 -1
- package/dist/features/admin/components/AdminSiteSettingsView.js +9 -1
- package/dist/features/admin/components/AdminStoreEditorView.js +1 -1
- package/dist/features/admin/components/AdminStoresGuideView.js +2 -2
- package/dist/features/admin/components/AdminSupportTicketDetailView.js +7 -7
- package/dist/features/admin/components/AdminTeamGuideView.js +2 -2
- package/dist/features/admin/components/AdminTrustGuideView.js +3 -3
- package/dist/features/admin/components/AdminUsersGuideView.js +3 -3
- package/dist/features/admin/components/DashboardStats.js +6 -5
- package/dist/features/admin/components/DataListingView.d.ts +1 -0
- package/dist/features/admin/components/DataTable.js +2 -2
- package/dist/features/admin/components/analytics/AdminAnalyticsCharts.js +4 -6
- package/dist/features/admin/components/analytics/AdminStatCard.js +4 -3
- package/dist/features/admin/components/analytics/AdminTopProductsTable.js +1 -1
- package/dist/features/admin/components/index.d.ts +2 -0
- package/dist/features/admin/components/index.js +1 -0
- package/dist/features/admin/schemas/firestore.d.ts +3 -8
- package/dist/features/auctions/components/AuctionBidsTable.js +1 -1
- package/dist/features/auctions/components/AuctionDetailPageView.js +1 -1
- package/dist/features/auctions/components/MarketplaceAuctionCard.js +3 -3
- package/dist/features/auctions/schemas/firestore.d.ts +2 -4
- package/dist/features/auctions/schemas/index.d.ts +2 -2
- package/dist/features/auth/components/ForgotPasswordView.js +19 -8
- package/dist/features/auth/components/LoginForm.js +10 -2
- package/dist/features/auth/components/RegisterForm.js +10 -2
- package/dist/features/auth/components/ResetPasswordView.js +19 -8
- package/dist/features/auth/components/SocialAuthButtons.js +1 -1
- package/dist/features/before-after/components/BeforeAfterSlider.js +1 -1
- package/dist/features/before-after/schemas/index.d.ts +2 -2
- package/dist/features/blog/api/[slug]/route.js +1 -1
- package/dist/features/blog/components/BlogFeaturedCard.js +1 -1
- package/dist/features/blog/components/BlogListView.js +1 -1
- package/dist/features/blog/components/BlogPostView.js +1 -1
- package/dist/features/blog/schemas/firestore.d.ts +2 -4
- package/dist/features/blog/schemas/index.d.ts +6 -6
- package/dist/features/cart/components/CartDrawer.js +2 -2
- package/dist/features/cart/components/CartView.js +1 -1
- package/dist/features/cart/components/CheckoutView.js +1 -1
- package/dist/features/cart/schemas/firestore.d.ts +2 -4
- package/dist/features/categories/components/BrandDetailPageView.js +2 -1
- package/dist/features/categories/components/BundleDetailView.js +1 -1
- package/dist/features/categories/components/BundleItemsPicker.js +1 -1
- package/dist/features/categories/components/CategoryBundlesListing.js +3 -1
- package/dist/features/categories/components/CategoryDetailPageView.js +1 -1
- package/dist/features/categories/components/CategoryGrid.js +2 -1
- package/dist/features/categories/components/CategoryTableColumns.js +5 -2
- package/dist/features/categories/components/CategoryTree.js +3 -2
- package/dist/features/categories/components/ConcernCard.js +1 -1
- package/dist/features/categories/schemas/firestore.d.ts +2 -4
- package/dist/features/categories/schemas/index.d.ts +6 -6
- package/dist/features/checkout/components/CheckoutStepper.js +1 -1
- package/dist/features/collections/components/CollectionCard.js +1 -1
- package/dist/features/contact/components/ContactPageView.js +27 -27
- package/dist/features/contact/email.js +4 -4
- package/dist/features/copilot/components/AdminCopilotView.js +3 -3
- package/dist/features/email/primitives.d.ts +4 -0
- package/dist/features/email/primitives.js +4 -0
- package/dist/features/events/components/EventCard.js +2 -2
- package/dist/features/events/components/EventOfferCard.js +1 -1
- package/dist/features/events/components/EventRaffleEntryForm.js +1 -1
- package/dist/features/events/components/EventRaffleWinnerView.js +2 -2
- package/dist/features/events/components/EventSaleBanner.js +0 -1
- package/dist/features/events/schemas/firestore.d.ts +2 -4
- package/dist/features/events/schemas/index.d.ts +4 -4
- package/dist/features/faq/components/ContactCTA.js +1 -1
- package/dist/features/faq/components/FAQAccordion.js +2 -2
- package/dist/features/faq/components/FAQCategorySidebar.js +2 -2
- package/dist/features/faq/components/FAQHelpfulButtons.js +2 -2
- package/dist/features/faq/components/RelatedFAQs.js +1 -1
- package/dist/features/faq/schemas/firestore.d.ts +2 -4
- package/dist/features/faq/schemas/index.d.ts +4 -4
- package/dist/features/filters/AsyncFacetSection.js +3 -3
- package/dist/features/filters/FilterFacetSection.js +6 -6
- package/dist/features/filters/RangeFilter.js +2 -2
- package/dist/features/filters/SwitchFilter.js +1 -1
- package/dist/features/forms/Checkbox.js +1 -1
- package/dist/features/forms/Slider.js +7 -2
- package/dist/features/forms/utils.d.ts +2 -2
- package/dist/features/forms/utils.js +2 -2
- package/dist/features/grouped/schemas/index.d.ts +2 -2
- package/dist/features/history/hooks/useHistory.js +1 -1
- package/dist/features/homepage/components/AdSlot.js +3 -3
- package/dist/features/homepage/components/AdvertisementBanner.js +5 -4
- package/dist/features/homepage/components/BeforeAfterCard.js +9 -1
- package/dist/features/homepage/components/CharacterHotspot.js +42 -49
- package/dist/features/homepage/components/CharacterHotspotForm.js +18 -20
- package/dist/features/homepage/components/CollectionCardsSection.js +2 -2
- package/dist/features/homepage/components/CustomCardsSection.js +3 -6
- package/dist/features/homepage/components/CustomerReviewsSection.js +1 -1
- package/dist/features/homepage/components/FAQSection.js +2 -2
- package/dist/features/homepage/components/FeaturedResultsSection.js +1 -1
- package/dist/features/homepage/components/GoogleReviewsSection.js +4 -4
- package/dist/features/homepage/components/HeroBanner.js +12 -63
- package/dist/features/homepage/components/HeroCarousel.js +6 -6
- package/dist/features/homepage/components/HeroSection.js +1 -1
- package/dist/features/homepage/components/HowItWorksInfoView.js +1 -1
- package/dist/features/homepage/components/HowItWorksSection.js +5 -3
- package/dist/features/homepage/components/NewsletterBanner.js +3 -7
- package/dist/features/homepage/components/PromoGrid.js +2 -26
- package/dist/features/homepage/components/SectionCarousel.js +1 -1
- package/dist/features/homepage/components/SecurityHighlightsSection.js +6 -3
- package/dist/features/homepage/components/ShopByCategorySection.js +3 -3
- package/dist/features/homepage/components/SiteFeaturesSection.js +1 -1
- package/dist/features/homepage/components/SocialPostCard.js +2 -3
- package/dist/features/homepage/components/StatsCounterSection.js +6 -3
- package/dist/features/homepage/components/TestimonialsCarousel.js +2 -25
- package/dist/features/homepage/components/TrustBadges.js +1 -9
- package/dist/features/homepage/components/TrustFeaturesSection.js +6 -3
- package/dist/features/homepage/components/TrustIndicatorsSection.js +1 -1
- package/dist/features/homepage/components/WelcomeSection.js +2 -2
- package/dist/features/homepage/components/WhatsAppCommunitySection.js +1 -1
- package/dist/features/homepage/lib/franchise-colors.d.ts +7 -0
- package/dist/features/homepage/lib/franchise-colors.js +7 -0
- package/dist/features/homepage/lib/live-stats.js +5 -5
- package/dist/features/homepage/schemas/firestore.d.ts +4 -12
- package/dist/features/homepage/schemas/index.d.ts +2 -2
- package/dist/features/layout/AppLayoutShell.js +7 -9
- package/dist/features/layout/BottomNavbar.js +1 -2
- package/dist/features/messages/hooks/useConversation.js +2 -1
- package/dist/features/messages/hooks/useConversations.js +1 -0
- package/dist/features/messages/schemas/firestore.d.ts +2 -4
- package/dist/features/messages/schemas/index.d.ts +2 -2
- package/dist/features/orders/components/OrdersList.js +1 -1
- package/dist/features/orders/components/RefundHistoryTable.d.ts +6 -0
- package/dist/features/orders/components/RefundHistoryTable.js +3 -2
- package/dist/features/orders/repository/orders.repository.d.ts +5 -0
- package/dist/features/orders/repository/orders.repository.js +26 -0
- package/dist/features/orders/schemas/firestore.d.ts +9 -5
- package/dist/features/orders/schemas/firestore.js +3 -0
- package/dist/features/payments/schemas/firestore.d.ts +2 -4
- package/dist/features/pre-orders/components/MarketplacePreorderCard.js +2 -2
- package/dist/features/pre-orders/components/PreOrderBadge.js +1 -1
- package/dist/features/pre-orders/components/PreOrderDetailPageView.js +2 -1
- package/dist/features/pre-orders/schemas/index.d.ts +2 -2
- package/dist/features/products/components/CompareOverlay.js +11 -8
- package/dist/features/products/components/CustomSectionTabContent.js +1 -1
- package/dist/features/products/components/FeatureBadge.js +11 -1
- package/dist/features/products/components/GroupSettingsPanel.js +2 -2
- package/dist/features/products/components/MarketplaceBundleCard.js +1 -1
- package/dist/features/products/components/MarketplacePrizeDrawCard.js +2 -2
- package/dist/features/products/components/PrizeDrawItemsEditor.js +1 -1
- package/dist/features/products/components/PrizeDrawsIndexListing.js +1 -1
- package/dist/features/products/components/ProductCardMetadataSection.js +0 -1
- package/dist/features/products/components/ProductDetailPageView.js +1 -1
- package/dist/features/products/components/ProductFeatureBadges.js +1 -1
- package/dist/features/products/components/ProductGalleryClient.js +1 -1
- package/dist/features/products/components/ProductGrid.js +7 -7
- package/dist/features/products/components/ShareButton.js +1 -1
- package/dist/features/products/components/ShowGroupSection.js +7 -5
- package/dist/features/products/components/SublistingCarouselSection.js +2 -2
- package/dist/features/products/constants/action-defs.d.ts +16 -0
- package/dist/features/products/constants/action-defs.js +16 -0
- package/dist/features/products/constants/listing-tabs.d.ts +48 -0
- package/dist/features/products/constants/listing-tabs.js +12 -0
- package/dist/features/products/repository/products.repository.d.ts +37 -0
- package/dist/features/products/repository/products.repository.js +28 -1
- package/dist/features/products/schemas/firestore.d.ts +8 -6
- package/dist/features/products/schemas/firestore.js +2 -0
- package/dist/features/products/schemas/index.d.ts +8 -8
- package/dist/features/products/types/index.d.ts +2 -0
- package/dist/features/promotions/components/CouponCard.js +2 -2
- package/dist/features/promotions/schemas/firestore.d.ts +2 -4
- package/dist/features/promotions/schemas/index.d.ts +6 -6
- package/dist/features/reviews/components/ReviewDetailShell.js +3 -3
- package/dist/features/reviews/components/ReviewModal.js +2 -4
- package/dist/features/reviews/components/ReviewSummary.js +3 -2
- package/dist/features/reviews/components/ReviewsList.js +1 -1
- package/dist/features/reviews/schemas/firestore.d.ts +2 -4
- package/dist/features/reviews/schemas/index.d.ts +2 -2
- package/dist/features/scams/actions/scam-actions.js +1 -1
- package/dist/features/scams/components/ScamProfileView.js +1 -1
- package/dist/features/scams/schemas/firestore.d.ts +2 -4
- package/dist/features/scams/schemas/index.d.ts +4 -4
- package/dist/features/search/components/Search.js +2 -2
- package/dist/features/search/components/SearchFiltersRow.js +1 -1
- package/dist/features/search/schemas/index.d.ts +3 -3
- package/dist/features/seller/components/BarcodeField.d.ts +17 -0
- package/dist/features/seller/components/BarcodeField.js +30 -0
- package/dist/features/seller/components/FulfillmentView.d.ts +5 -0
- package/dist/features/seller/components/FulfillmentView.js +120 -0
- package/dist/features/seller/components/PhysicalLocationModal.js +2 -3
- package/dist/features/seller/components/PrintCenterView.d.ts +3 -1
- package/dist/features/seller/components/PrintCenterView.js +52 -4
- package/dist/features/seller/components/SellerAddressesView.js +2 -1
- package/dist/features/seller/components/SellerAnalyticsAlertsView.js +1 -1
- package/dist/features/seller/components/SellerBidsView.js +1 -1
- package/dist/features/seller/components/SellerCouponEditorView.js +1 -1
- package/dist/features/seller/components/SellerGoogleReviewsView.js +1 -1
- package/dist/features/seller/components/SellerLiveView.js +1 -1
- package/dist/features/seller/components/SellerOffersPanel.js +1 -0
- package/dist/features/seller/components/SellerOrdersView.js +1 -1
- package/dist/features/seller/components/SellerPayoutMethodsView.js +8 -2
- package/dist/features/seller/components/SellerPayoutRequestView.js +1 -1
- package/dist/features/seller/components/SellerPayoutSettingsView.js +1 -1
- package/dist/features/seller/components/SellerProductShell.d.ts +2 -0
- package/dist/features/seller/components/SellerProductShell.js +4 -3
- package/dist/features/seller/components/SellerProductsCards.js +1 -1
- package/dist/features/seller/components/SellerProductsView.js +1 -1
- package/dist/features/seller/components/SellerReviewsView.js +2 -1
- package/dist/features/seller/components/SellerShippingConfigsView.js +9 -3
- package/dist/features/seller/components/SellerShippingView.js +1 -1
- package/dist/features/seller/components/SellerSidebar.js +3 -8
- package/dist/features/seller/components/SellerStoreCategoriesView.js +11 -3
- package/dist/features/seller/components/SellerTemplatesView.js +8 -2
- package/dist/features/seller/components/analytics/SellerRevenueChart.js +1 -1
- package/dist/features/seller/components/analytics/SellerTopProducts.js +1 -1
- package/dist/features/seller/components/index.d.ts +4 -0
- package/dist/features/seller/components/index.js +2 -0
- package/dist/features/seller/schemas/index.d.ts +4 -4
- package/dist/features/shell/FormShell.js +2 -2
- package/dist/features/shell/QuickFormDrawer.js +1 -1
- package/dist/features/site-settings/components/NavPermissionsManager.js +1 -1
- package/dist/features/store-extensions/schemas/firestore.d.ts +12 -44
- package/dist/features/stores/components/StoreCapabilitiesGuideView.js +1 -1
- package/dist/features/stores/components/StoreClassifiedsListing.d.ts +5 -0
- package/dist/features/stores/components/StoreClassifiedsListing.js +48 -0
- package/dist/features/stores/components/StoreClassifiedsPageView.d.ts +4 -0
- package/dist/features/stores/components/StoreClassifiedsPageView.js +20 -0
- package/dist/features/stores/components/StoreDetailLayoutView.js +23 -2
- package/dist/features/stores/components/StoreDigitalCodesListing.d.ts +5 -0
- package/dist/features/stores/components/StoreDigitalCodesListing.js +48 -0
- package/dist/features/stores/components/StoreDigitalCodesPageView.d.ts +4 -0
- package/dist/features/stores/components/StoreDigitalCodesPageView.js +20 -0
- package/dist/features/stores/components/StoreGuideHubView.js +2 -9
- package/dist/features/stores/components/StoreHeader.js +1 -1
- package/dist/features/stores/components/StoreListingsGuideView.js +4 -4
- package/dist/features/stores/components/StoreLiveItemsListing.d.ts +5 -0
- package/dist/features/stores/components/StoreLiveItemsListing.js +48 -0
- package/dist/features/stores/components/StoreLiveItemsPageView.d.ts +4 -0
- package/dist/features/stores/components/StoreLiveItemsPageView.js +20 -0
- package/dist/features/stores/components/StoreOrdersGuideView.js +2 -2
- package/dist/features/stores/components/StoresIndexListing.js +1 -1
- package/dist/features/stores/components/index.d.ts +9 -0
- package/dist/features/stores/components/index.js +3 -0
- package/dist/features/stores/schemas/firestore.d.ts +2 -4
- package/dist/features/stores/schemas/index.d.ts +4 -4
- package/dist/features/support/schemas/firestore.d.ts +2 -4
- package/dist/features/support/schemas/index.d.ts +2 -2
- package/dist/features/whatsapp-bot/components/SellerWhatsAppSettingsView.js +2 -2
- package/dist/features/wishlist/components/WishlistPage.js +1 -1
- package/dist/features/wishlist/components/WishlistToggleButton.js +3 -3
- package/dist/features/wishlist/hooks/useWishlistCount.js +1 -1
- package/dist/http/ApiClient.d.ts +1 -0
- package/dist/http/ApiClient.js +20 -0
- package/dist/monitoring/error-tracking.d.ts +0 -3
- package/dist/monitoring/error-tracking.js +1 -1
- package/dist/monitoring/server-logger.js +3 -3
- package/dist/next/components/GlobalError.js +1 -1
- package/dist/next/routing/route-map.d.ts +11 -0
- package/dist/next/routing/route-map.js +5 -0
- package/dist/react/ErrorBoundary.js +1 -1
- package/dist/schemas/registry.d.ts +24 -24
- package/dist/seed/grouped-listings-seed-data.d.ts +2 -1
- package/dist/seed/products-preorders-seed-data.d.ts +2 -1
- package/dist/seed/products-standard-seed-data.js +8 -0
- package/dist/server-entry.d.ts +3 -0
- package/dist/server-entry.js +3 -0
- package/dist/server.d.ts +4 -4
- package/dist/styles.css +45 -7
- package/dist/tailwind-utilities.css +1 -1
- package/dist/tokens/themes/default-light.js +3 -0
- package/dist/tokens/tokens.css +43 -6
- package/dist/ui/components/Anchor.d.ts +8 -1
- package/dist/ui/components/Anchor.js +16 -2
- package/dist/ui/components/Button.d.ts +5 -2
- package/dist/ui/components/Button.js +5 -2
- package/dist/ui/components/Details.d.ts +33 -2
- package/dist/ui/components/Details.js +73 -4
- package/dist/ui/components/Div.d.ts +3 -0
- package/dist/ui/components/Div.js +12 -1
- package/dist/ui/components/DynamicBgDiv.d.ts +13 -0
- package/dist/ui/components/DynamicBgDiv.js +18 -0
- package/dist/ui/components/Form.d.ts +3 -19
- package/dist/ui/components/Form.js +8 -1
- package/dist/ui/components/Layout.d.ts +12 -1
- package/dist/ui/components/Layout.js +9 -1
- package/dist/ui/components/Progress.d.ts +1 -1
- package/dist/ui/components/Progress.js +1 -0
- package/dist/ui/components/Progress.style.css +1 -0
- package/dist/ui/components/ProgressBarFill.d.ts +6 -0
- package/dist/ui/components/ProgressBarFill.js +11 -0
- package/dist/ui/components/Semantic.d.ts +26 -7
- package/dist/ui/components/Semantic.js +33 -8
- package/dist/ui/components/TextLink.d.ts +36 -1
- package/dist/ui/components/TextLink.js +30 -2
- package/dist/ui/components/Typography.d.ts +26 -6
- package/dist/ui/components/Typography.js +37 -13
- package/dist/ui/components/VacationBanner.js +0 -1
- package/dist/ui/components/surface-tokens.d.ts +12 -2
- package/dist/ui/components/surface-tokens.js +19 -1
- package/dist/ui/rich-text/RichText.js +1 -1
- package/dist/utils/id-generators.d.ts +8 -0
- package/dist/utils/id-generators.js +14 -0
- package/dist/validation/schemas.d.ts +1 -1
- package/package.json +2 -1
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* Bids/Auctions Firestore Document Types & Constants
|
|
3
3
|
*/
|
|
4
4
|
import { type GenerateBidIdInput } from "../../../utils/id-generators";
|
|
5
|
+
import type { BaseDocument } from "../../../_internal/shared/types/base-document";
|
|
5
6
|
export type BidStatus = "active" | "outbid" | "won" | "lost" | "cancelled";
|
|
6
7
|
/** Runtime-accessible bid status values — use instead of bare string literals. */
|
|
7
8
|
export declare const BidStatusValues: {
|
|
@@ -11,8 +12,7 @@ export declare const BidStatusValues: {
|
|
|
11
12
|
readonly LOST: "lost";
|
|
12
13
|
readonly CANCELLED: "cancelled";
|
|
13
14
|
};
|
|
14
|
-
export interface BidDocument {
|
|
15
|
-
id: string;
|
|
15
|
+
export interface BidDocument extends BaseDocument {
|
|
16
16
|
productId: string;
|
|
17
17
|
productTitle: string;
|
|
18
18
|
userId: string;
|
|
@@ -25,8 +25,6 @@ export interface BidDocument {
|
|
|
25
25
|
previousBidAmount?: number;
|
|
26
26
|
bidDate: Date;
|
|
27
27
|
autoMaxBid?: number;
|
|
28
|
-
createdAt: Date;
|
|
29
|
-
updatedAt: Date;
|
|
30
28
|
}
|
|
31
29
|
export declare const BID_COLLECTION: "bids";
|
|
32
30
|
export declare const BID_INDEXED_FIELDS: readonly ["productId", "userId", "status", "isWinning", "bidDate", "createdAt"];
|
|
@@ -63,13 +63,13 @@ export declare const auctionItemSchema: z.ZodObject<{
|
|
|
63
63
|
featured: boolean;
|
|
64
64
|
listingType: "auction";
|
|
65
65
|
createdAt: string;
|
|
66
|
-
id: string;
|
|
67
66
|
title: string;
|
|
68
67
|
slug: string;
|
|
69
68
|
price: number;
|
|
70
69
|
auctionEndDate: string;
|
|
71
70
|
startingBid: number;
|
|
72
71
|
bidCount: number;
|
|
72
|
+
id: string;
|
|
73
73
|
updatedAt: string;
|
|
74
74
|
sellerId: string;
|
|
75
75
|
storeId?: string | undefined;
|
|
@@ -92,13 +92,13 @@ export declare const auctionItemSchema: z.ZodObject<{
|
|
|
92
92
|
featured: boolean;
|
|
93
93
|
listingType: "auction";
|
|
94
94
|
createdAt: string;
|
|
95
|
-
id: string;
|
|
96
95
|
title: string;
|
|
97
96
|
slug: string;
|
|
98
97
|
price: number;
|
|
99
98
|
auctionEndDate: string;
|
|
100
99
|
startingBid: number;
|
|
101
100
|
bidCount: number;
|
|
101
|
+
id: string;
|
|
102
102
|
updatedAt: string;
|
|
103
103
|
sellerId: string;
|
|
104
104
|
storeId?: string | undefined;
|
|
@@ -1,21 +1,32 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { normalizeError } from "../../../errors/normalize";
|
|
3
4
|
import { useState } from "react";
|
|
4
|
-
import { Alert, Button, Div, Heading, Row, Stack, Text } from "../../../ui";
|
|
5
|
+
import { Alert, Button, Div, Heading, Row, Stack, Text, useToast } from "../../../ui";
|
|
5
6
|
import { Form } from "../../../ui/components/Form";
|
|
6
7
|
import { FieldInput } from "../../../ui/forms/FieldInput";
|
|
7
8
|
import { applyZodIssues } from "../../../ui/forms/FormShell";
|
|
8
9
|
import { forgotPasswordSchema } from "../schemas";
|
|
9
10
|
export function ForgotPasswordView({ onSubmit, isLoading = false, error, success, labels = {}, renderBackLink, className = "", }) {
|
|
10
11
|
const [email, setEmail] = useState("");
|
|
12
|
+
const { showToast } = useToast();
|
|
13
|
+
function buildClickHandler(setFieldError, clearErrors) {
|
|
14
|
+
return async () => {
|
|
15
|
+
clearErrors();
|
|
16
|
+
const parsed = forgotPasswordSchema.safeParse({ email });
|
|
17
|
+
if (!parsed.success)
|
|
18
|
+
return applyZodIssues(parsed.error.issues, setFieldError);
|
|
19
|
+
try {
|
|
20
|
+
await onSubmit(parsed.data.email);
|
|
21
|
+
}
|
|
22
|
+
catch (err) {
|
|
23
|
+
void normalizeError(err);
|
|
24
|
+
showToast(err instanceof Error ? err.message : "Failed to send reset link", "error");
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
}
|
|
11
28
|
return (_jsx(Row, { className: `min-h-[60vh] ${className}`, align: "center", justify: "center", padding: "x-md", children: _jsxs(Stack, { className: "max-w-md w-full", gap: "lg", children: [_jsxs(Div, { className: "text-center", children: [_jsx(Heading, { level: 1, className: "font-extrabold", size: "3xl", children: labels.title ?? "Forgot Password" }), _jsx(Text, { className: "mt-2 text-neutral-600 dark:text-neutral-400", size: "sm", children: labels.description ??
|
|
12
|
-
"Enter your email and we'll send you a reset link." })] }), error && (_jsx(Alert, { variant: "error", compact: true, children: error })), success && (_jsx(Alert, { variant: "success", compact: true, children: success })), !success && (_jsx(Form, { noValidate: true, onSubmit: (e) => e.preventDefault(), spacing: "md", children: ({ setFieldError, clearErrors }) => (_jsxs(_Fragment, { children: [_jsx(FieldInput, { name: "email", label: labels.emailLabel ?? "Email address", type: "email", autoComplete: "username", required: true, placeholder: labels.emailPlaceholder ?? "you@example.com", value: email, onChange: setEmail }), _jsx(Button, { type: "submit", isLoading: isLoading, disabled: isLoading, className: "w-full", onClick:
|
|
13
|
-
clearErrors();
|
|
14
|
-
const parsed = forgotPasswordSchema.safeParse({ email });
|
|
15
|
-
if (!parsed.success)
|
|
16
|
-
return applyZodIssues(parsed.error.issues, setFieldError);
|
|
17
|
-
await onSubmit(parsed.data.email);
|
|
18
|
-
}, children: isLoading
|
|
29
|
+
"Enter your email and we'll send you a reset link." })] }), error && (_jsx(Alert, { variant: "error", compact: true, children: error })), success && (_jsx(Alert, { variant: "success", compact: true, children: success })), !success && (_jsx(Form, { noValidate: true, onSubmit: (e) => e.preventDefault(), spacing: "md", children: ({ setFieldError, clearErrors }) => (_jsxs(_Fragment, { children: [_jsx(FieldInput, { name: "email", label: labels.emailLabel ?? "Email address", type: "email", autoComplete: "username", required: true, placeholder: labels.emailPlaceholder ?? "you@example.com", value: email, onChange: setEmail }), _jsx(Button, { type: "submit", isLoading: isLoading, disabled: isLoading, className: "w-full", onClick: buildClickHandler(setFieldError, clearErrors), children: isLoading
|
|
19
30
|
? (labels.submittingLabel ?? "Sending…")
|
|
20
31
|
: (labels.submitLabel ?? "Send reset link") })] })) })), renderBackLink && (_jsx(Div, { textSize: "sm", className: "text-center", children: renderBackLink() }))] }) }));
|
|
21
32
|
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { normalizeError } from "../../../errors/normalize";
|
|
3
4
|
import { useState } from "react";
|
|
4
|
-
import { Alert, Button, Div, Heading, Row, Stack, Text } from "../../../ui";
|
|
5
|
+
import { Alert, Button, Div, Heading, Row, Stack, Text, useToast } from "../../../ui";
|
|
5
6
|
import { Form } from "../../../ui/components/Form";
|
|
6
7
|
import { FieldInput } from "../../../ui/forms/FieldInput";
|
|
7
8
|
import { FieldCheckbox } from "../../../ui/forms/FieldCheckbox";
|
|
@@ -9,6 +10,7 @@ import { applyZodIssues } from "../../../ui/forms/FormShell";
|
|
|
9
10
|
import { loginSchema } from "../schemas";
|
|
10
11
|
import { SocialAuthButtons } from "./SocialAuthButtons";
|
|
11
12
|
export function LoginForm({ onSubmit, onGoogleLogin, isLoading = false, error, labels = {}, renderSocialButtons, renderCreateAccountLink, renderForgotPasswordLink, className = "", }) {
|
|
13
|
+
const { showToast } = useToast();
|
|
12
14
|
const [values, setValues] = useState({
|
|
13
15
|
email: "",
|
|
14
16
|
password: "",
|
|
@@ -19,7 +21,13 @@ export function LoginForm({ onSubmit, onGoogleLogin, isLoading = false, error, l
|
|
|
19
21
|
const parsed = loginSchema.safeParse(values);
|
|
20
22
|
if (!parsed.success)
|
|
21
23
|
return applyZodIssues(parsed.error.issues, setFieldError);
|
|
22
|
-
|
|
24
|
+
try {
|
|
25
|
+
await onSubmit(values);
|
|
26
|
+
}
|
|
27
|
+
catch (err) {
|
|
28
|
+
void normalizeError(err);
|
|
29
|
+
showToast(err instanceof Error ? err.message : "Sign in failed", "error");
|
|
30
|
+
}
|
|
23
31
|
}, children: isLoading
|
|
24
32
|
? (labels.submittingLabel ?? "Signing in…")
|
|
25
33
|
: (labels.submitLabel ?? "Sign in") })] })) }), onGoogleLogin && !renderSocialButtons ? (_jsx(SocialAuthButtons, { onGoogle: onGoogleLogin, disabled: isLoading, dividerLabel: labels.orSeparator ?? "Or continue with", googleLabel: "Sign in with Google" })) : (renderSocialButtons?.())] }) }));
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { normalizeError } from "../../../errors/normalize";
|
|
3
4
|
import { useState } from "react";
|
|
4
5
|
import { z } from "zod";
|
|
5
|
-
import { Alert, Button, Div, Heading, Row, Stack, Text } from "../../../ui";
|
|
6
|
+
import { Alert, Button, Div, Heading, Row, Stack, Text, useToast } from "../../../ui";
|
|
6
7
|
import { Form } from "../../../ui/components/Form";
|
|
7
8
|
import { FieldInput } from "../../../ui/forms/FieldInput";
|
|
8
9
|
import { FieldCheckbox } from "../../../ui/forms/FieldCheckbox";
|
|
@@ -19,6 +20,7 @@ const registerClientSchema = registerSchema.extend({
|
|
|
19
20
|
path: ["confirmPassword"],
|
|
20
21
|
});
|
|
21
22
|
export function RegisterForm({ onSubmit, isLoading = false, error, success, labels = {}, renderSocialButtons, renderLoginLink, renderTermsLink, renderPasswordStrength, className = "", }) {
|
|
23
|
+
const { showToast } = useToast();
|
|
22
24
|
const [values, setValues] = useState({
|
|
23
25
|
email: "",
|
|
24
26
|
password: "",
|
|
@@ -31,7 +33,13 @@ export function RegisterForm({ onSubmit, isLoading = false, error, success, labe
|
|
|
31
33
|
const parsed = registerClientSchema.safeParse(values);
|
|
32
34
|
if (!parsed.success)
|
|
33
35
|
return applyZodIssues(parsed.error.issues, setFieldError);
|
|
34
|
-
|
|
36
|
+
try {
|
|
37
|
+
await onSubmit(values);
|
|
38
|
+
}
|
|
39
|
+
catch (err) {
|
|
40
|
+
void normalizeError(err);
|
|
41
|
+
showToast(err instanceof Error ? err.message : "Registration failed", "error");
|
|
42
|
+
}
|
|
35
43
|
}, children: isLoading
|
|
36
44
|
? (labels.submittingLabel ?? "Creating account…")
|
|
37
45
|
: (labels.submitLabel ?? "Create account") })] })) }), renderSocialButtons?.()] }) }));
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { normalizeError } from "../../../errors/normalize";
|
|
3
4
|
import { useState } from "react";
|
|
4
5
|
import { z } from "zod";
|
|
5
|
-
import { Alert, Button, Div, Heading, Row, Stack, Text } from "../../../ui";
|
|
6
|
+
import { Alert, Button, Div, Heading, Row, Stack, Text, useToast } from "../../../ui";
|
|
6
7
|
import { Form } from "../../../ui/components/Form";
|
|
7
8
|
import { FieldInput } from "../../../ui/forms/FieldInput";
|
|
8
9
|
import { applyZodIssues } from "../../../ui/forms/FormShell";
|
|
@@ -14,15 +15,25 @@ const resetClientSchema = z.object({
|
|
|
14
15
|
path: ["confirmPassword"],
|
|
15
16
|
});
|
|
16
17
|
export function ResetPasswordView({ oobCode, onSubmit, isLoading = false, error, success, labels = {}, renderLoginLink, className = "", }) {
|
|
18
|
+
const { showToast } = useToast();
|
|
17
19
|
const [password, setPassword] = useState("");
|
|
18
20
|
const [confirmPassword, setConfirmPassword] = useState("");
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
21
|
+
function buildClickHandler(setFieldError, clearErrors) {
|
|
22
|
+
return async () => {
|
|
23
|
+
clearErrors();
|
|
24
|
+
const parsed = resetClientSchema.safeParse({ password, confirmPassword });
|
|
25
|
+
if (!parsed.success)
|
|
26
|
+
return applyZodIssues(parsed.error.issues, setFieldError);
|
|
27
|
+
try {
|
|
28
|
+
await onSubmit(oobCode, parsed.data.password);
|
|
29
|
+
}
|
|
30
|
+
catch (err) {
|
|
31
|
+
void normalizeError(err);
|
|
32
|
+
showToast(err instanceof Error ? err.message : "Password reset failed", "error");
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
return (_jsx(Row, { className: `min-h-[60vh] ${className}`, align: "center", justify: "center", padding: "x-md", children: _jsxs(Stack, { className: "max-w-md w-full", gap: "lg", children: [_jsxs(Div, { className: "text-center", children: [_jsx(Heading, { level: 1, className: "font-extrabold", size: "3xl", children: labels.title ?? "Reset Password" }), labels.description && (_jsx(Text, { className: "mt-2 text-neutral-600 dark:text-neutral-400", size: "sm", children: labels.description }))] }), error && (_jsx(Alert, { variant: "error", compact: true, children: error })), success ? (_jsxs(Alert, { variant: "success", compact: true, children: [success, renderLoginLink && _jsx(Div, { className: "mt-2", children: renderLoginLink() })] })) : (_jsx(Form, { noValidate: true, onSubmit: (e) => e.preventDefault(), spacing: "md", children: ({ setFieldError, clearErrors }) => (_jsxs(_Fragment, { children: [_jsx(FieldInput, { name: "password", label: labels.passwordLabel ?? "New password", type: "password", autoComplete: "new-password", required: true, placeholder: labels.passwordPlaceholder ?? "••••••••", value: password, onChange: setPassword }), _jsx(FieldInput, { name: "confirmPassword", label: labels.confirmPasswordLabel ?? "Confirm new password", type: "password", autoComplete: "new-password", required: true, placeholder: labels.confirmPasswordPlaceholder ?? "••••••••", value: confirmPassword, onChange: setConfirmPassword }), _jsx(Button, { type: "submit", variant: "primary", isLoading: isLoading, disabled: isLoading, className: "w-full", onClick: buildClickHandler(setFieldError, clearErrors), children: isLoading
|
|
26
37
|
? (labels.submittingLabel ?? "Resetting…")
|
|
27
38
|
: (labels.submitLabel ?? "Reset password") })] })) }))] }) }));
|
|
28
39
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { Button, Div, Row, Span } from "../../../ui";
|
|
3
3
|
export function SocialAuthButtons({ onGoogle, disabled, dividerLabel, googleLabel, }) {
|
|
4
|
-
return (_jsxs(_Fragment, { children: [_jsxs(Div, { className: "relative", children: [_jsx(Row, { className: "absolute inset-0", align: "center", children: _jsx(Div, { className: "w-full border-t border-neutral-200" }) }), _jsx(Row, { textSize: "sm", className: "relative", justify: "center", children: _jsx(Span, { className: "text-neutral-500 dark:text-neutral-400", padding: "x-xs", surface: "default", children: dividerLabel }) })] }), _jsx(Div, { layout: "grid", gap: "3", className: "grid-cols-1", children: _jsxs(Button, { rounded: "md", type: "button", onClick: onGoogle, disabled: disabled, variant: "outline", paddingX: "md", paddingY: "sm", textSize: "sm", weight: "medium", className: "inline- justify-center border border-neutral-300 dark:border-
|
|
4
|
+
return (_jsxs(_Fragment, { children: [_jsxs(Div, { className: "relative", children: [_jsx(Row, { className: "absolute inset-0", align: "center", children: _jsx(Div, { className: "w-full border-t border-neutral-200" }) }), _jsx(Row, { textSize: "sm", className: "relative", justify: "center", children: _jsx(Span, { className: "text-neutral-500 dark:text-neutral-400", padding: "x-xs", surface: "default", children: dividerLabel }) })] }), _jsx(Div, { layout: "grid", gap: "3", className: "grid-cols-1", children: _jsxs(Button, { rounded: "md", type: "button", onClick: onGoogle, disabled: disabled, variant: "outline", paddingX: "md", paddingY: "sm", textSize: "sm", weight: "medium", className: "inline- justify-[center] border border-neutral-300 dark:border-neutral-700 bg-[var(--appkit-color-surface)] dark:bg-neutral-900 text-neutral-900 dark:text-[var(--appkit-color-text)] hover:bg-neutral-50 dark:hover:bg-neutral-800 disabled:cursor-not-allowed disabled:opacity-50", children: [_jsxs("svg", { className: "mr-2 h-5 w-5", viewBox: "0 0 24 24", "aria-hidden": "true", children: [_jsx("path", { fill: "currentColor", 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: "currentColor", 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: "currentColor", 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: "currentColor", 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" })] }), googleLabel] }) })] }));
|
|
5
5
|
}
|
|
@@ -23,5 +23,5 @@ export function BeforeAfterSlider({ item, className = "", }) {
|
|
|
23
23
|
return (_jsxs(Div, { ref: containerRef, className: `relative aspect-square select-none overflow-hidden ${className}`, rounded: "xl", onPointerMove: handlePointerMove, onTouchMove: handleTouchMove, children: [_jsx(Div, { role: "img", "aria-label": "After", className: "absolute inset-0 h-full w-full bg-center bg-cover", style: { backgroundImage: `url(${item.afterImageUrl})` } }), _jsx(Div, { className: "absolute inset-0 overflow-hidden", style: { width: `${position}%` }, children: _jsx(Div, { role: "img", "aria-label": "Before", className: "h-full w-full bg-center bg-cover", style: {
|
|
24
24
|
width: containerRef.current?.offsetWidth ?? "100%",
|
|
25
25
|
backgroundImage: `url(${item.beforeImageUrl})`,
|
|
26
|
-
} }) }), _jsxs(Stack, { justify: "center", className: "absolute inset-y-0 w-1 -translate-x-1/2 cursor-ew-resize", align: "center", style: { left: `${position}%` }, children: [_jsx(Div, { className: "h-full w-0.5
|
|
26
|
+
} }) }), _jsxs(Stack, { justify: "center", className: "absolute inset-y-0 w-1 -translate-x-1/2 cursor-ew-resize", align: "center", style: { left: `${position}%` }, children: [_jsx(Div, { className: "h-full w-0.5", surface: "default", style: { boxShadow: "0 1px 3px 0 rgb(0 0 0 / 0.1)" } }), _jsx(Div, { className: "absolute h-8 w-8 border-2 border-white", surface: "default", rounded: "full", shadow: "md" })] }), _jsx(Span, { surface: "overlay-xs", color: "inverse", size: "xs", weight: "medium", className: "absolute left-2 top-2", rounded: "default", padding: "pill-xs", children: "Before" }), _jsx(Span, { surface: "overlay-xs", color: "inverse", size: "xs", weight: "medium", className: "absolute right-2 top-2", rounded: "default", padding: "pill-xs", children: "After" }), item.durationWeeks && (_jsxs(Span, { surface: "overlay-sm", color: "inverse", size: "xs", weight: "medium", className: "absolute bottom-2 left-1/2 -translate-x-1/2", rounded: "default", padding: "pill-md", children: [item.durationWeeks, " weeks"] }))] }));
|
|
27
27
|
}
|
|
@@ -22,8 +22,8 @@ export declare const beforeAfterItemSchema: z.ZodObject<{
|
|
|
22
22
|
sortOrder: z.ZodDefault<z.ZodNumber>;
|
|
23
23
|
createdAt: z.ZodOptional<z.ZodString>;
|
|
24
24
|
}, "strip", z.ZodTypeAny, {
|
|
25
|
-
id: string;
|
|
26
25
|
title: string;
|
|
26
|
+
id: string;
|
|
27
27
|
sortOrder: number;
|
|
28
28
|
isActive: boolean;
|
|
29
29
|
createdAt?: string | undefined;
|
|
@@ -34,8 +34,8 @@ export declare const beforeAfterItemSchema: z.ZodObject<{
|
|
|
34
34
|
afterImageUrl?: string | undefined;
|
|
35
35
|
durationWeeks?: number | undefined;
|
|
36
36
|
}, {
|
|
37
|
-
id: string;
|
|
38
37
|
title: string;
|
|
38
|
+
id: string;
|
|
39
39
|
createdAt?: string | undefined;
|
|
40
40
|
description?: string | undefined;
|
|
41
41
|
sortOrder?: number | undefined;
|
|
@@ -28,7 +28,7 @@ export async function GET(_request, context) {
|
|
|
28
28
|
return NextResponse.json({ success: false, error: "Blog post not found" }, { status: 404 });
|
|
29
29
|
}
|
|
30
30
|
// Increment view count fire-and-forget — must not block response
|
|
31
|
-
blogRepository.incrementViews(post.id).catch(
|
|
31
|
+
blogRepository.incrementViews(post.id).catch(console.error);
|
|
32
32
|
// Related posts: same category, latest 3, excluding current
|
|
33
33
|
const related = (await blogRepository.findRelated(post.category, post.id, 3)).map(toBlogPost);
|
|
34
34
|
const body = { post: toBlogPost(post), related };
|
|
@@ -30,5 +30,5 @@ export function BlogFeaturedCard({ post, href, labels = {}, className = "", sele
|
|
|
30
30
|
day: "numeric",
|
|
31
31
|
})
|
|
32
32
|
: "";
|
|
33
|
-
return (_jsxs(Article, { className: `group relative
|
|
33
|
+
return (_jsxs(Article, { rounded: "xl", shadow: "hover-md", className: `group relative h-full overflow-hidden border border-[var(--appkit-color-border)] bg-[var(--appkit-color-surface)] ${isSelected ? "ring-2 ring-primary outline outline-2 outline-primary" : ""} ${className}`, onMouseDown: onSelect && !isSelected ? longPress.onMouseDown : undefined, onMouseUp: onSelect && !isSelected ? longPress.onMouseUp : undefined, onMouseLeave: onSelect && !isSelected ? longPress.onMouseLeave : undefined, onTouchStart: onSelect && !isSelected ? longPress.onTouchStart : undefined, onTouchEnd: onSelect && !isSelected ? longPress.onTouchEnd : undefined, children: [onSelect && (_jsx(BaseListingCard.Checkbox, { selected: isSelected, onSelect: (e) => { e.preventDefault(); onSelect(post.id, !isSelected); }, label: isSelected ? "Deselect post" : "Select post", position: "top-2 left-2", className: selectable || isSelected ? "opacity-100" : "opacity-0 group-hover:opacity-100 transition-opacity" })), _jsxs(TextLink, { href: href, layout: "flex-col", className: "h-full", children: [_jsx(Div, { className: `aspect-video ${__O.hidden} flex-shrink-0`, children: coverImageUrl ? (_jsx("img", { src: coverImageUrl, alt: safeTitle, className: "h-full w-full object-cover transition-transform duration-300 group-hover:scale-105" })) : (_jsx(Div, { role: "img", "aria-label": safeTitle, surface: "muted", className: "h-full w-full" })) }), _jsxs(Stack, { className: `flex-1 ${__P.p4}`, children: [_jsxs(Row, { gap: "xs", className: "mb-2", wrap: true, children: [_jsx(Span, { size: "xs", weight: "medium", className: `inline-block capitalize ${CATEGORY_BADGE[post.category] ?? "bg-[var(--appkit-color-bg)] text-[var(--appkit-color-text-muted)]"}`, rounded: "full", padding: "pill-xs", children: post.category }), post.isFeatured && (_jsx(Span, { size: "xs", weight: "medium", className: CLS_FEATURED_BADGE, children: labels.featuredBadge ?? "Featured" }))] }), _jsx(Heading, { level: 3, className: `leading-snug mb-1`, color: "primary", truncate: 2, size: "base", weight: "semibold", children: safeTitle }), post.excerpt && (_jsx(Text, { className: `mb-3`, color: "muted", truncate: 2, size: "sm", children: post.excerpt })), _jsxs(Row, { color: "muted", textSize: "xs", className: "mt-auto", gap: "3", wrap: true, children: [post.authorName && (_jsx(Span, { children: safeDisplayName(post.authorName, "Author") })), post.readTimeMinutes != null && (_jsxs(Span, { children: [post.readTimeMinutes, " ", labels.readTime ?? "min read"] })), date && _jsx(Span, { children: date })] })] })] })] }));
|
|
34
34
|
}
|
|
@@ -25,7 +25,7 @@ export function BlogCard({ post, href, onClick, className = "" }) {
|
|
|
25
25
|
const isInteractive = !!(href || onClick);
|
|
26
26
|
const card = (_jsxs(Article, { role: onClick && !href ? "button" : undefined, tabIndex: onClick && !href ? 0 : undefined, onKeyDown: onClick && !href
|
|
27
27
|
? (e) => (e.key === "Enter" || e.key === " ") && onClick(post)
|
|
28
|
-
: undefined, onClick: onClick && !href ? () => onClick(post) : undefined, className: `group flex flex-col h-full overflow-hidden rounded-xl border border-neutral-200 dark:border-slate-700 bg-white dark:bg-slate-900 shadow-sm transition hover:shadow-md ${isInteractive ? "cursor-pointer" : ""} ${className}`, children: [_jsx(Div, { className: `aspect-video w-full ${__O.hidden} bg-neutral-100 dark:bg-
|
|
28
|
+
: undefined, onClick: onClick && !href ? () => onClick(post) : undefined, className: `group flex flex-col h-full overflow-hidden rounded-xl border border-neutral-200 dark:border-slate-700 bg-white dark:bg-slate-900 shadow-sm transition hover:shadow-md ${isInteractive ? "cursor-pointer" : ""} ${className}`, children: [_jsx(Div, { className: `aspect-video w-full ${__O.hidden} bg-neutral-100 dark:bg-[var(--appkit-color-surface-elevated)] flex-shrink-0`, children: coverImageUrl ? (_jsx("img", { src: coverImageUrl, alt: post.title, className: "h-full w-full object-cover transition-transform duration-300 group-hover:scale-105" })) : (_jsx(Row, { surface: "muted", className: "h-full w-full", align: "center", justify: "center", children: _jsx(Span, { className: "opacity-30", size: "4xl", "aria-hidden": "true", children: "\u270D\uFE0F" }) })) }), _jsxs(Stack, { className: `flex-1 ${__P.p5}`, children: [_jsxs(Row, { className: "mb-2", gap: "sm", wrap: true, children: [_jsx(Span, { size: "xs", weight: "medium", className: "bg-primary/10 text-primary", rounded: "full", padding: "pill-xs", transform: "capitalize", children: post.category }), post.isFeatured && (_jsx(Span, { size: "xs", weight: "medium", className: CLS_FEATURED_BADGE, children: "Featured" })), post.readTimeMinutes && (_jsxs(Span, { size: "xs", color: "muted", children: [post.readTimeMinutes, " min read"] }))] }), _jsx(Heading, { level: 3, className: `group-hover:text-primary`, color: "primary", truncate: 2, size: "base", weight: "semibold", children: post.title }), post.excerpt && (_jsx(Text, { className: `mt-2 flex-1`, color: "muted", truncate: 3, size: "sm", children: post.excerpt })), _jsxs(Row, { className: "mt-auto", padding: "t-sm", gap: "3", children: [post.authorAvatar ? (_jsx("img", { src: post.authorAvatar, alt: post.authorName ?? "author", className: "h-7 w-7 flex-shrink-0 object-cover rounded-full" })) : post.authorName ? (_jsx(Row, { textWeight: "bold", textSize: "xs", className: "h-7 w-7 flex-shrink-0 bg-primary/10 text-primary", align: "center", justify: "center", rounded: "full", children: post.authorName.charAt(0).toUpperCase() })) : null, _jsxs(Text, { className: "text-neutral-500 dark:text-neutral-400 min-w-0", size: "xs", children: [post.authorName && (_jsx(Span, { weight: "medium", className: "text-neutral-700", children: safeDisplayName(post.authorName, "Author") })), date && _jsxs(Span, { className: "ml-1 text-neutral-400", children: ["\u00B7 ", date] })] })] })] })] }));
|
|
29
29
|
if (href) {
|
|
30
30
|
return (_jsx(Link, { href: href, className: "block h-full", children: card }));
|
|
31
31
|
}
|
|
@@ -53,5 +53,5 @@ export function BlogPostView({ slug, initialData, labels = {}, renderImage, rend
|
|
|
53
53
|
})
|
|
54
54
|
: "";
|
|
55
55
|
const coverImageUrl = getMediaUrl(post.coverImage);
|
|
56
|
-
return (_jsxs(Div, { className: `min-h-screen ${className}`, children: [coverImageUrl && (_jsxs(Div, { className: `relative h-72 md:h-96 ${__O.hidden}`, children: [renderImage ? (renderImage(post)) : (_jsx(
|
|
56
|
+
return (_jsxs(Div, { className: `min-h-screen ${className}`, children: [coverImageUrl && (_jsxs(Div, { className: `relative h-72 md:h-96 ${__O.hidden}`, children: [renderImage ? (renderImage(post)) : (_jsx("img", { src: coverImageUrl, alt: post.title, className: "h-full w-full object-cover" })), _jsx(Scrim, { direction: "bottom-up", intensity: "subtle", className: "absolute inset-0" })] })), _jsxs(Div, { className: "max-w-3xl mx-auto", paddingY: "y-3xl", paddingX: "x-md", children: [renderBlogPostHeader(post, date, labels), post.tags && post.tags.length > 0 && (_jsx(Row, { wrap: true, gap: "sm", className: "mb-8", children: post.tags.map((tag) => (_jsxs(Link, { href: `${String(ROUTES.PUBLIC.BLOG)}?tags=${encodeURIComponent(tag)}`, className: "inline-block px-3 py-1 rounded-full bg-neutral-100 dark:bg-zinc-800 hover:bg-primary/10 text-zinc-600 dark:text-zinc-400 hover:text-primary text-xs font-medium transition-colors", children: ["#", tag] }, tag))) })), renderAuthorBio && _jsx(Div, { className: "mb-6", children: renderAuthorBio(post) }), _jsx(Div, { surface: "card", padding: "xl", className: "mb-12", children: renderContent ? renderContent(post) : (_jsx(RichText, { html: normalizeRichTextHtml(post.content ?? ""), proseClass: "prose max-w-none dark:prose-invert" })) }), renderBlogPostRelated(related, labels, renderRelatedCard), renderBackButton && _jsx(Div, { border: "default", className: "mt-10 border-t", padding: "t-xl", children: renderBackButton() })] })] }));
|
|
57
57
|
}
|
|
@@ -3,14 +3,14 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import type { MediaFieldInput, MediaField } from "../../media/types";
|
|
5
5
|
import type { BlogPostStatus, BlogPostCategory } from "../types";
|
|
6
|
+
import type { BaseDocument } from "../../../_internal/shared/types/base-document";
|
|
6
7
|
/** Runtime-accessible blog post status values — use instead of bare string literals. */
|
|
7
8
|
export declare const BlogPostStatusValues: {
|
|
8
9
|
readonly DRAFT: BlogPostStatus;
|
|
9
10
|
readonly PUBLISHED: BlogPostStatus;
|
|
10
11
|
readonly ARCHIVED: BlogPostStatus;
|
|
11
12
|
};
|
|
12
|
-
export interface BlogPostDocument {
|
|
13
|
-
id: string;
|
|
13
|
+
export interface BlogPostDocument extends BaseDocument {
|
|
14
14
|
title: string;
|
|
15
15
|
slug: string;
|
|
16
16
|
excerpt: string;
|
|
@@ -30,8 +30,6 @@ export interface BlogPostDocument {
|
|
|
30
30
|
views: number;
|
|
31
31
|
metaTitle?: string;
|
|
32
32
|
metaDescription?: string;
|
|
33
|
-
createdAt: Date;
|
|
34
|
-
updatedAt: Date;
|
|
35
33
|
}
|
|
36
34
|
export declare const BLOG_POSTS_COLLECTION: "blogPosts";
|
|
37
35
|
export declare const BLOG_POSTS_INDEXED_FIELDS: readonly ["status", "publishedAt", "isFeatured", "category", "slug"];
|
|
@@ -111,10 +111,10 @@ export declare const blogPostFirestoreSchema: z.ZodObject<{
|
|
|
111
111
|
createdAt: string | Date | z.objectOutputType<{
|
|
112
112
|
toDate: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodDate>;
|
|
113
113
|
}, z.ZodTypeAny, "passthrough">;
|
|
114
|
-
id: string;
|
|
115
114
|
title: string;
|
|
116
115
|
slug: string;
|
|
117
116
|
tags: string[];
|
|
117
|
+
id: string;
|
|
118
118
|
updatedAt: string | Date | z.objectOutputType<{
|
|
119
119
|
toDate: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodDate>;
|
|
120
120
|
}, z.ZodTypeAny, "passthrough">;
|
|
@@ -161,10 +161,10 @@ export declare const blogPostFirestoreSchema: z.ZodObject<{
|
|
|
161
161
|
createdAt: string | Date | z.objectInputType<{
|
|
162
162
|
toDate: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodDate>;
|
|
163
163
|
}, z.ZodTypeAny, "passthrough">;
|
|
164
|
-
id: string;
|
|
165
164
|
title: string;
|
|
166
165
|
slug: string;
|
|
167
166
|
tags: string[];
|
|
167
|
+
id: string;
|
|
168
168
|
updatedAt: string | Date | z.objectInputType<{
|
|
169
169
|
toDate: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodDate>;
|
|
170
170
|
}, z.ZodTypeAny, "passthrough">;
|
|
@@ -331,9 +331,9 @@ export declare const blogPostSchema: z.ZodObject<{
|
|
|
331
331
|
}, "strip", z.ZodTypeAny, {
|
|
332
332
|
status: "draft" | "published" | "archived";
|
|
333
333
|
category: "news" | "tips" | "guides" | "updates" | "community";
|
|
334
|
-
id: string;
|
|
335
334
|
title: string;
|
|
336
335
|
slug: string;
|
|
336
|
+
id: string;
|
|
337
337
|
coverImage: {
|
|
338
338
|
url: string;
|
|
339
339
|
type: "image" | "video" | "file";
|
|
@@ -378,9 +378,9 @@ export declare const blogPostSchema: z.ZodObject<{
|
|
|
378
378
|
}, {
|
|
379
379
|
status: "draft" | "published" | "archived";
|
|
380
380
|
category: "news" | "tips" | "guides" | "updates" | "community";
|
|
381
|
-
id: string;
|
|
382
381
|
title: string;
|
|
383
382
|
slug: string;
|
|
383
|
+
id: string;
|
|
384
384
|
createdAt?: string | undefined;
|
|
385
385
|
tags?: string[] | undefined;
|
|
386
386
|
updatedAt?: string | undefined;
|
|
@@ -434,15 +434,15 @@ export declare const blogListParamsSchema: z.ZodObject<{
|
|
|
434
434
|
category?: "news" | "tips" | "guides" | "updates" | "community" | undefined;
|
|
435
435
|
featured?: boolean | undefined;
|
|
436
436
|
tags?: string | undefined;
|
|
437
|
-
q?: string | undefined;
|
|
438
437
|
page?: number | undefined;
|
|
438
|
+
q?: string | undefined;
|
|
439
439
|
perPage?: number | undefined;
|
|
440
440
|
}, {
|
|
441
441
|
sort?: string | undefined;
|
|
442
442
|
category?: "news" | "tips" | "guides" | "updates" | "community" | undefined;
|
|
443
443
|
featured?: boolean | undefined;
|
|
444
444
|
tags?: string | undefined;
|
|
445
|
-
q?: string | undefined;
|
|
446
445
|
page?: number | undefined;
|
|
446
|
+
q?: string | undefined;
|
|
447
447
|
perPage?: number | undefined;
|
|
448
448
|
}>;
|
|
@@ -11,7 +11,7 @@ const __O = {
|
|
|
11
11
|
};
|
|
12
12
|
const CLS_REMOVE_BTN = "self-start text-zinc-400 dark:text-zinc-400 transition hover:text-error";
|
|
13
13
|
export function CartItemRow({ item, onQtyChange, onRemove, href, isOutOfStock = false }) {
|
|
14
|
-
return (_jsxs(Div, { layout: "flex", gap: "4", surface: "card", padding: "sm", className: `transition-opacity ${isOutOfStock ? "opacity-60" : ""}`, children: [_jsx(Div, { surface: "muted", className: `h-20 w-20 flex-shrink-0 ${__O.hidden}`, rounded: "lg", children: item.meta.image && (_jsx(
|
|
14
|
+
return (_jsxs(Div, { layout: "flex", gap: "4", surface: "card", padding: "sm", className: `transition-opacity ${isOutOfStock ? "opacity-60" : ""}`, children: [_jsx(Div, { surface: "muted", className: `h-20 w-20 flex-shrink-0 ${__O.hidden}`, rounded: "lg", children: item.meta.image && (_jsx("img", { src: item.meta.image, alt: item.meta.title, className: "h-full w-full object-cover" })) }), _jsxs(Stack, { justify: "between", className: "flex-1", children: [_jsxs(Row, { gap: "xs", className: "", align: "start", children: [href ? (_jsx("a", { href: href, target: "_blank", rel: "noopener noreferrer", className: "font-medium text-neutral-900 dark:text-zinc-100 hover:underline underline-offset-2 line-clamp-2", children: item.meta.title })) : (_jsx(Text, { truncate: 2, weight: "medium", color: "primary", children: item.meta.title })), isOutOfStock && (_jsx(Span, { padding: "pill-2xs", color: "error", surface: "danger-surface", weight: "semibold", className: "flex-shrink-0 text-[10px] tracking-wide", rounded: "default", transform: "uppercase", children: "Out of Stock" }))] }), item.meta.attributes &&
|
|
15
15
|
Object.keys(item.meta.attributes).length > 0 && (_jsx(Text, { className: "text-neutral-500 dark:text-neutral-400", size: "xs", children: Object.entries(item.meta.attributes)
|
|
16
16
|
.map(([k, v]) => `${k}: ${v}`)
|
|
17
17
|
.join(", ") })), _jsxs(Row, { justify: "between", children: [_jsx(Text, { className: "text-neutral-900 dark:text-neutral-100", weight: "semibold", children: formatCurrency(item.meta.price * item.quantity, item.meta.currency) }), onQtyChange && !isOutOfStock && (_jsxs(Row, { gap: "sm", children: [_jsx(Button, { rounded: "full", onClick: () => onQtyChange(item.id, item.quantity - 1), disabled: item.quantity <= 1, variant: "outline", size: "sm", className: "h-7 w-7 justify-center border border-neutral-200 dark:border-slate-600 text-sm disabled:opacity-40", children: "\u2212" }), _jsx(Span, { size: "sm", className: "min-w-[1.5rem]", align: "center", children: item.quantity }), _jsx(Button, { rounded: "full", onClick: () => onQtyChange(item.id, item.quantity + 1), variant: "outline", size: "sm", className: "h-7 w-7 justify-center border border-neutral-200 dark:border-slate-600 text-sm", children: "+" })] })), isOutOfStock && (_jsxs(Span, { size: "xs", color: "muted", children: ["Qty: ", item.quantity] }))] })] }), onRemove && (_jsx(Button, { onClick: () => onRemove(item.id), variant: "ghost", size: "sm", "aria-label": ACTIONS.CART["remove-item"].ariaLabel, className: CLS_REMOVE_BTN, children: "\u2715" }))] }));
|
|
@@ -19,5 +19,5 @@ export function CartItemRow({ item, onQtyChange, onRemove, href, isOutOfStock =
|
|
|
19
19
|
export function CartDrawer({ isOpen, onClose, items, subtotal = 0, currency, isLoading, onQtyChange, onRemove, onCheckout, labels = {}, }) {
|
|
20
20
|
if (!isOpen)
|
|
21
21
|
return null;
|
|
22
|
-
return (_jsxs(_Fragment, { children: [_jsx(Div, { surface: "overlay-xs", role: "presentation", className: "fixed inset-0 z-40", onClick: onClose }),
|
|
22
|
+
return (_jsxs(_Fragment, { children: [_jsx(Div, { surface: "overlay-xs", role: "presentation", className: "fixed inset-0 z-40", onClick: onClose }), _jsx(Aside, { surface: "sidePanel", shadow: "xl", className: "fixed inset-y-0 right-0 z-50 w-full max-w-sm", children: _jsxs(Stack, { className: "h-full", children: [_jsxs(Row, { justify: "between", border: "bottom", className: __P.p4, children: [_jsx(Heading, { level: 2, size: "lg", weight: "semibold", children: labels.title ?? "Cart" }), _jsx(Button, { onClick: onClose, variant: "ghost", size: "sm", "aria-label": "Close cart", textColor: "faint", className: "hover:text-neutral-900 dark:hover:text-[var(--appkit-color-text)]", children: "\u2715" })] }), _jsx(Stack, { className: `flex-1 ${__O.yAuto} ${__P.p4}`, gap: "3", children: isLoading ? (_jsx(Row, { justify: "center", padding: "y-3xl", children: _jsx(Div, { className: "h-8 w-8 animate-spin border-2 border-neutral-300 border-t-neutral-800 dark:border-t-zinc-200", rounded: "full" }) })) : items.length === 0 ? (_jsx(Text, { paddingY: "3xl", className: "text-neutral-500 dark:text-neutral-400", size: "sm", align: "center", children: labels.empty ?? "Your cart is empty" })) : (items.map((item) => (_jsx(CartItemRow, { item: item, onQtyChange: onQtyChange, onRemove: onRemove }, item.id)))) }), items.length > 0 && (_jsxs(Stack, { border: "top", className: __P.p4, gap: "md", children: [_jsxs(Row, { textSize: "sm", justify: "between", children: [_jsx(Span, { className: "text-neutral-600 dark:text-neutral-400", children: labels.subtotal ?? "Subtotal" }), _jsx(Span, { weight: "semibold", children: formatCurrency(subtotal, currency) })] }), onCheckout && (_jsx(Button, { rounded: "xl", onClick: onCheckout, variant: "primary", textSize: "sm", className: "w-full bg-neutral-900 py-[0.75rem] font-[600] text-white transition hover:bg-neutral-800", children: labels.checkout ?? ACTIONS.CART["checkout"].label }))] }))] }) })] }));
|
|
23
23
|
}
|
|
@@ -4,5 +4,5 @@ import { AdSlot } from "../../homepage/components/AdSlot";
|
|
|
4
4
|
export function CartView({ labels = {}, renderItems, renderGroups, groups = [], renderSummary, renderPromoCode, renderCheckoutButton, renderEmpty, isEmpty = false, isLoading = false, className = "", }) {
|
|
5
5
|
if (isEmpty && renderEmpty)
|
|
6
6
|
return _jsx(_Fragment, { children: renderEmpty() });
|
|
7
|
-
return (_jsxs(Div, { className: className, children: [labels.title && (_jsx(Heading, { level: 1, className: "mb-6", size: "2xl", weight: "bold", children: labels.title })), _jsxs(Stack, { direction: "lg-row", className: "lg:gap-
|
|
7
|
+
return (_jsxs(Div, { className: className, children: [labels.title && (_jsx(Heading, { level: 1, className: "mb-6", size: "2xl", weight: "bold", children: labels.title })), _jsxs(Stack, { direction: "lg-row", className: "lg:gap-[2rem]", gap: "lg", children: [_jsxs(Div, { className: "flex-1", children: [renderGroups ? renderGroups(groups, isLoading) : renderItems(isLoading), !renderGroups && renderPromoCode?.(), renderGroups && renderPromoCode?.(), _jsx(AdSlot, { id: "cart-upsell", className: "mt-6" })] }), _jsxs(Div, { className: "w-full lg:w-80", children: [renderSummary?.(), renderCheckoutButton?.(() => { }, isLoading)] })] })] }));
|
|
8
8
|
}
|
|
@@ -15,5 +15,5 @@ export function CheckoutView({ labels = {}, renderStep, renderStepIndicator, ren
|
|
|
15
15
|
}
|
|
16
16
|
onStepChange?.(nextStep);
|
|
17
17
|
}, [activeStep, onStepChange, step]);
|
|
18
|
-
return (_jsxs(Div, { className: className, children: [labels.title && (_jsx(Heading, { level: 1, className: "mb-6", size: "2xl", weight: "bold", children: labels.title })), renderStepIndicator?.(step, totalSteps, setStep), _jsxs(Stack, { direction: "lg-row", className: "lg:gap-
|
|
18
|
+
return (_jsxs(Div, { className: className, children: [labels.title && (_jsx(Heading, { level: 1, className: "mb-6", size: "2xl", weight: "bold", children: labels.title })), renderStepIndicator?.(step, totalSteps, setStep), _jsxs(Stack, { direction: "lg-row", className: "lg:gap-[2rem]", gap: "lg", children: [_jsxs(Div, { className: "flex-1", children: [renderStep(step, setStep), _jsx(AdSlot, { id: "checkout-upsell", className: "mt-6" })] }), renderOrderSummary && (_jsx(Div, { className: "w-full lg:w-80", children: renderOrderSummary() }))] })] }));
|
|
19
19
|
}
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* Canonical Firestore document interfaces, collection names, field constants
|
|
5
5
|
* for the cart feature.
|
|
6
6
|
*/
|
|
7
|
+
import type { BaseDocument } from "../../../_internal/shared/types/base-document";
|
|
7
8
|
export interface CartItemDocument {
|
|
8
9
|
itemId: string;
|
|
9
10
|
productId: string;
|
|
@@ -66,16 +67,13 @@ export interface CartAppliedCoupon {
|
|
|
66
67
|
/** Mirrors CouponDocument.restrictions.combineWithSellerCoupons — used for conflict detection when adding future coupons */
|
|
67
68
|
combineWithSellerCoupons?: boolean;
|
|
68
69
|
}
|
|
69
|
-
export interface CartDocument {
|
|
70
|
-
id: string;
|
|
70
|
+
export interface CartDocument extends BaseDocument {
|
|
71
71
|
userId: string;
|
|
72
72
|
items: CartItemDocument[];
|
|
73
73
|
/** Multiple coupons/deals applied at cart level */
|
|
74
74
|
appliedCoupons?: CartAppliedCoupon[];
|
|
75
75
|
/** Item IDs the user has selected for the next checkout (undefined = all items) */
|
|
76
76
|
selectedItemIds?: string[];
|
|
77
|
-
createdAt: Date;
|
|
78
|
-
updatedAt: Date;
|
|
79
77
|
}
|
|
80
78
|
export declare const CART_COLLECTION: "carts";
|
|
81
79
|
export declare const CART_INDEXED_FIELDS: string[];
|
|
@@ -5,6 +5,7 @@ import Link from "next/link";
|
|
|
5
5
|
import { categoriesRepository, productRepository, } from "../../../repositories";
|
|
6
6
|
import { ROUTES } from "../../../next";
|
|
7
7
|
import { Container, Div, Heading, Main, Nav, Section, Span, Text } from "../../../ui";
|
|
8
|
+
import { DynamicBgDiv } from "../../../ui/components/DynamicBgDiv";
|
|
8
9
|
import { BrandDetailTabs } from "./BrandDetailTabs";
|
|
9
10
|
const __O = {
|
|
10
11
|
hidden: "overflow-hidden",
|
|
@@ -89,5 +90,5 @@ export async function BrandDetailPageView({ slug, initialBrand }) {
|
|
|
89
90
|
counts.preOrders +
|
|
90
91
|
counts.prizeDraws +
|
|
91
92
|
counts.bundles;
|
|
92
|
-
return (_jsxs(Main, { children: [_jsxs(Section, { className: `relative ${__O.hidden} ${hasCover ? "min-h-[220px] md:min-h-[280px]" : "bg-
|
|
93
|
+
return (_jsxs(Main, { children: [_jsxs(Section, { className: `relative ${__O.hidden} ${hasCover ? "min-h-[220px] md:min-h-[280px]" : "bg-[var(--appkit-color-bg)]"}`, children: [hasCover && (_jsxs(_Fragment, { children: [_jsx("img", { src: coverImage, alt: "", className: "absolute inset-0 w-full h-full object-cover" }), _jsx(Div, { surface: "overlay-md", className: "absolute inset-0" })] })), !hasCover && (_jsx(DynamicBgDiv, { color: brandColor, className: "absolute inset-0 opacity-10" })), _jsxs(Div, { className: "relative z-10 max-w-7xl mx-auto", paddingY: hasCover ? "y-3xl" : "y-xl", padding: "x-md", children: [_jsxs(Nav, { layout: "flex", gap: "2xs", textSize: "sm", className: "mb-4", "aria-label": "Breadcrumb", children: [_jsx(Link, { href: String(ROUTES.HOME), className: hasCover ? "text-white/70 hover:text-white transition-colors" : "text-zinc-500 dark:text-zinc-400 hover:text-primary-600 transition-colors", children: "Home" }), _jsx(Span, { className: hasCover ? "text-white/40" : "text-zinc-400", children: "/" }), _jsx(Link, { href: String(ROUTES.PUBLIC.BRANDS ?? "/brands"), className: hasCover ? "text-white/70 hover:text-white transition-colors" : "text-zinc-500 dark:text-zinc-400 hover:text-primary-600 transition-colors", children: "Brands" }), _jsx(Span, { className: hasCover ? "text-white/40" : "text-zinc-400", children: "/" }), _jsx(Span, { weight: "medium", className: hasCover ? "text-white" : "text-zinc-900 dark:text-zinc-100", children: brand?.name ?? slug })] }), _jsxs(Row, { className: "mb-3", align: "center", gap: "md", children: [brand?.display?.icon && (_jsx(Span, { className: "leading-none", size: "5xl", children: brand.display.icon })), _jsxs(_Fragment, { children: [_jsx(Heading, { color: "inverse", level: 1, className: `${hasCover ? "" : "text-[var(--appkit-color-text)]"}`, size: "3xl", mdSize: "4xl", weight: "bold", children: brand?.name ?? slug }), brand?.description && typeof brand.description === "string" && !brand.description.startsWith("{") && (_jsx(Text, { color: hasCover ? "inverse" : "muted", className: `max-w-2xl mt-1 ${hasCover ? "/80" : ""}`, size: "base", children: brand.description }))] })] }), _jsxs(Row, { gap: "sm", wrap: true, className: "mt-3", children: [counts.products > 0 && (_jsxs(Span, { layout: "inline-flex", gap: "xs", color: "inverse", size: "xs", weight: "medium", className: `${hasCover ? "bg-[rgba(255,255,255,0.2)] backdrop-blur-sm" : "bg-primary/10 text-primary-700 dark:text-primary-400"}`, rounded: "full", padding: "pill-sm-tall", children: [counts.products.toLocaleString(), " ", counts.products === 1 ? "product" : "products"] })), counts.auctions > 0 && (_jsxs(Span, { layout: "inline-flex", gap: "xs", color: hasCover ? "inverse" : "warning", surface: hasCover ? undefined : "warning-surface", size: "xs", weight: "medium", className: hasCover ? "bg-[rgba(255,255,255,0.2)] backdrop-blur-sm" : "", rounded: "full", padding: "pill-sm-tall", children: [counts.auctions.toLocaleString(), " ", counts.auctions === 1 ? "auction" : "auctions"] })), counts.preOrders > 0 && (_jsxs(Span, { layout: "inline-flex", gap: "xs", color: hasCover ? "inverse" : "info", surface: hasCover ? undefined : "info-surface", size: "xs", weight: "medium", className: hasCover ? "bg-[rgba(255,255,255,0.2)] backdrop-blur-sm" : "", rounded: "full", padding: "pill-sm-tall", children: [counts.preOrders.toLocaleString(), " ", counts.preOrders === 1 ? "pre-order" : "pre-orders"] })), totalItems === 0 && (_jsx(Span, { size: "sm", className: hasCover ? "text-white/60" : "text-zinc-400", children: "No items listed yet" }))] })] })] }), _jsx(Section, { padding: "y-lg", children: _jsx(Container, { size: "xl", children: brandName ? (_jsx(BrandDetailTabs, { brandName: brandName, initialProductsData: productsResult ?? undefined, initialBundles: brandBundles, counts: counts })) : (_jsx(Text, { paddingY: "3xl", color: "muted", size: "sm", align: "center", children: "Brand not found." })) }) })] }));
|
|
93
94
|
}
|
|
@@ -22,5 +22,5 @@ export function BundleDetailView({ bundle, members = [], onBuyNow, }) {
|
|
|
22
22
|
const priceLabel = bundle.bundlePriceInPaise
|
|
23
23
|
? formatCurrency(bundle.bundlePriceInPaise / 100, "INR")
|
|
24
24
|
: BUNDLE_COPY.detail.priceFallback;
|
|
25
|
-
return (_jsx(Main, { children: _jsx(Section, { padding: "y-2xl", children: _jsx(Container, { size: "xl", children: _jsxs(Stack, { gap: "lg", children: [_jsxs(
|
|
25
|
+
return (_jsx(Main, { children: _jsx(Section, { padding: "y-2xl", children: _jsx(Container, { size: "xl", children: _jsxs(Stack, { gap: "lg", children: [_jsxs(Stack, { gap: "lg", direction: "md-row", align: "start", children: [_jsx(Div, { className: "w-full md:w-2/5", children: members.length > 0 ? (_jsx(BundleCollage, { members: members })) : (_jsx(Div, { className: `aspect-video w-full ${__O.hidden}`, rounded: "2xl", surface: "subtle", children: _jsx(Div, { className: "h-full w-full", children: _jsx(MediaImage, { src: cover, alt: bundle.name, size: "hero", fallback: PLACEHOLDER_EMOJI }) }) })) }), _jsxs(Stack, { gap: "md", className: "flex-1", children: [_jsx(Heading, { level: 1, size: "3xl", weight: "semibold", color: "primary", children: bundle.name }), _jsxs(Row, { gap: "sm", align: "center", children: [_jsx(Text, { size: "lg", weight: "bold", children: priceLabel }), _jsxs(Text, { size: "sm", color: "muted", children: ["\u00B7 ", BUNDLE_COPY.detail.itemCount(memberCount)] }), _jsx(Badge, { variant: BUNDLE_STOCK_VARIANT[stock], children: STOCK_BADGE_TEXT[stock] })] }), bundle.description && (_jsxs(Stack, { gap: "xs", children: [_jsx(Heading, { level: 2, className: "text-[var(--appkit-color-text-muted)]", size: "sm", weight: "semibold", children: BUNDLE_COPY.detailDescriptionHeading }), _jsx(Text, { className: "whitespace-pre-line", children: bundle.description })] })), onBuyNow ? (_jsx(BundleBuyNowCta, { bundleSlug: bundle.slug, outOfStock: stock === "out_of_stock", onBuyNow: onBuyNow })) : (_jsxs(Div, { textSize: "sm", className: "border-dashed", border: "strong", surface: "muted", rounded: "xl", padding: "md", "aria-live": "polite", children: [_jsx(Text, { weight: "semibold", className: "mb-1 block", children: BUNDLE_COPY.detail.ctaDisabled }), _jsx(Text, { size: "sm", color: "muted", children: BUNDLE_COPY.detail.ctaHint })] }))] })] }), _jsxs(Stack, { gap: "md", children: [_jsx(Heading, { level: 2, size: "xl", weight: "semibold", color: "primary", children: BUNDLE_COPY.detailItemsHeading }), members.length === 0 ? (_jsx(Text, { color: "muted", children: BUNDLE_COPY.detail.emptyMembers })) : (_jsx(Ul, { gap: "2", className: "grid grid-cols-1 sm:grid-cols-2", children: members.map((p, i) => (_jsxs(Li, { layout: "flex-center", gap: "2", rounded: "lg", border: "subtle", padding: "inlineSm", textSize: "sm", children: [_jsxs(Span, { size: "xs", weight: "semibold", className: "w-5", color: "faint", children: ["#", i + 1] }), _jsx(Link, { href: String(ROUTES.PUBLIC.PRODUCT_DETAIL?.(p.slug ?? p.id) ?? "#"), className: "flex-1 truncate font-medium hover:underline hover:text-primary", children: p.title })] }, p.id))) }))] })] }) }) }) }));
|
|
26
26
|
}
|
|
@@ -29,7 +29,7 @@ function renderBundleSelectedChips(props) {
|
|
|
29
29
|
const { value, metadata, remove } = props;
|
|
30
30
|
if (value.length === 0)
|
|
31
31
|
return null;
|
|
32
|
-
return (_jsx(
|
|
32
|
+
return (_jsx(Row, { gap: "sm", padding: "sm", rounded: "lg", surface: "muted", border: "default", wrap: true, children: value.map((id) => {
|
|
33
33
|
const meta = metadata[id];
|
|
34
34
|
const label = meta?.title ?? id;
|
|
35
35
|
return (_jsxs(Row, { textSize: "xs", gap: "xs", align: "center", paddingY: "y-2xs", border: "strong", padding: "x-sm", surface: "default", rounded: "full", children: [_jsx(Text, { size: "xs", className: "max-w-[200px] truncate", children: label }), _jsx(Button, { variant: "ghost", size: "sm", "aria-label": BUNDLE_COPY.picker.removeAria(label), onClick: () => remove(id), children: "\u00D7" })] }, id));
|