@mohasinac/appkit 2.8.2 → 2.8.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_internal/client/features/classified/ClassifiedDetailView.js +7 -1
- package/dist/_internal/client/features/digital-code/CodeRevealPanel.js +4 -1
- package/dist/_internal/client/features/digital-code/DigitalCodeDetailView.js +7 -1
- package/dist/_internal/client/features/layout/DashboardLayoutClient.js +3 -2
- package/dist/_internal/client/features/live/LiveItemDetailView.js +11 -2
- package/dist/_internal/client/scaffolds/AppShell.js +2 -1
- package/dist/_internal/client/scaffolds/DashboardScaffold.js +2 -1
- package/dist/_internal/server/features/checkout/actions.js +40 -39
- package/dist/_internal/shared/actions/action-registry.js +6 -0
- package/dist/_internal/shared/config/index.d.ts +1 -1
- package/dist/_internal/shared/config/schema.d.ts +0 -8
- package/dist/client-entry.d.ts +1 -1
- package/dist/client.d.ts +1 -1
- package/dist/client.js +1 -1
- package/dist/configs/next.js +12 -22
- package/dist/constants/api-endpoints.d.ts +6 -0
- package/dist/constants/api-endpoints.js +2 -0
- package/dist/core/hooks/useSiteSettings.d.ts +1 -1
- package/dist/features/about/components/AboutView.js +5 -2
- package/dist/features/about/components/FAQPageView.js +3 -3
- package/dist/features/about/components/FeesView.js +13 -5
- package/dist/features/about/components/HelpPageView.js +9 -5
- package/dist/features/about/components/HowAuctionsWorkView.js +9 -5
- package/dist/features/about/components/HowCheckoutWorksView.js +9 -5
- package/dist/features/about/components/HowOffersWorkView.js +10 -5
- package/dist/features/about/components/HowOrdersWorkView.js +10 -5
- package/dist/features/about/components/HowPayoutsWorkView.js +9 -5
- package/dist/features/about/components/HowPreOrdersWorkView.js +9 -5
- package/dist/features/about/components/HowReviewsWorkView.js +9 -5
- package/dist/features/about/components/PolicyPageView.js +3 -3
- package/dist/features/about/components/PublicProfileView.js +11 -4
- package/dist/features/about/components/SecurityPrivacyView.js +8 -4
- package/dist/features/about/components/ShippingPolicyView.js +3 -2
- package/dist/features/about/components/TrackOrderView.js +2 -2
- package/dist/features/about/components/UnauthorizedView.js +3 -3
- package/dist/features/account/components/AddressBook.js +1 -1
- package/dist/features/account/components/AddressForm.js +2 -2
- package/dist/features/account/components/AddressInlineSelect.d.ts +24 -0
- package/dist/features/account/components/AddressInlineSelect.js +78 -0
- package/dist/features/account/components/AddressSelectorCreate.d.ts +2 -1
- package/dist/features/account/components/AddressSelectorCreate.js +5 -32
- package/dist/features/account/components/AddressesIndexListing.js +3 -3
- package/dist/features/account/components/ChatWindow.js +2 -1
- package/dist/features/account/components/NotificationBell.js +13 -7
- package/dist/features/account/components/NotificationPreferencesPanel.js +4 -1
- package/dist/features/account/components/UserOffersPanel.js +2 -1
- package/dist/features/account/components/UserSidebar.js +11 -7
- package/dist/features/account/components/UserSupportView.js +13 -4
- package/dist/features/account/components/index.d.ts +2 -0
- package/dist/features/account/components/index.js +1 -0
- package/dist/features/account/hooks/useAccount.d.ts +2 -2
- package/dist/features/account/hooks/useAddressSelector.d.ts +1 -1
- package/dist/features/account/hooks/useAddresses.d.ts +2 -2
- package/dist/features/account/hooks/useNotifications.d.ts +1 -1
- package/dist/features/account/hooks/useProfile.d.ts +1 -1
- package/dist/features/account/hooks/usePublicProfile.d.ts +2 -2
- package/dist/features/addresses/repository/addresses.repository.d.ts +1 -0
- package/dist/features/addresses/repository/addresses.repository.js +13 -0
- package/dist/features/admin/components/AdminAdEditorView.js +8 -5
- package/dist/features/admin/components/AdminAddressEditorView.js +5 -5
- package/dist/features/admin/components/AdminAdsView.js +10 -7
- package/dist/features/admin/components/AdminBlogEditorView.js +15 -9
- package/dist/features/admin/components/AdminBrandEditorView.js +10 -4
- package/dist/features/admin/components/AdminBrandsView.js +4 -4
- package/dist/features/admin/components/AdminBundleEditorView.js +4 -5
- package/dist/features/admin/components/AdminBundlesView.js +3 -3
- package/dist/features/admin/components/AdminCarouselEditorView.js +6 -3
- package/dist/features/admin/components/AdminCarouselView.js +6 -6
- package/dist/features/admin/components/AdminCatalogGuideView.js +2 -1
- package/dist/features/admin/components/AdminCategoriesView.js +5 -5
- package/dist/features/admin/components/AdminCategoryEditorView.js +11 -5
- package/dist/features/admin/components/AdminContactEditorView.js +8 -1
- package/dist/features/admin/components/AdminCouponEditorView.js +23 -5
- package/dist/features/admin/components/AdminEmployeeEditorView.js +7 -4
- package/dist/features/admin/components/AdminFaqEditorView.js +9 -3
- package/dist/features/admin/components/AdminFaqsView.js +4 -4
- package/dist/features/admin/components/AdminFeatureEditorView.js +7 -1
- package/dist/features/admin/components/AdminFeatureFlagsView.js +4 -1
- package/dist/features/admin/components/AdminFilterBar.js +4 -4
- package/dist/features/admin/components/AdminGroupedListingsView.js +65 -30
- package/dist/features/admin/components/AdminGuideHubView.js +4 -1
- package/dist/features/admin/components/AdminMediaView.js +4 -1
- package/dist/features/admin/components/AdminNavigationView.js +7 -4
- package/dist/features/admin/components/AdminNotificationsView.js +2 -2
- package/dist/features/admin/components/AdminOrderEditorView.js +2 -2
- package/dist/features/admin/components/AdminPageHeader.js +5 -2
- package/dist/features/admin/components/AdminPrizeDrawsView.js +5 -5
- package/dist/features/admin/components/AdminProductEditorView.js +12 -5
- package/dist/features/admin/components/AdminProductsView.js +4 -4
- package/dist/features/admin/components/AdminReviewsView.js +2 -2
- package/dist/features/admin/components/AdminScammerEditorView.js +6 -2
- package/dist/features/admin/components/AdminScammersView.js +3 -3
- package/dist/features/admin/components/AdminSectionsView.js +20 -22
- package/dist/features/admin/components/AdminSessionsManager.js +2 -1
- package/dist/features/admin/components/AdminSessionsView.js +2 -2
- package/dist/features/admin/components/AdminSidebar.js +11 -7
- package/dist/features/admin/components/AdminSiteConfigGuideView.js +2 -1
- package/dist/features/admin/components/AdminSiteSettingsView.js +5 -1
- package/dist/features/admin/components/AdminStoreAddressesView.js +2 -2
- package/dist/features/admin/components/AdminStoreEditorView.js +5 -5
- package/dist/features/admin/components/AdminSublistingCategoryEditorView.js +3 -3
- package/dist/features/admin/components/AdminSupportTicketDetailView.js +10 -3
- package/dist/features/admin/components/AdminSupportTicketsView.js +3 -3
- package/dist/features/admin/components/AdminTrustGuideView.js +3 -3
- package/dist/features/admin/components/AdminUsersGuideView.js +3 -3
- package/dist/features/admin/components/AdminViewCards.js +12 -6
- package/dist/features/admin/components/BrandQuickCreateForm.js +2 -2
- package/dist/features/admin/components/CategoryQuickCreateForm.js +2 -2
- package/dist/features/admin/components/DashboardStats.js +9 -3
- package/dist/features/admin/components/DataListingView.js +3 -3
- package/dist/features/admin/components/DataTable.js +11 -7
- package/dist/features/admin/components/DrawerFormFooter.js +2 -2
- package/dist/features/admin/components/QuickEditMenu.js +2 -1
- package/dist/features/admin/components/analytics/AdminAnalyticsCharts.js +5 -1
- package/dist/features/admin/hooks/useAdmin.d.ts +1 -1
- package/dist/features/admin/hooks/useAdminSectionsListing.d.ts +1 -1
- package/dist/features/admin/hooks/useChat.d.ts +1 -1
- package/dist/features/auctions/components/AuctionBidsTable.js +4 -1
- package/dist/features/auctions/components/AuctionDetailPageView.js +14 -6
- package/dist/features/auctions/components/CollapsibleBidHistory.js +5 -1
- package/dist/features/auctions/components/MarketplaceAuctionCard.js +9 -3
- package/dist/features/auctions/components/MarketplaceAuctionGrid.js +8 -2
- package/dist/features/auctions/components/PlaceBidFormClient.js +4 -1
- package/dist/features/auctions/hooks/useAuctions.d.ts +8 -8
- package/dist/features/auth/components/RegisterForm.js +2 -2
- package/dist/features/auth/components/VerifyEmailView.js +5 -2
- package/dist/features/auth/hooks/useAuth.d.ts +2 -2
- package/dist/features/before-after/components/BeforeAfterSlider.js +1 -1
- package/dist/features/blog/components/BlogFeaturedCard.js +8 -1
- package/dist/features/blog/components/BlogIndexListing.js +11 -5
- package/dist/features/blog/components/BlogListView.js +11 -3
- package/dist/features/blog/components/BlogPostView.js +10 -3
- package/dist/features/cart/components/CartDrawer.js +11 -3
- package/dist/features/cart/components/CartSummary.js +2 -2
- package/dist/features/cart/components/CheckoutOtpModal.js +2 -1
- package/dist/features/cart/hooks/useCart.d.ts +1 -1
- package/dist/features/cart/hooks/useCartQuery.d.ts +1 -1
- package/dist/features/cart/hooks/useCheckoutReadQueries.d.ts +2 -2
- package/dist/features/cart/hooks/useOrder.d.ts +2 -2
- package/dist/features/categories/components/BrandDetailPageView.js +5 -2
- package/dist/features/categories/components/BrandDetailTabs.js +5 -1
- package/dist/features/categories/components/BundleDetailView.js +6 -3
- package/dist/features/categories/components/BundleDynamicRuleEditor.js +3 -1
- package/dist/features/categories/components/BundleItemsPicker.js +10 -3
- package/dist/features/categories/components/CategoriesIndexListing.js +12 -6
- package/dist/features/categories/components/CategoryBundlesListing.js +5 -2
- package/dist/features/categories/components/CategoryDetailPageView.js +6 -2
- package/dist/features/categories/components/CategoryDetailTabs.js +5 -1
- package/dist/features/categories/components/CategoryForm.js +6 -3
- package/dist/features/categories/components/CategoryGrid.js +9 -2
- package/dist/features/categories/components/CategoryProductsListing.js +10 -4
- package/dist/features/categories/components/CategorySelectorCreate.js +3 -3
- package/dist/features/categories/components/CategorySortSelect.js +1 -1
- package/dist/features/categories/components/CategoryStoresListing.js +3 -3
- package/dist/features/categories/components/CategoryTableColumns.js +10 -6
- package/dist/features/categories/components/CategoryTree.js +1 -1
- package/dist/features/categories/hooks/useCategories.d.ts +3 -3
- package/dist/features/categories/hooks/useCategorySelector.d.ts +3 -3
- package/dist/features/categories/hooks/useCategoryTree.d.ts +1 -1
- package/dist/features/checkout/hooks/useCheckoutApi.d.ts +2 -2
- package/dist/features/classified/components/ClassifiedFilters.js +2 -2
- package/dist/features/classified/components/ClassifiedIndexListing.js +9 -3
- package/dist/features/collections/components/CollectionCard.js +2 -1
- package/dist/features/collections/hooks/useCollections.d.ts +2 -2
- package/dist/features/contact/components/ContactForm.js +4 -2
- package/dist/features/contact/components/ContactInfoSidebar.js +4 -1
- package/dist/features/copilot/components/AdminCopilotView.js +13 -5
- package/dist/features/digital-codes/components/DigitalCodesIndexListing.js +9 -3
- package/dist/features/events/components/AdminEventEditorView.js +62 -40
- package/dist/features/events/components/AdminEventEntriesView.js +9 -6
- package/dist/features/events/components/EventCard.js +7 -1
- package/dist/features/events/components/EventFormDrawer.js +2 -1
- package/dist/features/events/components/EventLeaderboard.js +4 -4
- package/dist/features/events/components/EventOfferCard.js +4 -1
- package/dist/features/events/components/EventParticipateView.js +3 -2
- package/dist/features/events/components/EventPollWidget.js +6 -5
- package/dist/features/events/components/EventRaffleEntryForm.js +5 -2
- package/dist/features/events/components/EventRaffleWinnerView.js +7 -1
- package/dist/features/events/components/EventRafflesSection.js +2 -2
- package/dist/features/events/components/EventSaleBanner.js +5 -2
- package/dist/features/events/components/EventsIndexListing.js +8 -2
- package/dist/features/events/components/EventsListView.js +4 -1
- package/dist/features/events/components/SpinWheelView.js +7 -2
- package/dist/features/events/hooks/useEvent.d.ts +3 -3
- package/dist/features/events/hooks/useEvents.d.ts +1 -1
- package/dist/features/events/schemas/firestore.d.ts +1 -0
- package/dist/features/events/types/index.d.ts +1 -0
- package/dist/features/faq/components/ContactCTA.js +4 -1
- package/dist/features/faq/components/FAQCategorySidebar.js +2 -2
- package/dist/features/faq/components/FAQHelpfulButtons.js +8 -5
- package/dist/features/faq/components/FAQPageContent.js +5 -5
- package/dist/features/faq/components/FAQSortDropdown.js +2 -2
- package/dist/features/faq/hooks/useFAQs.d.ts +1 -1
- package/dist/features/faq/hooks/useFaqList.d.ts +15 -15
- package/dist/features/filters/AsyncFacetSection.js +4 -2
- package/dist/features/filters/FilterFacetSection.js +14 -6
- package/dist/features/filters/RangeFilter.js +4 -2
- package/dist/features/filters/SwitchFilter.js +2 -1
- package/dist/features/forms/Checkbox.js +1 -1
- package/dist/features/forms/Radio.js +1 -1
- package/dist/features/forms/Slider.js +1 -1
- package/dist/features/homepage/components/AdSlot.js +4 -4
- package/dist/features/homepage/components/AdvertisementBanner.js +13 -4
- package/dist/features/homepage/components/AnnouncementBar.js +2 -1
- package/dist/features/homepage/components/BeforeAfterCard.js +8 -2
- package/dist/features/homepage/components/BrandsSection.js +6 -3
- package/dist/features/homepage/components/CTABannerSection.js +2 -2
- package/dist/features/homepage/components/CharacterHotspot.js +5 -2
- package/dist/features/homepage/components/CharacterHotspotForm.js +8 -4
- package/dist/features/homepage/components/CustomCardsSection.js +13 -7
- package/dist/features/homepage/components/CustomerReviewsSection.js +9 -3
- package/dist/features/homepage/components/FAQSection.js +7 -4
- package/dist/features/homepage/components/FeaturedBundlesSection.js +8 -2
- package/dist/features/homepage/components/FeaturedResultsSection.js +1 -1
- package/dist/features/homepage/components/GoogleReviewsSection.js +14 -8
- package/dist/features/homepage/components/HeroCarousel.js +1 -1
- package/dist/features/homepage/components/HomepageSkeleton.js +7 -1
- package/dist/features/homepage/components/HowItWorksInfoView.js +2 -2
- package/dist/features/homepage/components/HowItWorksSection.js +2 -2
- package/dist/features/homepage/components/NewsletterBanner.js +3 -2
- package/dist/features/homepage/components/NewsletterSection.js +5 -2
- package/dist/features/homepage/components/PromoGrid.js +4 -1
- package/dist/features/homepage/components/SectionCarousel.js +7 -4
- package/dist/features/homepage/components/SecurityHighlightsSection.js +3 -3
- package/dist/features/homepage/components/ShopByCategorySection.js +10 -4
- package/dist/features/homepage/components/SiteFeaturesSection.js +5 -2
- package/dist/features/homepage/components/SocialFeedSection.js +4 -4
- package/dist/features/homepage/components/SocialPostCard.js +6 -3
- package/dist/features/homepage/components/TrustFeaturesSection.js +5 -5
- package/dist/features/homepage/components/TrustIndicatorsSection.js +5 -2
- package/dist/features/homepage/components/WelcomeSection.js +1 -1
- package/dist/features/homepage/components/WhatsAppCommunitySection.js +3 -3
- package/dist/features/homepage/hooks/useBlogArticles.d.ts +1 -1
- package/dist/features/homepage/hooks/useFeaturedAuctions.d.ts +1 -1
- package/dist/features/homepage/hooks/useFeaturedPreOrders.d.ts +1 -1
- package/dist/features/homepage/hooks/useFeaturedProducts.d.ts +1 -1
- package/dist/features/homepage/hooks/useFeaturedStores.d.ts +1 -1
- package/dist/features/homepage/hooks/useHeroCarousel.d.ts +1 -1
- package/dist/features/homepage/hooks/useHomepageEvents.d.ts +1 -1
- package/dist/features/homepage/hooks/useHomepageReviews.d.ts +1 -1
- package/dist/features/homepage/hooks/useHomepageSections.d.ts +1 -1
- package/dist/features/homepage/hooks/useTopBrands.d.ts +1 -1
- package/dist/features/homepage/hooks/useTopCategories.d.ts +1 -1
- package/dist/features/layout/AppLayoutShell.js +2 -1
- package/dist/features/layout/BackToTop.js +1 -1
- package/dist/features/layout/BottomActions.js +4 -3
- package/dist/features/layout/BottomNavItem.js +1 -1
- package/dist/features/layout/BottomSheet.js +4 -1
- package/dist/features/layout/FooterLayout.js +1 -1
- package/dist/features/layout/NavbarLayout.js +4 -1
- package/dist/features/layout/SidebarLayout.js +5 -2
- package/dist/features/live/components/LiveItemFilters.js +2 -2
- package/dist/features/live/components/LiveItemsIndexListing.js +9 -3
- package/dist/features/loyalty/components/CoinsDisplay.js +4 -2
- package/dist/features/loyalty/hooks/useLoyaltyBalance.d.ts +1 -1
- package/dist/features/media/AvatarUpload.js +2 -2
- package/dist/features/media/MediaLightbox.js +3 -2
- package/dist/features/media/modals/VideoThumbnailSelector.js +4 -1
- package/dist/features/media/modals/VideoTrimModal.js +1 -1
- package/dist/features/media/upload/CameraCapture.js +1 -1
- package/dist/features/media/upload/ImageUpload.js +4 -1
- package/dist/features/media/upload/MediaUploadField.js +11 -2
- package/dist/features/media/upload/MediaUploadList.js +5 -1
- package/dist/features/orders/components/MarketplaceOrderCard.js +2 -2
- package/dist/features/orders/components/OrdersList.js +2 -1
- package/dist/features/orders/components/RefundHistoryTable.js +4 -1
- package/dist/features/orders/components/RefundRequestView.js +2 -1
- package/dist/features/orders/hooks/useOrders.d.ts +2 -2
- package/dist/features/payments/hooks/usePayments.d.ts +1 -1
- package/dist/features/pre-orders/components/MarketplacePreorderCard.js +5 -1
- package/dist/features/pre-orders/components/PreOrderActionsClient.js +3 -3
- package/dist/features/pre-orders/components/PreOrderBadge.js +2 -1
- package/dist/features/pre-orders/components/PreOrderDetailPageView.js +16 -7
- package/dist/features/pre-orders/components/PreOrdersIndexListing.js +32 -24
- package/dist/features/pre-orders/hooks/usePreOrders.d.ts +2 -2
- package/dist/features/products/columns/productTableColumns.js +9 -4
- package/dist/features/products/components/AuctionsIndexListing.js +9 -3
- package/dist/features/products/components/BidHistory.js +4 -4
- package/dist/features/products/components/CompareOverlay.js +10 -2
- package/dist/features/products/components/CustomFieldsEditor.js +2 -1
- package/dist/features/products/components/CustomSectionTabContent.js +2 -2
- package/dist/features/products/components/CustomSectionsEditor.js +3 -2
- package/dist/features/products/components/GroupSettingsPanel.js +34 -26
- package/dist/features/products/components/MakeOfferButton.js +6 -2
- package/dist/features/products/components/MakeOfferForm.js +2 -1
- package/dist/features/products/components/MarketplaceBundleCard.js +6 -3
- package/dist/features/products/components/MarketplacePrizeDrawCard.js +3 -2
- package/dist/features/products/components/PlaceBidForm.js +2 -1
- package/dist/features/products/components/PrizeDrawCollage.js +6 -2
- package/dist/features/products/components/PrizeDrawDetailPageView.js +6 -1
- package/dist/features/products/components/PrizeDrawItemsEditor.js +4 -2
- package/dist/features/products/components/PrizeDrawsIndexListing.js +6 -3
- package/dist/features/products/components/PrizeDrawsSection.js +2 -2
- package/dist/features/products/components/PrizeRevealModal.js +5 -1
- package/dist/features/products/components/ProductDetailPageView.js +32 -16
- package/dist/features/products/components/ProductFeatureBadges.js +9 -9
- package/dist/features/products/components/ProductForm.d.ts +11 -1
- package/dist/features/products/components/ProductForm.js +10 -5
- package/dist/features/products/components/ProductGalleryClient.js +8 -4
- package/dist/features/products/components/ProductGradingTab.js +4 -1
- package/dist/features/products/components/ProductGrid.js +35 -14
- package/dist/features/products/components/ProductInfo.js +2 -1
- package/dist/features/products/components/ProductTabs.js +2 -1
- package/dist/features/products/components/ProductTabsShell.js +5 -1
- package/dist/features/products/components/ProductsIndexListing.js +32 -24
- package/dist/features/products/components/ProductsIndexPageView.js +2 -2
- package/dist/features/products/components/RelatedProducts.js +3 -3
- package/dist/features/products/components/ShowGroupSection.js +10 -6
- package/dist/features/products/components/SublistingCarouselSection.js +7 -3
- package/dist/features/products/components/SublistingCategorySelect.d.ts +3 -1
- package/dist/features/products/components/SublistingCategorySelect.js +4 -37
- package/dist/features/products/constants/action-defs.js +3 -3
- package/dist/features/products/hooks/useProductDetail.d.ts +1 -1
- package/dist/features/products/hooks/useRelatedProducts.d.ts +1 -1
- package/dist/features/promotions/components/CouponCard.js +5 -3
- package/dist/features/promotions/components/CouponsIndexListing.js +7 -3
- package/dist/features/promotions/hooks/usePromotions.d.ts +2 -2
- package/dist/features/promotions/repository/coupons.repository.d.ts +8 -0
- package/dist/features/promotions/repository/coupons.repository.js +2 -0
- package/dist/features/reviews/components/ReviewDetailPageView.js +3 -3
- package/dist/features/reviews/components/ReviewDetailShell.js +15 -3
- package/dist/features/reviews/components/ReviewSummary.js +4 -2
- package/dist/features/reviews/components/ReviewsIndexListing.js +8 -2
- package/dist/features/reviews/components/ReviewsList.js +1 -1
- package/dist/features/reviews/hooks/useReviews.d.ts +2 -2
- package/dist/features/scams/components/ScamAwarenessModal.js +2 -2
- package/dist/features/scams/components/ScamProfileView.js +3 -3
- package/dist/features/scams/components/ScamRegistryView.js +6 -4
- package/dist/features/search/components/Search.js +9 -6
- package/dist/features/search/components/SearchFiltersRow.js +1 -1
- package/dist/features/search/components/SearchResultsSection.js +1 -1
- package/dist/features/search/hooks/useSearch.d.ts +2 -2
- package/dist/features/seller/components/CouponInlineSelect.d.ts +22 -0
- package/dist/features/seller/components/CouponInlineSelect.js +103 -0
- package/dist/features/seller/components/GroupInlineSelect.d.ts +23 -0
- package/dist/features/seller/components/GroupInlineSelect.js +80 -0
- package/dist/features/seller/components/PhysicalLocationModal.js +2 -1
- package/dist/features/seller/components/PrintCenterView.js +2 -1
- package/dist/features/seller/components/ProductInlineSelect.d.ts +24 -0
- package/dist/features/seller/components/ProductInlineSelect.js +42 -0
- package/dist/features/seller/components/QuickProductForm.js +4 -1
- package/dist/features/seller/components/SellerAddressesView.js +8 -3
- package/dist/features/seller/components/SellerAnalyticsAlertsView.js +6 -3
- package/dist/features/seller/components/SellerAnalyticsView.js +2 -2
- package/dist/features/seller/components/SellerBidsView.js +7 -7
- package/dist/features/seller/components/SellerBundlesView.js +2 -1
- package/dist/features/seller/components/SellerCouponEditorView.d.ts +2 -0
- package/dist/features/seller/components/SellerCouponEditorView.js +15 -3
- package/dist/features/seller/components/SellerCouponsView.js +1 -1
- package/dist/features/seller/components/SellerDashboardView.js +2 -2
- package/dist/features/seller/components/SellerDigitalCodesView.js +2 -2
- package/dist/features/seller/components/SellerGoogleReviewsView.js +2 -2
- package/dist/features/seller/components/SellerGroupedListingsView.js +5 -5
- package/dist/features/seller/components/SellerOrdersView.js +13 -10
- package/dist/features/seller/components/SellerPayoutMethodsView.js +5 -4
- package/dist/features/seller/components/SellerPayoutRequestView.js +5 -1
- package/dist/features/seller/components/SellerPayoutSettingsView.js +5 -2
- package/dist/features/seller/components/SellerPreOrdersView.js +6 -6
- package/dist/features/seller/components/SellerPrizeDrawsView.js +6 -6
- package/dist/features/seller/components/SellerProductShell.js +1 -1
- package/dist/features/seller/components/SellerProductsCards.js +4 -1
- package/dist/features/seller/components/SellerProductsView.js +5 -5
- package/dist/features/seller/components/SellerReviewsView.js +7 -3
- package/dist/features/seller/components/SellerShippingConfigsView.js +4 -4
- package/dist/features/seller/components/SellerShippingView.js +1 -1
- package/dist/features/seller/components/SellerSidebar.js +15 -8
- package/dist/features/seller/components/SellerStoreCategoriesView.js +1 -1
- package/dist/features/seller/components/SellerStorefrontView.js +2 -2
- package/dist/features/seller/components/SellerTemplatesView.js +7 -4
- package/dist/features/seller/components/SublistingInlineSelect.d.ts +19 -0
- package/dist/features/seller/components/SublistingInlineSelect.js +83 -0
- package/dist/features/seller/components/analytics/SellerTopProducts.js +1 -1
- package/dist/features/seller/components/index.d.ts +8 -0
- package/dist/features/seller/components/index.js +4 -0
- package/dist/features/seller/hooks/useSellerPayouts.d.ts +3 -3
- package/dist/features/seller/hooks/useSellerStore.d.ts +6 -6
- package/dist/features/seller/hooks/useSellerStorefront.d.ts +2 -2
- package/dist/features/shell/FormShell.js +10 -2
- package/dist/features/shell/QuickFormDrawer.js +5 -5
- package/dist/features/shell/StepForm.js +6 -6
- package/dist/features/site-settings/components/ActionPermissionsManager.js +8 -4
- package/dist/features/site-settings/components/NavPermissionsManager.js +7 -4
- package/dist/features/stores/components/InteractiveStoreCard.js +5 -1
- package/dist/features/stores/components/StoreAboutView.js +4 -1
- package/dist/features/stores/components/StoreAddressSelectorCreate.d.ts +2 -1
- package/dist/features/stores/components/StoreAddressSelectorCreate.js +5 -31
- package/dist/features/stores/components/StoreAuctionsListing.js +6 -3
- package/dist/features/stores/components/StoreGuideHubView.js +5 -2
- package/dist/features/stores/components/StoreHeader.js +8 -1
- package/dist/features/stores/components/StorePreOrdersListing.js +6 -3
- package/dist/features/stores/components/StoreProductsListing.js +6 -3
- package/dist/features/stores/components/StoreReviewsListing.js +8 -2
- package/dist/features/stores/components/StoresIndexListing.js +12 -6
- package/dist/features/stores/hooks/useStoreAddressSelector.d.ts +1 -1
- package/dist/features/stores/hooks/useStores.d.ts +6 -6
- package/dist/features/whatsapp-bot/components/SellerWhatsAppSettingsView.js +7 -1
- package/dist/features/whatsapp-bot/components/WhatsAppChatButton.js +2 -1
- package/dist/features/wishlist/components/WishlistPage.js +2 -1
- package/dist/features/wishlist/hooks/useUserWishlist.d.ts +15 -15
- package/dist/features/wishlist/hooks/useWishlist.d.ts +1 -1
- package/dist/features/wishlist/hooks/useWishlistWithGuest.d.ts +1 -1
- package/dist/index.d.ts +10 -0
- package/dist/index.js +13 -1
- package/dist/next/components/GlobalError.js +2 -2
- package/dist/next/routing/route-map.d.ts +2 -0
- package/dist/next/routing/route-map.js +1 -0
- package/dist/react/ErrorBoundary.js +2 -2
- package/dist/styles.css +2 -1
- package/dist/tailwind-utilities.css +1 -1
- package/dist/ui/DataTable.js +17 -16
- package/dist/ui/components/DateInput.js +2 -2
- package/dist/ui/components/DetailPageGallery.js +4 -1
- package/dist/ui/components/DetailPageTabs.js +6 -2
- package/dist/ui/components/ImageLightbox.js +5 -3
- package/dist/ui/components/Input.js +6 -3
- package/dist/ui/components/Layout.d.ts +4 -0
- package/dist/ui/components/Layout.js +1 -1
- package/dist/ui/components/Layout.style.css +1 -0
- package/dist/ui/components/ListingFilterDrawer.js +4 -1
- package/dist/ui/components/ListingLayout.js +9 -8
- package/dist/ui/components/ListingToolbar.js +5 -1
- package/dist/ui/components/PaginatedSelect.d.ts +1 -2
- package/dist/ui/components/PaginatedSelect.js +1 -2
- package/dist/ui/components/Radio.js +1 -1
- package/dist/ui/components/Select.js +2 -1
- package/dist/ui/components/Slider.js +1 -1
- package/dist/ui/components/VacationBanner.js +2 -1
- package/dist/ui/components/surface-tokens.d.ts +1 -0
- package/dist/ui/components/surface-tokens.js +1 -0
- package/package.json +11 -2
|
@@ -4,4 +4,4 @@ export interface UseHomepageReviewsOptions {
|
|
|
4
4
|
initialData?: Review[];
|
|
5
5
|
staleTime?: number;
|
|
6
6
|
}
|
|
7
|
-
export declare function useHomepageReviews(options?: UseHomepageReviewsOptions): import("@tanstack/react-query").UseQueryResult<Review[]
|
|
7
|
+
export declare function useHomepageReviews(options?: UseHomepageReviewsOptions): import("@tanstack/react-query").UseQueryResult<NoInfer<Review[]>, Error>;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import type { HomepageSectionDocument } from "../schemas";
|
|
2
|
-
export declare function useHomepageSections(params?: string): import("@tanstack/react-query").UseQueryResult<HomepageSectionDocument[]
|
|
2
|
+
export declare function useHomepageSections(params?: string): import("@tanstack/react-query").UseQueryResult<NoInfer<HomepageSectionDocument[]>, Error>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { CategoryItem } from "../../categories/types";
|
|
2
2
|
export declare function useTopBrands(limit?: number, options?: {
|
|
3
3
|
initialData?: CategoryItem[];
|
|
4
|
-
}): import("@tanstack/react-query").UseQueryResult<CategoryItem[]
|
|
4
|
+
}): import("@tanstack/react-query").UseQueryResult<NoInfer<CategoryItem[]>, Error>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { CategoryItem } from "../../categories/types";
|
|
2
2
|
export declare function useTopCategories(limit?: number, options?: {
|
|
3
3
|
initialData?: CategoryItem[];
|
|
4
|
-
}): import("@tanstack/react-query").UseQueryResult<CategoryItem[]
|
|
4
|
+
}): import("@tanstack/react-query").UseQueryResult<NoInfer<CategoryItem[]>, Error>;
|
|
@@ -28,6 +28,7 @@ const DEFAULT_LIGHT_BG = {
|
|
|
28
28
|
};
|
|
29
29
|
const CLS_STAT_BOX = "flex flex-col items-center gap-1 p-2 bg-zinc-100 dark:bg-zinc-800 rounded-lg text-center";
|
|
30
30
|
const CLS_STAT_LABEL = "text-xs text-zinc-500 dark:text-zinc-400";
|
|
31
|
+
const CLS_LOGOUT_BTN = "flex w-full items-center gap-3 rounded-lg px-3 py-2 text-sm text-red-600 transition-colors hover:bg-red-50 hover:text-red-700 dark:text-red-400 dark:hover:bg-red-950/30 dark:hover:text-red-300";
|
|
31
32
|
const DEFAULT_DARK_BG = {
|
|
32
33
|
type: "color",
|
|
33
34
|
value: "#030712",
|
|
@@ -91,7 +92,7 @@ function SidebarContent({ sidebarItems, sidebarSections, sidebarPrimaryActions,
|
|
|
91
92
|
action.variant === "outline"
|
|
92
93
|
? "border border-zinc-300 text-zinc-700 hover:bg-zinc-50 dark:border-slate-700 dark:text-zinc-100 dark:hover:bg-slate-800"
|
|
93
94
|
: "bg-primary text-white hover:bg-primary-600 dark:bg-primary dark:hover:bg-primary-600 btn-glow",
|
|
94
|
-
].join(" "), children: action.label }, `${action.href}-${action.label}`))) })), isAuthenticated && (_jsx(CollapsibleNavGroup, { title: labels.sectionTitle, children: _jsxs(Ul, { className: "space-y-0.5", children: [_jsx(Li, { children: _jsx(TextLink, { href: profileHref, variant: "none", className: navItemClass, children: labels.profile }) }), userOrdersHref && (_jsx(Li, { children: _jsx(TextLink, { href: userOrdersHref, variant: "none", className: navItemClass, children: labels.orders }) })), userWishlistHref && (_jsx(Li, { children: _jsx(TextLink, { href: userWishlistHref, variant: "none", className: navItemClass, children: labels.wishlist }) })), userSettingsHref && (_jsx(Li, { children: _jsx(TextLink, { href: userSettingsHref, variant: "none", className: navItemClass, children: labels.settings }) }))] }) })), isAuthenticated && user?.stats && (_jsxs(Div, { className: "grid grid-cols-2 gap-2", children: [user.stats.totalOrders != null && (_jsxs(Div, { className: CLS_STAT_BOX, children: [_jsx(Text, { className: "text-lg font-bold text-zinc-900 dark:text-zinc-100 leading-none", children: user.stats.totalOrders }), _jsx(Text, { className: CLS_STAT_LABEL, children: "Orders" })] })), user.stats.reviewsCount != null && (_jsxs(Div, { className: CLS_STAT_BOX, children: [_jsx(Text, { className: "text-lg font-bold text-zinc-900 dark:text-zinc-100 leading-none", children: user.stats.reviewsCount }), _jsx(Text, { className: CLS_STAT_LABEL, children: "Reviews" })] })), user.stats.auctionsWon != null && (_jsxs(Div, { className: CLS_STAT_BOX, children: [_jsx(Text, { className: "text-lg font-bold text-zinc-900 dark:text-zinc-100 leading-none", children: user.stats.auctionsWon }), _jsx(Text, { className: CLS_STAT_LABEL, children: "Auctions Won" })] })), user.stats.itemsSold != null && (_jsxs(Div, { className: CLS_STAT_BOX, children: [_jsx(Text, { className: "text-lg font-bold text-zinc-900 dark:text-zinc-100 leading-none", children: user.stats.itemsSold }), _jsx(Text, { className: CLS_STAT_LABEL, children: "Items Sold" })] }))] })), isAuthenticated && isAdminOrSeller && (adminHref || resolvedStoreHref) && (_jsx(CollapsibleNavGroup, { title: labels.dashboardSectionTitle, children: _jsxs(Ul, { className: "space-y-0.5", children: [adminHref && role === "admin" && (_jsx(Li, { children: _jsx(TextLink, { href: adminHref, variant: "none", className: navItemClass, children: labels.adminDashboard }) })), resolvedStoreHref && isAdminOrSeller && (_jsx(Li, { children: _jsx(TextLink, { href: resolvedStoreHref, variant: "none", className: navItemClass, children: labels.storeDashboard }) }))] }) })), normalizedSections.map((section, sectionIndex) => (_jsx(CollapsibleSidebarSection, { section: section, navItemClass: navItemClass }, `sidebar-section-${sectionIndex}`))), (sidebarLocaleSlot || showThemeToggleInSidebar || (isAuthenticated && onLogout)) && (_jsxs(Div, { className: "border-t border-zinc-200 pt-4 space-y-3 dark:border-slate-800", children: [sidebarLocaleSlot, showThemeToggleInSidebar && (_jsxs("button", { type: "button", onClick: toggleTheme, className: "flex w-full items-center gap-3 rounded-lg px-3 py-2 text-sm text-zinc-700 transition-colors hover:bg-primary-50 hover:text-primary-800 dark:text-zinc-300 dark:hover:bg-slate-800 dark:hover:text-secondary-300", children: [_jsx("span", { "aria-hidden": "true", children: theme === "dark" ? "☀️" : "🌙" }), theme === "dark" ? "Light mode" : "Dark mode"] })), isAuthenticated && onLogout && (_jsx("button", { type: "button", onClick: () => { onLogout(); onAfterLogout(); }, className:
|
|
95
|
+
].join(" "), children: action.label }, `${action.href}-${action.label}`))) })), isAuthenticated && (_jsx(CollapsibleNavGroup, { title: labels.sectionTitle, children: _jsxs(Ul, { className: "space-y-0.5", children: [_jsx(Li, { children: _jsx(TextLink, { href: profileHref, variant: "none", className: navItemClass, children: labels.profile }) }), userOrdersHref && (_jsx(Li, { children: _jsx(TextLink, { href: userOrdersHref, variant: "none", className: navItemClass, children: labels.orders }) })), userWishlistHref && (_jsx(Li, { children: _jsx(TextLink, { href: userWishlistHref, variant: "none", className: navItemClass, children: labels.wishlist }) })), userSettingsHref && (_jsx(Li, { children: _jsx(TextLink, { href: userSettingsHref, variant: "none", className: navItemClass, children: labels.settings }) }))] }) })), isAuthenticated && user?.stats && (_jsxs(Div, { className: "grid grid-cols-2 gap-2", children: [user.stats.totalOrders != null && (_jsxs(Div, { className: CLS_STAT_BOX, children: [_jsx(Text, { className: "text-lg font-bold text-zinc-900 dark:text-zinc-100 leading-none", children: user.stats.totalOrders }), _jsx(Text, { className: CLS_STAT_LABEL, children: "Orders" })] })), user.stats.reviewsCount != null && (_jsxs(Div, { className: CLS_STAT_BOX, children: [_jsx(Text, { className: "text-lg font-bold text-zinc-900 dark:text-zinc-100 leading-none", children: user.stats.reviewsCount }), _jsx(Text, { className: CLS_STAT_LABEL, children: "Reviews" })] })), user.stats.auctionsWon != null && (_jsxs(Div, { className: CLS_STAT_BOX, children: [_jsx(Text, { className: "text-lg font-bold text-zinc-900 dark:text-zinc-100 leading-none", children: user.stats.auctionsWon }), _jsx(Text, { className: CLS_STAT_LABEL, children: "Auctions Won" })] })), user.stats.itemsSold != null && (_jsxs(Div, { className: CLS_STAT_BOX, children: [_jsx(Text, { className: "text-lg font-bold text-zinc-900 dark:text-zinc-100 leading-none", children: user.stats.itemsSold }), _jsx(Text, { className: CLS_STAT_LABEL, children: "Items Sold" })] }))] })), isAuthenticated && isAdminOrSeller && (adminHref || resolvedStoreHref) && (_jsx(CollapsibleNavGroup, { title: labels.dashboardSectionTitle, children: _jsxs(Ul, { className: "space-y-0.5", children: [adminHref && role === "admin" && (_jsx(Li, { children: _jsx(TextLink, { href: adminHref, variant: "none", className: navItemClass, children: labels.adminDashboard }) })), resolvedStoreHref && isAdminOrSeller && (_jsx(Li, { children: _jsx(TextLink, { href: resolvedStoreHref, variant: "none", className: navItemClass, children: labels.storeDashboard }) }))] }) })), normalizedSections.map((section, sectionIndex) => (_jsx(CollapsibleSidebarSection, { section: section, navItemClass: navItemClass }, `sidebar-section-${sectionIndex}`))), (sidebarLocaleSlot || showThemeToggleInSidebar || (isAuthenticated && onLogout)) && (_jsxs(Div, { className: "border-t border-zinc-200 pt-4 space-y-3 dark:border-slate-800", children: [sidebarLocaleSlot, showThemeToggleInSidebar && (_jsxs("button", { type: "button", onClick: toggleTheme, className: "flex w-full items-center gap-3 rounded-lg px-3 py-2 text-sm text-zinc-700 transition-colors hover:bg-primary-50 hover:text-primary-800 dark:text-zinc-300 dark:hover:bg-slate-800 dark:hover:text-secondary-300", children: [_jsx("span", { "aria-hidden": "true", children: theme === "dark" ? "☀️" : "🌙" }), theme === "dark" ? "Light mode" : "Dark mode"] })), isAuthenticated && onLogout && (_jsx("button", { type: "button", onClick: () => { onLogout(); onAfterLogout(); }, className: CLS_LOGOUT_BTN, children: labels.logout }))] }))] }));
|
|
95
96
|
}
|
|
96
97
|
// ─── Main component ────────────────────────────────────────────────────────────
|
|
97
98
|
export function AppLayoutShell({ children, navItems, sidebarItems = [], sidebarSections, sidebarPrimaryActions, sidebarTitle = "Navigation", hiddenNavItems, user, brandName, brandShortName, siteLogoUrl, logoHref, promotionsHref, cartHref, wishlistHref, userId, profileHref, loginHref, registerHref, homeHref, shopHref, footer, searchSlot, searchSlotRenderer, titleBarNavSlot, titleBarNotificationSlot, titleBarDevSlot, titleBarPromoStripText, showThemeToggle = false, suppressDashboardNav = false, hideSidebarToggle = false, onLogout, adminHref, storeHref, sellerHref, userOrdersHref, userWishlistHref, userSettingsHref, sidebarLocaleSlot, showThemeToggleInSidebar = false, sidebarProfileLabels, eventBannerSlot, contentClassName, lightBackground = DEFAULT_LIGHT_BG, darkBackground = DEFAULT_DARK_BG, }) {
|
|
@@ -21,5 +21,5 @@ export function BackToTop({ threshold = 400, ariaLabel = "Back to top", classNam
|
|
|
21
21
|
}
|
|
22
22
|
/** SkipToMain — visually hidden link that becomes visible on focus for keyboard users. */
|
|
23
23
|
export function SkipToMain({ mainId = "main-content" }) {
|
|
24
|
-
return (_jsx(Link, { href: `#${mainId}`, className: "sr-only focus:not-sr-only focus:fixed focus:top-4 focus:left-4 focus:z-[
|
|
24
|
+
return (_jsx(Link, { href: `#${mainId}`, className: "sr-only focus:not-sr-only focus:fixed focus:top-4 focus:left-4 focus:z-[var(--appkit-z-toast)] focus:px-4 focus:py-2 focus:rounded-lg focus:bg-white dark:focus:bg-slate-900 focus:text-zinc-900 dark:focus:text-zinc-100 focus:shadow-lg focus:ring-2 focus:ring-primary-500 focus:outline-none text-sm font-medium", children: "Skip to main content" }));
|
|
25
25
|
}
|
|
@@ -31,12 +31,13 @@ import { useState, useRef, useEffect } from "react";
|
|
|
31
31
|
import { X, ChevronUp, ChevronDown, Check } from "lucide-react";
|
|
32
32
|
import { useBottomActionsContext } from "./BottomActionsContext";
|
|
33
33
|
import { useClickOutside } from "../../react";
|
|
34
|
-
import { Row, Span, Text, Button } from "../../ui";
|
|
34
|
+
import { Div, Row, Span, Text, Button } from "../../ui";
|
|
35
35
|
// Token values inlined from @mohasinac/appkit/tokens
|
|
36
36
|
const BOTTOM_NAV_BG = "bg-white/90 dark:bg-slate-950/90 backdrop-blur-md border-t border-zinc-200/80 dark:border-slate-800/80";
|
|
37
37
|
const Z_BOTTOM_ACTIONS = "z-40";
|
|
38
38
|
const BOTTOM_NAV_HEIGHT = "h-14";
|
|
39
39
|
const FLEX_CENTER = "flex items-center justify-center";
|
|
40
|
+
const CLS_COUNT_BADGE = "bg-red-500 text-white";
|
|
40
41
|
// ─── Sub-components ───────────────────────────────────────────────────────────
|
|
41
42
|
function BulkPickerPanel({ bulkActions, selectedActionId, pickerOpen, onSelect, }) {
|
|
42
43
|
return (_jsx("div", { role: "listbox", "aria-label": "Bulk actions", className: [
|
|
@@ -75,7 +76,7 @@ function PageActionsRow({ pageActions, dispatchAction, }) {
|
|
|
75
76
|
isIconOnly ? "px-0 justify-center" : "",
|
|
76
77
|
]
|
|
77
78
|
.filter(Boolean)
|
|
78
|
-
.join(" "), children: [action.icon && (_jsx(Span, { className: ["flex-shrink-0", action.label ? "mr-1.5" : ""].join(" "), "aria-hidden": "true", children: action.icon })), action.label && _jsx(Span, { className: "truncate leading-none", children: action.label }), action.badge !== undefined && (_jsx(Span, { className: `absolute -top-1.5 -right-1.5 min-w-[18px] h-[18px]
|
|
79
|
+
.join(" "), children: [action.icon && (_jsx(Span, { className: ["flex-shrink-0", action.label ? "mr-1.5" : ""].join(" "), "aria-hidden": "true", children: action.icon })), action.label && _jsx(Span, { className: "truncate leading-none", children: action.label }), action.badge !== undefined && (_jsx(Span, { className: `absolute -top-1.5 -right-1.5 min-w-[18px] h-[18px] ${CLS_COUNT_BADGE} text-[10px] font-bold rounded-full ${FLEX_CENTER} px-1 pointer-events-none select-none`, "aria-hidden": "true", children: action.badge }))] }, action.id));
|
|
79
80
|
}) }));
|
|
80
81
|
}
|
|
81
82
|
export default function BottomActions() {
|
|
@@ -126,7 +127,7 @@ export default function BottomActions() {
|
|
|
126
127
|
isVisible ? "translate-y-0" : "translate-y-full pointer-events-none",
|
|
127
128
|
]
|
|
128
129
|
.filter(Boolean)
|
|
129
|
-
.join(" "), "data-section": "bottomactions-div-401", children: [isBulkMode && (_jsx(BulkPickerPanel, { bulkActions: bulkActions, selectedActionId: selectedActionId, pickerOpen: pickerOpen, onSelect: (id) => { setSelectedActionId(id); setPickerOpen(false); } })), isBulkMode && (_jsx(
|
|
130
|
+
.join(" "), "data-section": "bottomactions-div-401", children: [isBulkMode && (_jsx(BulkPickerPanel, { bulkActions: bulkActions, selectedActionId: selectedActionId, pickerOpen: pickerOpen, onSelect: (id) => { setSelectedActionId(id); setPickerOpen(false); } })), isBulkMode && (_jsx(Div, { className: "h-[3px] w-full bg-gradient-to-r from-primary-600 via-secondary-400 to-primary-600 dark:from-primary-600 dark:via-primary-400 dark:to-primary-600" })), infoLabel && !isBulkMode && (_jsx(Div, { className: "px-4 pt-2 pb-0 border-b border-zinc-100/80 dark:border-slate-800/80", children: _jsx(Text, { className: "text-xs font-semibold text-zinc-500 dark:text-zinc-400 leading-5 truncate", children: infoLabel }) })), _jsx(Row, { className: `gap-2 px-3 ${BOTTOM_NAV_HEIGHT}`, children: isBulkMode && bulk ? (_jsxs(_Fragment, { children: [_jsxs(Button, { type: "button", variant: "ghost", onClick: dispatchBulkClear, className: "inline-flex items-center gap-1.5 flex-shrink-0 bg-primary-50 hover:bg-primary-100 active:bg-primary-200 dark:bg-primary-950/30 dark:hover:bg-primary-900/50 text-primary-700 dark:text-primary-300 rounded-full pl-2 pr-3 h-8 border border-primary-200/70 dark:border-primary-800/50 transition-colors min-h-0", "aria-label": "Clear selection", children: [_jsx(X, { className: "w-3.5 h-3.5 flex-shrink-0", "aria-hidden": "true" }), _jsx(Span, { size: "xs", weight: "semibold", className: "tabular-nums whitespace-nowrap leading-none", children: bulk.noun
|
|
130
131
|
? `${bulk.selectedCount} ${bulk.noun}`
|
|
131
132
|
: `${bulk.selectedCount} selected` })] }), bulkActions.length > 0 && (_jsxs(Button, { type: "button", variant: "ghost", onClick: () => setPickerOpen((o) => !o), "aria-haspopup": "listbox", "aria-expanded": pickerOpen, className: [
|
|
132
133
|
"flex-1 min-w-0 h-10 flex items-center gap-2 px-3 rounded-lg border text-sm font-medium transition-colors",
|
|
@@ -23,5 +23,5 @@ export function BottomNavItem({ href, label, icon, badge, isActive = false, clas
|
|
|
23
23
|
// Consumer projects may swap for next/link if preferred.
|
|
24
24
|
return (_jsx(Li, { className: "flex-1", children: _jsxs("a", { href: href, "aria-label": label, "aria-current": isActive ? "page" : undefined, className: `relative flex flex-col items-center justify-center gap-0.5 h-full w-full min-h-[44px] transition-colors ${isActive
|
|
25
25
|
? "text-primary-600 dark:text-secondary-400"
|
|
26
|
-
: "text-zinc-500 dark:text-zinc-400 hover:text-zinc-700 dark:hover:text-zinc-200"}${className ? ` ${className}` : ""}`, children: [_jsxs(Span, { className: "relative", children: [icon, badge != null && badge > 0 && (_jsx(Span, { "aria-label": `${badge} items`, className: "absolute -top-1.5 -right-1.5 min-w-[16px] h-4 px-1 rounded-full text-[10px] font-bold bg-secondary-500 text-white flex items-center justify-center leading-none", children: badge > 99 ? "99+" : badge }))] }), _jsx(Span, { className: "text-[10px]
|
|
26
|
+
: "text-zinc-500 dark:text-zinc-400 hover:text-zinc-700 dark:hover:text-zinc-200"}${className ? ` ${className}` : ""}`, children: [_jsxs(Span, { className: "relative", children: [icon, badge != null && badge > 0 && (_jsx(Span, { "aria-label": `${badge} items`, className: "absolute -top-1.5 -right-1.5 min-w-[16px] h-4 px-1 rounded-full text-[10px] font-bold bg-secondary-500 text-white flex items-center justify-center leading-none", children: badge > 99 ? "99+" : badge }))] }), _jsx(Span, { weight: "medium", className: "text-[10px] leading-none", children: label })] }) }));
|
|
27
27
|
}
|
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { useEffect, useCallback } from "react";
|
|
4
4
|
import { Button, Div, Row, Span } from "../../ui";
|
|
5
|
+
const __O = {
|
|
6
|
+
yAuto: "overflow-y-auto",
|
|
7
|
+
};
|
|
5
8
|
/**
|
|
6
9
|
* BottomSheet — mobile-first drawer that slides up from the bottom.
|
|
7
10
|
*
|
|
@@ -35,5 +38,5 @@ export function BottomSheet({ open, onClose, title, children, className, maxHeig
|
|
|
35
38
|
}, [open, handleEscape]);
|
|
36
39
|
if (!open)
|
|
37
40
|
return null;
|
|
38
|
-
return (_jsxs(Div, { className: "fixed inset-0 z-50 lg:hidden", role: "presentation", children: [_jsx(Div, { className: "absolute inset-0 bg-black/50 backdrop-blur-sm", "aria-hidden": "true", onClick: onClose }), _jsxs(Div, { role: "dialog", "aria-modal": "true", "aria-label": title, className: `absolute bottom-0 inset-x-0 flex flex-col rounded-t-2xl bg-white dark:bg-zinc-900 border-t border-zinc-200 dark:border-zinc-800 shadow-2xl ${maxHeight} animate-slide-up${className ? ` ${className}` : ""}`, children: [_jsxs(Row, { justify: "between", className: "px-4 py-3 border-b border-zinc-100 dark:border-zinc-800 shrink-0", children: [_jsx(Div, { className: "absolute top-2 left-1/2 -translate-x-1/2 w-10 h-1 rounded-full bg-zinc-300 dark:bg-zinc-600" }), title && (_jsx(Span, {
|
|
41
|
+
return (_jsxs(Div, { className: "fixed inset-0 z-50 lg:hidden", role: "presentation", children: [_jsx(Div, { className: "absolute inset-0 bg-black/50 backdrop-blur-sm", "aria-hidden": "true", onClick: onClose }), _jsxs(Div, { role: "dialog", "aria-modal": "true", "aria-label": title, className: `absolute bottom-0 inset-x-0 flex flex-col rounded-t-2xl bg-white dark:bg-zinc-900 border-t border-zinc-200 dark:border-zinc-800 shadow-2xl ${maxHeight} animate-slide-up${className ? ` ${className}` : ""}`, children: [_jsxs(Row, { justify: "between", className: "px-4 py-3 border-b border-zinc-100 dark:border-zinc-800 shrink-0", children: [_jsx(Div, { className: "absolute top-2 left-1/2 -translate-x-1/2 w-10 h-1 rounded-full bg-zinc-300 dark:bg-zinc-600" }), title && (_jsx(Span, { size: "sm", weight: "semibold", className: "text-zinc-800 dark:text-zinc-100 mt-2", children: title })), _jsx(Button, { type: "button", onClick: onClose, "aria-label": "Close", className: "ml-auto mt-2 p-1.5 rounded-lg text-zinc-500 hover:text-zinc-700 hover:bg-zinc-100 dark:text-zinc-400 dark:hover:text-zinc-200 dark:hover:bg-zinc-800 transition-colors min-h-[44px] min-w-[44px] flex items-center justify-center", children: _jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [_jsx("line", { x1: "18", y1: "6", x2: "6", y2: "18" }), _jsx("line", { x1: "6", y1: "6", x2: "18", y2: "18" })] }) })] }), _jsx(Div, { className: `flex-1 ${__O.yAuto} overscroll-contain pb-[env(safe-area-inset-bottom)]`, children: children })] })] }));
|
|
39
42
|
}
|
|
@@ -8,7 +8,7 @@ export function FooterLayout({ brandName, brandDescription, socialLinks, linkGro
|
|
|
8
8
|
const [openGroups, setOpenGroups] = useState({});
|
|
9
9
|
const toggleGroup = (idx) => setOpenGroups((prev) => ({ ...prev, [idx]: !prev[idx] }));
|
|
10
10
|
const visibleTrustItems = trustBarItems.filter((item) => item.visible !== false);
|
|
11
|
-
return (_jsxs(BlockFooter, { id: id, className: "bg-zinc-50 dark:bg-slate-950 border-t border-zinc-200 dark:border-slate-800", children: [showTrustBar && visibleTrustItems.length > 0 && (_jsx(Div, { className: "border-b border-zinc-100 dark:border-slate-800 py-8", children: _jsx(Div, { className: "container mx-auto px-4 sm:px-6 lg:px-8 max-w-[1920px]", children: _jsx(Row, { as: "ul", wrap: true, justify: "center", gap: "lg", className: "lg:gap-10", children: visibleTrustItems.map((item, i) => (_jsx(Li, { children: _jsxs(Row, { gap: "sm", className: "text-sm min-w-[160px]", children: [_jsx(Span, { className: "flex-shrink-0 text-primary-600 dark:text-secondary-400 w-5 h-5", children: item.icon }), _jsxs(Span, { children: [_jsx(Span, {
|
|
11
|
+
return (_jsxs(BlockFooter, { id: id, className: "bg-zinc-50 dark:bg-slate-950 border-t border-zinc-200 dark:border-slate-800", children: [showTrustBar && visibleTrustItems.length > 0 && (_jsx(Div, { className: "border-b border-zinc-100 dark:border-slate-800 py-8", children: _jsx(Div, { className: "container mx-auto px-4 sm:px-6 lg:px-8 max-w-[1920px]", children: _jsx(Row, { as: "ul", wrap: true, justify: "center", gap: "lg", className: "lg:gap-10", children: visibleTrustItems.map((item, i) => (_jsx(Li, { children: _jsxs(Row, { gap: "sm", className: "text-sm min-w-[160px]", children: [_jsx(Span, { className: "flex-shrink-0 text-primary-600 dark:text-secondary-400 w-5 h-5", children: item.icon }), _jsxs(Span, { children: [_jsx(Span, { size: "sm", weight: "bold", className: "text-zinc-900 dark:text-zinc-100 block", children: item.label }), item.subtitle && (_jsx(Span, { size: "xs", className: "text-zinc-500 dark:text-zinc-400 block", children: item.subtitle }))] })] }) }, item.id ?? String(i)))) }) }) })), _jsxs(Div, { className: "container mx-auto px-4 sm:px-6 lg:px-8 max-w-[1920px] py-10 lg:py-14", children: [_jsxs(Div, { className: "grid grid-cols-1 lg:grid-cols-5 gap-10 lg:gap-16", children: [_jsxs(Div, { className: "lg:col-span-2 space-y-4", children: [_jsx(Heading, { level: 5, className: "text-zinc-900 dark:text-zinc-50 font-bold text-xl", children: brandName }), _jsx(Text, { className: "text-sm text-zinc-600 dark:text-zinc-400 leading-relaxed max-w-sm", children: brandDescription }), socialLinks.length > 0 && (_jsx(Row, { as: Ul, gap: "sm", children: socialLinks.map((link) => (_jsx(Li, { children: _jsx(Link, { href: link.href, "aria-label": link.ariaLabel, target: "_blank", rel: "noopener noreferrer", className: "flex items-center justify-center w-9 h-9 rounded-full border border-zinc-200 dark:border-slate-700 text-zinc-500 dark:text-zinc-400 hover:text-primary dark:hover:text-secondary hover:border-primary/40 dark:hover:border-secondary/40 transition-colors", children: link.icon }) }, link.platform))) })), newsletterEnabled && newsletterSlot && (_jsx(Div, { className: "pt-2", children: newsletterSlot }))] }), _jsx(Div, { className: `lg:col-span-3 grid grid-cols-1 gap-0 lg:gap-8 ${linkGroups.length <= 3 ? "lg:grid-cols-3" :
|
|
12
12
|
linkGroups.length === 4 ? "lg:grid-cols-4" :
|
|
13
13
|
"lg:grid-cols-5"}`, children: linkGroups.map((group, idx) => (_jsxs(Div, { children: [_jsxs(Button, { type: "button", variant: "ghost", onClick: () => toggleGroup(idx), className: "flex w-full items-center justify-between border-b border-zinc-200 py-3 text-left text-sm font-semibold text-zinc-800 transition-colors hover:text-zinc-950 dark:border-slate-800 dark:text-zinc-100 dark:hover:text-white lg:hidden", "aria-expanded": !!openGroups[idx], children: [group.heading, _jsx(ChevronDown, { className: `w-4 h-4 transition-transform duration-200 ${openGroups[idx] ? "rotate-180" : ""}` })] }), _jsx(Ul, { className: `lg:hidden overflow-hidden transition-all duration-200 ${openGroups[idx] ? "max-h-96 py-3" : "max-h-0"} space-y-2.5`, children: group.links.map((link) => (_jsx(Li, { children: _jsx(Link, { href: link.href, className: "text-sm text-zinc-500 dark:text-zinc-400 hover:text-primary dark:hover:text-secondary transition-colors", children: link.label }) }, link.href))) }), _jsxs(Div, { className: "hidden lg:block", children: [_jsx(Text, { className: "text-xs font-semibold uppercase tracking-wider text-zinc-500 dark:text-zinc-400 mb-3", children: group.heading }), _jsx(Ul, { className: "space-y-2.5", children: group.links.map((link) => (_jsx(Li, { children: _jsx(Link, { href: link.href, className: "text-sm text-zinc-500 dark:text-zinc-400 hover:text-primary dark:hover:text-secondary transition-colors", children: link.label }) }, link.href))) })] })] }, idx))) })] }), _jsxs(Div, { className: "mt-10 pt-6 border-t border-zinc-200 dark:border-slate-800 flex flex-col sm:flex-row items-center justify-between gap-3 text-xs text-zinc-600 dark:text-zinc-400", children: [_jsx(Text, { className: "text-xs text-zinc-600 dark:text-zinc-400", children: copyrightText }), bottomLinks.length > 0 && (_jsx("nav", { "aria-label": "Site utilities", children: _jsx(Ul, { className: "flex flex-wrap items-center gap-x-4 gap-y-1 justify-center", children: bottomLinks.map((link) => (_jsx(Li, { children: _jsx(Link, { href: link.href, className: "text-xs text-zinc-500 dark:text-zinc-400 hover:text-primary dark:hover:text-secondary transition-colors underline-offset-2 hover:underline", children: link.label }) }, link.href))) }) })), madeInText && (_jsx(Text, { className: "text-xs text-zinc-600 dark:text-zinc-400", children: madeInText }))] })] })] }));
|
|
14
14
|
}
|
|
@@ -3,6 +3,9 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
3
3
|
import { useRef, useState, useEffect, useCallback } from "react";
|
|
4
4
|
import Link from "next/link";
|
|
5
5
|
import { Div, Li, Nav, Span, Ul } from "../../ui";
|
|
6
|
+
const __O = {
|
|
7
|
+
hidden: "overflow-hidden",
|
|
8
|
+
};
|
|
6
9
|
function DefaultNavItem({ item, isActive, }) {
|
|
7
10
|
const activeClasses = item.highlighted
|
|
8
11
|
? "border border-primary-400/40 dark:border-secondary-400/30 text-primary-700 dark:text-secondary-400 bg-primary-50/80 dark:bg-secondary-900/30 px-3 transition-colors duration-150"
|
|
@@ -48,5 +51,5 @@ export function NavbarLayout({ items, activeHref, id = "main-navbar", ariaLabel
|
|
|
48
51
|
if (inline) {
|
|
49
52
|
return (_jsx(Ul, { "aria-label": ariaLabel, className: "hidden xl:flex items-center gap-0.5 xl:gap-1", children: items.map((item) => (_jsx(Li, { children: renderItem ? (renderItem(item, activeHref === item.href)) : (_jsx(DefaultNavItem, { item: item, isActive: activeHref === item.href })) }, item.href))) }));
|
|
50
53
|
}
|
|
51
|
-
return (_jsx(Nav, { id: id, "aria-label": ariaLabel, className: "hidden lg:block bg-white/95 dark:bg-slate-950/95 backdrop-blur-md border-b border-zinc-100 dark:border-slate-800", children: _jsxs(Div, { className: "container mx-auto px-4 sm:px-6 lg:px-8 max-w-[1920px] flex items-center h-10", children: [_jsxs(Div, { className:
|
|
54
|
+
return (_jsx(Nav, { id: id, "aria-label": ariaLabel, className: "hidden lg:block bg-white/95 dark:bg-slate-950/95 backdrop-blur-md border-b border-zinc-100 dark:border-slate-800", children: _jsxs(Div, { className: "container mx-auto px-4 sm:px-6 lg:px-8 max-w-[1920px] flex items-center h-10", children: [_jsxs(Div, { className: `relative flex-1 ${__O.hidden}`, children: [canScrollLeft && (_jsx("button", { type: "button", onClick: () => scroll("left"), "aria-label": "Scroll navigation left", className: `${chevronBtn} left-0 bg-gradient-to-r`, children: _jsx("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", "aria-hidden": "true", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M15 19l-7-7 7-7" }) }) })), _jsx("ul", { ref: scrollRef, className: "flex items-center gap-0.5 lg:gap-1 overflow-x-auto [&::-webkit-scrollbar]:hidden [-ms-overflow-style:none] [scrollbar-width:none]", children: items.map((item) => (_jsx("li", { className: "shrink-0", children: renderItem ? (renderItem(item, activeHref === item.href)) : (_jsx(DefaultNavItem, { item: item, isActive: activeHref === item.href })) }, item.href))) }), canScrollRight && (_jsx("button", { type: "button", onClick: () => scroll("right"), "aria-label": "Scroll navigation right", className: `${chevronBtn} right-0 bg-gradient-to-l`, children: _jsx("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", "aria-hidden": "true", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 5l7 7-7 7" }) }) }))] }), rightSlot && _jsx(Div, { className: "shrink-0 ml-2", children: rightSlot })] }) }));
|
|
52
55
|
}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { forwardRef } from "react";
|
|
3
3
|
import { Aside, Div } from "../../ui";
|
|
4
|
+
const __O = {
|
|
5
|
+
yAuto: "overflow-y-auto",
|
|
6
|
+
};
|
|
4
7
|
/**
|
|
5
8
|
* SidebarLayout — generic slide-out sidebar shell.
|
|
6
9
|
*
|
|
@@ -14,7 +17,7 @@ import { Aside, Div } from "../../ui";
|
|
|
14
17
|
* to the rendered `aside` element.
|
|
15
18
|
*/
|
|
16
19
|
export const SidebarLayout = forwardRef(function SidebarLayout({ isOpen, ariaLabel, onClose, header, children, id = "secondary-sidebar" }, ref) {
|
|
17
|
-
return (_jsxs(_Fragment, { children: [isOpen && (_jsx(Div, { className: "fixed inset-0 bg-black/40 backdrop-blur-[2px] z-[
|
|
20
|
+
return (_jsxs(_Fragment, { children: [isOpen && (_jsx(Div, { className: "fixed inset-0 bg-black/40 backdrop-blur-[2px] z-[var(--appkit-z-overlay)] transition-opacity duration-300", onClick: onClose, "aria-hidden": "true" })), _jsxs(Aside, { ref: ref, id: id, "aria-label": ariaLabel, className: `
|
|
18
21
|
fixed inset-y-0 right-0
|
|
19
22
|
w-80
|
|
20
23
|
bg-white dark:bg-slate-900 border-l border-zinc-200 dark:border-slate-800
|
|
@@ -23,6 +26,6 @@ export const SidebarLayout = forwardRef(function SidebarLayout({ isOpen, ariaLab
|
|
|
23
26
|
z-50
|
|
24
27
|
${isOpen ? "translate-x-0" : "translate-x-full"}
|
|
25
28
|
flex flex-col
|
|
26
|
-
`, children: [_jsx(Div, { className: "flex-shrink-0 px-6 py-5 border-b border-zinc-200 dark:border-slate-800 bg-zinc-50 dark:bg-slate-900/80", children: header }), _jsx(Div, { className:
|
|
29
|
+
`, children: [_jsx(Div, { className: "flex-shrink-0 px-6 py-5 border-b border-zinc-200 dark:border-slate-800 bg-zinc-50 dark:bg-slate-900/80", children: header }), _jsx(Div, { className: `flex-1 ${__O.yAuto} scrollbar-thin px-6 py-4`, children: children })] })] }));
|
|
27
30
|
});
|
|
28
31
|
SidebarLayout.displayName = "SidebarLayout";
|
|
@@ -3,7 +3,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
3
3
|
import { FilterFacetSection } from "../../filters/FilterFacetSection";
|
|
4
4
|
import { AsyncFacetSection } from "../../filters/AsyncFacetSection";
|
|
5
5
|
import { RangeFilter } from "../../filters/RangeFilter";
|
|
6
|
-
import { Div } from "../../../ui";
|
|
6
|
+
import { Div, Label } from "../../../ui";
|
|
7
7
|
const SEX_OPTIONS = [
|
|
8
8
|
{ value: "male", label: "Male" },
|
|
9
9
|
{ value: "female", label: "Female" },
|
|
@@ -20,5 +20,5 @@ export function LiveItemFilters({ table, categoryOptions = [], loadCategoryOptio
|
|
|
20
20
|
: [];
|
|
21
21
|
const selectedSex = table.get("liveSex") ? [table.get("liveSex")] : [];
|
|
22
22
|
const selectedTransport = table.get("liveTransportMethod") ? [table.get("liveTransportMethod")] : [];
|
|
23
|
-
return (_jsxs(Div, { children: [loadCategoryOptions ? (_jsx(AsyncFacetSection, { title: "Category", loadOptions: loadCategoryOptions, selected: selectedCategories, onChange: (vals) => table.set("category", vals.join("|")), defaultCollapsed: false })) : categoryOptions.length > 0 ? (_jsx(FilterFacetSection, { title: "Category", options: categoryOptions, selected: selectedCategories, onChange: (vals) => table.set("category", vals.join("|")), searchable: true, defaultCollapsed: categoryOptions.length > 6 })) : null, _jsxs(
|
|
23
|
+
return (_jsxs(Div, { children: [loadCategoryOptions ? (_jsx(AsyncFacetSection, { title: "Category", loadOptions: loadCategoryOptions, selected: selectedCategories, onChange: (vals) => table.set("category", vals.join("|")), defaultCollapsed: false })) : categoryOptions.length > 0 ? (_jsx(FilterFacetSection, { title: "Category", options: categoryOptions, selected: selectedCategories, onChange: (vals) => table.set("category", vals.join("|")), searchable: true, defaultCollapsed: categoryOptions.length > 6 })) : null, _jsxs(Div, { className: "border-t border-[var(--appkit-color-border)] pt-4 mt-4", children: [_jsx(Label, { className: "block text-sm font-medium text-[var(--appkit-color-text)] mb-2", children: "Species / Animal" }), _jsx("input", { type: "text", value: table.get("species") || "", onChange: (e) => table.set("species", e.target.value), placeholder: "e.g. Axolotl, Parrot", className: "w-full rounded-lg border border-[var(--appkit-color-border)] bg-[var(--appkit-color-surface)] px-3 py-2 text-sm text-[var(--appkit-color-text)] placeholder-[var(--appkit-color-text-faint)] focus:outline-none focus:ring-2 focus:ring-[var(--appkit-color-primary)]" })] }), _jsxs(Div, { className: "border-t border-[var(--appkit-color-border)] pt-4 mt-4", children: [_jsx(Label, { className: "block text-sm font-medium text-[var(--appkit-color-text)] mb-2", children: "Jurisdiction (state/UT)" }), _jsx("input", { type: "text", value: table.get("jurisdiction") || "", onChange: (e) => table.set("jurisdiction", e.target.value), placeholder: "e.g. Maharashtra", className: "w-full rounded-lg border border-[var(--appkit-color-border)] bg-[var(--appkit-color-surface)] px-3 py-2 text-sm text-[var(--appkit-color-text)] placeholder-[var(--appkit-color-text-faint)] focus:outline-none focus:ring-2 focus:ring-[var(--appkit-color-primary)]" })] }), _jsx(FilterFacetSection, { title: "Sex", options: SEX_OPTIONS, selected: selectedSex, onChange: (vals) => table.set("liveSex", vals[0] ?? ""), searchable: false, selectionMode: "single", defaultCollapsed: false }), _jsx(FilterFacetSection, { title: "Transport Method", options: TRANSPORT_OPTIONS, selected: selectedTransport, onChange: (vals) => table.set("liveTransportMethod", vals[0] ?? ""), searchable: false, selectionMode: "single", defaultCollapsed: false }), _jsx(RangeFilter, { title: "Price", minValue: table.get("minPrice"), maxValue: table.get("maxPrice"), onMinChange: (v) => table.set("minPrice", v), onMaxChange: (v) => table.set("maxPrice", v), prefix: currencyPrefix, showSlider: true, minBound: 0, maxBound: 200000, step: 100, minPlaceholder: "Min price", maxPlaceholder: "Max price", defaultCollapsed: false })] }));
|
|
24
24
|
}
|
|
@@ -3,7 +3,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
3
3
|
import { useState, useCallback } from "react";
|
|
4
4
|
import { useUrlTable } from "../../../react/hooks/useUrlTable";
|
|
5
5
|
import { useProducts } from "../../products/hooks/useProducts";
|
|
6
|
-
import { BulkActionBar, FilterDrawer, ListingToolbar, LoginRequiredModal, Pagination, Text, useToast } from "../../../ui";
|
|
6
|
+
import { BulkActionBar, Div, FilterDrawer, ListingToolbar, LoginRequiredModal, Pagination, Text, useToast } from "../../../ui";
|
|
7
7
|
import { usePendingTable } from "../../../react/hooks/usePendingTable";
|
|
8
8
|
import { useAuthGate } from "../../../react/hooks/useAuthGate";
|
|
9
9
|
import { useBulkSelection } from "../../../react/hooks/useBulkSelection";
|
|
@@ -18,6 +18,12 @@ import { InteractiveProductCard } from "../../products/components/InteractivePro
|
|
|
18
18
|
import { LiveItemFilters } from "./LiveItemFilters";
|
|
19
19
|
import { ACTION_ID } from "../../products/constants/action-defs";
|
|
20
20
|
import { useBottomActions } from "../../layout";
|
|
21
|
+
const __P = {
|
|
22
|
+
p3: "p-3",
|
|
23
|
+
};
|
|
24
|
+
const __O = {
|
|
25
|
+
hidden: "overflow-hidden",
|
|
26
|
+
};
|
|
21
27
|
const DEFAULT_SORT = sortBy(PRODUCT_FIELDS.CREATED_AT);
|
|
22
28
|
const SORT_OPTIONS = [
|
|
23
29
|
{ value: sortBy(PRODUCT_FIELDS.CREATED_AT), label: "Newest First" },
|
|
@@ -103,7 +109,7 @@ export function LiveItemsIndexListing({ initialData }) {
|
|
|
103
109
|
}
|
|
104
110
|
}
|
|
105
111
|
useBottomActions(selection.selectedCount > 0 ? { bulk: { selectedCount: selection.selectedCount, onClearSelection: selection.clearSelection, actions: [] } } : {});
|
|
106
|
-
return (_jsxs(
|
|
112
|
+
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")
|
|
107
113
|
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")
|
|
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(
|
|
114
|
+
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 ${__O.hidden} animate-pulse`, children: [_jsx(Div, { className: "aspect-square bg-zinc-200 dark:bg-slate-700" }), _jsxs(Div, { className: `${__P.p3} 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 })] }));
|
|
109
115
|
}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { Div, Span, Text } from "../../../ui";
|
|
3
|
+
const CLS_COIN_PILL = "inline-flex items-center gap-1 rounded-full bg-amber-100 px-2 py-0.5 text-xs font-semibold text-amber-800";
|
|
4
|
+
const CLS_COIN_TOTAL = "text-3xl font-bold text-amber-600";
|
|
3
5
|
export function CoinsBadge({ coins, className }) {
|
|
4
|
-
return (_jsxs(Span, { className:
|
|
6
|
+
return (_jsxs(Span, { className: `${CLS_COIN_PILL} ${className ?? ""}`, children: [_jsx(Span, { "aria-hidden": "true", children: "\uD83E\uDE99" }), coins.toLocaleString()] }));
|
|
5
7
|
}
|
|
6
8
|
export function CoinsDisplay({ coins, label = "HC Coins" }) {
|
|
7
|
-
return (_jsxs(Div, { className: "flex flex-col items-center gap-1", children: [_jsx(Text, { className:
|
|
9
|
+
return (_jsxs(Div, { className: "flex flex-col items-center gap-1", children: [_jsx(Text, { className: CLS_COIN_TOTAL, children: coins.toLocaleString() }), _jsx(Text, { className: "text-sm text-gray-500", children: label })] }));
|
|
8
10
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { LoyaltyBalance } from "../types";
|
|
2
2
|
export declare function useLoyaltyBalance(uid: string | undefined, opts?: {
|
|
3
3
|
endpoint?: string;
|
|
4
|
-
}): import("@tanstack/react-query").UseQueryResult<LoyaltyBalance | null
|
|
4
|
+
}): import("@tanstack/react-query").UseQueryResult<NoInfer<LoyaltyBalance | null>, Error>;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
3
|
import { useEffect, useRef, useState } from "react";
|
|
4
|
-
import { Alert, Button, Input, Progress, Text, useToast } from "../../ui";
|
|
4
|
+
import { Alert, Button, Div, Input, Progress, Text, useToast } from "../../ui";
|
|
5
5
|
import { useMediaUpload } from "./hooks/useMedia";
|
|
6
6
|
import { ImageCropModal } from "./modals/ImageCropModal";
|
|
7
7
|
import { AvatarDisplay } from "../../ui/components/AvatarDisplay";
|
|
@@ -106,6 +106,6 @@ export function AvatarUpload({ currentPhotoURL, currentCropData, userId, display
|
|
|
106
106
|
fileInputRef.current.value = "";
|
|
107
107
|
};
|
|
108
108
|
const hasPending = pendingCropData !== null && pendingUploadFile !== null;
|
|
109
|
-
return (_jsxs(_Fragment, { children: [_jsxs(
|
|
109
|
+
return (_jsxs(_Fragment, { children: [_jsxs(Div, { className: "space-y-4", children: [_jsxs(Div, { className: "flex items-start gap-6", children: [_jsx(Div, { className: "shrink-0", children: _jsx(AvatarDisplay, { cropData: hasPending ? pendingCropData : cropData, size: "2xl", className: `border-4 ${hasPending ? "border-primary/60 ring-2 ring-primary/20" : "border-zinc-200 dark:border-slate-700"}`, displayName: displayName }) }), _jsxs(Div, { className: "flex-1 space-y-3", children: [_jsx(Text, { variant: "secondary", className: "text-xs", children: "JPG, PNG, WEBP or GIF up to 10MB." }), isUploading ? (_jsx(Progress, { value: 50, variant: "primary", size: "sm", label: t.uploading })) : null, hasPending && !isUploading ? (_jsxs(Div, { className: "space-y-2", children: [_jsx(Text, { variant: "secondary", className: "text-xs text-primary", children: t.readyToSave }), _jsxs(Div, { className: "flex gap-3", children: [_jsx(Button, { type: "button", onClick: handleConfirmSave, size: "sm", children: t.saveAvatar }), _jsx(Button, { type: "button", variant: "secondary", size: "sm", onClick: handleCancelPending, children: t.cancelChange })] })] })) : null, !hasPending && !isUploading ? (_jsxs(Div, { className: "flex gap-3", children: [_jsx(Button, { type: "button", onClick: () => fileInputRef.current?.click(), size: "sm", children: previewUrl ? t.changePhoto : t.chooseImage }), previewUrl ? (_jsx(Button, { type: "button", variant: "secondary", size: "sm", onClick: handleRemovePhoto, children: t.removePhoto })) : null] })) : null, _jsx(Input, { ref: fileInputRef, bare: true, type: "file", accept: "image/*", onChange: handleFileSelect, className: "hidden", "aria-label": t.changePhoto })] })] }), uploadApiError ? (_jsx(Alert, { variant: "error", children: uploadApiError.message })) : null] }), showCropModal && tempImageUrl ? (_jsx(ImageCropModal, { isOpen: showCropModal, imageUrl: tempImageUrl, onClose: handleCropCancel, onSave: handleCropSave, initialCropData: cropData || undefined })) : null] }));
|
|
110
110
|
}
|
|
111
111
|
export default AvatarUpload;
|
|
@@ -4,6 +4,7 @@ import { useEffect, useCallback, useRef, useState } from "react";
|
|
|
4
4
|
import { X, ZoomIn, ZoomOut, Maximize, Minimize, ChevronLeft, ChevronRight, RotateCcw, } from "lucide-react";
|
|
5
5
|
import { MediaImage } from "./MediaImage";
|
|
6
6
|
import { Button, Div, Span } from "../../ui";
|
|
7
|
+
const CLS_CLOSE_HOVER = "hover:!bg-red-500/50";
|
|
7
8
|
const MIN_ZOOM = 1;
|
|
8
9
|
const MAX_ZOOM = 4;
|
|
9
10
|
const ZOOM_STEP = 0.5;
|
|
@@ -27,7 +28,7 @@ function IconBtn({ onClick, disabled, ariaLabel, ariaCurrent, className, childre
|
|
|
27
28
|
}
|
|
28
29
|
// --- Controls bar sub-components ---------------------------------------------
|
|
29
30
|
function LightboxControlsBar({ items, index, zoom, isFullscreen, L, goPrev, goNext, zoomIn, zoomOut, resetZoom, toggleFullscreen, onClose, }) {
|
|
30
|
-
return (_jsxs(Div, { className: "flex items-center justify-center gap-1.5 px-4 py-3 bg-black/85 backdrop-blur-sm shrink-0 border-t border-white/10 flex-wrap", children: [items.length > 1 && (_jsx(IconBtn, { onClick: (e) => { e.stopPropagation(); goPrev(); }, ariaLabel: L.prevImage, children: _jsx(ChevronLeft, { className: "w-7 h-7" }) })), _jsx(IconBtn, { onClick: zoomOut, disabled: zoom <= MIN_ZOOM, ariaLabel: L.zoomOut, children: _jsx(ZoomOut, { className: "w-7 h-7" }) }), _jsxs(Span, { className: "text-white/70 w-14 text-center tabular-nums
|
|
31
|
+
return (_jsxs(Div, { className: "flex items-center justify-center gap-1.5 px-4 py-3 bg-black/85 backdrop-blur-sm shrink-0 border-t border-white/10 flex-wrap", children: [items.length > 1 && (_jsx(IconBtn, { onClick: (e) => { e.stopPropagation(); goPrev(); }, ariaLabel: L.prevImage, children: _jsx(ChevronLeft, { className: "w-7 h-7" }) })), _jsx(IconBtn, { onClick: zoomOut, disabled: zoom <= MIN_ZOOM, ariaLabel: L.zoomOut, children: _jsx(ZoomOut, { className: "w-7 h-7" }) }), _jsxs(Span, { size: "xs", className: "text-white/70 w-14 text-center tabular-nums", children: [Math.round(zoom * 100), "%"] }), _jsx(IconBtn, { onClick: zoomIn, disabled: zoom >= MAX_ZOOM, ariaLabel: L.zoomIn, children: _jsx(ZoomIn, { className: "w-7 h-7" }) }), zoom > 1 && (_jsx(IconBtn, { onClick: resetZoom, ariaLabel: L.resetZoom, children: _jsx(RotateCcw, { className: "w-7 h-7" }) })), _jsx(Span, { className: "w-px h-6 bg-white/15 mx-1 shrink-0", "aria-hidden": "true" }), _jsxs(Span, { size: "xs", className: "text-white/60 w-12 text-center tabular-nums", children: [index + 1, " / ", items.length] }), _jsx(Span, { className: "w-px h-6 bg-white/15 mx-1 shrink-0", "aria-hidden": "true" }), _jsx(IconBtn, { onClick: toggleFullscreen, ariaLabel: isFullscreen ? L.exitFullscreen : L.enterFullscreen, children: isFullscreen ? _jsx(Minimize, { className: "w-6 h-6" }) : _jsx(Maximize, { className: "w-6 h-6" }) }), _jsx(IconBtn, { onClick: onClose, ariaLabel: L.close, className: CLS_CLOSE_HOVER, children: _jsx(X, { className: "w-7 h-7" }) }), items.length > 1 && (_jsx(IconBtn, { onClick: (e) => { e.stopPropagation(); goNext(); }, ariaLabel: L.nextImage, children: _jsx(ChevronRight, { className: "w-7 h-7" }) }))] }));
|
|
31
32
|
}
|
|
32
33
|
function LightboxThumbnailStrip({ items, index, onSelect, resetZoom, L, }) {
|
|
33
34
|
return (_jsx(Div, { className: "flex gap-2 px-4 py-3 bg-black/70 backdrop-blur-sm overflow-x-auto shrink-0 justify-center", style: { paddingBottom: "calc(0.75rem + env(safe-area-inset-bottom, 0px))" }, children: items.map((item, i) => (_jsx(Button, { type: "button", onClick: () => { onSelect(i); resetZoom(); }, "aria-label": L.imageThumbnail(i + 1), "aria-current": i === index ? "true" : undefined, className: cn("relative shrink-0 w-14 h-14 p-0 overflow-hidden rounded-lg border-2 transition-all active:scale-95", i === index ? "border-white opacity-100" : "border-transparent opacity-40 hover:opacity-75"), children: _jsx(MediaImage, { src: item.src, alt: item.alt, size: "thumbnail" }) }, i))) }));
|
|
@@ -222,7 +223,7 @@ export function MediaLightbox({ items, initialIndex = 0, isOpen, onClose, labels
|
|
|
222
223
|
if (!isOpen || items.length === 0)
|
|
223
224
|
return null;
|
|
224
225
|
const current = items[index];
|
|
225
|
-
return (_jsxs(Div, { ref: containerRef, className: "fixed inset-0 z-[
|
|
226
|
+
return (_jsxs(Div, { ref: containerRef, className: "fixed inset-0 z-[var(--appkit-z-tooltip)] bg-black/95 flex flex-col", role: "dialog", "aria-modal": "true", "aria-label": L.lightboxTitle, children: [_jsx(Div, { ref: imageAreaRef, className: "flex-1 relative overflow-hidden select-none", onMouseDown: handleMouseDown, onMouseMove: handleMouseMove, onMouseUp: handleMouseUp, onMouseLeave: handleMouseUp, onTouchStart: handleTouchStart, onTouchMove: handleTouchMove, onTouchEnd: handleTouchEnd, style: {
|
|
226
227
|
cursor: zoom > 1 ? (isDragging ? "grabbing" : "grab") : "default",
|
|
227
228
|
touchAction: "none",
|
|
228
229
|
}, onClick: (e) => {
|
|
@@ -9,6 +9,9 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
9
9
|
import { useState, useRef } from "react";
|
|
10
10
|
import { useTranslations } from "next-intl";
|
|
11
11
|
import { Alert, Button, Div, Modal, Row, Span, Spinner, Text, } from "../../../ui";
|
|
12
|
+
const __O = {
|
|
13
|
+
hidden: "overflow-hidden",
|
|
14
|
+
};
|
|
12
15
|
export function VideoThumbnailSelector({ isOpen, videoUrl, onClose, onSelect, onUpload, }) {
|
|
13
16
|
const t = useTranslations("mediaEditor");
|
|
14
17
|
const [isCapturing, setIsCapturing] = useState(false);
|
|
@@ -47,5 +50,5 @@ export function VideoThumbnailSelector({ isOpen, videoUrl, onClose, onSelect, on
|
|
|
47
50
|
setIsCapturing(false);
|
|
48
51
|
}
|
|
49
52
|
};
|
|
50
|
-
return (_jsx(Modal, { isOpen: isOpen, onClose: onClose, title: t("thumbnailTitle"), size: "lg", children: _jsxs(Div, { className: "space-y-4", children: [_jsx(Text, { variant: "secondary", className: "text-xs", children: t("thumbnailInstruction") }), _jsx(Div, { className:
|
|
53
|
+
return (_jsx(Modal, { isOpen: isOpen, onClose: onClose, title: t("thumbnailTitle"), size: "lg", children: _jsxs(Div, { className: "space-y-4", children: [_jsx(Text, { variant: "secondary", className: "text-xs", children: t("thumbnailInstruction") }), _jsx(Div, { className: `relative aspect-video ${__O.hidden} rounded-lg bg-black`, children: _jsx("video", { ref: videoRef, src: videoUrl, className: "absolute inset-0 w-full h-full object-contain", controls: true, preload: "metadata" }) }), _jsx("canvas", { ref: canvasRef, className: "hidden", "aria-hidden": "true" }), error && _jsx(Alert, { variant: "error", children: error }), _jsxs(Row, { justify: "end", className: "gap-2", children: [_jsx(Button, { type: "button", variant: "outline", size: "sm", onClick: onClose, disabled: isCapturing, children: t("thumbnailSkip") }), _jsx(Button, { type: "button", variant: "primary", size: "sm", onClick: handleCapture, disabled: isCapturing, children: isCapturing ? (_jsxs(Span, { className: "flex items-center gap-2", children: [_jsx(Spinner, { size: "sm" }), t("thumbnailCapturing")] })) : (t("thumbnailCapture")) })] })] }) }));
|
|
51
54
|
}
|
|
@@ -69,5 +69,5 @@ export function VideoTrimModal({ isOpen, videoUrl, onClose, onSave, endpoint, })
|
|
|
69
69
|
medium: t("trimQualityMedium"),
|
|
70
70
|
high: t("trimQualityHigh"),
|
|
71
71
|
};
|
|
72
|
-
return (_jsx(Modal, { isOpen: isOpen, onClose: onClose, title: t("trimTitle"), size: "lg", children: _jsxs(Stack, { gap: "md", children: [_jsx(Text, { variant: "secondary", className: "text-xs", children: t("trimInstruction") }), _jsx(Div, { className: "relative aspect-video overflow-hidden rounded-lg bg-black", children: _jsx("video", { ref: videoRef, src: videoUrl, className: "absolute inset-0 w-full h-full object-contain", controls: true, onLoadedMetadata: handleLoadedMetadata }) }), duration > 0 && (_jsxs(_Fragment, { children: [_jsxs(Stack, { gap: "xs", children: [_jsxs(Row, { justify: "between", children: [_jsx(Text, { size: "sm", children: t("trimStart") }), _jsx(Span, {
|
|
72
|
+
return (_jsx(Modal, { isOpen: isOpen, onClose: onClose, title: t("trimTitle"), size: "lg", children: _jsxs(Stack, { gap: "md", children: [_jsx(Text, { variant: "secondary", className: "text-xs", children: t("trimInstruction") }), _jsx(Div, { className: "relative aspect-video overflow-hidden rounded-lg bg-black", children: _jsx("video", { ref: videoRef, src: videoUrl, className: "absolute inset-0 w-full h-full object-contain", controls: true, onLoadedMetadata: handleLoadedMetadata }) }), duration > 0 && (_jsxs(_Fragment, { children: [_jsxs(Stack, { gap: "xs", children: [_jsxs(Row, { justify: "between", children: [_jsx(Text, { size: "sm", children: t("trimStart") }), _jsx(Span, { size: "sm", className: "font-mono tabular-nums", children: formatTime(startTime) })] }), _jsx(MediaSlider, { value: startTime, min: 0, max: duration, step: 0.1, onChange: handleStartChange })] }), _jsxs(Stack, { gap: "xs", children: [_jsxs(Row, { justify: "between", children: [_jsx(Text, { size: "sm", children: t("trimEnd") }), _jsx(Span, { size: "sm", className: "font-mono tabular-nums", children: formatTime(endTime) })] }), _jsx(MediaSlider, { value: endTime, min: 0, max: duration, step: 0.1, onChange: handleEndChange })] }), _jsx(Text, { size: "xs", variant: "secondary", children: t("trimDuration", { duration: (endTime - startTime).toFixed(1) }) }), _jsxs(Stack, { gap: "xs", children: [_jsx(Text, { size: "sm", children: t("trimQuality") }), _jsx(Div, { className: "flex gap-2", children: ["low", "medium", "high"].map((q) => (_jsx(Button, { type: "button", variant: quality === q ? "primary" : "outline", size: "sm", onClick: () => setQuality(q), disabled: isPending, children: qualityLabels[q] }, q))) })] })] })), error && _jsx(Alert, { variant: "error", children: error }), _jsxs(Row, { justify: "end", className: "gap-2", children: [_jsx(Button, { type: "button", variant: "outline", size: "sm", onClick: onClose, disabled: isPending, children: t("trimSkip") }), _jsx(Button, { type: "button", variant: "primary", size: "sm", onClick: handleTrim, disabled: isPending || duration === 0, children: isPending ? t("trimming") : t("trimSave") })] })] }) }));
|
|
73
73
|
}
|
|
@@ -53,7 +53,7 @@ export default function CameraCapture({ mode, facingMode = "environment", onCapt
|
|
|
53
53
|
};
|
|
54
54
|
const showPhotoButton = mode === "photo" || mode === "both";
|
|
55
55
|
const showVideoButton = mode === "video" || mode === "both";
|
|
56
|
-
return (_jsxs(Div, { className: `relative rounded-xl overflow-hidden bg-black ${className ?? ""}`, children: [_jsx("video", { ref: camera.videoRef, autoPlay: true, muted: true, playsInline: true, className: "w-full aspect-video object-cover" }), isStarting && (_jsx(Div, { className: "absolute inset-0 flex items-center justify-center bg-black/60", children: _jsxs(Div, { className: "flex flex-col items-center gap-2", children: [_jsx(Spinner, {}), _jsx(Span, { className: "text-white
|
|
56
|
+
return (_jsxs(Div, { className: `relative rounded-xl overflow-hidden bg-black ${className ?? ""}`, children: [_jsx("video", { ref: camera.videoRef, autoPlay: true, muted: true, playsInline: true, className: "w-full aspect-video object-cover" }), isStarting && (_jsx(Div, { className: "absolute inset-0 flex items-center justify-center bg-black/60", children: _jsxs(Div, { className: "flex flex-col items-center gap-2", children: [_jsx(Spinner, {}), _jsx(Span, { size: "sm", className: "text-white", children: t("starting") })] }) })), camera.error && (_jsx(Div, { className: "absolute top-2 left-2 right-2", children: _jsx(Alert, { variant: "error", children: camera.error }) })), !isStarting && !camera.error && camera.isActive && (_jsxs(Div, { className: "absolute bottom-0 left-0 right-0 p-3 bg-black/40 flex items-center justify-center gap-3", children: [showPhotoButton && (_jsx(Button, { variant: "secondary", onClick: handleTakePhoto, "aria-label": t("takePhoto"), disabled: camera.isCapturing, children: t("takePhoto") })), showVideoButton && (_jsx(Button, { variant: camera.isCapturing ? "danger" : "secondary", onClick: camera.isCapturing
|
|
57
57
|
? handleStopRecording
|
|
58
58
|
: () => camera.startRecording(), "aria-label": camera.isCapturing ? t("stopRecording") : t("startRecording"), children: camera.isCapturing ? t("stopRecording") : t("startRecording") })), hasMultipleCameras && (_jsx(Button, { variant: "outline", onClick: () => void camera.switchCamera(), "aria-label": t("flipCamera"), disabled: camera.isCapturing, children: t("flipCamera") }))] }))] }));
|
|
59
59
|
}
|
|
@@ -15,6 +15,9 @@ import { MediaImage } from "../MediaImage";
|
|
|
15
15
|
import { ImageCropModal } from "../modals/ImageCropModal";
|
|
16
16
|
import { ImageEditor } from "../modals/ImageEditor";
|
|
17
17
|
import CameraCapture from "./CameraCapture";
|
|
18
|
+
const __O = {
|
|
19
|
+
hidden: "overflow-hidden",
|
|
20
|
+
};
|
|
18
21
|
function formatFileSize(bytes) {
|
|
19
22
|
if (bytes < 1024 * 1024)
|
|
20
23
|
return `${(bytes / 1024).toFixed(1)}KB`;
|
|
@@ -162,7 +165,7 @@ export function ImageUpload({ currentImage, onUpload, onChange, accept = "image/
|
|
|
162
165
|
fileInputRef.current.value = "";
|
|
163
166
|
onChange?.("");
|
|
164
167
|
};
|
|
165
|
-
return (_jsxs(Div, { className: "space-y-3", children: [label && (_jsx(Label, { className: "block text-sm font-medium text-zinc-600 dark:text-zinc-400", children: label })), _jsx(Div, { className: "relative", children: preview ? (_jsxs(Div, { className: "space-y-2", children: [_jsxs(Div, { className:
|
|
168
|
+
return (_jsxs(Div, { className: "space-y-3", children: [label && (_jsx(Label, { className: "block text-sm font-medium text-zinc-600 dark:text-zinc-400", children: label })), _jsx(Div, { className: "relative", children: preview ? (_jsxs(Div, { className: "space-y-2", children: [_jsxs(Div, { className: `relative h-32 max-w-xs mx-auto ${__O.hidden} rounded-lg border border-zinc-200 dark:border-zinc-700`, children: [_jsx(MediaImage, { src: preview, alt: "Preview", size: "card" }), uploading && progress > 0 && (_jsx(Div, { className: "absolute inset-x-0 bottom-0", children: _jsx(Progress, { value: progress, size: "sm" }) }))] }), !uploading && (_jsxs(Row, { wrap: true, gap: "sm", children: [(enableCrop || enableAdvancedCrop) && (_jsx(Button, { type: "button", onClick: () => openEditor(preview), variant: "secondary", size: "sm", children: tMediaEditor("editImage") })), _jsx(Button, { type: "button", onClick: () => fileInputRef.current?.click(), variant: "outline", size: "sm", children: tUpload("change") }), _jsx(Button, { type: "button", onClick: handleRemove, variant: "danger", size: "sm", children: tUpload("remove") })] }))] })) : (_jsxs(_Fragment, { children: [showCamera && isCameraSupported && (_jsx(CameraCapture, { mode: "photo", facingMode: "environment", onCapture: handleCameraCapture, onError: setError })), !showCamera && (_jsxs(Div, { className: "space-y-2", children: [_jsxs(Row, { gap: "sm", className: "flex-wrap", children: [showFileInput && (_jsx(Button, { type: "button", onClick: () => fileInputRef.current?.click(), disabled: uploading, variant: "outline", size: "sm", children: uploading ? tUpload("uploading") : tUpload("clickToUpload") })), captureSource !== "file-only" && isCameraSupported && (_jsx(Button, { type: "button", onClick: () => setCaptureMode("camera"), disabled: uploading, variant: "ghost", size: "sm", children: t("switchToCamera") })), captureSource !== "file-only" && !isCameraSupported && (_jsx(Button, { type: "button", onClick: () => mobileCaptureRef.current?.click(), disabled: uploading, variant: "ghost", size: "sm", children: t("switchToCamera") }))] }), _jsxs(Text, { size: "xs", variant: "secondary", children: [accept === "image/*"
|
|
166
169
|
? `JPG PNG GIF WebP`
|
|
167
170
|
: accept.split(",").map((a) => a.split("/")[1]?.toUpperCase() ?? a).join(" "), " ", "\u2014 max ", maxSizeMB, "MB"] })] }))] })) }), _jsx("input", { ref: fileInputRef, type: "file", accept: accept, onChange: handleFileChange, className: "hidden", "aria-hidden": "true", "data-testid": "media-upload-input" }), showCamera && !isCameraSupported && (_jsx("input", { ref: mobileCaptureRef, type: "file", accept: "image/*", capture: "environment", onChange: handleFileChange, className: "hidden", "aria-hidden": "true", "data-testid": "media-upload-capture-input" })), helperText && !error && (_jsx(Text, { variant: "secondary", size: "xs", children: helperText })), error && _jsx(Alert, { variant: "error", children: error }), uploading && (_jsxs(Row, { className: "gap-2", children: [_jsx(Spinner, { size: "sm" }), _jsx(Text, { size: "sm", variant: "secondary", children: tUpload("uploadingProgress", { progress }) })] })), cropPreviewUrl && !enableAdvancedCrop && (_jsx(ImageCropModal, { isOpen: showCropModal, imageUrl: cropPreviewUrl, onClose: handleCropClose, onSave: handleCropSave })), cropPreviewUrl && enableAdvancedCrop && (_jsx(ImageEditor, { isOpen: showAdvancedEditor, imageUrl: cropPreviewUrl, onClose: handleAdvancedEditorClose, onSave: handleAdvancedEditorSave, aspectRatio: cropAspectRatio }))] }));
|
|
168
171
|
}
|
|
@@ -9,13 +9,22 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
9
9
|
import { useState, useRef, useEffect } from "react";
|
|
10
10
|
import { useTranslations } from "next-intl";
|
|
11
11
|
import { useCamera } from "../../../react";
|
|
12
|
-
import { Alert, Button, Div, Label, Row, Spinner, Text } from "../../../ui";
|
|
12
|
+
import { Alert, Button, Div, Label, Row, Span, Spinner, Text } from "../../../ui";
|
|
13
13
|
import { MediaImage } from "../MediaImage";
|
|
14
14
|
import { MediaVideo } from "../MediaVideo";
|
|
15
15
|
import { VideoTrimModal } from "../modals/VideoTrimModal";
|
|
16
16
|
import { VideoThumbnailSelector } from "../modals/VideoThumbnailSelector";
|
|
17
17
|
import CameraCapture from "./CameraCapture";
|
|
18
18
|
import { inferMediaTypeFromMime } from "../types/index";
|
|
19
|
+
const __P = {
|
|
20
|
+
p3: "p-3",
|
|
21
|
+
};
|
|
22
|
+
const __O = {
|
|
23
|
+
hidden: "overflow-hidden",
|
|
24
|
+
};
|
|
25
|
+
const CLS_PDF_BADGE = "flex h-8 w-8 shrink-0 items-center justify-center rounded-lg bg-rose-100 text-rose-700 dark:bg-rose-900/40 dark:text-rose-300";
|
|
26
|
+
const CLS_PDF_NAME = "text-sm font-medium text-blue-600 underline break-all dark:text-blue-400";
|
|
27
|
+
const CLS_PDF_LINK = "text-sm underline break-all text-blue-600 dark:text-blue-400";
|
|
19
28
|
const KIND_DEFAULTS = {
|
|
20
29
|
image: { accept: "image/*", maxSizeMB: 25 },
|
|
21
30
|
video: { accept: "video/*", maxSizeMB: 200 },
|
|
@@ -72,7 +81,7 @@ function ExternalUrlTabPanel({ extInput, setExtInput, extError, setExtError, onA
|
|
|
72
81
|
return (_jsxs(Div, { className: "space-y-2", children: [_jsxs(Row, { gap: "sm", children: [_jsx("input", { type: "url", value: extInput, onChange: (e) => { setExtInput(e.target.value); setExtError(""); }, placeholder: "https://example.com/image.jpg", className: "appkit-input flex-1" }), _jsx(Button, { type: "button", variant: "primary", size: "sm", onClick: onApply, children: "Apply" })] }), extError && _jsx(Alert, { variant: "error", children: extError }), _jsx(Text, { size: "xs", variant: "secondary", children: "External URLs are stored as-is and are not watermarked." })] }));
|
|
73
82
|
}
|
|
74
83
|
function MediaPreviewPanel({ value, label, disabled, enableTrim, enableThumbnail, onEditVideo, onRemove, tUpload, tMediaEditor, }) {
|
|
75
|
-
return (_jsxs(Div, { className:
|
|
84
|
+
return (_jsxs(Div, { className: `rounded-lg border border-zinc-200 dark:border-zinc-700 bg-zinc-50 dark:bg-zinc-900 ${__P.p3}`, children: [isVideo(value) ? (_jsxs(Div, { className: "space-y-2", children: [_jsx(Div, { className: `relative aspect-video ${__O.hidden} rounded-lg`, children: _jsx(MediaVideo, { src: value, alt: label, controls: true, objectFit: "contain" }) }), _jsx(Text, { size: "xs", variant: "secondary", children: "Video uploaded successfully. Large videos may take longer to process." })] })) : isImage(value) ? (_jsx(Div, { className: `relative aspect-video ${__O.hidden} rounded-lg`, children: _jsx(MediaImage, { src: value, alt: label, size: "card", objectFit: "contain" }) })) : isPdf(value) ? (_jsxs(Div, { className: "space-y-2", children: [_jsx(Div, { className: `relative w-full ${__O.hidden} rounded-lg border border-zinc-200 dark:border-zinc-700`, style: { height: 280 }, children: _jsx("iframe", { src: value, title: filenameFromUrl(value), className: "w-full h-full border-0" }) }), _jsxs(Row, { gap: "md", align: "center", children: [_jsx(Div, { "aria-hidden": true, className: CLS_PDF_BADGE, children: _jsx(Span, { size: "xs", weight: "bold", children: "PDF" }) }), _jsx("a", { href: value, target: "_blank", rel: "noopener noreferrer", className: CLS_PDF_NAME, children: filenameFromUrl(value) })] })] })) : (_jsx("a", { href: value, target: "_blank", rel: "noopener noreferrer", className: CLS_PDF_LINK, children: filenameFromUrl(value) })), !disabled && (_jsxs(Row, { wrap: true, gap: "sm", className: "mt-2", children: [isVideo(value) && (enableTrim || enableThumbnail) && (_jsx(Button, { type: "button", onClick: () => onEditVideo(value), variant: "secondary", size: "sm", children: tMediaEditor("editVideo") })), _jsx(Button, { type: "button", onClick: onRemove, variant: "danger", size: "sm", children: tUpload("remove") })] }))] }));
|
|
76
85
|
}
|
|
77
86
|
export function MediaUploadField({ label, value, onChange, onChangeField, onUpload,
|
|
78
87
|
// SB-UNI-Z5 2026-05-13 — `kind` derives accept/maxSizeMB when not set
|
|
@@ -5,6 +5,10 @@ import { Alert, Button, Div, Label, Spinner, Text } from "../../../ui";
|
|
|
5
5
|
import { MediaImage } from "../MediaImage";
|
|
6
6
|
import { MediaVideo } from "../MediaVideo";
|
|
7
7
|
import { inferMediaTypeFromMime } from "../types/index";
|
|
8
|
+
const __O = {
|
|
9
|
+
hidden: "overflow-hidden",
|
|
10
|
+
};
|
|
11
|
+
const CLS_PDF_LINK = "text-sm underline break-all text-blue-600 dark:text-blue-400";
|
|
8
12
|
function fileNameFromUrl(url) {
|
|
9
13
|
try {
|
|
10
14
|
const parts = new URL(url).pathname.split("/");
|
|
@@ -100,5 +104,5 @@ export function MediaUploadList({ label, value, onChange, onUpload, accept = "im
|
|
|
100
104
|
unstageUrl(target.url);
|
|
101
105
|
}
|
|
102
106
|
};
|
|
103
|
-
return (_jsxs(Div, { className: "space-y-2", children: [_jsx(Label, { className: "block text-sm font-medium text-zinc-600 dark:text-zinc-400", children: label }), value.length > 0 && (_jsx(Div, { className: "grid grid-cols-1 sm:grid-cols-2 gap-3", children: value.map((item, index) => (_jsxs(Div, { className: "rounded-lg border border-zinc-200 dark:border-zinc-700 bg-zinc-50 dark:bg-zinc-900 p-3", children: [item.type === "video" ? (_jsx(Div, { className:
|
|
107
|
+
return (_jsxs(Div, { className: "space-y-2", children: [_jsx(Label, { className: "block text-sm font-medium text-zinc-600 dark:text-zinc-400", children: label }), value.length > 0 && (_jsx(Div, { className: "grid grid-cols-1 sm:grid-cols-2 gap-3", children: value.map((item, index) => (_jsxs(Div, { className: "rounded-lg border border-zinc-200 dark:border-zinc-700 bg-zinc-50 dark:bg-zinc-900 p-3", children: [item.type === "video" ? (_jsx(Div, { className: `relative aspect-square max-h-24 ${__O.hidden} rounded-lg`, children: _jsx(MediaVideo, { src: item.url, alt: item.alt || `Media ${index + 1}`, controls: true }) })) : item.type === "image" ? (_jsx(Div, { className: `relative aspect-square max-h-24 ${__O.hidden} rounded-lg`, children: _jsx(MediaImage, { src: item.url, alt: item.alt || `Media ${index + 1}`, size: "card", objectFit: "contain" }) })) : (_jsx("a", { href: item.url, target: "_blank", rel: "noopener noreferrer", className: CLS_PDF_LINK, children: fileNameFromUrl(item.url) })), !disabled && (_jsx(Div, { className: "mt-2", children: _jsx(Button, { type: "button", size: "sm", variant: "danger", onClick: () => removeAt(index), children: "Remove" }) }))] }, `${item.url}-${index}`))) })), !disabled && value.length < maxItems && (_jsx(Button, { type: "button", variant: "outline", size: "sm", onClick: () => inputRef.current?.click(), disabled: isLoading, children: isLoading ? "Uploading..." : `+ Add Files (${value.length}/${maxItems})` })), isLoading && (_jsxs(Div, { className: "flex items-center gap-2", children: [_jsx(Spinner, { size: "sm" }), _jsx(Text, { size: "sm", variant: "secondary", children: "Uploading" })] })), _jsx("input", { ref: inputRef, type: "file", multiple: true, accept: accept, onChange: handleFileChange, className: "hidden", "aria-hidden": "true", "data-testid": "media-upload-list-input" }), helperText && !error && (_jsx(Text, { variant: "secondary", size: "xs", children: helperText })), error && _jsx(Alert, { variant: "error", children: error })] }));
|
|
104
108
|
}
|