@mohasinac/appkit 2.7.56 → 2.7.58
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_internal/client/features/layout/DashboardLayoutClient.d.ts +7 -1
- package/dist/_internal/client/features/layout/DashboardLayoutClient.js +8 -2
- package/dist/_internal/shared/actions/action-registry.js +31 -5
- package/dist/client.d.ts +2 -4
- package/dist/client.js +2 -3
- package/dist/configs/tailwind.d.ts +16 -3
- package/dist/configs/tailwind.js +18 -5
- package/dist/constants/field-names.d.ts +3 -0
- package/dist/constants/field-names.js +3 -0
- package/dist/features/about/components/FAQPageView.js +2 -2
- package/dist/features/about/components/FeesView.js +1 -1
- package/dist/features/about/components/PolicyPageView.js +1 -1
- package/dist/features/about/components/PublicProfileView.js +1 -1
- package/dist/features/account/components/AddressBook.js +1 -1
- package/dist/features/account/components/AddressesIndexListing.js +1 -1
- package/dist/features/account/components/BuyerAccountGuideView.js +7 -7
- package/dist/features/account/components/BuyerAuctionsGuideView.js +7 -7
- package/dist/features/account/components/BuyerOrdersGuideView.js +6 -6
- package/dist/features/account/components/BuyerShoppingGuideView.js +7 -7
- package/dist/features/account/components/MessagesView.js +1 -1
- package/dist/features/account/components/NotificationPreferencesPanel.js +12 -3
- package/dist/features/account/components/UserOffersPanel.js +2 -2
- package/dist/features/account/components/UserSidebar.js +3 -3
- package/dist/features/account/components/UserSupportView.js +5 -5
- package/dist/features/admin/components/AdminAdsView.js +1 -1
- package/dist/features/admin/components/AdminAllEventEntriesView.js +2 -2
- package/dist/features/admin/components/AdminAnalyticsGuideView.js +3 -3
- package/dist/features/admin/components/AdminBidsView.js +6 -2
- package/dist/features/admin/components/AdminBlogView.js +7 -2
- package/dist/features/admin/components/AdminBrandsView.js +7 -2
- package/dist/features/admin/components/AdminBundleEditorView.js +13 -9
- package/dist/features/admin/components/AdminBundlesView.js +4 -2
- package/dist/features/admin/components/AdminCarouselEditorView.js +7 -8
- package/dist/features/admin/components/AdminCarouselView.js +6 -4
- package/dist/features/admin/components/AdminCartsView.js +1 -1
- package/dist/features/admin/components/AdminCatalogGuideView.js +5 -5
- package/dist/features/admin/components/AdminCategoriesView.js +7 -2
- package/dist/features/admin/components/AdminContactEditorView.js +2 -2
- package/dist/features/admin/components/AdminContactView.js +4 -2
- package/dist/features/admin/components/AdminContentGuideView.js +6 -6
- package/dist/features/admin/components/AdminCouponsView.js +4 -2
- package/dist/features/admin/components/AdminEmployeeEditorView.js +1 -1
- package/dist/features/admin/components/AdminFaqsView.js +4 -2
- package/dist/features/admin/components/AdminFeatureFlagsView.js +1 -1
- package/dist/features/admin/components/AdminFeaturesView.js +5 -1
- package/dist/features/admin/components/AdminGuideHubView.js +1 -1
- package/dist/features/admin/components/AdminHistoryView.js +1 -1
- package/dist/features/admin/components/AdminListingScaffold.js +1 -1
- package/dist/features/admin/components/AdminMediaView.js +10 -5
- package/dist/features/admin/components/AdminNavigationView.js +1 -1
- package/dist/features/admin/components/AdminNewsletterView.js +4 -2
- package/dist/features/admin/components/AdminNotificationsView.js +7 -2
- package/dist/features/admin/components/AdminOrdersGuideView.js +5 -5
- package/dist/features/admin/components/AdminOrdersView.js +11 -2
- package/dist/features/admin/components/AdminPayoutsView.js +6 -2
- package/dist/features/admin/components/AdminPrizeDrawsView.js +4 -0
- package/dist/features/admin/components/AdminProductsView.js +14 -2
- package/dist/features/admin/components/AdminReturnRequestsView.js +1 -1
- package/dist/features/admin/components/AdminReviewsView.js +7 -2
- package/dist/features/admin/components/AdminScammerEditorView.js +3 -3
- package/dist/features/admin/components/AdminScammersView.js +5 -5
- package/dist/features/admin/components/AdminSectionsView.js +2 -2
- package/dist/features/admin/components/AdminSessionsView.js +6 -2
- package/dist/features/admin/components/AdminSidebar.js +3 -3
- package/dist/features/admin/components/AdminSiteSettingsView.js +1 -1
- package/dist/features/admin/components/AdminStoreAddressesView.js +1 -1
- package/dist/features/admin/components/AdminStoreEditorView.js +1 -1
- package/dist/features/admin/components/AdminStoresGuideView.js +6 -6
- package/dist/features/admin/components/AdminStoresView.js +7 -2
- package/dist/features/admin/components/AdminSublistingCategoriesView.js +3 -1
- package/dist/features/admin/components/AdminSupportTicketDetailView.js +4 -4
- package/dist/features/admin/components/AdminSupportTicketsView.js +8 -8
- package/dist/features/admin/components/AdminTeamGuideView.js +4 -4
- package/dist/features/admin/components/AdminTeamView.js +4 -2
- package/dist/features/admin/components/AdminTrustGuideView.js +5 -5
- package/dist/features/admin/components/AdminUserEditorView.js +2 -2
- package/dist/features/admin/components/AdminUsersGuideView.js +5 -5
- package/dist/features/admin/components/AdminUsersView.js +6 -2
- package/dist/features/admin/components/AdminViewCards.js +3 -3
- package/dist/features/admin/components/AdminWishlistsView.js +1 -1
- package/dist/features/admin/components/DataTable.js +1 -1
- package/dist/features/admin/constants/filter-tabs.d.ts +9 -0
- package/dist/features/admin/constants/filter-tabs.js +3 -0
- package/dist/features/auctions/components/AuctionBidsTable.js +1 -1
- package/dist/features/auctions/components/AuctionBottomActions.d.ts +7 -0
- package/dist/features/auctions/components/AuctionBottomActions.js +24 -0
- package/dist/features/auctions/components/AuctionDetailPageView.js +7 -7
- package/dist/features/auctions/components/AuctionsListView.js +1 -1
- package/dist/features/auctions/components/MarketplaceAuctionCard.js +2 -2
- package/dist/features/auctions/components/MarketplaceAuctionGrid.js +1 -1
- package/dist/features/auctions/components/PlaceBidFormClient.js +1 -1
- package/dist/features/auth/components/LoginForm.js +1 -1
- package/dist/features/auth/components/VerifyEmailView.js +2 -2
- package/dist/features/before-after/components/BeforeAfterGallery.js +1 -1
- package/dist/features/blog/components/BlogFeaturedCard.js +1 -1
- package/dist/features/blog/components/BlogIndexListing.js +1 -1
- package/dist/features/blog/components/BlogListView.js +2 -2
- package/dist/features/blog/components/BlogPostView.js +8 -8
- package/dist/features/cart/components/CartDrawer.js +2 -2
- package/dist/features/cart/repository/cart.repository.js +11 -4
- package/dist/features/cart/schemas/firestore.d.ts +3 -0
- package/dist/features/categories/components/BrandDetailPageView.js +1 -1
- package/dist/features/categories/components/CategoriesIndexListing.js +1 -1
- package/dist/features/categories/components/CategoryDetailPageView.js +39 -3
- package/dist/features/categories/components/CategoryDetailTabs.d.ts +4 -1
- package/dist/features/categories/components/CategoryDetailTabs.js +7 -2
- package/dist/features/categories/components/CategoryGrid.js +1 -1
- package/dist/features/categories/components/CategoryProductsView.js +1 -1
- package/dist/features/categories/components/CategoryStoresListing.d.ts +5 -0
- package/dist/features/categories/components/CategoryStoresListing.js +11 -0
- package/dist/features/categories/components/CategoryTableColumns.js +2 -2
- package/dist/features/categories/components/CategoryTree.js +1 -1
- package/dist/features/categories/components/index.d.ts +2 -0
- package/dist/features/categories/components/index.js +1 -0
- package/dist/features/checkout/components/CheckoutStepper.js +2 -2
- package/dist/features/classified/components/ClassifiedIndexListing.js +2 -0
- package/dist/features/classified/components/ClassifiedListView.js +1 -1
- package/dist/features/collections/components/CollectionCard.js +1 -1
- package/dist/features/contact/components/ContactInfoSidebar.js +1 -1
- package/dist/features/copilot/components/AdminCopilotView.js +2 -2
- package/dist/features/digital-codes/components/DigitalCodesIndexListing.js +2 -0
- package/dist/features/digital-codes/components/DigitalCodesListView.js +1 -1
- package/dist/features/events/components/AdminEventsView.js +5 -1
- package/dist/features/events/components/EventCard.js +1 -1
- package/dist/features/events/components/EventPollWidget.js +3 -3
- package/dist/features/events/components/EventStatusBadge.js +5 -5
- package/dist/features/events/components/EventsIndexListing.js +1 -1
- package/dist/features/events/components/EventsListView.js +2 -2
- package/dist/features/events/components/SpinWheelView.js +5 -3
- package/dist/features/faq/components/FAQAccordion.js +2 -2
- package/dist/features/filters/AsyncFacetSection.js +3 -3
- package/dist/features/filters/FilterFacetSection.js +5 -5
- package/dist/features/filters/RangeFilter.js +1 -1
- package/dist/features/forms/Input.js +5 -5
- package/dist/features/forms/Select.js +3 -3
- package/dist/features/forms/Slider.js +1 -1
- package/dist/features/forms/Textarea.js +3 -3
- package/dist/features/forms/utils.d.ts +2 -2
- package/dist/features/forms/utils.js +2 -2
- package/dist/features/history/hooks/useHistory.js +23 -10
- package/dist/features/homepage/components/AdvertisementBanner.js +2 -2
- package/dist/features/homepage/components/CharacterHotspotForm.js +2 -2
- package/dist/features/homepage/components/FeaturedResultsSection.js +1 -1
- package/dist/features/homepage/components/HeroSection.js +1 -1
- package/dist/features/homepage/components/NewsletterSection.js +1 -1
- package/dist/features/homepage/components/SectionCarousel.js +1 -1
- package/dist/features/layout/BottomActions.js +2 -2
- package/dist/features/layout/ListingLayout.js +3 -3
- package/dist/features/layout/TitleBarLayout.js +1 -1
- package/dist/features/live/components/LiveItemsIndexListing.js +2 -0
- package/dist/features/live/components/LiveItemsListView.js +1 -1
- package/dist/features/media/index.d.ts +2 -0
- package/dist/features/media/index.js +1 -0
- package/dist/features/media/modals/ImageCropModal.js +1 -1
- package/dist/features/media/modals/ImageEditor.d.ts +12 -0
- package/dist/features/media/modals/ImageEditor.js +73 -0
- package/dist/features/media/upload/ImageUpload.d.ts +5 -1
- package/dist/features/media/upload/ImageUpload.js +33 -8
- package/dist/features/media/upload/MediaUploadField.d.ts +5 -1
- package/dist/features/media/upload/MediaUploadField.js +26 -12
- package/dist/features/orders/components/OrdersList.js +12 -12
- package/dist/features/orders/components/RefundHistoryTable.js +2 -2
- package/dist/features/orders/components/RefundRequestView.js +3 -3
- package/dist/features/pre-orders/components/MarketplacePreorderCard.js +1 -1
- package/dist/features/pre-orders/components/PreOrderActionsClient.js +1 -1
- package/dist/features/pre-orders/components/PreOrderBadge.js +5 -5
- package/dist/features/pre-orders/components/PreOrderBottomActions.d.ts +5 -0
- package/dist/features/pre-orders/components/PreOrderBottomActions.js +22 -0
- package/dist/features/pre-orders/components/PreOrderDetailPageView.js +5 -5
- package/dist/features/pre-orders/components/PreOrdersIndexListing.js +47 -0
- package/dist/features/pre-orders/components/PreOrdersListView.js +1 -1
- package/dist/features/pre-orders/components/PreorderCard.js +3 -3
- package/dist/features/products/components/AuctionsIndexListing.js +23 -0
- package/dist/features/products/components/BidHistory.js +2 -2
- package/dist/features/products/components/CompareOverlay.js +1 -1
- package/dist/features/products/components/CustomFieldsEditor.js +1 -1
- package/dist/features/products/components/CustomSectionTabContent.js +1 -1
- package/dist/features/products/components/CustomSectionsEditor.js +1 -1
- package/dist/features/products/components/GroupSettingsPanel.js +2 -2
- package/dist/features/products/components/MakeOfferButton.js +2 -2
- package/dist/features/products/components/PrizeDrawBottomActions.d.ts +6 -0
- package/dist/features/products/components/PrizeDrawBottomActions.js +24 -0
- package/dist/features/products/components/PrizeDrawDetailPageView.js +5 -7
- package/dist/features/products/components/PrizeDrawEntryActions.js +5 -18
- package/dist/features/products/components/PrizeDrawItemsEditor.js +3 -3
- package/dist/features/products/components/PrizeRevealModal.js +7 -4
- package/dist/features/products/components/ProductDetailActions.d.ts +6 -1
- package/dist/features/products/components/ProductDetailActions.js +36 -6
- package/dist/features/products/components/ProductDetailPageView.js +19 -18
- package/dist/features/products/components/ProductFeaturesSelector.js +1 -1
- package/dist/features/products/components/ProductGalleryClient.js +1 -1
- package/dist/features/products/components/ProductGrid.js +8 -8
- package/dist/features/products/components/ProductTabs.js +1 -1
- package/dist/features/products/components/ProductTabsShell.js +1 -1
- package/dist/features/products/components/ProductsIndexListing.js +47 -0
- package/dist/features/products/components/RelatedProducts.js +1 -1
- package/dist/features/products/components/ShowGroupSection.js +1 -1
- package/dist/features/products/components/SublistingCarouselSection.js +1 -1
- package/dist/features/products/components/SublistingCategorySelect.js +1 -1
- package/dist/features/products/components/index.d.ts +0 -2
- package/dist/features/products/components/index.js +0 -1
- package/dist/features/products/constants/action-defs.d.ts +7 -0
- package/dist/features/products/constants/action-defs.js +14 -0
- package/dist/features/products/constants/listing-tabs.d.ts +6 -0
- package/dist/features/products/constants/listing-tabs.js +1 -0
- package/dist/features/promotions/components/CouponCard.js +3 -3
- package/dist/features/promotions/components/CouponsIndexListing.js +2 -2
- package/dist/features/promotions/components/PromotionsView.js +1 -1
- package/dist/features/reviews/components/ReviewDetailPageView.js +1 -1
- package/dist/features/reviews/components/ReviewDetailShell.js +4 -4
- package/dist/features/reviews/components/ReviewModal.js +2 -2
- package/dist/features/reviews/components/ReviewSummary.js +1 -1
- package/dist/features/reviews/components/ReviewsIndexListing.js +1 -1
- package/dist/features/reviews/components/ReviewsList.js +1 -1
- package/dist/features/seller/components/SellerAddressesView.js +4 -3
- package/dist/features/seller/components/SellerAnalyticsAlertsView.js +2 -2
- package/dist/features/seller/components/SellerAuctionsView.js +11 -4
- package/dist/features/seller/components/SellerBidsView.js +22 -7
- package/dist/features/seller/components/SellerBundlesView.js +11 -4
- package/dist/features/seller/components/SellerClassifiedView.js +12 -5
- package/dist/features/seller/components/SellerCouponEditorView.js +2 -2
- package/dist/features/seller/components/SellerCouponsView.js +13 -4
- package/dist/features/seller/components/SellerDigitalCodesView.js +11 -4
- package/dist/features/seller/components/SellerFeaturesView.js +1 -1
- package/dist/features/seller/components/SellerGoogleReviewsView.js +10 -5
- package/dist/features/seller/components/SellerGroupedListingsView.js +2 -0
- package/dist/features/seller/components/SellerLiveView.js +13 -6
- package/dist/features/seller/components/SellerOffersPanel.js +2 -2
- package/dist/features/seller/components/SellerOffersView.js +2 -2
- package/dist/features/seller/components/SellerOrdersView.js +41 -18
- package/dist/features/seller/components/SellerPayoutMethodsView.js +14 -5
- package/dist/features/seller/components/SellerPayoutsView.js +2 -2
- package/dist/features/seller/components/SellerPreOrdersView.js +7 -2
- package/dist/features/seller/components/SellerPrizeDrawsView.js +7 -2
- package/dist/features/seller/components/SellerProductShell.js +27 -9
- package/dist/features/seller/components/SellerProductsCards.js +2 -1
- package/dist/features/seller/components/SellerProductsView.js +22 -9
- package/dist/features/seller/components/SellerReviewsView.js +9 -1
- package/dist/features/seller/components/SellerShippingConfigsView.js +15 -6
- package/dist/features/seller/components/SellerSidebar.js +2 -2
- package/dist/features/seller/components/SellerStoreCategoriesView.js +11 -4
- package/dist/features/seller/components/SellerTemplatesView.js +20 -7
- package/dist/features/seller/components/analytics/SellerTopProducts.js +1 -1
- package/dist/features/shell/StepForm.js +9 -3
- package/dist/features/site-settings/components/ActionPermissionsManager.js +1 -1
- package/dist/features/site-settings/components/NavPermissionsManager.js +1 -1
- package/dist/features/stores/components/InteractiveStoreCard.js +1 -1
- package/dist/features/stores/components/StoreDetailLayoutView.js +1 -1
- package/dist/features/stores/components/StoreFinanceGuideView.js +2 -2
- package/dist/features/stores/components/StoreHeader.js +1 -1
- package/dist/features/stores/components/StoreListingsGuideView.js +3 -3
- package/dist/features/stores/components/StoreOrdersGuideView.js +4 -4
- package/dist/features/stores/components/StoreReviewsListing.js +1 -1
- package/dist/features/stores/components/StoreSettingsGuideView.js +2 -2
- package/dist/features/stores/components/StoresIndexListing.js +17 -1
- package/dist/features/whatsapp-bot/components/SellerWhatsAppSettingsView.js +4 -4
- package/dist/features/wishlist/components/WishlistPage.js +3 -3
- package/dist/features/wishlist/hooks/useWishlistToggle.js +6 -1
- package/dist/index.d.ts +5 -2
- package/dist/index.js +9 -3
- package/dist/react/hooks/use-action-dispatch.d.ts +5 -0
- package/dist/react/hooks/use-action-dispatch.js +10 -0
- package/dist/seed/cart-seed-data.js +50 -3
- package/dist/seed/categories-seed-data.js +80 -16
- package/dist/seed/index.d.ts +3 -0
- package/dist/seed/index.js +3 -0
- package/dist/seed/manifest.js +15 -1
- package/dist/seed/products-classifieds-seed-data.d.ts +10 -0
- package/dist/seed/products-classifieds-seed-data.js +197 -0
- package/dist/seed/products-digital-codes-seed-data.d.ts +10 -0
- package/dist/seed/products-digital-codes-seed-data.js +204 -0
- package/dist/seed/products-live-items-seed-data.d.ts +13 -0
- package/dist/seed/products-live-items-seed-data.js +190 -0
- package/dist/styles.css +301 -3
- package/dist/tailwind-utilities.css +1 -1
- package/dist/tokens/index.d.ts +3 -3
- package/dist/tokens/index.js +3 -3
- package/dist/tokens/motion.d.ts +162 -0
- package/dist/tokens/motion.js +89 -0
- package/dist/ui/DataTable.js +6 -5
- package/dist/ui/components/Accordion.js +2 -1
- package/dist/ui/components/Button.style.css +15 -0
- package/dist/ui/components/Card.d.ts +5 -2
- package/dist/ui/components/Card.js +29 -11
- package/dist/ui/components/Div.d.ts +2 -16
- package/dist/ui/components/Div.js +2 -16
- package/dist/ui/components/Input.js +1 -1
- package/dist/ui/components/Layout.d.ts +9 -19
- package/dist/ui/components/Layout.js +9 -7
- package/dist/ui/components/ListingToolbar.js +1 -1
- package/dist/ui/components/Modal.js +7 -4
- package/dist/ui/components/Motion.d.ts +75 -0
- package/dist/ui/components/Motion.js +122 -0
- package/dist/ui/components/Select.js +1 -1
- package/dist/ui/components/Semantic.d.ts +81 -14
- package/dist/ui/components/Semantic.js +75 -10
- package/dist/ui/components/Semantic.style.css +261 -2
- package/dist/ui/components/SideDrawer.d.ts +1 -1
- package/dist/ui/components/SideDrawer.js +8 -6
- package/dist/ui/components/SideModal.d.ts +1 -1
- package/dist/ui/components/SideModal.js +11 -9
- package/dist/ui/components/StackedViewShell.js +6 -1
- package/dist/ui/components/StatsGrid.js +1 -1
- package/dist/ui/components/Toast.js +5 -2
- package/dist/ui/components/Typography.d.ts +44 -3
- package/dist/ui/components/Typography.js +15 -30
- package/dist/ui/components/Typography.style.css +24 -0
- package/dist/ui/components/VacationBanner.js +2 -1
- package/dist/ui/components/surface-tokens.d.ts +70 -0
- package/dist/ui/components/surface-tokens.js +68 -0
- package/dist/ui/forms/FormShell.d.ts +6 -1
- package/dist/ui/forms/FormShell.js +32 -4
- package/dist/ui/index.d.ts +9 -6
- package/dist/ui/index.js +4 -4
- package/dist/validation/schemas.d.ts +28 -28
- package/package.json +3 -1
- package/dist/_internal/client/features/seller/print-center/InventoryLabel.d.ts +0 -12
- package/dist/_internal/client/features/seller/print-center/InventoryLabel.js +0 -49
- package/dist/_internal/client/features/seller/print-center/LabelDesignPicker.d.ts +0 -7
- package/dist/_internal/client/features/seller/print-center/LabelDesignPicker.js +0 -32
- package/dist/_internal/client/features/seller/print-center/OrderPackingLabel.d.ts +0 -28
- package/dist/_internal/client/features/seller/print-center/OrderPackingLabel.js +0 -33
- package/dist/_internal/client/features/seller/print-center/PhysicalLocationModal.d.ts +0 -12
- package/dist/_internal/client/features/seller/print-center/PhysicalLocationModal.js +0 -30
- package/dist/_internal/client/features/seller/print-center/PrintCenterView.d.ts +0 -12
- package/dist/_internal/client/features/seller/print-center/PrintCenterView.js +0 -102
- package/dist/_internal/client/features/seller/print-center/PrintGrid.d.ts +0 -12
- package/dist/_internal/client/features/seller/print-center/PrintGrid.js +0 -13
- package/dist/_internal/client/features/seller/print-center/StoreCard.d.ts +0 -19
- package/dist/_internal/client/features/seller/print-center/StoreCard.js +0 -30
- package/dist/_internal/client/features/seller/print-center/WebsiteCard.d.ts +0 -11
- package/dist/_internal/client/features/seller/print-center/WebsiteCard.js +0 -25
- package/dist/_internal/client/features/seller/print-center/index.d.ts +0 -11
- package/dist/_internal/client/features/seller/print-center/index.js +0 -10
- package/dist/_internal/client/features/seller/print-center/types.d.ts +0 -20
- package/dist/_internal/client/features/seller/print-center/types.js +0 -20
- package/dist/_internal/client/features/seller/print-center/useInventoryPdf.d.ts +0 -18
- package/dist/_internal/client/features/seller/print-center/useInventoryPdf.js +0 -76
- package/dist/features/account/repository/address.repository.d.ts +0 -17
- package/dist/features/account/repository/address.repository.js +0 -184
- package/dist/features/auctions/components/AuctionCard.d.ts +0 -29
- package/dist/features/auctions/components/AuctionCard.js +0 -38
- package/dist/features/categories/components/BundleAddToCartCta.d.ts +0 -16
- package/dist/features/categories/components/BundleAddToCartCta.js +0 -54
- package/dist/features/categories/components/CategoriesListView.d.ts +0 -31
- package/dist/features/categories/components/CategoriesListView.js +0 -27
- package/dist/features/products/components/AuctionsView.d.ts +0 -6
- package/dist/features/products/components/AuctionsView.js +0 -5
- package/dist/features/products/components/BuyBar.d.ts +0 -21
- package/dist/features/products/components/BuyBar.js +0 -19
- package/dist/features/products/components/PreOrdersView.d.ts +0 -6
- package/dist/features/products/components/PreOrdersView.js +0 -5
- package/dist/features/reviews/components/ReviewsListView.d.ts +0 -31
- package/dist/features/reviews/components/ReviewsListView.js +0 -16
- package/dist/features/stores/components/StoresListView.d.ts +0 -19
- package/dist/features/stores/components/StoresListView.js +0 -25
- package/dist/features/stores/repository/store-address.repository.d.ts +0 -55
- package/dist/features/stores/repository/store-address.repository.js +0 -187
- package/dist/ui/components/BulkActionsBar.d.ts +0 -18
- package/dist/ui/components/BulkActionsBar.js +0 -25
- package/dist/ui/components/CollageLightbox.d.ts +0 -18
- package/dist/ui/components/CollageLightbox.js +0 -41
- package/dist/ui/components/StickyBottomBar.d.ts +0 -22
- package/dist/ui/components/StickyBottomBar.js +0 -20
|
@@ -63,12 +63,12 @@ export function FilterFacetSection({ title, options, selected, onChange, selecti
|
|
|
63
63
|
? "border-emerald-500 bg-emerald-50 text-emerald-700 dark:border-emerald-500/60 dark:bg-emerald-900/20 dark:text-emerald-300"
|
|
64
64
|
: "border-zinc-200 bg-white text-zinc-700 hover:border-zinc-400 dark:border-slate-700 dark:bg-slate-900 dark:text-zinc-200 dark:hover:border-slate-500"), children: [title, hasValue && (_jsx(Span, { className: "inline-flex h-4 w-4 items-center justify-center rounded-full bg-emerald-600 text-[10px] font-bold text-white", children: selected.length })), _jsx("svg", { className: cn("h-3.5 w-3.5 text-zinc-400 transition-transform", dropdownOpen ? "rotate-180" : ""), fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, "aria-hidden": "true", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M19 9l-7 7-7-7" }) })] }), dropdownOpen && (_jsxs(Div, { className: "absolute left-0 top-full z-[var(--appkit-z-dropdown,50)] mt-1 min-w-[180px] max-w-[260px] rounded-xl border border-zinc-200 bg-white shadow-lg dark:border-slate-700 dark:bg-slate-900", children: [searchable && (_jsx(Div, { className: "border-b border-zinc-100 p-2 dark:border-slate-800", children: _jsx(Input, { type: "search", placeholder: "Search\u2026", value: search, onChange: (e) => handleSearch(e.target.value), className: "w-full rounded-md border border-zinc-200 bg-white px-2 py-1 text-xs text-zinc-900 focus:outline-none dark:border-slate-700 dark:bg-slate-800/60 dark:text-zinc-100" }) })), _jsxs(Div, { className: "max-h-56 overflow-y-auto py-1", children: [filtered.map((option) => {
|
|
65
65
|
const isSelected = selected.includes(option.value);
|
|
66
|
-
return (_jsxs(Row, { gap: "xs", className: "cursor-pointer rounded-lg px-3 py-1.5 hover:bg-zinc-50 dark:hover:bg-slate-800 mx-1", onClick: () => toggle(option.value), children: [_jsx("input", { type: selectionMode === "single" ? "radio" : "checkbox", checked: isSelected, onChange: () => toggle(option.value), "aria-label": option.label, className: "h-3.5 w-3.5 flex-shrink-0 cursor-pointer rounded border-zinc-300 text-primary-600 dark:border-slate-600 dark:text-secondary-500" }), _jsx(Span, { className: "flex-1 truncate text-xs text-zinc-700 dark:text-zinc-300", children: option.label }), option.count !== undefined && (_jsx(Span, { className: "flex-shrink-0 text-[10px] tabular-nums text-zinc-400 dark:text-zinc-
|
|
67
|
-
}), filtered.length === 0 && (_jsx(Text, { className: "px-3 py-2 text-xs text-zinc-400 dark:text-zinc-
|
|
66
|
+
return (_jsxs(Row, { gap: "xs", className: "cursor-pointer rounded-lg px-3 py-1.5 hover:bg-zinc-50 dark:hover:bg-slate-800 mx-1", onClick: () => toggle(option.value), children: [_jsx("input", { type: selectionMode === "single" ? "radio" : "checkbox", checked: isSelected, onChange: () => toggle(option.value), "aria-label": option.label, className: "h-3.5 w-3.5 flex-shrink-0 cursor-pointer rounded border-zinc-300 text-primary-600 dark:border-slate-600 dark:text-secondary-500" }), _jsx(Span, { className: "flex-1 truncate text-xs text-zinc-700 dark:text-zinc-300", children: option.label }), option.count !== undefined && (_jsx(Span, { className: "flex-shrink-0 text-[10px] tabular-nums text-zinc-400 dark:text-zinc-400", children: option.count }))] }, option.value));
|
|
67
|
+
}), filtered.length === 0 && (_jsx(Text, { className: "px-3 py-2 text-xs text-zinc-400 dark:text-zinc-400", children: "No results" }))] }), hasValue && (_jsx(Div, { className: "border-t border-zinc-100 p-1 dark:border-slate-800", children: _jsx(Button, { type: "button", variant: "ghost", size: "sm", className: "w-full py-1 text-xs text-zinc-400 transition-colors hover:text-red-600", onClick: () => { onChange([]); onClear?.(); setDropdownOpen(false); }, children: "Clear" }) }))] }))] }));
|
|
68
68
|
}
|
|
69
69
|
// ── Accordion variant (default) ─────────────────────────────────────────
|
|
70
|
-
return (_jsxs(Div, { className: cn("p-4 border-b border-zinc-200 dark:border-slate-700 last:border-b-0", className), children: [_jsxs(Row, { gap: "xs", children: [_jsxs(Button, { type: "button", onClick: handleToggle, variant: "ghost", size: "sm", className: "flex flex-1 items-center justify-between text-sm font-semibold text-zinc-900 dark:text-zinc-50 py-1 hover:opacity-80 transition-opacity", "aria-expanded": !isCollapsed, children: [_jsxs(Row, { as: Span, gap: "xs", children: [title, hasValue && (_jsx(Span, { className: "inline-flex items-center justify-center w-5 h-5 text-xs rounded-full bg-emerald-50 dark:bg-emerald-900/30 text-emerald-700 dark:text-emerald-300 ring-1 ring-emerald-600/20 dark:ring-emerald-400/20", children: selected.length }))] }), _jsx("svg", { className: cn("w-4 h-4 text-zinc-500 dark:text-zinc-400 transition-transform duration-200", isCollapsed ? "" : "rotate-180"), fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, "aria-hidden": "true", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M19 9l-7 7-7-7" }) })] }), onClear && hasValue && (_jsx(Button, { type: "button", onClick: onClear, variant: "ghost", size: "sm", className: "inline-flex items-center justify-center w-5 h-5 p-0 text-zinc-500 dark:text-zinc-400 hover:text-red-600 dark:hover:text-red-400 hover:bg-zinc-100 dark:hover:bg-slate-700 transition-colors rounded-full", "aria-label": "Clear filter", children: _jsx("svg", { className: "w-3 h-3", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2.5, "aria-hidden": "true", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M6 18L18 6M6 6l12 12" }) }) }))] }), isCollapsed && hasValue && (_jsxs(Div, { className: "mt-2 flex flex-wrap gap-1", children: [selectedLabels.map((label) => (_jsx(Span, { className: "inline-flex items-center px-2 py-0.5 rounded-full text-xs bg-zinc-100 dark:bg-slate-700 text-zinc-700 dark:text-zinc-300 border border-zinc-200 dark:border-slate-600", children: label }, label))), selected.length > 3 && (_jsxs(Span, { className: "inline-flex items-center px-2 py-0.5 rounded-full text-xs text-zinc-400 dark:text-zinc-
|
|
70
|
+
return (_jsxs(Div, { className: cn("p-4 border-b border-zinc-200 dark:border-slate-700 last:border-b-0", className), children: [_jsxs(Row, { gap: "xs", children: [_jsxs(Button, { type: "button", onClick: handleToggle, variant: "ghost", size: "sm", className: "flex flex-1 items-center justify-between text-sm font-semibold text-zinc-900 dark:text-zinc-50 py-1 hover:opacity-80 transition-opacity", "aria-expanded": !isCollapsed, children: [_jsxs(Row, { as: Span, gap: "xs", children: [title, hasValue && (_jsx(Span, { className: "inline-flex items-center justify-center w-5 h-5 text-xs rounded-full bg-emerald-50 dark:bg-emerald-900/30 text-emerald-700 dark:text-emerald-300 ring-1 ring-emerald-600/20 dark:ring-emerald-400/20", children: selected.length }))] }), _jsx("svg", { className: cn("w-4 h-4 text-zinc-500 dark:text-zinc-400 transition-transform duration-200", isCollapsed ? "" : "rotate-180"), fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, "aria-hidden": "true", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M19 9l-7 7-7-7" }) })] }), onClear && hasValue && (_jsx(Button, { type: "button", onClick: onClear, variant: "ghost", size: "sm", className: "inline-flex items-center justify-center w-5 h-5 p-0 text-zinc-500 dark:text-zinc-400 hover:text-red-600 dark:hover:text-red-400 hover:bg-zinc-100 dark:hover:bg-slate-700 transition-colors rounded-full", "aria-label": "Clear filter", children: _jsx("svg", { className: "w-3 h-3", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2.5, "aria-hidden": "true", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M6 18L18 6M6 6l12 12" }) }) }))] }), isCollapsed && hasValue && (_jsxs(Div, { className: "mt-2 flex flex-wrap gap-1", children: [selectedLabels.map((label) => (_jsx(Span, { className: "inline-flex items-center px-2 py-0.5 rounded-full text-xs bg-zinc-100 dark:bg-slate-700 text-zinc-700 dark:text-zinc-300 border border-zinc-200 dark:border-slate-600", children: label }, label))), selected.length > 3 && (_jsxs(Span, { className: "inline-flex items-center px-2 py-0.5 rounded-full text-xs text-zinc-400 dark:text-zinc-400", children: ["+", selected.length - 3, " more"] }))] })), searchable && (_jsx(Div, { className: "mt-2", children: _jsx(Input, { type: "search", placeholder: "Search\u2026", value: search, onChange: (e) => handleSearch(e.target.value), className: "w-full rounded-md border border-zinc-200 dark:border-slate-700 bg-white dark:bg-slate-800/60 px-2.5 py-1.5 text-xs text-zinc-900 dark:text-zinc-100 focus:outline-none focus:ring-2 focus:ring-primary-500/20 dark:focus:ring-secondary-400/20" }) })), !isCollapsed && (_jsxs(Div, { className: "mt-3 space-y-1", children: [filtered.map((option) => {
|
|
71
71
|
const isSelected = selected.includes(option.value);
|
|
72
|
-
return (_jsxs(Row, { gap: "2.5", className: "py-1 cursor-pointer group", children: [selectionMode === "single" ? (_jsx("input", { type: "radio", checked: isSelected, onChange: () => toggle(option.value), "aria-label": option.label, className: cn("flex-shrink-0 border-zinc-300 dark:border-slate-600 cursor-pointer", "w-4 h-4 rounded-full text-primary-600 dark:text-secondary-500", "focus:ring-primary-500/30 dark:focus:ring-secondary-400/30") })) : (_jsx("input", { type: "checkbox", checked: isSelected, onChange: () => toggle(option.value), "aria-label": option.label, className: cn("flex-shrink-0 border-zinc-300 dark:border-slate-600 cursor-pointer", "w-4 h-4 rounded text-primary-600 dark:text-secondary-500 checked:bg-primary-600 dark:checked:bg-secondary-500", "focus:ring-primary-500/30 dark:focus:ring-secondary-400/30") })), _jsx(Span, { className: "flex-1 text-sm text-zinc-700 dark:text-zinc-300 group-hover:text-zinc-900 dark:group-hover:text-zinc-100 transition-colors truncate", children: option.label }), option.count !== undefined && (_jsx(Span, { className: "text-xs text-zinc-400 dark:text-zinc-
|
|
73
|
-
}), filtered.length === 0 && (_jsx(Text, { className: "text-xs text-zinc-400 dark:text-zinc-
|
|
72
|
+
return (_jsxs(Row, { gap: "2.5", className: "py-1 cursor-pointer group", children: [selectionMode === "single" ? (_jsx("input", { type: "radio", checked: isSelected, onChange: () => toggle(option.value), "aria-label": option.label, className: cn("flex-shrink-0 border-zinc-300 dark:border-slate-600 cursor-pointer", "w-4 h-4 rounded-full text-primary-600 dark:text-secondary-500", "focus:ring-primary-500/30 dark:focus:ring-secondary-400/30") })) : (_jsx("input", { type: "checkbox", checked: isSelected, onChange: () => toggle(option.value), "aria-label": option.label, className: cn("flex-shrink-0 border-zinc-300 dark:border-slate-600 cursor-pointer", "w-4 h-4 rounded text-primary-600 dark:text-secondary-500 checked:bg-primary-600 dark:checked:bg-secondary-500", "focus:ring-primary-500/30 dark:focus:ring-secondary-400/30") })), _jsx(Span, { className: "flex-1 text-sm text-zinc-700 dark:text-zinc-300 group-hover:text-zinc-900 dark:group-hover:text-zinc-100 transition-colors truncate", children: option.label }), option.count !== undefined && (_jsx(Span, { className: "text-xs text-zinc-400 dark:text-zinc-400 tabular-nums flex-shrink-0", children: option.count }))] }, option.value));
|
|
73
|
+
}), filtered.length === 0 && (_jsx(Text, { className: "text-xs text-zinc-400 dark:text-zinc-400 py-1", children: "No results" }))] }))] }));
|
|
74
74
|
}
|
|
@@ -24,5 +24,5 @@ export function RangeFilter({ title, minLabel, maxLabel, minValue, maxValue, onM
|
|
|
24
24
|
maxBound !== undefined;
|
|
25
25
|
const hasValue = !!(minValue || maxValue);
|
|
26
26
|
const inputClass = "w-full rounded-md border border-zinc-200 dark:border-slate-700 bg-white dark:bg-slate-800/60 px-2.5 py-1.5 text-xs text-zinc-900 dark:text-zinc-100 focus:outline-none focus:ring-2 focus:ring-primary-500/20 dark:focus:ring-secondary-400/20";
|
|
27
|
-
return (_jsxs(Div, { role: "group", "aria-labelledby": `rf-${title}`, className: cn("p-4 border-b border-zinc-200 dark:border-slate-700 last:border-b-0", className), children: [_jsxs(Div, { className: "flex items-center gap-2", children: [_jsxs(Button, { type: "button", id: `rf-${title}`, onClick: handleToggle, variant: "ghost", size: "sm", className: "flex flex-1 items-center justify-between text-sm font-semibold text-zinc-900 dark:text-zinc-50 py-1 hover:opacity-80 transition-opacity", "aria-expanded": !isCollapsed, children: [_jsxs(Span, { className: "flex items-center gap-2", children: [title, hasValue && (_jsx(Span, { className: "inline-flex items-center justify-center w-5 h-5 text-xs rounded-full bg-emerald-50 dark:bg-emerald-900/30 text-emerald-700 dark:text-emerald-300 ring-1 ring-emerald-600/20", children: "1" }))] }), _jsx("svg", { className: cn("w-4 h-4 text-zinc-500 dark:text-zinc-400 transition-transform duration-200", isCollapsed ? "" : "rotate-180"), fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, "aria-hidden": "true", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M19 9l-7 7-7-7" }) })] }), onClear && hasValue && (_jsx(Button, { type: "button", onClick: onClear, variant: "ghost", size: "sm", className: "inline-flex items-center justify-center w-5 h-5 text-zinc-500 dark:text-zinc-400 hover:text-red-600 dark:hover:text-red-400 rounded-full transition-colors", "aria-label": "Clear", children: _jsx("svg", { className: "w-3 h-3", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2.5, "aria-hidden": "true", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M6 18L18 6M6 6l12 12" }) }) }))] }), !isCollapsed && (_jsxs(Stack, { gap: "3", className: "mt-3", children: [canShowSlider && (_jsx(DualSlider, { minValue: minValue, maxValue: maxValue, onMinChange: onMinChange, onMaxChange: onMaxChange, minBound: minBound, maxBound: maxBound, step: step, prefix: prefix })), _jsxs(Div, { className: "flex items-end gap-2", children: [_jsxs(Div, { className: "flex-1 min-w-0", children: [minLabel && (_jsx(Text, { className: "text-xs text-zinc-500 dark:text-zinc-400 mb-1", children: minLabel })), _jsxs(Div, { className: "relative", children: [prefix && (_jsx(Span, { className: "absolute left-2 top-1/2 -translate-y-1/2 text-xs text-zinc-400 dark:text-zinc-
|
|
27
|
+
return (_jsxs(Div, { role: "group", "aria-labelledby": `rf-${title}`, className: cn("p-4 border-b border-zinc-200 dark:border-slate-700 last:border-b-0", className), children: [_jsxs(Div, { className: "flex items-center gap-2", children: [_jsxs(Button, { type: "button", id: `rf-${title}`, onClick: handleToggle, variant: "ghost", size: "sm", className: "flex flex-1 items-center justify-between text-sm font-semibold text-zinc-900 dark:text-zinc-50 py-1 hover:opacity-80 transition-opacity", "aria-expanded": !isCollapsed, children: [_jsxs(Span, { className: "flex items-center gap-2", children: [title, hasValue && (_jsx(Span, { className: "inline-flex items-center justify-center w-5 h-5 text-xs rounded-full bg-emerald-50 dark:bg-emerald-900/30 text-emerald-700 dark:text-emerald-300 ring-1 ring-emerald-600/20", children: "1" }))] }), _jsx("svg", { className: cn("w-4 h-4 text-zinc-500 dark:text-zinc-400 transition-transform duration-200", isCollapsed ? "" : "rotate-180"), fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, "aria-hidden": "true", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M19 9l-7 7-7-7" }) })] }), onClear && hasValue && (_jsx(Button, { type: "button", onClick: onClear, variant: "ghost", size: "sm", className: "inline-flex items-center justify-center w-5 h-5 text-zinc-500 dark:text-zinc-400 hover:text-red-600 dark:hover:text-red-400 rounded-full transition-colors", "aria-label": "Clear", children: _jsx("svg", { className: "w-3 h-3", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2.5, "aria-hidden": "true", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M6 18L18 6M6 6l12 12" }) }) }))] }), !isCollapsed && (_jsxs(Stack, { gap: "3", className: "mt-3", children: [canShowSlider && (_jsx(DualSlider, { minValue: minValue, maxValue: maxValue, onMinChange: onMinChange, onMaxChange: onMaxChange, minBound: minBound, maxBound: maxBound, step: step, prefix: prefix })), _jsxs(Div, { className: "flex items-end gap-2", children: [_jsxs(Div, { className: "flex-1 min-w-0", children: [minLabel && (_jsx(Text, { className: "text-xs text-zinc-500 dark:text-zinc-400 mb-1", children: minLabel })), _jsxs(Div, { className: "relative", children: [prefix && (_jsx(Span, { className: "absolute left-2 top-1/2 -translate-y-1/2 text-xs text-zinc-400 dark:text-zinc-400 pointer-events-none", children: prefix })), _jsx(Input, { type: type, value: minValue, onChange: (e) => onMinChange(e.target.value), placeholder: minPlaceholder ?? (type === "date" ? "From" : "Min"), className: cn(inputClass, prefix ? "pl-5" : "") })] })] }), _jsx(Span, { className: "flex-shrink-0 pb-1.5 text-zinc-400 dark:text-zinc-400 text-xs", children: "-" }), _jsxs(Div, { className: "flex-1 min-w-0", children: [maxLabel && (_jsx(Text, { className: "text-xs text-zinc-500 dark:text-zinc-400 mb-1", children: maxLabel })), _jsxs(Div, { className: "relative", children: [prefix && (_jsx(Span, { className: "absolute left-2 top-1/2 -translate-y-1/2 text-xs text-zinc-400 dark:text-zinc-400 pointer-events-none", children: prefix })), _jsx(Input, { type: type, value: maxValue, onChange: (e) => onMaxChange(e.target.value), placeholder: maxPlaceholder ?? (type === "date" ? "To" : "Max"), className: cn(inputClass, prefix ? "pl-5" : "") })] })] })] })] }))] }));
|
|
28
28
|
}
|
|
@@ -10,14 +10,14 @@ export const Input = React.forwardRef(function Input({ label, error, helperText,
|
|
|
10
10
|
: disabled
|
|
11
11
|
? INPUT_DISABLED
|
|
12
12
|
: "";
|
|
13
|
-
return (_jsxs(Div, { className: "w-full", children: [label && (_jsxs("label", { className: LABEL_BASE, children: [label, required && (_jsx(Span, { className: "text-
|
|
14
|
-
? "text-
|
|
15
|
-
: "text-zinc-400 dark:text-zinc-
|
|
13
|
+
return (_jsxs(Div, { className: "w-full", children: [label && (_jsxs("label", { className: LABEL_BASE, children: [label, required && (_jsx(Span, { className: "text-error ml-1", "aria-hidden": "true", children: "*" }))] })), _jsxs(Div, { className: "relative group", children: [icon && (_jsx(Div, { className: cn("absolute left-3 top-1/2 -translate-y-1/2 transition-colors duration-150", error
|
|
14
|
+
? "text-error"
|
|
15
|
+
: "text-zinc-400 dark:text-zinc-400", "group-focus-within:text-primary-500 dark:group-focus-within:text-secondary-400"), children: icon })), _jsx("input", { ref: ref, className: cn("w-full", INPUT_BASE, icon ? INPUT_WITH_ICON : "", rightIcon ? "pr-10" : "", stateClasses, className), disabled: disabled, "aria-invalid": error ? "true" : undefined, "aria-describedby": error
|
|
16
16
|
? `${props.id}-error`
|
|
17
17
|
: helperText
|
|
18
18
|
? `${props.id}-helper`
|
|
19
19
|
: undefined, ...props }), rightIcon && (_jsx(Div, { className: cn("absolute right-3 top-1/2 -translate-y-1/2 transition-colors duration-150", error
|
|
20
|
-
? "text-
|
|
21
|
-
: "text-zinc-400 dark:text-zinc-
|
|
20
|
+
? "text-error"
|
|
21
|
+
: "text-zinc-400 dark:text-zinc-400"), children: rightIcon }))] }), error && (_jsx(Text, { id: `${props.id}-error`, className: ERROR_BASE, role: "alert", children: error })), !error && helperText && (_jsx(Text, { id: `${props.id}-helper`, className: HELPER_BASE, children: helperText }))] }));
|
|
22
22
|
});
|
|
23
23
|
Input.displayName = "Input";
|
|
@@ -2,7 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { Div, Span, Text } from "../../ui";
|
|
3
3
|
import { cn, INPUT_BASE, INPUT_ERROR, LABEL_BASE, HELPER_BASE, ERROR_BASE, } from "./utils";
|
|
4
4
|
export function Select({ label, error, helperText, options, placeholder, className = "", required, ...props }) {
|
|
5
|
-
return (_jsxs(Div, { className: "w-full", children: [label && (_jsxs("label", { className: LABEL_BASE, children: [label, required && (_jsx(Span, { className: "text-
|
|
6
|
-
? "text-
|
|
7
|
-
: "text-zinc-400 dark:text-zinc-
|
|
5
|
+
return (_jsxs(Div, { className: "w-full", children: [label && (_jsxs("label", { className: LABEL_BASE, children: [label, required && (_jsx(Span, { className: "text-error ml-1", "aria-hidden": "true", children: "*" }))] })), _jsxs(Div, { className: "relative group", children: [_jsxs("select", { className: cn(INPUT_BASE, "pr-10 appearance-none cursor-pointer", error ? INPUT_ERROR : "", className), "aria-invalid": error ? "true" : undefined, ...props, children: [placeholder && (_jsx("option", { value: "", disabled: true, children: placeholder })), options.map((option) => (_jsx("option", { value: option.value, children: option.label }, option.value)))] }), _jsx(Div, { className: "absolute right-3 top-1/2 -translate-y-1/2 pointer-events-none transition-colors duration-150", children: _jsx("svg", { className: cn("w-5 h-5 transition-transform duration-200", error
|
|
6
|
+
? "text-error"
|
|
7
|
+
: "text-zinc-400 dark:text-zinc-400"), viewBox: "0 0 20 20", fill: "currentColor", "aria-hidden": "true", children: _jsx("path", { fillRule: "evenodd", d: "M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z", clipRule: "evenodd" }) }) })] }), error && (_jsx(Text, { className: ERROR_BASE, role: "alert", children: error })), !error && helperText && _jsx(Text, { className: HELPER_BASE, children: helperText })] }));
|
|
8
8
|
}
|
|
@@ -18,5 +18,5 @@ export function Slider({ value: controlledValue, defaultValue = 0, min = 0, max
|
|
|
18
18
|
onChange?.(newVal);
|
|
19
19
|
};
|
|
20
20
|
const displayValue = formatValue ? formatValue(value) : String(value);
|
|
21
|
-
return (_jsxs(Div, { className: cn("w-full space-y-2", className), children: [(label || showValue) && (_jsxs(Row, { justify: "between", children: [label && (_jsx("label", { htmlFor: sliderId, className: LABEL_BASE, children: label })), showValue && (_jsx(Span, { className: "text-sm font-semibold tabular-nums text-zinc-900 dark:text-zinc-100", children: displayValue }))] })), _jsxs(Row, { className: "relative h-5", children: [_jsx(Div, { className: "absolute inset-y-0 flex items-center w-full", children: _jsx(Div, { className: "w-full h-1.5 rounded-full bg-zinc-200 dark:bg-slate-700", children: _jsx(Div, { className: "h-full rounded-full bg-primary-500 dark:bg-secondary-500 transition-all", style: { width: `${pct}%` } }) }) }), _jsx("input", { type: "range", id: sliderId, min: min, max: max, step: step, value: value, disabled: disabled, onChange: handleChange, className: cn("relative w-full appearance-none bg-transparent cursor-pointer", "focus:outline-none", "[&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:w-4 [&::-webkit-slider-thumb]:h-4", "[&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:bg-white", "[&::-webkit-slider-thumb]:border-2 [&::-webkit-slider-thumb]:border-primary-500 dark:[&::-webkit-slider-thumb]:border-secondary-500", "[&::-webkit-slider-thumb]:shadow-sm", "[&::-moz-range-thumb]:w-4 [&::-moz-range-thumb]:h-4", "[&::-moz-range-thumb]:rounded-full [&::-moz-range-thumb]:bg-white", "[&::-moz-range-thumb]:border-2 [&::-moz-range-thumb]:border-primary-500 dark:[&::-moz-range-thumb]:border-secondary-500", disabled && "opacity-50 cursor-not-allowed") })] }), _jsxs(Row, { justify: "between", className: "text-xs text-zinc-400 dark:text-zinc-
|
|
21
|
+
return (_jsxs(Div, { className: cn("w-full space-y-2", className), children: [(label || showValue) && (_jsxs(Row, { justify: "between", children: [label && (_jsx("label", { htmlFor: sliderId, className: LABEL_BASE, children: label })), showValue && (_jsx(Span, { className: "text-sm font-semibold tabular-nums text-zinc-900 dark:text-zinc-100", children: displayValue }))] })), _jsxs(Row, { className: "relative h-5", children: [_jsx(Div, { className: "absolute inset-y-0 flex items-center w-full", children: _jsx(Div, { className: "w-full h-1.5 rounded-full bg-zinc-200 dark:bg-slate-700", children: _jsx(Div, { className: "h-full rounded-full bg-primary-500 dark:bg-secondary-500 transition-all", style: { width: `${pct}%` } }) }) }), _jsx("input", { type: "range", id: sliderId, min: min, max: max, step: step, value: value, disabled: disabled, onChange: handleChange, className: cn("relative w-full appearance-none bg-transparent cursor-pointer", "focus:outline-none", "[&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:w-4 [&::-webkit-slider-thumb]:h-4", "[&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:bg-white", "[&::-webkit-slider-thumb]:border-2 [&::-webkit-slider-thumb]:border-primary-500 dark:[&::-webkit-slider-thumb]:border-secondary-500", "[&::-webkit-slider-thumb]:shadow-sm", "[&::-moz-range-thumb]:w-4 [&::-moz-range-thumb]:h-4", "[&::-moz-range-thumb]:rounded-full [&::-moz-range-thumb]:bg-white", "[&::-moz-range-thumb]:border-2 [&::-moz-range-thumb]:border-primary-500 dark:[&::-moz-range-thumb]:border-secondary-500", disabled && "opacity-50 cursor-not-allowed") })] }), _jsxs(Row, { justify: "between", className: "text-xs text-zinc-400 dark:text-zinc-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
|
}
|
|
@@ -8,8 +8,8 @@ export const Textarea = React.forwardRef(function Textarea({ label, error, helpe
|
|
|
8
8
|
: typeof defaultValue === "string"
|
|
9
9
|
? defaultValue.length
|
|
10
10
|
: 0;
|
|
11
|
-
return (_jsxs(Div, { className: "w-full", children: [label && (_jsxs("label", { className: LABEL_BASE, children: [label, required && (_jsx(Span, { className: "text-
|
|
12
|
-
? "text-
|
|
13
|
-
: "text-zinc-400 dark:text-zinc-
|
|
11
|
+
return (_jsxs(Div, { className: "w-full", children: [label && (_jsxs("label", { className: LABEL_BASE, children: [label, required && (_jsx(Span, { className: "text-error ml-1", "aria-hidden": "true", children: "*" }))] })), _jsx("textarea", { ref: ref, className: cn(INPUT_BASE, "resize-y min-h-[80px]", error ? INPUT_ERROR : "", className), "aria-invalid": error ? "true" : undefined, maxLength: maxLength, value: value, defaultValue: defaultValue, ...props }), _jsxs(Div, { className: "flex items-center justify-between mt-1.5", children: [_jsxs(Div, { className: "flex-1", children: [error && (_jsx(Text, { className: ERROR_BASE, role: "alert", children: error })), !error && helperText && (_jsx(Text, { className: HELPER_BASE, children: helperText }))] }), showCharCount && maxLength && (_jsxs("p", { className: cn("text-xs tabular-nums ml-2 flex-shrink-0", charCount >= maxLength
|
|
12
|
+
? "text-error"
|
|
13
|
+
: "text-zinc-400 dark:text-zinc-400"), children: [charCount, " / ", maxLength] }))] })] }));
|
|
14
14
|
});
|
|
15
15
|
Textarea.displayName = "Textarea";
|
|
@@ -3,8 +3,8 @@ export declare function cn(...classes: (string | undefined | null | false)[]): s
|
|
|
3
3
|
export declare const INPUT_BASE = "rounded-lg border border-zinc-200 dark:border-slate-700 bg-white dark:bg-slate-800/60 px-3.5 py-2.5 text-sm text-zinc-900 dark:text-zinc-100 focus:ring-2 focus:ring-primary-500/20 dark:focus:ring-secondary-400/20 focus:border-primary-500 dark:focus:border-secondary-400 focus:outline-none transition-colors duration-150 placeholder:text-zinc-400 dark:placeholder:text-zinc-500";
|
|
4
4
|
export declare const INPUT_ERROR = "border-red-400 dark:border-red-500 focus:ring-red-500/20 focus:border-red-500 bg-red-50/30 dark:bg-red-950/10";
|
|
5
5
|
export declare const INPUT_SUCCESS = "border-emerald-400 dark:border-emerald-500 focus:ring-emerald-500/20 focus:border-emerald-500";
|
|
6
|
-
export declare const INPUT_DISABLED = "bg-zinc-50 dark:bg-slate-800/30 text-zinc-400 dark:text-zinc-
|
|
6
|
+
export declare const INPUT_DISABLED = "bg-zinc-50 dark:bg-slate-800/30 text-zinc-400 dark:text-zinc-400 cursor-not-allowed opacity-60";
|
|
7
7
|
export declare const INPUT_WITH_ICON = "pl-10";
|
|
8
8
|
export declare const LABEL_BASE = "block text-sm font-medium text-zinc-700 dark:text-zinc-300 mb-1.5";
|
|
9
9
|
export declare const HELPER_BASE = "text-xs text-zinc-500 dark:text-zinc-400 mt-1";
|
|
10
|
-
export declare const ERROR_BASE = "text-xs text-
|
|
10
|
+
export declare const ERROR_BASE = "text-xs text-error mt-1";
|
|
@@ -6,8 +6,8 @@ export function cn(...classes) {
|
|
|
6
6
|
export const INPUT_BASE = "rounded-lg border border-zinc-200 dark:border-slate-700 bg-white dark:bg-slate-800/60 px-3.5 py-2.5 text-sm text-zinc-900 dark:text-zinc-100 focus:ring-2 focus:ring-primary-500/20 dark:focus:ring-secondary-400/20 focus:border-primary-500 dark:focus:border-secondary-400 focus:outline-none transition-colors duration-150 placeholder:text-zinc-400 dark:placeholder:text-zinc-500";
|
|
7
7
|
export const INPUT_ERROR = "border-red-400 dark:border-red-500 focus:ring-red-500/20 focus:border-red-500 bg-red-50/30 dark:bg-red-950/10";
|
|
8
8
|
export const INPUT_SUCCESS = "border-emerald-400 dark:border-emerald-500 focus:ring-emerald-500/20 focus:border-emerald-500";
|
|
9
|
-
export const INPUT_DISABLED = "bg-zinc-50 dark:bg-slate-800/30 text-zinc-400 dark:text-zinc-
|
|
9
|
+
export const INPUT_DISABLED = "bg-zinc-50 dark:bg-slate-800/30 text-zinc-400 dark:text-zinc-400 cursor-not-allowed opacity-60";
|
|
10
10
|
export const INPUT_WITH_ICON = "pl-10";
|
|
11
11
|
export const LABEL_BASE = "block text-sm font-medium text-zinc-700 dark:text-zinc-300 mb-1.5";
|
|
12
12
|
export const HELPER_BASE = "text-xs text-zinc-500 dark:text-zinc-400 mt-1";
|
|
13
|
-
export const ERROR_BASE = "text-xs text-
|
|
13
|
+
export const ERROR_BASE = "text-xs text-error mt-1";
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
* per page session even across remounts.
|
|
11
11
|
*/
|
|
12
12
|
import { useCallback, useEffect, useRef, useState } from "react";
|
|
13
|
+
import { useToast } from "../../../ui";
|
|
13
14
|
import { ACCOUNT_ENDPOINTS } from "../../../constants/api-endpoints";
|
|
14
15
|
import { clearGuestHistory, getGuestHistory, removeGuestHistoryItem, trackGuestHistory, } from "../utils/guest-history";
|
|
15
16
|
const TRACK_DEBOUNCE_MS = 1500;
|
|
@@ -64,14 +65,20 @@ async function deleteAuthAll() {
|
|
|
64
65
|
}
|
|
65
66
|
export function useHistory(userId) {
|
|
66
67
|
const isAuth = !!userId;
|
|
68
|
+
const { showToast } = useToast();
|
|
67
69
|
const [items, setItems] = useState([]);
|
|
68
70
|
const trackTimers = useRef(new Map());
|
|
69
71
|
const loadItems = useCallback(async () => {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
+
try {
|
|
73
|
+
if (isAuth) {
|
|
74
|
+
setItems(await fetchAuthHistory());
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
setItems(getGuestHistory());
|
|
78
|
+
}
|
|
72
79
|
}
|
|
73
|
-
|
|
74
|
-
|
|
80
|
+
catch {
|
|
81
|
+
// Data loading — silent fallback to empty
|
|
75
82
|
}
|
|
76
83
|
}, [isAuth]);
|
|
77
84
|
useEffect(() => {
|
|
@@ -128,14 +135,20 @@ export function useHistory(userId) {
|
|
|
128
135
|
}
|
|
129
136
|
}, [isAuth, loadItems]);
|
|
130
137
|
const clear = useCallback(async () => {
|
|
131
|
-
|
|
132
|
-
|
|
138
|
+
try {
|
|
139
|
+
if (isAuth) {
|
|
140
|
+
await deleteAuthAll();
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
clearGuestHistory();
|
|
144
|
+
}
|
|
145
|
+
setItems([]);
|
|
146
|
+
showToast("History cleared.", "success");
|
|
133
147
|
}
|
|
134
|
-
|
|
135
|
-
|
|
148
|
+
catch {
|
|
149
|
+
showToast("Failed to clear history.", "error");
|
|
136
150
|
}
|
|
137
|
-
|
|
138
|
-
}, [isAuth]);
|
|
151
|
+
}, [isAuth, showToast]);
|
|
139
152
|
return {
|
|
140
153
|
items,
|
|
141
154
|
count: items.length,
|
|
@@ -13,7 +13,7 @@ export function AdvertisementBanner({ title, subtitle, ctaLabel = "Shop now", on
|
|
|
13
13
|
}
|
|
14
14
|
// -- Split layout: when a backgroundImage is provided --
|
|
15
15
|
if (backgroundImage) {
|
|
16
|
-
return (_jsx(Section, { className: `p-8 ${wrapClass} ${className}`, children: _jsx("div", { className: CLS_CONTAINER, "data-section": "advertisementbanner-div-298", children: _jsx("div", { className: "relative overflow-hidden rounded-2xl bg-zinc-900 shadow-xl", "data-section": "advertisementbanner-div-299", children: _jsxs("div", { className: `${THEME_CONSTANTS.grid.cols2Md} min-h-[clamp(300px,40vh,420px)]`, "data-section": "advertisementbanner-div-300", children: [_jsxs("div", { className: `relative ${THEME_CONSTANTS.card.aspectBanner} order-last md:order-first min-h-0 min-h-[clamp(300px,40vh,420px)]`, "data-section": "advertisementbanner-div-301", children: [_jsx(MediaImage, { src: backgroundImage, alt: title, size: "banner", priority: true }), _jsx("div", { className: "hidden md:block absolute inset-y-0 right-0 w-24 bg-gradient-to-r from-transparent to-zinc-900/60 pointer-events-none" })] }), _jsxs("div", { className: "relative flex flex-col justify-center px-8 py-10 md:px-12 md:py-14", "data-section": "advertisementbanner-div-302", children: [_jsx("div", { className: "absolute top-0 right-0 w-32 h-32 opacity-10 pointer-events-none bg-[radial-gradient(circle,_white_1px,_transparent_1px)] bg-[length:12px_12px]", "aria-hidden": true }), tagLabel && (_jsxs("div", { className: "inline-flex items-center gap-1.5 self-start bg-white/10 text-white/80 text-xs font-semibold uppercase tracking-widest px-3 py-1 rounded-full mb-5 backdrop-blur-sm", "data-section": "advertisementbanner-div-303", children: [_jsx(Sparkles, { className: "w-3.5 h-3.5" }), tagLabel] })), _jsx(Heading, { level: 2, variant: "none", className: "text-3xl md:text-4xl lg:text-5xl font-extrabold text-white mb-4 leading-tight", children: title }), subtitle && (_jsx(Text, { variant: "none", className: "text-white/75 text-base md:text-lg mb-8 leading-relaxed", children: subtitle })), ctaLabel && onCtaClick && (_jsxs(Button, { variant: "secondary", size: "lg", onClick: onCtaClick, className: "self-start bg-white text-zinc-900 hover:bg-zinc-100 font-semibold shadow-lg gap-2", children: [ctaLabel, _jsx(ArrowRight, { className: "w-4 h-4" })] }))] })] }) }) }) }));
|
|
16
|
+
return (_jsx(Section, { className: `p-8 ${wrapClass} ${className}`, children: _jsx("div", { className: CLS_CONTAINER, "data-section": "advertisementbanner-div-298", children: _jsx("div", { className: "relative overflow-hidden rounded-2xl bg-zinc-900 shadow-xl", "data-section": "advertisementbanner-div-299", children: _jsxs("div", { className: `${THEME_CONSTANTS.grid.cols2Md} min-h-[clamp(300px,40vh,420px)]`, "data-section": "advertisementbanner-div-300", children: [_jsxs("div", { className: `relative ${THEME_CONSTANTS.card.aspectBanner} order-last md:order-first min-h-0 min-h-[clamp(300px,40vh,420px)]`, "data-section": "advertisementbanner-div-301", children: [_jsx(MediaImage, { src: backgroundImage, alt: title, size: "banner", priority: true }), _jsx("div", { className: "hidden md:block absolute inset-y-0 right-0 w-24 bg-gradient-to-r from-transparent to-zinc-900/60 pointer-events-none" })] }), _jsxs("div", { className: "relative flex flex-col justify-center px-8 py-10 md:px-12 md:py-14", "data-section": "advertisementbanner-div-302", children: [_jsx("div", { className: "absolute top-0 right-0 w-32 h-32 opacity-10 pointer-events-none bg-[radial-gradient(circle,_white_1px,_transparent_1px)] bg-[length:12px_12px]", "aria-hidden": true }), tagLabel && (_jsxs("div", { className: "inline-flex items-center gap-1.5 self-start bg-white/10 text-white/80 text-xs font-semibold uppercase tracking-widest px-3 py-1 rounded-full mb-5 backdrop-blur-sm", "data-section": "advertisementbanner-div-303", children: [_jsx(Sparkles, { className: "w-3.5 h-3.5" }), tagLabel] })), _jsx(Heading, { level: 2, variant: "none", className: "text-3xl md:text-4xl lg:text-5xl font-extrabold text-white mb-4 leading-tight", children: title }), subtitle && (_jsx(Text, { variant: "none", className: "text-white/75 text-base md:text-lg mb-8 leading-relaxed", children: subtitle })), ctaLabel && onCtaClick && (_jsxs(Button, { variant: "secondary", size: "lg", onClick: onCtaClick, className: "self-start bg-white text-zinc-900 hover:bg-zinc-100 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
17
|
}
|
|
18
18
|
// -- Full-width gradient layout --
|
|
19
19
|
return (_jsx(Section, { className: `p-8 ${wrapClass} ${className}`, children: _jsx("div", { className: CLS_CONTAINER, "data-section": "advertisementbanner-div-304", children: _jsxs("div", { className: [
|
|
@@ -21,5 +21,5 @@ export function AdvertisementBanner({ title, subtitle, ctaLabel = "Shop now", on
|
|
|
21
21
|
compact
|
|
22
22
|
? "h-[clamp(112px,16vh,160px)]"
|
|
23
23
|
: "min-h-[clamp(240px,34vh,360px)]",
|
|
24
|
-
].join(" "), style: backgroundColor ? { backgroundColor } : undefined, "data-section": "advertisementbanner-div-305", children: [!backgroundColor && (_jsx("div", { className: "absolute inset-0 bg-gradient-to-br from-indigo-600 via-purple-600 to-fuchsia-600", "aria-hidden": true })), _jsxs("div", { className: "absolute inset-0 overflow-hidden", "aria-hidden": true, "data-section": "advertisementbanner-div-306", 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("div", { className: "inline-flex items-center gap-2", "data-section": "advertisementbanner-div-307", children: [_jsx(Sparkles, { className: "w-4 h-4 text-white/80" }), _jsx(Span, { className: "text-white font-semibold text-sm", children: title })] }), ctaLabel && onCtaClick && (_jsxs(Button, { variant: "secondary", size: "sm", onClick: onCtaClick, className: "bg-white text-indigo-700 hover:bg-zinc-50 font-semibold gap-1.5 flex-shrink-0", 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", "data-section": "advertisementbanner-div-308", children: [tagLabel && (_jsxs("div", { className: "inline-flex items-center gap-1.5 bg-white/15 text-white/90 text-xs font-semibold uppercase tracking-widest px-4 py-1.5 rounded-full mb-5 backdrop-blur-sm shadow-sm", "data-section": "advertisementbanner-div-309", 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: "bg-white text-indigo-700 hover:bg-zinc-50 font-semibold shadow-lg gap-2", children: [ctaLabel, _jsx(ArrowRight, { className: "w-4 h-4" })] }))] }))] }) }) }));
|
|
24
|
+
].join(" "), style: backgroundColor ? { backgroundColor } : undefined, "data-section": "advertisementbanner-div-305", children: [!backgroundColor && (_jsx("div", { className: "absolute inset-0 bg-gradient-to-br from-indigo-600 via-purple-600 to-fuchsia-600", "aria-hidden": true })), _jsxs("div", { className: "absolute inset-0 overflow-hidden", "aria-hidden": true, "data-section": "advertisementbanner-div-306", 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("div", { className: "inline-flex items-center gap-2", "data-section": "advertisementbanner-div-307", children: [_jsx(Sparkles, { className: "w-4 h-4 text-white/80" }), _jsx(Span, { className: "text-white font-semibold text-sm", children: title })] }), ctaLabel && onCtaClick && (_jsxs(Button, { variant: "secondary", size: "sm", onClick: onCtaClick, className: "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", 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", "data-section": "advertisementbanner-div-308", children: [tagLabel && (_jsxs("div", { className: "inline-flex items-center gap-1.5 bg-white/15 text-white/90 text-xs font-semibold uppercase tracking-widest px-4 py-1.5 rounded-full mb-5 backdrop-blur-sm shadow-sm", "data-section": "advertisementbanner-div-309", 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: "bg-white dark:bg-zinc-100 text-indigo-700 hover:bg-zinc-50 dark:hover:bg-zinc-200 font-semibold shadow-lg gap-2", children: [ctaLabel, _jsx(ArrowRight, { className: "w-4 h-4" })] }))] }))] }) }) }));
|
|
25
25
|
}
|
|
@@ -146,7 +146,7 @@ export function CharacterHotspotForm({ initial, onUploadImage, onSave, onAfterSa
|
|
|
146
146
|
}, children: "Next: Place Pins \u2192" })] })] })), step === "place" && (_jsxs(Div, { className: CLS_STEP, style: {
|
|
147
147
|
borderColor: "var(--border-ink)",
|
|
148
148
|
background: "var(--surface-elevated)",
|
|
149
|
-
}, children: [_jsx(Heading, { level: 2, className: "text-lg font-bold", children: "Place a Pin" }), _jsxs(Text, { className: "text-sm", style: { color: "var(--color-muted)" }, children: [_jsx("
|
|
149
|
+
}, children: [_jsx(Heading, { level: 2, className: "text-lg font-bold", children: "Place a Pin" }), _jsxs(Text, { className: "text-sm", style: { color: "var(--color-muted)" }, children: [_jsx(Span, { weight: "bold", children: "Click anywhere on the image" }), " to drop a pin, or enter exact coordinates below."] }), _jsxs(Div, { ref: containerRef, className: CLS_IMG_WRAP, style: {
|
|
150
150
|
paddingTop: "56.25%",
|
|
151
151
|
cursor: "crosshair",
|
|
152
152
|
background: "#111",
|
|
@@ -220,7 +220,7 @@ export function CharacterHotspotForm({ initial, onUploadImage, onSave, onAfterSa
|
|
|
220
220
|
}, children: "Continue: Add Details \u2192" })] })] })] })), step === "details" && (_jsxs(Div, { className: CLS_STEP, style: {
|
|
221
221
|
borderColor: "var(--border-ink)",
|
|
222
222
|
background: "var(--surface-elevated)",
|
|
223
|
-
}, children: [_jsx(Heading, { level: 2, className: "text-lg font-bold", children: "Pin Details" }), _jsxs(Text, { className: "text-sm", style: { color: "var(--color-muted)" }, children: ["Fill in the details for the pin at", " ", _jsxs("
|
|
223
|
+
}, children: [_jsx(Heading, { level: 2, className: "text-lg font-bold", children: "Pin Details" }), _jsxs(Text, { className: "text-sm", style: { color: "var(--color-muted)" }, children: ["Fill in the details for the pin at", " ", _jsxs(Span, { weight: "bold", children: [draftPos?.xPct, "%, ", draftPos?.yPct, "%"] }), "."] }), _jsx(Div, { className: "grid grid-cols-2 gap-3", children: [
|
|
224
224
|
{
|
|
225
225
|
label: "Name *",
|
|
226
226
|
value: draftName,
|
|
@@ -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-
|
|
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, { className: "text-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,
|
|
@@ -8,5 +8,5 @@ export function HeroSection({ section, onCtaClick }) {
|
|
|
8
8
|
backgroundSize: "cover",
|
|
9
9
|
backgroundPosition: "center",
|
|
10
10
|
}
|
|
11
|
-
: undefined, children: [_jsx(Div, { className: "absolute inset-0 bg-black/40" }), _jsxs(Div, { className: "relative mx-auto max-w-7xl px-4 py-16 text-center text-white sm:px-6 lg:px-8", children: [content?.title && (_jsx(Heading, { level: 1, className: "text-4xl font-bold leading-tight sm:text-5xl lg:text-6xl", children: content.title })), content?.subtitle && (_jsx(Text, { className: "mx-auto mt-4 max-w-2xl text-lg opacity-90", children: content.subtitle })), content?.ctaLabel && (_jsx(Button, { onClick: onCtaClick, className: "mt-8 inline-block rounded-full bg-white px-8 py-3 text-sm font-semibold text-
|
|
11
|
+
: undefined, children: [_jsx(Div, { className: "absolute inset-0 bg-black/40" }), _jsxs(Div, { className: "relative mx-auto max-w-7xl px-4 py-16 text-center text-white sm:px-6 lg:px-8", children: [content?.title && (_jsx(Heading, { level: 1, className: "text-4xl font-bold leading-tight sm:text-5xl lg:text-6xl", children: content.title })), content?.subtitle && (_jsx(Text, { className: "mx-auto mt-4 max-w-2xl text-lg opacity-90", children: content.subtitle })), content?.ctaLabel && (_jsx(Button, { onClick: onCtaClick, className: "mt-8 inline-block rounded-full bg-white px-8 py-3 text-sm font-semibold text-zinc-900 dark:text-zinc-100 transition hover:bg-neutral-100", children: content.ctaLabel }))] })] }));
|
|
12
12
|
}
|
|
@@ -3,5 +3,5 @@ import { Heading, Section, Text, TextLink } from "../../../ui";
|
|
|
3
3
|
import { Mail } from "lucide-react";
|
|
4
4
|
// --- Section -----------------------------------------------------------------
|
|
5
5
|
export function NewsletterSection({ title, subtitle, privacyLabel, privacyHref, renderForm, className = "", }) {
|
|
6
|
-
return (_jsxs(Section, { className: `py-16 px-4 relative overflow-hidden ${className}`, children: [_jsx("div", { className: "absolute inset-0 bg-gradient-to-br from-primary/10 via-cobalt/5 to-secondary/10 dark:from-primary/15 dark:via-cobalt/10 dark:to-secondary/15 pointer-events-none", "aria-hidden": true }), _jsx("div", { className: "absolute -top-20 -right-20 w-80 h-80 rounded-full bg-primary/5 dark:bg-primary/10 pointer-events-none", "aria-hidden": true }), _jsx("div", { className: "absolute -bottom-16 -left-16 w-64 h-64 rounded-full bg-cobalt/5 dark:bg-cobalt/10 pointer-events-none", "aria-hidden": true }), _jsxs("div", { className: "relative z-10 max-w-2xl mx-auto text-center", "data-section": "newslettersection-div-347", children: [_jsx("div", { className: "inline-flex items-center justify-center w-14 h-14 rounded-2xl bg-primary/10 dark:bg-primary/20 border border-primary/20 mb-5 mx-auto", "data-section": "newslettersection-div-348", children: _jsx(Mail, { className: "w-7 h-7 text-primary" }) }), _jsx(Heading, { level: 2, className: "text-2xl sm:text-3xl font-bold text-zinc-900 dark:text-white mb-3", children: title }), subtitle && (_jsx(Text, { size: "base", className: "text-zinc-500 dark:text-zinc-400 mb-8 max-w-md mx-auto", children: subtitle })), renderForm(), privacyLabel && privacyHref && (_jsxs(Text, { size: "xs", className: "text-zinc-400 dark:text-zinc-
|
|
6
|
+
return (_jsxs(Section, { className: `py-16 px-4 relative overflow-hidden ${className}`, children: [_jsx("div", { className: "absolute inset-0 bg-gradient-to-br from-primary/10 via-cobalt/5 to-secondary/10 dark:from-primary/15 dark:via-cobalt/10 dark:to-secondary/15 pointer-events-none", "aria-hidden": true }), _jsx("div", { className: "absolute -top-20 -right-20 w-80 h-80 rounded-full bg-primary/5 dark:bg-primary/10 pointer-events-none", "aria-hidden": true }), _jsx("div", { className: "absolute -bottom-16 -left-16 w-64 h-64 rounded-full bg-cobalt/5 dark:bg-cobalt/10 pointer-events-none", "aria-hidden": true }), _jsxs("div", { className: "relative z-10 max-w-2xl mx-auto text-center", "data-section": "newslettersection-div-347", children: [_jsx("div", { className: "inline-flex items-center justify-center w-14 h-14 rounded-2xl bg-primary/10 dark:bg-primary/20 border border-primary/20 mb-5 mx-auto", "data-section": "newslettersection-div-348", children: _jsx(Mail, { className: "w-7 h-7 text-primary" }) }), _jsx(Heading, { level: 2, className: "text-2xl sm:text-3xl font-bold text-zinc-900 dark:text-white mb-3", children: title }), subtitle && (_jsx(Text, { size: "base", className: "text-zinc-500 dark:text-zinc-400 mb-8 max-w-md mx-auto", children: subtitle })), renderForm(), privacyLabel && privacyHref && (_jsxs(Text, { size: "xs", className: "text-zinc-400 dark:text-zinc-400 mt-4", children: [privacyLabel, " ", _jsx(TextLink, { href: privacyHref, className: "underline underline-offset-2 hover:text-primary", children: "Privacy Policy" }), "."] }))] })] }));
|
|
7
7
|
}
|
|
@@ -36,7 +36,7 @@ export function SectionCarousel({ title, description, headingVariant = "editoria
|
|
|
36
36
|
headingClass,
|
|
37
37
|
]
|
|
38
38
|
.filter(Boolean)
|
|
39
|
-
.join(" "), children: title }), headingVariant === "editorial" && (_jsxs("div", { className: `${flex.center} gap-2 mt-1 text-zinc-400 dark:text-zinc-
|
|
39
|
+
.join(" "), children: title }), headingVariant === "editorial" && (_jsxs("div", { className: `${flex.center} gap-2 mt-1 text-zinc-400 dark:text-zinc-400 text-xs select-none`, "aria-hidden": "true", "data-section": "sectioncarousel-div-355", children: [_jsx(Span, { className: "h-px w-6 bg-current" }), _jsx(Span, { className: "text-xs", children: "\u2736" }), _jsx(Span, { className: "h-px w-6 bg-current" })] })), description && (_jsx(Text, { className: `text-base ${descVariant} mt-2`, children: description }))] }), isLoading ? (_jsx(CarouselSkeleton, { count: skeletonCount })) : (_jsx(HorizontalScroller, { items: items, renderItem: renderItem, perView: perView, gap: gap, autoScroll: autoScroll, autoScrollInterval: autoScrollInterval, loop: rows === 1, keyExtractor: keyExtractor, rows: rows, minItemWidth: minItemWidth, showArrows: true, snapToItems: true, showFadeEdges: true, showScrollbar: false, pauseOnHover: true })), viewMoreHref && !isLoading && (_jsx("div", { className: "mt-6 flex justify-center", "data-section": "sectioncarousel-div-356", children: _jsx(TextLink, { href: viewMoreHref, className: `inline-flex items-center gap-1.5 rounded-lg border px-6 py-2.5 text-sm font-medium transition-colors ${useLightText
|
|
40
40
|
? "border-white/40 text-white hover:bg-white/10"
|
|
41
41
|
: "border-zinc-200 dark:border-zinc-700 text-zinc-700 dark:text-zinc-300 hover:bg-zinc-50 dark:hover:bg-zinc-800"}`, children: viewMoreLabel }) }))] })] }));
|
|
42
42
|
}
|
|
@@ -55,7 +55,7 @@ function BulkPickerPanel({ bulkActions, selectedActionId, pickerOpen, onSelect,
|
|
|
55
55
|
i > 0 ? "border-t border-zinc-100/80 dark:border-slate-800/80" : "",
|
|
56
56
|
isSelected ? "bg-zinc-50 dark:bg-slate-800/60" : "",
|
|
57
57
|
action.variant === "danger"
|
|
58
|
-
? "text-
|
|
58
|
+
? "text-error hover:bg-error-surface"
|
|
59
59
|
: "text-zinc-800 dark:text-zinc-100 hover:bg-zinc-50 dark:hover:bg-slate-800/60",
|
|
60
60
|
action.disabled || action.loading ? "opacity-50 cursor-not-allowed" : "",
|
|
61
61
|
]
|
|
@@ -133,7 +133,7 @@ export default function BottomActions() {
|
|
|
133
133
|
"bg-zinc-50 hover:bg-zinc-100 active:bg-zinc-200 dark:bg-slate-800/60 dark:hover:bg-slate-700/60",
|
|
134
134
|
"border-zinc-200 dark:border-slate-700",
|
|
135
135
|
selectedAction?.variant === "danger"
|
|
136
|
-
? "text-
|
|
136
|
+
? "text-error"
|
|
137
137
|
: "text-zinc-800 dark:text-zinc-100",
|
|
138
138
|
]
|
|
139
139
|
.filter(Boolean)
|
|
@@ -69,7 +69,7 @@ export function ListingLayout({ headerSlot, statusTabsSlot, filterContent, filte
|
|
|
69
69
|
sidebarOpen
|
|
70
70
|
? "bg-primary/10 border-primary/30 text-primary dark:bg-primary/15 dark:border-primary/40"
|
|
71
71
|
: "border-zinc-200 dark:border-slate-700 text-zinc-600 dark:text-slate-300 hover:border-zinc-300 dark:hover:border-slate-600 hover:bg-zinc-50 dark:hover:bg-slate-800/60",
|
|
72
|
-
].join(" "), children: [l.filtersTitle, filterActiveCount > 0 && (_jsx(Span, { className: "inline-flex items-center justify-center w-4 h-4 text-[10px] font-bold rounded-full bg-primary text-white", children: filterActiveCount }))] })), searchSlot && _jsx(Div, { className: "flex-1 min-w-0", children: searchSlot }), _jsxs(Row, { className: "gap-1.5 flex-shrink-0", children: [sortSlot, viewToggleSlot && (_jsx(Row, { className: "gap-0.5 rounded-full
|
|
72
|
+
].join(" "), children: [l.filtersTitle, filterActiveCount > 0 && (_jsx(Span, { className: "inline-flex items-center justify-center w-4 h-4 text-[10px] font-bold rounded-full bg-primary text-white", children: filterActiveCount }))] })), searchSlot && _jsx(Div, { className: "flex-1 min-w-0", children: searchSlot }), _jsxs(Row, { className: "gap-1.5 flex-shrink-0", children: [sortSlot, viewToggleSlot && (_jsx(Row, { surface: "card", className: "gap-0.5 rounded-full p-0.5", children: viewToggleSlot })), actionsSlot] }), toolbarPaginationSlot && (_jsx(Div, { className: "ml-auto flex-shrink-0 pl-3 border-l border-zinc-200/70 dark:border-slate-700/70", children: toolbarPaginationSlot }))] }), _jsxs(Div, { className: "flex flex-col gap-2 md:hidden", children: [_jsxs(Row, { className: "gap-2", children: [hasFilter && (_jsxs(Button, { type: "button", onClick: () => setMobileFilterOpen(true), "aria-label": l.filtersTitle, variant: "ghost", size: "sm", className: [
|
|
73
73
|
"flex-shrink-0 flex items-center gap-1.5",
|
|
74
74
|
"rounded-full h-9 px-3 text-sm font-medium",
|
|
75
75
|
"border border-zinc-200 dark:border-slate-700",
|
|
@@ -85,7 +85,7 @@ export function ListingLayout({ headerSlot, statusTabsSlot, filterContent, filte
|
|
|
85
85
|
sidebarOpen
|
|
86
86
|
? "w-60 xl:w-64 2xl:w-72 opacity-100"
|
|
87
87
|
: "w-0 opacity-0 pointer-events-none",
|
|
88
|
-
].join(" "), children: _jsxs(Div, { className: "w-60 xl:w-64 2xl:w-72
|
|
88
|
+
].join(" "), children: _jsxs(Div, { surface: "elevated", className: "w-60 xl:w-64 2xl:w-72 overflow-hidden", children: [_jsxs(Row, { justify: "between", className: "px-4 py-3 border-b border-zinc-100 dark:border-slate-800", children: [_jsx(Div, { className: "font-semibold text-sm", children: panelTitle }), filterActiveCount > 0 && (_jsx(Button, { type: "button", variant: "ghost", size: "sm", onClick: onFilterClear, className: "text-xs text-primary hover:text-primary/80 hover:underline p-0 h-auto leading-none font-medium", children: l.clearAll }))] }), _jsx(Div, { className: "px-3 pt-5 pb-3 max-h-[calc(100vh-15rem)] overflow-y-auto space-y-4", children: filterContent }), _jsx(Div, { className: "px-3 pb-3 pt-2 border-t border-zinc-100 dark:border-slate-800", children: _jsx(Button, { type: "button", variant: "primary", className: "w-full rounded-xl bg-primary text-white py-2 px-3", onClick: onFilterApply, children: l.applyFilters }) })] }) })), _jsxs(Div, { className: "flex-1 min-w-0 space-y-3", children: [activeFiltersSlot, errorSlot ? (errorSlot) : (_jsxs(_Fragment, { children: [children, paginationSlot && _jsx(Div, { className: "pt-2", children: paginationSlot })] }))] })] }), toolbarPaginationSlot && (_jsx(Nav, { "aria-label": "Pagination", className: [
|
|
89
89
|
"fixed left-0 right-0 md:hidden",
|
|
90
90
|
isDashboard
|
|
91
91
|
? "bottom-0"
|
|
@@ -97,7 +97,7 @@ export function ListingLayout({ headerSlot, statusTabsSlot, filterContent, filte
|
|
|
97
97
|
"shadow-[0_-2px_8px_rgba(0,0,0,0.06)] dark:shadow-[0_-2px_8px_rgba(0,0,0,0.20)]",
|
|
98
98
|
"h-10 flex items-center justify-center px-3 overflow-x-auto pb-px",
|
|
99
99
|
"[scrollbar-width:none] [&::-webkit-scrollbar]:hidden",
|
|
100
|
-
].join(" "), children: toolbarPaginationSlot })), hasFilter && mobileFilterOpen && (_jsxs(_Fragment, { children: [_jsx(Div, { className: "fixed inset-0 z-40 bg-black/40 lg:hidden", onClick: () => setMobileFilterOpen(false), "aria-hidden": "true" }), _jsxs(Div, { ref: mobileOverlayRef, className: "fixed inset-0 z-50 flex flex-col lg:hidden bg-white dark:bg-slate-950", role: "dialog", "aria-modal": "true", "aria-label": panelTitle, children: [_jsxs(Row, { justify: "between", className: "px-4 py-3 border-b border-zinc-100 dark:border-slate-800 flex-shrink-0", children: [_jsxs(Div, { className: "font-semibold", children: [panelTitle, filterActiveCount > 0 && (_jsx(Span, { className: "ml-2 inline-flex items-center justify-center w-5 h-5 text-[11px] font-bold rounded-full bg-primary text-white", children: filterActiveCount }))] }), _jsx(Button, { type: "button", variant: "ghost", size: "sm", onClick: () => setMobileFilterOpen(false), "aria-label": l.close, className: "rounded-full w-8 h-8 p-0 flex items-center justify-center hover:bg-zinc-100 dark:hover:bg-slate-800", children: "x" })] }), _jsx(Div, { className: "flex-1 overflow-y-auto px-4 pt-6 pb-4 space-y-4", children: filterContent }), _jsxs(Div, { className: "flex-shrink-0 flex gap-3 px-4 py-4 border-t border-zinc-100 dark:border-slate-800
|
|
100
|
+
].join(" "), children: toolbarPaginationSlot })), hasFilter && mobileFilterOpen && (_jsxs(_Fragment, { children: [_jsx(Div, { className: "fixed inset-0 z-40 bg-black/40 lg:hidden", onClick: () => setMobileFilterOpen(false), "aria-hidden": "true" }), _jsxs(Div, { ref: mobileOverlayRef, className: "fixed inset-0 z-50 flex flex-col lg:hidden bg-white dark:bg-slate-950", role: "dialog", "aria-modal": "true", "aria-label": panelTitle, children: [_jsxs(Row, { justify: "between", className: "px-4 py-3 border-b border-zinc-100 dark:border-slate-800 flex-shrink-0", children: [_jsxs(Div, { className: "font-semibold", children: [panelTitle, filterActiveCount > 0 && (_jsx(Span, { className: "ml-2 inline-flex items-center justify-center w-5 h-5 text-[11px] font-bold rounded-full bg-primary text-white", children: filterActiveCount }))] }), _jsx(Button, { type: "button", variant: "ghost", size: "sm", onClick: () => setMobileFilterOpen(false), "aria-label": l.close, className: "rounded-full w-8 h-8 p-0 flex items-center justify-center hover:bg-zinc-100 dark:hover:bg-slate-800", children: "x" })] }), _jsx(Div, { className: "flex-1 overflow-y-auto px-4 pt-6 pb-4 space-y-4", children: filterContent }), _jsxs(Div, { surface: "muted", className: "flex-shrink-0 flex gap-3 px-4 py-4 border-t border-zinc-100 dark:border-slate-800", children: [_jsx(Button, { type: "button", variant: "outline", className: "flex-1 rounded-xl bg-zinc-200 dark:bg-slate-700 py-2 px-3", onClick: () => {
|
|
101
101
|
onFilterClear?.();
|
|
102
102
|
}, children: l.clearAll }), _jsx(Button, { type: "button", variant: "primary", className: "flex-1 rounded-xl bg-primary text-white py-2 px-3", onClick: handleMobileApply, children: l.applyFilters })] })] })] }))] }));
|
|
103
103
|
}
|
|
@@ -31,7 +31,7 @@ export function TitleBarLayout({ onToggleSidebar, sidebarOpen, onSearchToggle, s
|
|
|
31
31
|
const profileEl = profileHref ? (_jsx(Link, { href: profileHref, "aria-label": user ? `Profile — ${user.displayName ?? user.email}` : "Sign in", className: `relative ${iconBtn}`, children: user?.photoURL ? (
|
|
32
32
|
// eslint-disable-next-line @next/next/no-img-element
|
|
33
33
|
_jsx("img", { src: user.photoURL, alt: user.displayName ?? "Profile", width: 28, height: 28, loading: "lazy", className: "w-7 h-7 rounded-full object-cover" })) : (_jsx("svg", { className: "w-5 h-5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", "aria-hidden": "true", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M15.75 6a3.75 3.75 0 1 1-7.5 0 3.75 3.75 0 0 1 7.5 0zM4.501 20.118a7.5 7.5 0 0 1 14.998 0A17.933 17.933 0 0 1 12 21.75c-2.676 0-5.216-.584-7.499-1.632z" }) })) })) : null;
|
|
34
|
-
const authButtonsEl = !user && (loginHref || registerHref) ? (_jsxs(Row, { gap: "xs", className: "hidden lg:flex
|
|
34
|
+
const authButtonsEl = !user && (loginHref || registerHref) ? (_jsxs(Row, { gap: "xs", className: "hidden lg:flex", children: [loginHref && (_jsx(Link, { href: loginHref, className: "px-3 py-1.5 text-sm font-medium text-zinc-700 dark:text-zinc-300 hover:text-primary-700 dark:hover:text-secondary-400 transition-colors rounded-lg hover:bg-primary-50 dark:hover:bg-slate-800", children: "Sign in" })), registerHref && (_jsx(Link, { href: registerHref, className: "px-3 py-1.5 text-sm font-semibold rounded-lg bg-primary text-white hover:bg-primary/90 transition-colors btn-glow shadow-sm", children: "Register" }))] })) : null;
|
|
35
35
|
const hasTb2 = !!(notificationsEl || wishlistEl || cartEl || profileEl);
|
|
36
36
|
// ── Render ───────────────────────────────────────────────────────────────────
|
|
37
37
|
return (_jsxs(BlockHeader, { id: id, className: `sticky top-0 z-50 bg-white/95 dark:bg-slate-950/95 backdrop-blur-md border-b border-zinc-100 dark:border-slate-800 shadow-sm ${className}`, children: [promoStripText && (_jsx(Div, { className: "bg-gradient-to-r from-primary-700 to-secondary-600 dark:from-primary-700 dark:to-cobalt-700 text-white text-xs py-1 text-center font-medium", children: promoStripText })), _jsxs(Div, { className: "container mx-auto px-4 sm:px-6 lg:px-8 max-w-[1920px]", children: [_jsxs(Row, { justify: "between", gap: "none", className: "relative h-14", children: [_jsx(Row, { gap: "3", children: _jsx(Link, { href: logoHref, "aria-label": brandName, className: "flex items-center transition-opacity hover:opacity-80", children: _jsx(SiteLogo, { title: brandName, className: "h-7 md:h-9 lg:h-10" }) }) }), siteLogoUrl ? (_jsx(Div, { className: "absolute inset-y-0 left-1/2 -translate-x-1/2 flex items-center", children: _jsx(Link, { href: logoHref, "aria-label": brandName, className: "flex items-center transition-opacity hover:opacity-80", children: _jsx(SiteLogo, { src: siteLogoUrl, title: brandName, className: "h-7 md:h-9 lg:h-10" }) }) })) : (navSlot && _jsx(Div, { className: "hidden md:flex", children: navSlot })), _jsxs(Row, { gap: "xs", children: [devSlot, compareEl, notificationSlot, notificationsEl && _jsx(Div, { className: "hidden lg:flex", children: notificationsEl }), wishlistEl && _jsx(Div, { className: "hidden lg:flex", children: wishlistEl }), cartEl && _jsx(Div, { className: "hidden lg:flex", children: cartEl }), user
|
|
@@ -17,6 +17,7 @@ import { ROUTES } from "../../../next";
|
|
|
17
17
|
import { InteractiveProductCard } from "../../products/components/InteractiveProductCard";
|
|
18
18
|
import { LiveItemFilters } from "./LiveItemFilters";
|
|
19
19
|
import { ACTION_ID } from "../../products/constants/action-defs";
|
|
20
|
+
import { useBottomActions } from "../../layout";
|
|
20
21
|
const DEFAULT_SORT = sortBy(PRODUCT_FIELDS.CREATED_AT);
|
|
21
22
|
const SORT_OPTIONS = [
|
|
22
23
|
{ value: sortBy(PRODUCT_FIELDS.CREATED_AT), label: "Newest First" },
|
|
@@ -101,6 +102,7 @@ export function LiveItemsIndexListing({ initialData }) {
|
|
|
101
102
|
wishlistActions.addToWishlist(id);
|
|
102
103
|
}
|
|
103
104
|
}
|
|
105
|
+
useBottomActions(selection.selectedCount > 0 ? { bulk: { selectedCount: selection.selectedCount, onClearSelection: selection.clearSelection, actions: [] } } : {});
|
|
104
106
|
return (_jsxs("div", { className: "min-h-screen", children: [_jsx(ListingToolbar, { filterCount: filterActiveCount, onFiltersClick: openFilters, searchValue: searchInput, searchPlaceholder: "Search live items\u2026", onSearchChange: setSearchInput, onSearchCommit: commitSearch, onSearchKeyDown: (e) => { if (e.key === "Enter")
|
|
105
107
|
commitSearch(); }, sortValue: table.get(TABLE_KEYS.SORT) || DEFAULT_SORT, sortOptions: SORT_OPTIONS, onSortChange: (v) => { table.set(TABLE_KEYS.SORT, v); }, view: view, onViewChange: (v) => { if (v !== "table")
|
|
106
108
|
setView(v); }, onResetAll: resetAll, hasActiveState: hasActiveState, bulkMode: selection.isSelecting, bulkSelectedCount: selection.selectedCount, bulkTotalCount: products.length, onBulkSelectAll: selection.toggleAll, onBulkClear: selection.clearSelection }), _jsx(BulkActionBar, { selectedCount: selection.selectedCount, onClearSelection: selection.clearSelection, actions: [] }), totalPages > 1 && (_jsx("div", { className: "sticky top-[calc(var(--header-height,0px)+44px)] z-10 flex justify-center bg-white/95 dark:bg-slate-900/95 backdrop-blur-sm border-b border-zinc-200 dark:border-slate-700 px-3 py-1.5", children: _jsx(Pagination, { currentPage: page, totalPages: totalPages, onPageChange: (p) => table.setPage(p) }) })), _jsx("div", { className: "py-6", children: isLoading ? (_jsx("div", { className: gridClass, children: Array.from({ length: 10 }).map((_, i) => (_jsxs("div", { className: "rounded-xl border border-zinc-100 dark:border-slate-700 overflow-hidden animate-pulse", children: [_jsx("div", { className: "aspect-square bg-zinc-200 dark:bg-slate-700" }), _jsxs("div", { className: "p-3 space-y-2", children: [_jsx("div", { className: "h-3 bg-zinc-200 dark:bg-slate-700 rounded w-3/4" }), _jsx("div", { className: "h-4 bg-zinc-200 dark:bg-slate-700 rounded w-1/3" })] })] }, i))) })) : products.length === 0 ? (_jsx(Text, { className: "py-12 text-center text-sm text-zinc-500 dark:text-zinc-400", children: "No live item listings found." })) : (_jsx("div", { className: view === "list" ? "flex flex-col divide-y divide-zinc-100 dark:divide-zinc-800 rounded-xl border border-zinc-100 dark:border-zinc-800" : gridClass, children: products.map((product) => (_jsx(InteractiveProductCard, { product: product, href: String(ROUTES.PUBLIC.LIVE_DETAIL(product.id)), variant: view === "list" ? "list" : "grid", isWishlisted: wishlistActions.isWishlisted(product.id), onToggleWishlist: handleToggleWishlist, selectable: selection.isSelecting, isSelected: selection.isSelected(product.id), onSelect: (id) => selection.toggle(id) }, product.id))) })) }), _jsx(FilterDrawer, { open: filterOpen, onOpen: openFilters, onClose: () => setFilterOpen(false), onApply: applyFilters, onReset: onFilterClear, activeCount: filterActiveCount, hideTrigger: true, children: _jsx(LiveItemFilters, { table: pendingTable, categoryOptions: categoryOptions }) }), _jsx(LoginRequiredModal, { isOpen: modalOpen, onClose: closeModal, message: modalMessage })] }));
|
|
@@ -39,5 +39,5 @@ export async function LiveItemsListView({ searchParams = {} }) {
|
|
|
39
39
|
const result = await productRepository
|
|
40
40
|
.list({ filters, sorts: sort, page, pageSize })
|
|
41
41
|
.catch(() => null);
|
|
42
|
-
return (_jsx(Main, { children: _jsx(Section, { className: "py-10", children: _jsxs(Container, { size: "xl", children: [_jsx(Heading, { level: 1, className: "mb-8 text-3xl font-semibold text-zinc-900", children: "Live Items" }), _jsx(AdSlot, { id: "listing-sidebar-top", className: "mb-6" }), _jsx(LiveItemsIndexListing, { initialData: result ?? undefined }), _jsx(AdSlot, { id: "listing-sidebar-bottom", className: "mt-8" })] }) }) }));
|
|
42
|
+
return (_jsx(Main, { children: _jsx(Section, { className: "py-10", children: _jsxs(Container, { size: "xl", children: [_jsx(Heading, { level: 1, className: "mb-8 text-3xl font-semibold text-zinc-900 dark:text-zinc-50", children: "Live Items" }), _jsx(AdSlot, { id: "listing-sidebar-top", className: "mb-6" }), _jsx(LiveItemsIndexListing, { initialData: result ?? undefined }), _jsx(AdSlot, { id: "listing-sidebar-bottom", className: "mt-8" })] }) }) }));
|
|
43
43
|
}
|
|
@@ -14,6 +14,8 @@ export { MediaPickerModal } from "./MediaPickerModal";
|
|
|
14
14
|
export type { MediaPickerModalProps } from "./MediaPickerModal";
|
|
15
15
|
export { ImageCropModal } from "./modals/ImageCropModal";
|
|
16
16
|
export type { ImageCropData, ImageCropModalProps, } from "./modals/ImageCropModal";
|
|
17
|
+
export { ImageEditor } from "./modals/ImageEditor";
|
|
18
|
+
export type { ImageEditorProps } from "./modals/ImageEditor";
|
|
17
19
|
export { VideoTrimModal } from "./modals/VideoTrimModal";
|
|
18
20
|
export type { VideoTrimModalProps } from "./modals/VideoTrimModal";
|
|
19
21
|
export { VideoThumbnailSelector } from "./modals/VideoThumbnailSelector";
|
|
@@ -11,6 +11,7 @@ export { useMediaUpload, useMediaAbort, useMediaCrop, useMediaTrim, useMediaClea
|
|
|
11
11
|
// Modals
|
|
12
12
|
export { MediaPickerModal } from "./MediaPickerModal";
|
|
13
13
|
export { ImageCropModal } from "./modals/ImageCropModal";
|
|
14
|
+
export { ImageEditor } from "./modals/ImageEditor";
|
|
14
15
|
export { VideoTrimModal } from "./modals/VideoTrimModal";
|
|
15
16
|
export { VideoThumbnailSelector } from "./modals/VideoThumbnailSelector";
|
|
16
17
|
// Upload components
|
|
@@ -95,5 +95,5 @@ export function ImageCropModal({ isOpen, imageUrl, onClose, onSave, initialCropD
|
|
|
95
95
|
left: `${position.x}%`,
|
|
96
96
|
top: `${position.y}%`,
|
|
97
97
|
transform: "translate(-50%, -50%)",
|
|
98
|
-
} }), _jsxs(Div, { className: "absolute inset-0 pointer-events-none", children: [_jsx(Div, { className: "absolute w-full h-full grid grid-cols-3 grid-rows-3", children: Array.from({ length: 9 }).map((_, i) => (_jsx(Div, { className: "border border-white/20 dark:border-slate-600/30" }, i))) }), _jsxs(Div, { className: "absolute inset-0 flex items-center justify-center", children: [_jsx(Div, { className: "w-6 h-px bg-white/50" }), _jsx(Div, { className: "absolute h-6 w-px bg-white/50" })] })] })] }), _jsxs(Div, { className: "space-y-1", children: [_jsxs(Row, { justify: "between", children: [_jsx(Text, { className: "text-xs font-medium", children: t("cropZoom") }), _jsxs(Text, { className: "text-xs text-zinc-500 dark:text-slate-400", children: [Math.round(zoom * 100), "%"] })] }), _jsxs(Row, { className: "gap-3", children: [_jsx(Button, { type: "button", variant: "ghost", size: "sm", onClick: () => setZoom(Math.max(0.1, zoom - 0.1)), "aria-label": t("cropZoomOut"), children: _jsx("svg", { className: "w-4 h-4", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", "aria-hidden": "true", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0zM13 10H7" }) }) }), _jsx(MediaSlider, { value: zoom, min: 0.1, max: 3, step: 0.01, onChange: (v) => setZoom(v), className: "flex-1" }), _jsx(Button, { type: "button", variant: "ghost", size: "sm", onClick: () => setZoom(Math.min(3, zoom + 0.1)), "aria-label": t("cropZoomIn"), children: _jsx("svg", { className: "w-4 h-4", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", "aria-hidden": "true", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0zM10 7v3m0 0v3m0-3h3m-3 0H7" }) }) })] }), _jsx(Div, { className: "flex gap-2", children: [0.5, 1, 1.5, 2].map((preset) => (_jsxs(Button, { type: "button", variant: "ghost", size: "sm", onClick: () => setZoom(preset), className: "px-3 py-1 text-xs rounded-lg bg-zinc-100 dark:bg-slate-800", children: [preset * 100, "%"] }, preset))) })] }), showZoomWarning && (_jsxs(Alert, { variant: "warning", children: [_jsx("
|
|
98
|
+
} }), _jsxs(Div, { className: "absolute inset-0 pointer-events-none", children: [_jsx(Div, { className: "absolute w-full h-full grid grid-cols-3 grid-rows-3", children: Array.from({ length: 9 }).map((_, i) => (_jsx(Div, { className: "border border-white/20 dark:border-slate-600/30" }, i))) }), _jsxs(Div, { className: "absolute inset-0 flex items-center justify-center", children: [_jsx(Div, { className: "w-6 h-px bg-white/50" }), _jsx(Div, { className: "absolute h-6 w-px bg-white/50" })] })] })] }), _jsxs(Div, { className: "space-y-1", children: [_jsxs(Row, { justify: "between", children: [_jsx(Text, { className: "text-xs font-medium", children: t("cropZoom") }), _jsxs(Text, { className: "text-xs text-zinc-500 dark:text-slate-400", children: [Math.round(zoom * 100), "%"] })] }), _jsxs(Row, { className: "gap-3", children: [_jsx(Button, { type: "button", variant: "ghost", size: "sm", onClick: () => setZoom(Math.max(0.1, zoom - 0.1)), "aria-label": t("cropZoomOut"), children: _jsx("svg", { className: "w-4 h-4", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", "aria-hidden": "true", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0zM13 10H7" }) }) }), _jsx(MediaSlider, { value: zoom, min: 0.1, max: 3, step: 0.01, onChange: (v) => setZoom(v), className: "flex-1" }), _jsx(Button, { type: "button", variant: "ghost", size: "sm", onClick: () => setZoom(Math.min(3, zoom + 0.1)), "aria-label": t("cropZoomIn"), children: _jsx("svg", { className: "w-4 h-4", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", "aria-hidden": "true", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0zM10 7v3m0 0v3m0-3h3m-3 0H7" }) }) })] }), _jsx(Div, { className: "flex gap-2", children: [0.5, 1, 1.5, 2].map((preset) => (_jsxs(Button, { type: "button", variant: "ghost", size: "sm", onClick: () => setZoom(preset), className: "px-3 py-1 text-xs rounded-lg bg-zinc-100 dark:bg-slate-800", children: [preset * 100, "%"] }, preset))) })] }), showZoomWarning && (_jsxs(Alert, { variant: "warning", children: [_jsx(Span, { weight: "bold", children: t("cropWarningTitle") }), " ", t("cropWarningMessage")] })), _jsxs(Row, { justify: "between", className: "text-xs text-zinc-500 dark:text-slate-400", children: [_jsxs(Span, { children: [t("cropPosition"), ": ", Math.round(position.x), "%, ", Math.round(position.y), "%"] }), _jsx(Button, { type: "button", variant: "ghost", size: "sm", onClick: handleReset, className: "text-primary-600 dark:text-primary-400 hover:underline", children: t("cropReset") })] }), _jsxs(Div, { className: "flex gap-2 pt-2", children: [_jsx(Button, { onClick: handleSave, variant: "primary", className: "flex-1", children: t("cropSave") }), _jsx(Button, { onClick: onClose, variant: "secondary", className: "flex-1", children: t("cropCancel") })] })] }) }));
|
|
99
99
|
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import "react-advanced-cropper/dist/style.css";
|
|
2
|
+
export interface ImageEditorProps {
|
|
3
|
+
isOpen: boolean;
|
|
4
|
+
imageUrl: string;
|
|
5
|
+
onClose: () => void;
|
|
6
|
+
onSave: (croppedFile: File) => void;
|
|
7
|
+
aspectRatio?: number;
|
|
8
|
+
outputFormat?: "image/jpeg" | "image/png" | "image/webp";
|
|
9
|
+
outputQuality?: number;
|
|
10
|
+
maxOutputWidth?: number;
|
|
11
|
+
}
|
|
12
|
+
export declare function ImageEditor({ isOpen, imageUrl, onClose, onSave, aspectRatio, outputFormat, outputQuality, maxOutputWidth, }: ImageEditorProps): import("react/jsx-runtime").JSX.Element;
|