@mohasinac/appkit 3.2.7 → 3.2.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_internal/client/features/filters/filter-load-options.js +11 -9
- package/dist/_internal/client/theme/ThemeProvider.js +14 -4
- package/dist/_internal/server/features/auth/firebase-identity.d.ts +12 -0
- package/dist/_internal/server/features/auth/firebase-identity.js +25 -0
- package/dist/_internal/server/features/site-settings/safe-settings.d.ts +12 -0
- package/dist/_internal/server/features/site-settings/safe-settings.js +25 -0
- package/dist/_internal/shared/features/layout/config.js +7 -7
- package/dist/_internal/shared/styles/skeleton.d.ts +8 -8
- package/dist/_internal/shared/styles/skeleton.js +10 -10
- package/dist/_internal/shared/styles/themed.d.ts +12 -12
- package/dist/_internal/shared/styles/themed.js +12 -12
- package/dist/features/about/components/AboutView.js +1 -1
- package/dist/features/about/components/FAQPageView.js +1 -1
- package/dist/features/about/components/FeesView.js +2 -2
- package/dist/features/about/components/HowAuctionsWorkView.js +2 -2
- package/dist/features/about/components/HowCheckoutWorksView.js +2 -2
- package/dist/features/about/components/HowOffersWorkView.js +2 -2
- package/dist/features/about/components/HowOrdersWorkView.js +2 -2
- package/dist/features/about/components/HowPayoutsWorkView.js +2 -2
- package/dist/features/about/components/HowPreOrdersWorkView.js +2 -2
- package/dist/features/about/components/HowReviewsWorkView.js +2 -2
- package/dist/features/about/components/PublicProfileView.js +3 -3
- package/dist/features/about/components/SecurityPrivacyView.js +2 -2
- package/dist/features/account/components/AddressBook.js +2 -2
- package/dist/features/account/components/AddressesIndexListing.js +1 -1
- package/dist/features/account/components/ChatWindow.js +1 -1
- package/dist/features/account/components/MessagesView.js +1 -1
- package/dist/features/account/components/NotificationBell.js +2 -2
- package/dist/features/account/components/NotificationPreferencesPanel.js +1 -1
- package/dist/features/account/components/UserSidebar.js +3 -3
- package/dist/features/account/components/UserSupportView.js +3 -3
- package/dist/features/admin/components/AdminAdEditorView.js +1 -1
- package/dist/features/admin/components/AdminAdsView.js +5 -5
- package/dist/features/admin/components/AdminAnalyticsView.js +1 -1
- package/dist/features/admin/components/AdminBrandsView.js +1 -1
- package/dist/features/admin/components/AdminBundlesView.js +2 -2
- package/dist/features/admin/components/AdminCarouselEditorView.js +4 -4
- package/dist/features/admin/components/AdminCarouselView.js +2 -2
- package/dist/features/admin/components/AdminCategoriesView.js +2 -2
- package/dist/features/admin/components/AdminContactEditorView.js +1 -1
- package/dist/features/admin/components/AdminCouponEditorView.js +1 -1
- package/dist/features/admin/components/AdminEmployeeEditorView.js +3 -3
- package/dist/features/admin/components/AdminFaqsView.js +1 -1
- package/dist/features/admin/components/AdminFeatureEditorView.js +2 -2
- package/dist/features/admin/components/AdminFeatureFlagsView.js +1 -1
- package/dist/features/admin/components/AdminFeaturesView.js +2 -2
- package/dist/features/admin/components/AdminNavigationView.js +2 -2
- package/dist/features/admin/components/AdminNotificationsView.js +1 -1
- package/dist/features/admin/components/AdminOrderEditorView.js +1 -1
- package/dist/features/admin/components/AdminPageHeader.d.ts +1 -1
- package/dist/features/admin/components/AdminPageHeader.js +1 -1
- package/dist/features/admin/components/AdminReviewsView.js +1 -1
- package/dist/features/admin/components/AdminScammerEditorView.js +3 -3
- package/dist/features/admin/components/AdminScammersView.js +1 -1
- package/dist/features/admin/components/AdminSectionsView.js +1 -1
- package/dist/features/admin/components/AdminSessionsView.js +1 -1
- package/dist/features/admin/components/AdminSidebar.js +5 -5
- package/dist/features/admin/components/AdminSiteSettingsView.js +3 -3
- package/dist/features/admin/components/AdminStoreEditorView.js +3 -3
- package/dist/features/admin/components/AdminSupportTicketDetailView.js +3 -3
- package/dist/features/admin/components/AdminSupportTicketsView.js +2 -2
- package/dist/features/admin/components/AdminViewCards.js +5 -5
- package/dist/features/admin/components/DataTable.js +1 -1
- package/dist/features/admin/components/DrawerFormFooter.js +1 -1
- package/dist/features/admin/components/QuickActionsPanel.js +1 -1
- package/dist/features/admin/components/analytics/AdminTopProductsTable.js +1 -1
- package/dist/features/auctions/components/AuctionDetailPageView.js +2 -2
- package/dist/features/auctions/components/CollapsibleBidHistory.js +1 -1
- package/dist/features/auctions/components/MarketplaceAuctionCard.js +1 -1
- package/dist/features/auth/components/ForgotPasswordView.js +1 -1
- package/dist/features/auth/components/Guards.js +1 -1
- package/dist/features/auth/components/RegisterForm.js +1 -1
- package/dist/features/auth/components/ResetPasswordView.js +1 -1
- package/dist/features/auth/components/SocialAuthButtons.js +1 -1
- package/dist/features/blog/components/BlogIndexListing.js +1 -1
- package/dist/features/blog/components/BlogListView.js +3 -3
- package/dist/features/blog/components/BlogPostView.js +1 -1
- package/dist/features/cart/components/CartDrawer.js +5 -5
- package/dist/features/categories/components/BrandDetailPageView.js +1 -1
- package/dist/features/categories/components/BrandDetailTabs.js +1 -1
- package/dist/features/categories/components/CategoriesIndexListing.js +2 -2
- package/dist/features/categories/components/CategoryDetailPageView.js +1 -1
- package/dist/features/categories/components/CategoryDetailTabs.js +1 -1
- package/dist/features/categories/components/CategoryGrid.js +3 -3
- package/dist/features/categories/components/CategoryTree.js +2 -2
- package/dist/features/categories/components/ConcernCard.js +1 -1
- package/dist/features/checkout/components/CheckoutStepper.js +1 -1
- package/dist/features/classified/components/ClassifiedIndexListing.js +1 -1
- package/dist/features/collections/components/CollectionCard.js +1 -1
- package/dist/features/collections/hooks/useCollections.js +12 -12
- package/dist/features/contact/components/ContactForm.js +1 -1
- package/dist/features/copilot/components/AdminCopilotView.js +5 -5
- package/dist/features/digital-codes/components/DigitalCodesIndexListing.js +1 -1
- package/dist/features/events/components/AdminEventEntriesView.js +1 -1
- package/dist/features/events/components/EventCard.js +1 -1
- package/dist/features/events/components/EventPollWidget.js +1 -1
- package/dist/features/events/components/EventStatusBadge.js +1 -1
- package/dist/features/events/components/EventsIndexListing.js +1 -1
- package/dist/features/faq/components/ContactCTA.js +2 -2
- package/dist/features/faq/components/FAQAccordion.js +4 -4
- package/dist/features/faq/components/FAQCategorySidebar.js +2 -2
- package/dist/features/faq/components/FAQHelpfulButtons.js +4 -4
- package/dist/features/faq/components/RelatedFAQs.js +1 -1
- package/dist/features/filters/AsyncFacetSection.js +3 -3
- package/dist/features/filters/FilterFacetSection.js +5 -5
- package/dist/features/filters/RangeFilter.js +3 -3
- package/dist/features/filters/SwitchFilter.js +2 -2
- package/dist/features/forms/Checkbox.js +1 -1
- package/dist/features/forms/Input.js +2 -2
- package/dist/features/forms/Radio.js +2 -2
- package/dist/features/forms/Select.js +1 -1
- package/dist/features/forms/Slider.js +1 -1
- package/dist/features/forms/Textarea.js +1 -1
- package/dist/features/forms/Toggle.js +3 -3
- package/dist/features/forms/utils.d.ts +4 -4
- package/dist/features/forms/utils.js +4 -4
- package/dist/features/homepage/components/AdSlot.js +1 -1
- package/dist/features/homepage/components/AdvertisementBanner.js +3 -3
- package/dist/features/homepage/components/BrandsSection.js +2 -2
- package/dist/features/homepage/components/GoogleReviewsSection.js +1 -1
- package/dist/features/homepage/components/HeroSection.js +1 -1
- package/dist/features/homepage/components/HomepageCustomerReviewsSection.js +1 -1
- package/dist/features/homepage/components/HowItWorksSection.js +1 -1
- package/dist/features/homepage/components/ShopByCategorySection.js +2 -2
- package/dist/features/homepage/components/SiteFeaturesSection.js +1 -1
- package/dist/features/homepage/components/SocialPostCard.js +1 -1
- package/dist/features/homepage/components/StatsCounterSection.js +1 -1
- package/dist/features/homepage/components/TrustIndicatorsSection.js +1 -1
- package/dist/features/homepage/constants/hero-carousel-styles.d.ts +3 -3
- package/dist/features/homepage/constants/hero-carousel-styles.js +3 -3
- package/dist/features/homepage/hooks/useActiveAd.d.ts +1 -3
- package/dist/features/homepage/hooks/useActiveAd.js +9 -17
- package/dist/features/layout/AppLayoutShell.js +12 -12
- package/dist/features/layout/AutoBreadcrumbs.js +1 -1
- package/dist/features/layout/BackToTop.js +2 -2
- package/dist/features/layout/BottomActions.js +8 -8
- package/dist/features/layout/BottomNavItem.js +1 -1
- package/dist/features/layout/BottomNavLayout.js +1 -1
- package/dist/features/layout/BottomNavbar.d.ts +1 -1
- package/dist/features/layout/BottomNavbar.js +2 -2
- package/dist/features/layout/BottomSheet.js +1 -1
- package/dist/features/layout/Breadcrumbs.js +2 -2
- package/dist/features/layout/FooterLayout.js +2 -2
- package/dist/features/layout/MainNavbar.js +1 -1
- package/dist/features/layout/NavItem.js +1 -1
- package/dist/features/layout/NavbarLayout.js +3 -3
- package/dist/features/layout/SidebarLayout.js +1 -1
- package/dist/features/layout/TitleBarLayout.js +3 -3
- package/dist/features/live/components/LiveItemsIndexListing.js +1 -1
- package/dist/features/loyalty/components/CoinsDisplay.js +1 -1
- package/dist/features/loyalty/hooks/useLoyaltyBalance.js +11 -3
- package/dist/features/media/AvatarUpload.js +1 -1
- package/dist/features/media/MediaPickerModal.js +1 -1
- package/dist/features/media/components/MediaSlider.js +1 -1
- package/dist/features/media/finalize.d.ts +12 -1
- package/dist/features/media/finalize.js +64 -11
- package/dist/features/media/modals/ImageCropModal.js +1 -1
- package/dist/features/media/modals/ImageEditor.js +1 -1
- package/dist/features/media/repository/media-assets.repository.d.ts +33 -0
- package/dist/features/media/repository/media-assets.repository.js +43 -0
- package/dist/features/media/upload/MediaUploadField.js +1 -1
- package/dist/features/messages/hooks/useConversation.js +12 -17
- package/dist/features/messages/hooks/useConversations.js +3 -5
- package/dist/features/orders/components/MarketplaceOrderCard.js +1 -1
- package/dist/features/orders/components/OrdersList.js +3 -3
- package/dist/features/pre-orders/components/MarketplacePreorderCard.js +1 -1
- package/dist/features/pre-orders/components/PreOrderBadge.js +1 -1
- package/dist/features/pre-orders/components/PreOrderDetailPageView.js +2 -2
- package/dist/features/pre-orders/components/PreOrdersIndexListing.js +1 -1
- package/dist/features/pre-orders/hooks/usePreOrders.js +12 -12
- package/dist/features/products/columns/productTableColumns.js +3 -3
- package/dist/features/products/components/BidHistory.js +1 -1
- package/dist/features/products/components/CompareOverlay.js +9 -9
- package/dist/features/products/components/CustomSectionTabContent.js +1 -1
- package/dist/features/products/components/CustomSectionsEditor.js +1 -1
- package/dist/features/products/components/FeatureBadge.js +2 -2
- package/dist/features/products/components/GroupSettingsPanel.js +2 -2
- package/dist/features/products/components/PrizeDrawDetailPageView.js +2 -2
- package/dist/features/products/components/PrizeDrawsIndexListing.js +1 -1
- package/dist/features/products/components/ProductDetailPageView.js +4 -4
- package/dist/features/products/components/ProductFeatureBadges.js +2 -2
- package/dist/features/products/components/ProductFeaturesSelector.js +4 -4
- package/dist/features/products/components/ProductGalleryClient.js +1 -1
- package/dist/features/products/components/ProductGrid.js +8 -8
- package/dist/features/products/components/ProductTabs.js +1 -1
- package/dist/features/products/components/ProductTabsShell.js +1 -1
- package/dist/features/products/components/ShareButton.js +1 -1
- package/dist/features/products/components/ShowGroupSection.js +2 -2
- package/dist/features/products/components/SublistingCarouselSection.js +2 -2
- package/dist/features/promotions/components/CouponCard.js +2 -2
- package/dist/features/promotions/components/CouponsIndexListing.js +2 -2
- package/dist/features/reviews/components/ReviewDetailPageView.js +1 -1
- package/dist/features/reviews/components/ReviewDetailShell.js +5 -5
- package/dist/features/reviews/components/ReviewModal.js +1 -1
- package/dist/features/reviews/components/ReviewSummary.js +2 -2
- package/dist/features/reviews/components/ReviewsIndexListing.js +1 -1
- package/dist/features/reviews/components/ReviewsList.js +2 -2
- package/dist/features/scams/components/ScamRegistryView.js +2 -2
- package/dist/features/search/components/Search.js +11 -11
- package/dist/features/search/components/SearchFiltersRow.js +1 -1
- package/dist/features/search/components/SearchResultsSection.js +2 -2
- package/dist/features/seller/components/SellerAddressesView.js +4 -4
- package/dist/features/seller/components/SellerAnalyticsAlertsView.js +1 -1
- package/dist/features/seller/components/SellerCouponEditorView.js +1 -1
- package/dist/features/seller/components/SellerCouponsView.js +1 -1
- package/dist/features/seller/components/SellerFeaturesView.js +2 -2
- package/dist/features/seller/components/SellerGoogleReviewsView.js +1 -1
- package/dist/features/seller/components/SellerOrdersView.js +1 -1
- package/dist/features/seller/components/SellerPayoutMethodsView.js +1 -1
- package/dist/features/seller/components/SellerSidebar.js +4 -4
- package/dist/features/seller/components/analytics/SellerRevenueChart.js +1 -1
- package/dist/features/seller/components/analytics/SellerTopProducts.js +1 -1
- package/dist/features/site-settings/components/ActionPermissionsManager.js +2 -2
- package/dist/features/site-settings/components/NavPermissionsManager.js +1 -1
- package/dist/features/stores/components/InteractiveStoreCard.js +3 -3
- package/dist/features/stores/components/StoreHeader.js +2 -2
- package/dist/features/stores/components/StoreNavTabs.js +2 -2
- package/dist/features/stores/components/StorePreOrdersListing.js +1 -1
- package/dist/features/stores/components/StoreReviewsListing.js +1 -1
- package/dist/features/stores/components/StoresIndexListing.js +1 -1
- package/dist/features/whatsapp-bot/components/SellerWhatsAppSettingsView.js +2 -2
- package/dist/features/wishlist/components/WishlistPage.js +2 -2
- package/dist/features/wishlist/hooks/useWishlistCount.js +5 -13
- package/dist/http/index.d.ts +1 -0
- package/dist/http/index.js +1 -0
- package/dist/http/retry.d.ts +1 -0
- package/dist/http/retry.js +26 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +8 -0
- package/dist/next/ErrorBoundary.js +1 -1
- package/dist/repositories/index.d.ts +2 -0
- package/dist/repositories/index.js +2 -0
- package/dist/seed/site-settings-seed-data.js +476 -0
- package/dist/server.d.ts +4 -0
- package/dist/server.js +9 -0
- package/dist/styles.css +1 -1
- package/dist/tailwind-utilities.css +1 -1
- package/dist/tokens/index.d.ts +6 -6
- package/dist/tokens/index.js +59 -59
- package/dist/ui/DataTable.js +3 -3
- package/dist/ui/components/Avatar.js +1 -1
- package/dist/ui/components/BaseListingCard.js +7 -7
- package/dist/ui/components/Button.js +3 -3
- package/dist/ui/components/DetailPageGallery.js +3 -3
- package/dist/ui/components/DetailPageHero.js +1 -1
- package/dist/ui/components/DetailPageTabs.js +4 -4
- package/dist/ui/components/FilterChipGroup.js +2 -2
- package/dist/ui/components/Input.js +1 -1
- package/dist/ui/components/Layout.d.ts +2 -2
- package/dist/ui/components/ListingFilterDrawer.js +2 -2
- package/dist/ui/components/ListingToolbar.js +6 -6
- package/dist/ui/components/LoginRequiredModal.js +1 -1
- package/dist/ui/components/Modal.js +1 -1
- package/dist/ui/components/NavbarChevron.js +1 -1
- package/dist/ui/components/PageLoader.js +3 -3
- package/dist/ui/components/Radio.js +1 -1
- package/dist/ui/components/RichTextEditor.js +1 -1
- package/dist/ui/components/Select.js +1 -1
- package/dist/ui/components/SettingsSection.js +3 -3
- package/dist/ui/components/SideModal.js +1 -1
- package/dist/ui/components/Slider.js +2 -2
- package/dist/ui/components/StatsGrid.js +1 -1
- package/dist/ui/components/Typography.js +3 -3
- package/dist/ui/components/surface-tokens.d.ts +11 -11
- package/dist/ui/components/surface-tokens.js +12 -12
- package/dist/utils/safe-fire-forget.d.ts +14 -0
- package/dist/utils/safe-fire-forget.js +23 -0
- package/package.json +1 -1
|
@@ -7,5 +7,5 @@ const __P = {
|
|
|
7
7
|
// --- Section -----------------------------------------------------------------
|
|
8
8
|
export function SiteFeaturesSection({ title, subtitle, features, className = "", }) {
|
|
9
9
|
const themed = { textPrimary: THEMED_TEXT_PRIMARY, textSecondary: THEMED_TEXT_SECONDARY };
|
|
10
|
-
return (_jsx(Section, { className: `${__P.p8} ${className}`, surface: "subtle", children: _jsxs(Div, { className: "w-full", children: [_jsxs(Div, { className: "text-center mb-12", children: [_jsx(Heading, { level: 2, className: `${themed.textPrimary} mb-3`, size: "3xl", mdSize: "4xl", weight: "bold", children: title }), subtitle && (_jsx(Text, { className: `${themed.textSecondary} max-w-2xl mx-auto`, size: "base", children: subtitle }))] }), _jsx(Grid, { gap: "section", className: "grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4", children: features.map((feature) => (_jsxs("div", { className: "p-6 text-center hover:shadow-lg transition-all group rounded-2xl bg-
|
|
10
|
+
return (_jsx(Section, { className: `${__P.p8} ${className}`, surface: "subtle", children: _jsxs(Div, { className: "w-full", children: [_jsxs(Div, { className: "text-center mb-12", children: [_jsx(Heading, { level: 2, className: `${themed.textPrimary} mb-3`, size: "3xl", mdSize: "4xl", weight: "bold", children: title }), subtitle && (_jsx(Text, { className: `${themed.textSecondary} max-w-2xl mx-auto`, size: "base", children: subtitle }))] }), _jsx(Grid, { gap: "section", className: "grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4", children: features.map((feature) => (_jsxs("div", { className: "p-6 text-center hover:shadow-lg transition-all group rounded-2xl bg-[var(--appkit-color-surface)] border border-zinc-100 border-[var(--appkit-color-border-subtle)]", children: [_jsx(Div, { className: "text-[3.75rem] mb-4 group-hover:scale-110 transition-transform", children: feature.icon }), _jsx(Heading, { level: 3, className: `${themed.textPrimary} mb-2`, size: "base", weight: "bold", children: feature.title }), _jsx(Text, { className: `${themed.textSecondary}`, size: "base", children: feature.description })] }, feature.id))) })] }) }));
|
|
11
11
|
}
|
|
@@ -53,5 +53,5 @@ export function SocialPostCard({ post, showCaption = true, showStats = true }) {
|
|
|
53
53
|
return _jsx(YouTubeCard, { post: post, showCaption: showCaption });
|
|
54
54
|
}
|
|
55
55
|
const meta = PLATFORM_META[post.platform];
|
|
56
|
-
return (_jsxs("a", { href: post.permalink, target: "_blank", rel: "noopener noreferrer", className: "group relative block aspect-square overflow-hidden rounded-xl bg-
|
|
56
|
+
return (_jsxs("a", { href: post.permalink, target: "_blank", rel: "noopener noreferrer", className: "group relative block aspect-square overflow-hidden rounded-xl bg-[var(--appkit-color-surface)] focus:outline-none focus-visible:ring-2 focus-visible:ring-[var(--appkit-color-primary)] bg-[var(--appkit-color-surface-elevated)]", "aria-label": post.caption ?? `View on ${meta.label}`, children: [post.imageUrl ? (_jsx("img", { src: post.imageUrl, alt: post.caption ?? `${meta.label} post`, className: "h-full w-full object-cover transition-transform duration-300 group-hover:scale-105", loading: "lazy" })) : (_jsx(Row, { className: "h-full w-full", surface: "subtle", align: "center", justify: "center", children: _jsx(Span, { size: "sm", color: "faint", children: "No preview" }) })), post.mediaType === "video" && (_jsx(Row, { className: "pointer-events-none absolute inset-0", align: "center", justify: "center", children: _jsx(Row, { surface: "overlay-sm", className: "h-12 w-12 backdrop-blur-sm", align: "center", justify: "center", rounded: "full", children: _jsx("svg", { className: "ml-1 h-5 w-5 text-white", viewBox: "0 0 24 24", fill: "currentColor", children: _jsx("path", { d: "M8 5v14l11-7z" }) }) }) })), post.mediaType === "carousel" && (_jsx(Div, { className: "pointer-events-none absolute right-2 top-2", children: _jsx(Row, { surface: "overlay-sm", className: "h-6 w-6 backdrop-blur-sm", rounded: "default", align: "center", justify: "center", children: _jsxs("svg", { className: "h-3.5 w-3.5 text-white", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [_jsx("rect", { x: "2", y: "3", width: "15", height: "15", rx: "2" }), _jsx("path", { d: "M7 8h14M7 12h14M7 16h14" })] }) }) })), _jsxs(Row, { textWeight: "medium", textSize: "xs", className: `absolute left-2 top-2 px-[0.375rem] text-white ${meta.colorClass}`, padding: "y-2xs", align: "center", gap: "xs", rounded: "default", children: [meta.icon, _jsx(Span, { className: "hidden sm:inline", children: meta.label })] }), _jsxs(Stack, { justify: "end", surface: "overlay-xl", className: `pointer-events-none absolute inset-0 ${__P.p3} opacity-0 transition-opacity duration-200 group-hover:opacity-100`, children: [showCaption && post.caption && (_jsx(Text, { color: "inverse", className: "mb-2 line-clamp-3", size: "xs", children: post.caption })), showStats && (_jsxs(Row, { textSize: "xs", className: "text-white/80", align: "center", gap: "3", children: [post.stats.likes != null && (_jsxs(Span, { layout: "flex", gap: "xs", children: [_jsx("svg", { className: "h-3 w-3", viewBox: "0 0 24 24", fill: "currentColor", children: _jsx("path", { d: "M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z" }) }), formatCount(post.stats.likes)] })), post.stats.views != null && (_jsxs(Span, { layout: "flex", gap: "xs", children: [_jsx("svg", { className: "h-3 w-3", viewBox: "0 0 24 24", fill: "currentColor", children: _jsx("path", { d: "M12 4.5C7 4.5 2.73 7.61 1 12c1.73 4.39 6 7.5 11 7.5s9.27-3.11 11-7.5c-1.73-4.39-6-7.5-11-7.5zM12 17c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5zm0-8c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3z" }) }), formatCount(post.stats.views)] })), post.stats.comments != null && (_jsxs(Span, { layout: "flex", gap: "xs", children: [_jsx("svg", { className: "h-3 w-3", viewBox: "0 0 24 24", fill: "currentColor", children: _jsx("path", { d: "M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" }) }), formatCount(post.stats.comments)] }))] }))] })] }));
|
|
57
57
|
}
|
|
@@ -11,7 +11,7 @@ function StatCard({ stat, visible, delayClass, isLast, }) {
|
|
|
11
11
|
"transition-all duration-700",
|
|
12
12
|
delayClass,
|
|
13
13
|
visible ? "translate-y-0 opacity-100" : "translate-y-6 opacity-0",
|
|
14
|
-
!isLast ? "border-r border-
|
|
14
|
+
!isLast ? "border-r border-[var(--appkit-color-border)]" : "",
|
|
15
15
|
].join(" "), children: [stat.renderIcon && (_jsx(Row, { className: "mb-4 h-14 w-14 bg-primary-50 dark:bg-primary-950/40 border border-[var(--appkit-color-primary-100)] dark:border-[var(--appkit-color-primary-900)]/30", align: "center", justify: "center", rounded: "2xl", children: stat.renderIcon({ className: "w-7 h-7" }) })), _jsx(Heading, { level: 2, variant: "none", gradient: "brand", className: "mb-1 font-display font-black", mdSize: "5xl", size: "4xl", children: stat.value }), _jsx(Text, { variant: "none", className: "uppercase tracking-widest", color: "muted", size: "xs", weight: "medium", children: stat.label })] }));
|
|
16
16
|
}
|
|
17
17
|
// --- Sectmon -----------------------------------------------------------------
|
|
@@ -7,5 +7,5 @@ const __P = {
|
|
|
7
7
|
// --- Section -----------------------------------------------------------------
|
|
8
8
|
export function TrustIndicatorsSection({ items, className = "", }) {
|
|
9
9
|
const themed = { textPrimary: THEMED_TEXT_PRIMARY, textSecondary: THEMED_TEXT_SECONDARY };
|
|
10
|
-
return (_jsx(Section, { className: `${__P.p6} ${className}`, surface: "subtle", children: _jsx(Div, { className: "w-full", children: _jsx(Grid, { gap: "section", className: "grid-cols-2 sm:grid-cols-3 md:grid-cols-4 xl:grid-cols-4 2xl:grid-cols-4", children: items.map((indicator, index) => (_jsxs("div", { className: "text-center p-4 rounded-2xl bg-
|
|
10
|
+
return (_jsx(Section, { className: `${__P.p6} ${className}`, surface: "subtle", children: _jsx(Div, { className: "w-full", children: _jsx(Grid, { gap: "section", className: "grid-cols-2 sm:grid-cols-3 md:grid-cols-4 xl:grid-cols-4 2xl:grid-cols-4", children: items.map((indicator, index) => (_jsxs("div", { className: "text-center p-4 rounded-2xl bg-[var(--appkit-color-surface)] border border-zinc-100 border-[var(--appkit-color-border-subtle)] hover:shadow-md transition-shadow", children: [_jsx(Div, { className: "text-[2.25rem] md:text-[3rem] mb-2 md:mb-3", children: indicator.icon }), _jsx(Heading, { level: 3, className: `${themed.textPrimary} mb-1 md:mb-2`, size: "sm", weight: "semibold", children: indicator.title }), _jsx(Text, { className: `${themed.textSecondary}`, size: "xs", children: indicator.description })] }, index))) }) }) }));
|
|
11
11
|
}
|
|
@@ -4,12 +4,12 @@
|
|
|
4
4
|
* Extracted from `THEME_CONSTANTS.carousel.{arrow,dotActive,dotInactive}`
|
|
5
5
|
* so the consumer sweep can drop the THEME_CONSTANTS dependency.
|
|
6
6
|
*/
|
|
7
|
-
export declare const HERO_CAROUSEL_ARROW = "w-10 h-10 rounded-2xl bg-
|
|
8
|
-
export declare const HERO_CAROUSEL_DOT_ACTIVE = "w-8 h-2 !min-h-0 rounded-full bg-
|
|
7
|
+
export declare const HERO_CAROUSEL_ARROW = "w-10 h-10 rounded-2xl bg-[color-mix(in_srgb,var(--appkit-color-surface)_85%,transparent)] backdrop-blur-sm shadow-lg border border-[var(--appkit-color-border)] text-[var(--appkit-color-text)] hover:-translate-y-0.5 hover:bg-[var(--appkit-color-surface)] hover:shadow-xl active:scale-95 transition-all duration-200 flex items-center justify-center";
|
|
8
|
+
export declare const HERO_CAROUSEL_DOT_ACTIVE = "w-8 h-2 !min-h-0 rounded-full bg-[var(--appkit-color-surface)] shadow-sm transition-all duration-500";
|
|
9
9
|
export declare const HERO_CAROUSEL_DOT_INACTIVE = "w-2 h-2 !min-h-0 rounded-full bg-white/55 shadow-sm transition-all duration-500";
|
|
10
10
|
/** Absolute fill helper — `position: absolute; inset: 0`. */
|
|
11
11
|
export declare const POSITION_FILL = "absolute inset-0";
|
|
12
12
|
/** Flex centering helper — `flex items-center justify-center`. */
|
|
13
13
|
export declare const FLEX_CENTER = "flex items-center justify-center";
|
|
14
14
|
/** Background for hero placeholder skeleton. */
|
|
15
|
-
export declare const HERO_PLACEHOLDER_BG = "bg-
|
|
15
|
+
export declare const HERO_PLACEHOLDER_BG = "bg-[var(--appkit-color-border-subtle)]";
|
|
@@ -4,12 +4,12 @@
|
|
|
4
4
|
* Extracted from `THEME_CONSTANTS.carousel.{arrow,dotActive,dotInactive}`
|
|
5
5
|
* so the consumer sweep can drop the THEME_CONSTANTS dependency.
|
|
6
6
|
*/
|
|
7
|
-
export const HERO_CAROUSEL_ARROW = "w-10 h-10 rounded-2xl bg-
|
|
8
|
-
export const HERO_CAROUSEL_DOT_ACTIVE = "w-8 h-2 !min-h-0 rounded-full bg-
|
|
7
|
+
export const HERO_CAROUSEL_ARROW = "w-10 h-10 rounded-2xl bg-[color-mix(in_srgb,var(--appkit-color-surface)_85%,transparent)] backdrop-blur-sm shadow-lg border border-[var(--appkit-color-border)] text-[var(--appkit-color-text)] hover:-translate-y-0.5 hover:bg-[var(--appkit-color-surface)] hover:shadow-xl active:scale-95 transition-all duration-200 flex items-center justify-center";
|
|
8
|
+
export const HERO_CAROUSEL_DOT_ACTIVE = "w-8 h-2 !min-h-0 rounded-full bg-[var(--appkit-color-surface)] shadow-sm transition-all duration-500";
|
|
9
9
|
export const HERO_CAROUSEL_DOT_INACTIVE = "w-2 h-2 !min-h-0 rounded-full bg-white/55 shadow-sm transition-all duration-500";
|
|
10
10
|
/** Absolute fill helper — `position: absolute; inset: 0`. */
|
|
11
11
|
export const POSITION_FILL = "absolute inset-0";
|
|
12
12
|
/** Flex centering helper — `flex items-center justify-center`. */
|
|
13
13
|
export const FLEX_CENTER = "flex items-center justify-center";
|
|
14
14
|
/** Background for hero placeholder skeleton. */
|
|
15
|
-
export const HERO_PLACEHOLDER_BG = "bg-
|
|
15
|
+
export const HERO_PLACEHOLDER_BG = "bg-[var(--appkit-color-border-subtle)]";
|
|
@@ -15,9 +15,7 @@ export type ActiveAdRecord = {
|
|
|
15
15
|
requiresConsent?: boolean;
|
|
16
16
|
creative: ActiveAdCreative;
|
|
17
17
|
};
|
|
18
|
-
|
|
18
|
+
export declare function useActiveAd(slotId: AdSlotId): {
|
|
19
19
|
loading: boolean;
|
|
20
20
|
ad: ActiveAdRecord | null;
|
|
21
21
|
};
|
|
22
|
-
export declare function useActiveAd(slotId: AdSlotId): State;
|
|
23
|
-
export {};
|
|
@@ -1,20 +1,12 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import {
|
|
2
|
+
import { useQuery } from "@tanstack/react-query";
|
|
3
|
+
import { apiClient } from "../../../http/ApiClient";
|
|
3
4
|
export function useActiveAd(slotId) {
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
setState({ loading: false, ad: json?.data ?? null });
|
|
12
|
-
})
|
|
13
|
-
.catch(() => {
|
|
14
|
-
if (!cancelled)
|
|
15
|
-
setState({ loading: false, ad: null });
|
|
16
|
-
});
|
|
17
|
-
return () => { cancelled = true; };
|
|
18
|
-
}, [slotId]);
|
|
19
|
-
return state;
|
|
5
|
+
const { data, isPending } = useQuery({
|
|
6
|
+
queryKey: ["active-ad", slotId],
|
|
7
|
+
queryFn: () => apiClient.get(`/api/ads?slot=${encodeURIComponent(slotId)}`),
|
|
8
|
+
staleTime: 60000,
|
|
9
|
+
retry: 1,
|
|
10
|
+
});
|
|
11
|
+
return { loading: isPending, ad: data ?? null };
|
|
20
12
|
}
|
|
@@ -28,13 +28,13 @@ import { BackToTop } from "./BackToTop";
|
|
|
28
28
|
import { useDashboardNav } from "./DashboardNavContext";
|
|
29
29
|
import { usePathname } from "next/navigation";
|
|
30
30
|
import { OVERLAY_FALLBACK_COLOR, SEED_DARK_BG as DEFAULT_DARK_BG, SEED_LIGHT_BG as DEFAULT_LIGHT_BG } from "./background-seed-defaults";
|
|
31
|
-
const CLS_STAT_BOX = "flex flex-col items-center gap-1 p-2 bg-
|
|
32
|
-
const CLS_STAT_LABEL = "text-xs text-
|
|
31
|
+
const CLS_STAT_BOX = "flex flex-col items-center gap-1 p-2 bg-[var(--appkit-color-surface)] rounded-lg text-center";
|
|
32
|
+
const CLS_STAT_LABEL = "text-xs text-[var(--appkit-color-text-muted)]";
|
|
33
33
|
const CLS_LOGOUT_BTN = "flex w-full items-center gap-3 rounded-lg px-3 py-2 text-sm text-error transition-colors hover:bg-error-surface hover:text-error dark:text-error dark:hover:bg-error-surface dark:hover:text-error";
|
|
34
34
|
/** Collapsible accordion section for the public sidebar. */
|
|
35
35
|
function CollapsibleNavGroup({ title, children, }) {
|
|
36
36
|
const [open, setOpen] = useState(false);
|
|
37
|
-
return (_jsxs(Stack, { gap: "none", className: "", children: [_jsxs("button", { type: "button", onClick: () => setOpen((v) => !v), className: "flex w-full items-center justify-between px-1 py-1 text-xs font-semibold uppercase tracking-wider text-
|
|
37
|
+
return (_jsxs(Stack, { gap: "none", className: "", children: [_jsxs("button", { type: "button", onClick: () => setOpen((v) => !v), className: "flex w-full items-center justify-between px-1 py-1 text-xs font-semibold uppercase tracking-wider text-[var(--appkit-color-text-muted)] hover:text-[var(--appkit-color-text-muted)] transition-colors", children: [_jsx(Span, { children: title }), _jsx("svg", { className: `w-3.5 h-3.5 transition-transform duration-200 ${open ? "rotate-180" : ""}`, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", "aria-hidden": "true", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 9l-7 7-7-7" }) })] }), open && _jsx(Stack, { gap: "none", className: "", children: children })] }));
|
|
38
38
|
}
|
|
39
39
|
function CollapsibleSidebarSection({ section, navItemClass, }) {
|
|
40
40
|
const [open, setOpen] = useState(section.defaultOpen ?? false);
|
|
@@ -42,7 +42,7 @@ function CollapsibleSidebarSection({ section, navItemClass, }) {
|
|
|
42
42
|
if (!hasTitle) {
|
|
43
43
|
return (_jsx(Ul, { spacing: "2xs", children: section.items.map((item) => (_jsx(Li, { children: _jsxs(TextLink, { href: item.href, variant: "none", className: navItemClass, children: [item.icon && (_jsx(Span, { className: "flex-shrink-0 w-5 text-center", "aria-hidden": "true", children: item.icon })), item.label] }) }, `${item.href}-${item.label}`))) }));
|
|
44
44
|
}
|
|
45
|
-
return (_jsxs(Stack, { gap: "none", className: "", children: [_jsxs("button", { type: "button", onClick: () => setOpen((v) => !v), className: "flex w-full items-center justify-between px-1 py-1 text-xs font-semibold uppercase tracking-wider text-
|
|
45
|
+
return (_jsxs(Stack, { gap: "none", className: "", children: [_jsxs("button", { type: "button", onClick: () => setOpen((v) => !v), className: "flex w-full items-center justify-between px-1 py-1 text-xs font-semibold uppercase tracking-wider text-[var(--appkit-color-text-muted)] hover:text-[var(--appkit-color-text-muted)] transition-colors", children: [_jsx(Span, { children: section.title }), _jsx("svg", { className: `w-3.5 h-3.5 transition-transform duration-200 ${open ? "rotate-180" : ""}`, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", "aria-hidden": "true", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 9l-7 7-7-7" }) })] }), open && (_jsx(Ul, { spacing: "2xs", children: section.items.map((item) => (_jsx(Li, { children: _jsxs(TextLink, { href: item.href, variant: "none", className: navItemClass, children: [item.icon && (_jsx(Span, { className: "flex-shrink-0 w-5 text-center", "aria-hidden": "true", children: item.icon })), item.label] }) }, `${item.href}-${item.label}`))) }))] }));
|
|
46
46
|
}
|
|
47
47
|
/** Sidebar header when a user is logged in — avatar + display name + close button. */
|
|
48
48
|
function SidebarUserHeader({ user, onClose, }) {
|
|
@@ -54,13 +54,13 @@ function SidebarUserHeader({ user, onClose, }) {
|
|
|
54
54
|
}
|
|
55
55
|
: user.photoURL
|
|
56
56
|
? { url: user.photoURL, position: { x: 50, y: 50 }, zoom: 1 }
|
|
57
|
-
: null, size: "md", alt: user.displayName || "User", displayName: user.displayName, email: user.email }), user.role && !isBuyerUser(user) && (_jsx(Row, { textWeight: "bold", className: `absolute -bottom-0.5 -right-0.5 w-4 h-4 border-2 border-white text-white text-[9px] leading-none select-none ${ROLE_DOT_BG_CLASS[user.role] ?? "bg-[var(--appkit-color-text-muted)]"}`, align: "center", justify: "center", rounded: "full", title: user.role.charAt(0).toUpperCase() + user.role.slice(1), "aria-label": user.role, children: user.role.charAt(0).toUpperCase() }))] }), _jsxs(Div, { className: "flex-1 min-w-0", children: [_jsx(Text, { className: "truncate", color: "primary", size: "sm", weight: "medium", children: user.displayName || "User" }), _jsx(Text, { className: "truncate", color: "muted", size: "xs", children: user.email || "" })] })] }), _jsx("button", { type: "button", "aria-label": "Close menu", onClick: onClose, className: "flex-shrink-0 rounded-full p-2 text-
|
|
57
|
+
: null, size: "md", alt: user.displayName || "User", displayName: user.displayName, email: user.email }), user.role && !isBuyerUser(user) && (_jsx(Row, { textWeight: "bold", className: `absolute -bottom-0.5 -right-0.5 w-4 h-4 border-2 border-white text-white text-[9px] leading-none select-none ${ROLE_DOT_BG_CLASS[user.role] ?? "bg-[var(--appkit-color-text-muted)]"}`, align: "center", justify: "center", rounded: "full", title: user.role.charAt(0).toUpperCase() + user.role.slice(1), "aria-label": user.role, children: user.role.charAt(0).toUpperCase() }))] }), _jsxs(Div, { className: "flex-1 min-w-0", children: [_jsx(Text, { className: "truncate", color: "primary", size: "sm", weight: "medium", children: user.displayName || "User" }), _jsx(Text, { className: "truncate", color: "muted", size: "xs", children: user.email || "" })] })] }), _jsx("button", { type: "button", "aria-label": "Close menu", onClick: onClose, className: "flex-shrink-0 rounded-full p-2 text-[var(--appkit-color-text-muted)] hover:bg-zinc-200 hover:text-zinc-900 text-[var(--appkit-color-text-muted)] hover:bg-[var(--appkit-color-surface-elevated)] dark:hover:text-zinc-100 transition-all hover:rotate-90", 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: "M6 18L18 6M6 6l12 12" }) }) })] }));
|
|
58
58
|
}
|
|
59
59
|
/** Sidebar header when no user is logged in — title + close button. */
|
|
60
60
|
function SidebarGuestHeader({ sidebarTitle, onClose, }) {
|
|
61
|
-
return (_jsxs(Row, { align: "center", justify: "between", children: [_jsx(Div, { textWeight: "semibold", textSize: "sm", color: "primary", children: sidebarTitle }), _jsx("button", { type: "button", "aria-label": "Close menu", onClick: onClose, className: "rounded-full p-2 text-
|
|
61
|
+
return (_jsxs(Row, { align: "center", justify: "between", children: [_jsx(Div, { textWeight: "semibold", textSize: "sm", color: "primary", children: sidebarTitle }), _jsx("button", { type: "button", "aria-label": "Close menu", onClick: onClose, className: "rounded-full p-2 text-[var(--appkit-color-text-muted)] hover:bg-zinc-200 hover:text-zinc-900 text-[var(--appkit-color-text-muted)] hover:bg-[var(--appkit-color-surface-elevated)] dark:hover:text-zinc-100 transition-all hover:rotate-90", 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: "M6 18L18 6M6 6l12 12" }) }) })] }));
|
|
62
62
|
}
|
|
63
|
-
function SidebarContent({ sidebarItems, sidebarSections, sidebarPrimaryActions, user, profileHref, userOrdersHref, userWishlistHref, userSettingsHref, adminHref, storeHref, sellerHref, sidebarLocaleSlot, showThemeToggleInSidebar, sidebarProfileLabels, theme, toggleTheme, onLogout, onAfterLogout, }) {
|
|
63
|
+
function SidebarContent({ sidebarItems, sidebarSections, sidebarPrimaryActions, user, profileHref, userOrdersHref, userWishlistHref, userSettingsHref, adminHref, storeHref, sellerHref, sidebarLocaleSlot, showThemeToggleInSidebar, sidebarProfileLabels, theme, activeThemeName, toggleTheme, onLogout, onAfterLogout, }) {
|
|
64
64
|
const hasLegacyItems = sidebarItems.length > 0;
|
|
65
65
|
const hasSections = !!(sidebarSections && sidebarSections.length > 0);
|
|
66
66
|
const isAuthenticated = !!user;
|
|
@@ -78,7 +78,7 @@ function SidebarContent({ sidebarItems, sidebarSections, sidebarPrimaryActions,
|
|
|
78
78
|
storeDashboard: sidebarProfileLabels?.storeDashboard ?? sidebarProfileLabels?.sellerDashboard ?? "Store Dashboard",
|
|
79
79
|
logout: sidebarProfileLabels?.logout ?? "Logout",
|
|
80
80
|
};
|
|
81
|
-
const navItemClass = "flex items-center gap-2 rounded-lg px-3 py-2 text-sm text-zinc-700 transition-colors hover:bg-primary-50 hover:text-primary-800
|
|
81
|
+
const navItemClass = "flex items-center gap-2 rounded-lg px-3 py-2 text-sm text-zinc-700 transition-colors hover:bg-primary-50 hover:text-primary-800 text-[var(--appkit-color-text-muted)] hover:bg-[var(--appkit-color-surface-elevated)] dark:hover:text-secondary-300";
|
|
82
82
|
const normalizedSections = hasSections
|
|
83
83
|
? sidebarSections
|
|
84
84
|
: hasLegacyItems
|
|
@@ -87,9 +87,9 @@ function SidebarContent({ sidebarItems, sidebarSections, sidebarPrimaryActions,
|
|
|
87
87
|
return (_jsxs(Stack, { gap: "lg", children: [!isAuthenticated && sidebarPrimaryActions && sidebarPrimaryActions.length > 0 && (_jsx(Stack, { gap: "sm", children: sidebarPrimaryActions.map((action) => (_jsx(TextLink, { href: action.href, variant: "none", className: [
|
|
88
88
|
"block w-full rounded-lg px-3 py-2.5 text-center text-sm font-semibold transition-all duration-200 hover:scale-[1.02] shadow-sm",
|
|
89
89
|
action.variant === "outline"
|
|
90
|
-
? "border border-zinc-300 text-zinc-700 hover:bg-zinc-50
|
|
90
|
+
? "border border-zinc-300 text-zinc-700 hover:bg-zinc-50 border-[var(--appkit-color-border)] text-[var(--appkit-color-text)] hover:bg-[var(--appkit-color-surface-elevated)]"
|
|
91
91
|
: "bg-primary text-white hover:bg-primary-600 dark:bg-primary dark:hover:bg-primary-600 btn-glow",
|
|
92
|
-
].join(" "), children: action.label }, `${action.href}-${action.label}`))) })), isAuthenticated && (_jsx(CollapsibleNavGroup, { title: labels.sectionTitle, children: _jsxs(Ul, { spacing: "2xs", 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, { layout: "grid", gap: "2", className: "grid-cols-2", children: [user.stats.totalOrders != null && (_jsxs(Div, { className: CLS_STAT_BOX, children: [_jsx(Text, { className: "leading-none", color: "primary", size: "lg", weight: "bold", 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: "leading-none", color: "primary", size: "lg", weight: "bold", 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: "leading-none", color: "primary", size: "lg", weight: "bold", 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: "leading-none", color: "primary", size: "lg", weight: "bold", 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, { spacing: "2xs", 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(Stack, { border: "default", className: "border-t
|
|
92
|
+
].join(" "), children: action.label }, `${action.href}-${action.label}`))) })), isAuthenticated && (_jsx(CollapsibleNavGroup, { title: labels.sectionTitle, children: _jsxs(Ul, { spacing: "2xs", 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, { layout: "grid", gap: "2", className: "grid-cols-2", children: [user.stats.totalOrders != null && (_jsxs(Div, { className: CLS_STAT_BOX, children: [_jsx(Text, { className: "leading-none", color: "primary", size: "lg", weight: "bold", 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: "leading-none", color: "primary", size: "lg", weight: "bold", 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: "leading-none", color: "primary", size: "lg", weight: "bold", 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: "leading-none", color: "primary", size: "lg", weight: "bold", 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, { spacing: "2xs", 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(Stack, { border: "default", className: "border-t border-[var(--appkit-color-border-subtle)]", padding: "t-md", gap: "3", 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-[var(--appkit-color-text-muted)] transition-colors hover:bg-primary-50 hover:text-primary-800", children: [_jsx(Span, { "aria-hidden": "true", children: theme === "dark" ? "☀️" : "🌙" }), activeThemeName] })), isAuthenticated && onLogout && (_jsx("button", { type: "button", onClick: () => { onLogout(); onAfterLogout(); }, className: CLS_LOGOUT_BTN, children: labels.logout }))] }))] }));
|
|
93
93
|
}
|
|
94
94
|
// ─── Main component ────────────────────────────────────────────────────────────
|
|
95
95
|
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, onTourStart, contentClassName, lightBackground = DEFAULT_LIGHT_BG, darkBackground = DEFAULT_DARK_BG, }) {
|
|
@@ -103,7 +103,7 @@ export function AppLayoutShell({ children, navItems, sidebarItems = [], sidebarS
|
|
|
103
103
|
const [searchOpen, setSearchOpen] = useState(false);
|
|
104
104
|
const pathname = usePathname();
|
|
105
105
|
useEffect(() => { setSidebarOpen(false); }, [pathname]);
|
|
106
|
-
const { theme, toggleTheme } = useTheme();
|
|
106
|
+
const { theme, toggleTheme, activeTheme } = useTheme();
|
|
107
107
|
const { closeNav: closeDashboardNav, hasNav: hasDashboardNav, toggleNav: toggleDashboardNav } = useDashboardNav();
|
|
108
108
|
const { state: bottomActionsState } = useBottomActionsContext();
|
|
109
109
|
const { user: authUser } = useAuth();
|
|
@@ -133,7 +133,7 @@ export function AppLayoutShell({ children, navItems, sidebarItems = [], sidebarS
|
|
|
133
133
|
const hasBottomActions = bottomActionsState.actions.length > 0 ||
|
|
134
134
|
!!(bottomActionsState.bulk && bottomActionsState.bulk.selectedCount > 0) ||
|
|
135
135
|
!!bottomActionsState.infoLabel;
|
|
136
|
-
const sidebarContent = (_jsx(SidebarContent, { sidebarItems: sidebarItems, sidebarSections: sidebarSections, sidebarPrimaryActions: sidebarPrimaryActions, user: user, profileHref: profileHref, userOrdersHref: userOrdersHref, userWishlistHref: userWishlistHref, userSettingsHref: userSettingsHref, adminHref: adminHref, storeHref: storeHref, sellerHref: sellerHref, sidebarLocaleSlot: sidebarLocaleSlot, showThemeToggleInSidebar: showThemeToggleInSidebar, sidebarProfileLabels: sidebarProfileLabels, theme: theme, toggleTheme: toggleTheme, onLogout: onLogout, onAfterLogout: () => setSidebarOpen(false) }));
|
|
136
|
+
const sidebarContent = (_jsx(SidebarContent, { sidebarItems: sidebarItems, sidebarSections: sidebarSections, sidebarPrimaryActions: sidebarPrimaryActions, user: user, profileHref: profileHref, userOrdersHref: userOrdersHref, userWishlistHref: userWishlistHref, userSettingsHref: userSettingsHref, adminHref: adminHref, storeHref: storeHref, sellerHref: sellerHref, sidebarLocaleSlot: sidebarLocaleSlot, showThemeToggleInSidebar: showThemeToggleInSidebar, sidebarProfileLabels: sidebarProfileLabels, theme: theme, activeThemeName: activeTheme.name, toggleTheme: toggleTheme, onLogout: onLogout, onAfterLogout: () => setSidebarOpen(false) }));
|
|
137
137
|
const normalizedLightBackground = {
|
|
138
138
|
type: lightBackground.type,
|
|
139
139
|
value: lightBackground.value,
|
|
@@ -79,6 +79,6 @@ export function AutoBreadcrumbs({ pathLabels, separator = "/", className = "", r
|
|
|
79
79
|
const allCrumbs = [{ label: "Home", href: localePrefix || "/" }, ...crumbs];
|
|
80
80
|
return (_jsx(Div, { border: "default", className: "border-y /80 backdrop-blur supports-[backdrop-filter]:bg-white/90 dark:supports-[backdrop-filter]:bg-slate-950/85", surface: "default", children: _jsx(Div, { className: "container mx-auto max-w-[1920px] px-5 sm:px-6 lg:px-8", padding: "y-xs", children: _jsx(Nav, { "aria-label": "Breadcrumb", className: className, children: _jsx(Ol, { className: "flex items-center gap-2 flex-wrap", size: "sm", children: allCrumbs.map((crumb, index) => {
|
|
81
81
|
const isLast = index === allCrumbs.length - 1;
|
|
82
|
-
return (_jsxs(Li, { layout: "flex-center", gap: "2", children: [isLast ? (_jsx(Span, { "aria-current": "page", color: "primary", children: crumb.label })) : renderLink ? (renderLink(crumb.href, crumb.label)) : (_jsx(Link, { href: crumb.href, className: "text-
|
|
82
|
+
return (_jsxs(Li, { layout: "flex-center", gap: "2", children: [isLast ? (_jsx(Span, { "aria-current": "page", color: "primary", children: crumb.label })) : renderLink ? (renderLink(crumb.href, crumb.label)) : (_jsx(Link, { href: crumb.href, className: "text-[var(--appkit-color-text-muted)] hover:text-zinc-950 dark:hover:text-white transition-colors", children: crumb.label })), !isLast && (_jsx(Span, { className: "text-[var(--appkit-color-text-muted)]/90 select-none", color: "muted", "aria-hidden": "true", children: separator }))] }, crumb.href));
|
|
83
83
|
}) }) }) }) }));
|
|
84
84
|
}
|
|
@@ -17,9 +17,9 @@ export function BackToTop({ threshold = 400, ariaLabel = "Back to top", classNam
|
|
|
17
17
|
}, [threshold]);
|
|
18
18
|
if (!visible)
|
|
19
19
|
return null;
|
|
20
|
-
return (_jsx(Button, { type: "button", variant: "outline", size: "sm", "aria-label": ariaLabel, onClick: () => window.scrollTo({ top: 0, behavior: "smooth" }), className: `fixed bottom-20 right-4 z-40 flex items-center justify-center w-10 h-10 rounded-full bg-
|
|
20
|
+
return (_jsx(Button, { type: "button", variant: "outline", size: "sm", "aria-label": ariaLabel, onClick: () => window.scrollTo({ top: 0, behavior: "smooth" }), className: `fixed bottom-20 right-4 z-40 flex items-center justify-center w-10 h-10 rounded-full bg-[var(--appkit-color-surface)] border border-[var(--appkit-color-border)] shadow-md text-[var(--appkit-color-text-muted)] hover:bg-[var(--appkit-color-surface)] dark:hover:bg-slate-700 transition-colors ${className}`, children: _jsx(ChevronUp, { className: "w-5 h-5", "aria-hidden": "true" }) }));
|
|
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-[var(--appkit-z-toast)] focus:px-4 focus:py-2 focus:rounded-lg focus:bg-
|
|
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-[var(--appkit-color-surface)] 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
|
}
|
|
@@ -6,7 +6,7 @@ import { useBottomActionsContext } from "./BottomActionsContext";
|
|
|
6
6
|
import { useClickOutside } from "../../react";
|
|
7
7
|
import { Div, Row, Span, Text, Button } from "../../ui";
|
|
8
8
|
// Token values inlined from @mohasinac/appkit/tokens
|
|
9
|
-
const BOTTOM_NAV_BG = "bg-
|
|
9
|
+
const BOTTOM_NAV_BG = "bg-[color-mix(in_srgb,var(--appkit-color-bg)_90%,transparent)] backdrop-blur-md border-t border-[var(--appkit-color-border)]";
|
|
10
10
|
const Z_BOTTOM_ACTIONS = "z-40";
|
|
11
11
|
const BOTTOM_NAV_HEIGHT = "h-14";
|
|
12
12
|
const FLEX_CENTER = "flex items-center justify-center";
|
|
@@ -16,7 +16,7 @@ function BulkPickerPanel({ bulkActions, selectedActionId, pickerOpen, onSelect,
|
|
|
16
16
|
return (_jsx("div", { role: "listbox", "aria-label": "Bulk actions", className: [
|
|
17
17
|
"absolute bottom-full left-0 right-0 overflow-hidden",
|
|
18
18
|
BOTTOM_NAV_BG,
|
|
19
|
-
"border-t border-zinc-200/80
|
|
19
|
+
"border-t border-zinc-200/80 border-[var(--appkit-color-border)]/80",
|
|
20
20
|
"shadow-[0_-8px_24px_rgba(0,0,0,0.10)] dark:shadow-[0_-8px_24px_rgba(0,0,0,0.35)]",
|
|
21
21
|
"transition-[max-height,opacity] duration-200 ease-out",
|
|
22
22
|
pickerOpen ? "max-h-64 opacity-100" : "max-h-0 opacity-0 pointer-events-none",
|
|
@@ -26,11 +26,11 @@ function BulkPickerPanel({ bulkActions, selectedActionId, pickerOpen, onSelect,
|
|
|
26
26
|
const isSelected = action.id === selectedActionId;
|
|
27
27
|
return (_jsxs(Button, { role: "option", "aria-selected": isSelected, type: "button", variant: "ghost", disabled: action.disabled || action.loading, onClick: () => onSelect(action.id), className: [
|
|
28
28
|
"w-full flex items-center gap-3 px-5 py-3.5 text-left text-sm font-medium transition-colors rounded-none",
|
|
29
|
-
i > 0 ? "border-t border-zinc-100/80
|
|
30
|
-
isSelected ? "bg-zinc-50
|
|
29
|
+
i > 0 ? "border-t border-zinc-100/80 border-[var(--appkit-color-border-subtle)]" : "",
|
|
30
|
+
isSelected ? "bg-zinc-50 bg-[var(--appkit-color-surface-input)]" : "",
|
|
31
31
|
action.variant === "danger"
|
|
32
32
|
? "text-error hover:bg-error-surface"
|
|
33
|
-
: "text-
|
|
33
|
+
: "text-[var(--appkit-color-text)] hover:bg-zinc-50 hover:bg-[var(--appkit-color-surface-elevated)]/60",
|
|
34
34
|
action.disabled || action.loading ? "opacity-50 cursor-not-allowed" : "",
|
|
35
35
|
]
|
|
36
36
|
.filter(Boolean)
|
|
@@ -104,11 +104,11 @@ export default function BottomActions() {
|
|
|
104
104
|
? `${bulk.selectedCount} ${bulk.noun}`
|
|
105
105
|
: `${bulk.selectedCount} selected` })] }), bulkActions.length > 0 && (_jsxs(Button, { type: "button", variant: "ghost", onClick: () => setPickerOpen((o) => !o), "aria-haspopup": "listbox", "aria-expanded": pickerOpen, className: [
|
|
106
106
|
"flex-1 min-w-0 h-10 flex items-center gap-2 px-3 rounded-lg border text-sm font-medium transition-colors",
|
|
107
|
-
"bg-zinc-50 hover:bg-
|
|
108
|
-
"border-
|
|
107
|
+
"bg-zinc-50 hover:bg-[var(--appkit-color-surface)] active:bg-zinc-200 bg-[var(--appkit-color-surface-input)] dark:hover:bg-slate-700/60",
|
|
108
|
+
"border-[var(--appkit-color-border)]",
|
|
109
109
|
selectedAction?.variant === "danger"
|
|
110
110
|
? "text-error"
|
|
111
|
-
: "text-
|
|
111
|
+
: "text-[var(--appkit-color-text)]",
|
|
112
112
|
]
|
|
113
113
|
.filter(Boolean)
|
|
114
114
|
.join(" "), children: [selectedAction?.icon && (_jsx(Span, { className: `flex-shrink-0 w-4 h-4 ${FLEX_CENTER}`, "aria-hidden": "true", children: selectedAction.icon })), _jsx(Span, { className: "flex-1 truncate leading-none", align: "start", children: selectedAction?.label ?? "Bulk actions" }), pickerOpen ? (_jsx(ChevronDown, { className: "w-4 h-4 flex-shrink-0 text-zinc-400", "aria-hidden": "true" })) : (_jsx(ChevronUp, { className: "w-4 h-4 flex-shrink-0 text-zinc-400", "aria-hidden": "true" }))] })), bulkActions.length > 0 && (_jsx(Button, { type: "button", variant: selectedAction?.variant ?? "primary", size: "sm", isLoading: selectedAction?.loading, disabled: !selectedActionId ||
|
|
@@ -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-
|
|
26
|
+
: "text-[var(--appkit-color-text-muted)] hover:text-zinc-700 hover:text-[var(--appkit-color-text-muted)]"}${className ? ` ${className}` : ""}`, children: [_jsxs(Span, { className: "relative", children: [icon, badge != null && badge > 0 && (_jsx(Span, { layout: "flex-center", color: "inverse", "aria-label": `${badge} items`, className: "absolute -top-1.5 -right-1.5 min-w-[16px] h-4 px-1 text-[10px] bg-secondary-500 leading-none", rounded: "full", weight: "bold", children: badge > 99 ? "99+" : badge }))] }), _jsx(Span, { weight: "medium", className: "text-[10px] leading-none", children: label })] }) }));
|
|
27
27
|
}
|
|
@@ -28,5 +28,5 @@ export function BottomNavLayout({ ariaLabel, children, id = "bottom-navbar", cla
|
|
|
28
28
|
root.style.setProperty("--bottom-nav-height", "0px");
|
|
29
29
|
};
|
|
30
30
|
}, []);
|
|
31
|
-
return (_jsx(Nav, { id: id, "aria-label": ariaLabel, className: `fixed bottom-0 left-0 right-0 lg:hidden z-40 bg-
|
|
31
|
+
return (_jsx(Nav, { id: id, "aria-label": ariaLabel, className: `fixed bottom-0 left-0 right-0 lg:hidden z-40 bg-[color-mix(in_srgb,var(--appkit-color-bg)_90%,transparent)] backdrop-blur-md border-t border-[var(--appkit-color-border)] shadow-2xl pb-safe${className ? ` ${className}` : ""}`, children: _jsx(Ul, { className: "flex items-stretch h-16", children: children }) }));
|
|
32
32
|
}
|
|
@@ -50,7 +50,7 @@ export interface BottomNavbarProps {
|
|
|
50
50
|
onMoreToggle?: () => void;
|
|
51
51
|
/** CSS class applied to the active nav item. Default: "text-primary-600 dark:text-primary-400" */
|
|
52
52
|
activeClassName?: string;
|
|
53
|
-
/** CSS class applied to inactive nav items. Default: "text-
|
|
53
|
+
/** CSS class applied to inactive nav items. Default: "text-[var(--appkit-color-text-muted)] text-[var(--appkit-color-text-muted)]" */
|
|
54
54
|
inactiveClassName?: string;
|
|
55
55
|
/** CSS class applied to nav icons */
|
|
56
56
|
iconClassName?: string;
|
|
@@ -9,7 +9,7 @@ import { NavItem } from "./NavItem";
|
|
|
9
9
|
*
|
|
10
10
|
* Pass `user` from your auth context to render the profile slot with avatar.
|
|
11
11
|
*/
|
|
12
|
-
export function BottomNavbar({ user, homeHref, shopHref, cartHref, profileHref, loginHref, onSearchToggle, navItems, onMoreToggle, activeClassName = "text-primary-600 dark:text-primary-400", inactiveClassName = "text-
|
|
12
|
+
export function BottomNavbar({ user, homeHref, shopHref, cartHref, profileHref, loginHref, onSearchToggle, navItems, onMoreToggle, activeClassName = "text-primary-600 dark:text-primary-400", inactiveClassName = "text-[var(--appkit-color-text-muted)] text-[var(--appkit-color-text-muted)]", iconClassName, labelClassName = "text-[11px] leading-tight font-medium", getRoleBadgeClass, }) {
|
|
13
13
|
const pathname = usePathname();
|
|
14
14
|
const labels = {
|
|
15
15
|
mobileNav: "Mobile navigation",
|
|
@@ -27,5 +27,5 @@ export function BottomNavbar({ user, homeHref, shopHref, cartHref, profileHref,
|
|
|
27
27
|
return (_jsxs(BottomNavLayout, { ariaLabel: labels.mobileNav, children: [visibleItems.map((item) => (_jsx(Li, { className: "flex-1", children: _jsx(NavItem, { href: item.href, label: item.label, icon: item.icon ?? defaultIcon, isActive: pathname === item.href || (item.href !== "/" && pathname.startsWith(item.href + "/")), variant: "vertical", activeClassName: activeClassName, inactiveClassName: inactiveClassName, iconClassName: iconClassName, labelClassName: labelClassName }) }, item.key))), _jsx(Li, { className: "flex-1", children: _jsxs("button", { type: "button", onClick: onMoreToggle, className: `${slotClassName} ${inactiveClassName}`, "aria-label": labels.more, children: [_jsx("svg", { xmlns: "http://www.w3.org/2000/svg", className: "w-5 h-5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", "aria-hidden": "true", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 6h16M4 12h16M4 18h16" }) }), _jsx(Span, { className: labelClassName, children: labels.more })] }) })] }));
|
|
28
28
|
}
|
|
29
29
|
return (_jsxs(BottomNavLayout, { ariaLabel: labels.mobileNav, children: [_jsx(Li, { className: "flex-1 w-1/5", children: _jsx(NavItem, { href: homeHref, label: labels.home, icon: _jsx("svg", { xmlns: "http://www.w3.org/2000/svg", className: "w-5 h-5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6" }) }), isActive: pathname === homeHref, variant: "vertical", activeClassName: activeClassName, inactiveClassName: inactiveClassName, iconClassName: iconClassName, labelClassName: labelClassName }) }), _jsx(Li, { className: "flex-1", children: _jsx(NavItem, { href: shopHref, label: labels.products, icon: _jsx("svg", { xmlns: "http://www.w3.org/2000/svg", className: "w-5 h-5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M16 11V7a4 4 0 00-8 0v4M5 9h14l1 12H4L5 9z" }) }), isActive: pathname === shopHref, variant: "vertical", activeClassName: activeClassName, inactiveClassName: inactiveClassName, iconClassName: iconClassName, labelClassName: labelClassName }) }), _jsx(Li, { className: "flex-1", children: _jsxs("button", { type: "button", onClick: onSearchToggle, className: `${slotClassName} ${inactiveClassName}`, "aria-label": labels.search, children: [_jsx("svg", { xmlns: "http://www.w3.org/2000/svg", className: "h-5 w-5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" }) }), _jsx(Span, { className: labelClassName, children: labels.search })] }) }), _jsx(Li, { className: "flex-1", children: _jsxs(TextLink, { href: cartHref, variant: "none", className: `${slotClassName} ${pathname === cartHref ? activeClassName : inactiveClassName}`, "aria-label": labels.cart, children: [_jsx("svg", { xmlns: "http://www.w3.org/2000/svg", className: "h-5 w-5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M3 3h2l.4 2M7 13h10l4-8H5.4M7 13L5.4 5M7 13l-2.293 2.293c-.63.63-.184 1.707.707 1.707H17m0 0a2 2 0 100 4 2 2 0 000-4zm-8 2a2 2 0 11-4 0 2 2 0 014 0z" }) }), _jsx(Span, { className: labelClassName, children: labels.cart })] }) }), _jsx(Li, { className: "flex-1", children: user ? (_jsxs(TextLink, { href: profileHref, variant: "none", className: `${slotClassName} ${pathname === profileHref ? activeClassName : inactiveClassName}`, "aria-label": labels.profile, children: [_jsx(AvatarDisplay, { cropData: user.avatarMetadata ||
|
|
30
|
-
(user.photoURL ? { url: user.photoURL, position: { x: 50, y: 50 }, zoom: 1 } : null), size: "sm", alt: user.displayName || "User", displayName: user.displayName, email: user.email }), user.role && (_jsx(Span, { className: `text-[7px] uppercase leading-none ${getRoleBadgeClass ? getRoleBadgeClass(user.role) : "text-
|
|
30
|
+
(user.photoURL ? { url: user.photoURL, position: { x: 50, y: 50 }, zoom: 1 } : null), size: "sm", alt: user.displayName || "User", displayName: user.displayName, email: user.email }), user.role && (_jsx(Span, { className: `text-[7px] uppercase leading-none ${getRoleBadgeClass ? getRoleBadgeClass(user.role) : "text-[var(--appkit-color-text-muted)] text-[var(--appkit-color-text-muted)]"}`, weight: "semibold", children: user.role }))] })) : (_jsx(NavItem, { href: loginHref, label: labels.profile, icon: _jsx("svg", { xmlns: "http://www.w3.org/2000/svg", className: "h-5 w-5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z" }) }), isActive: pathname === loginHref, variant: "vertical", activeClassName: activeClassName, inactiveClassName: inactiveClassName, iconClassName: iconClassName, labelClassName: labelClassName })) })] }));
|
|
31
31
|
}
|
|
@@ -38,5 +38,5 @@ export function BottomSheet({ open, onClose, title, children, className, maxHeig
|
|
|
38
38
|
}, [open, handleEscape]);
|
|
39
39
|
if (!open)
|
|
40
40
|
return null;
|
|
41
|
-
return (_jsxs(Div, { className: "fixed inset-0 z-50 lg:hidden", role: "presentation", children: [_jsx(Div, { surface: "overlay-sm", className: "absolute inset-0 backdrop-blur-sm", "aria-hidden": "true", onClick: onClose }), _jsxs(Stack, { role: "dialog", "aria-modal": "true", "aria-label": title, className: `absolute bottom-0 inset-x-0 rounded-t-2xl border-t border-
|
|
41
|
+
return (_jsxs(Div, { className: "fixed inset-0 z-50 lg:hidden", role: "presentation", children: [_jsx(Div, { surface: "overlay-sm", className: "absolute inset-0 backdrop-blur-sm", "aria-hidden": "true", onClick: onClose }), _jsxs(Stack, { role: "dialog", "aria-modal": "true", "aria-label": title, className: `absolute bottom-0 inset-x-0 rounded-t-2xl border-t border-[var(--appkit-color-border-subtle)] shadow-2xl ${maxHeight} animate-slide-up${className ? ` ${className}` : ""}`, surface: "default", children: [_jsxs(Row, { border: "subtle", justify: "between", className: "border-b shrink-0", padding: "inline", children: [_jsx(Div, { surface: "skeleton", className: "absolute top-2 left-1/2 -translate-x-1/2 w-10 h-1 bg-[var(--appkit-color-border)]", rounded: "full" }), title && (_jsx(Span, { size: "sm", weight: "semibold", className: "mt-2", color: "primary", children: title })), _jsx(Button, { rounded: "lg", type: "button", onClick: onClose, "aria-label": "Close", className: "ml-auto mt-2 p-1.5 text-[var(--appkit-color-text-muted)] hover:text-zinc-700 hover:bg-[var(--appkit-color-surface)] text-[var(--appkit-color-text-muted)] hover:text-[var(--appkit-color-text-muted)] hover:bg-[var(--appkit-color-surface-elevated)] transition-colors min-h-[44px] min-w-[44px] 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 })] })] }));
|
|
42
42
|
}
|
|
@@ -15,11 +15,11 @@ import { Li, Nav, Ol, Span } from "../../ui";
|
|
|
15
15
|
*/
|
|
16
16
|
export function Breadcrumbs({ children, separator = "/", className = "", }) {
|
|
17
17
|
const items = React.Children.toArray(children);
|
|
18
|
-
return (_jsx(Nav, { "aria-label": "Breadcrumb", className: className, children: _jsx(Ol, { className: "flex items-center gap-2 flex-wrap", size: "sm", children: items.map((item, index) => (_jsxs(Li, { layout: "flex-center", gap: "2", children: [item, index < items.length - 1 && (_jsx(Span, { className: "
|
|
18
|
+
return (_jsx(Nav, { "aria-label": "Breadcrumb", className: className, children: _jsx(Ol, { className: "flex items-center gap-2 flex-wrap", size: "sm", children: items.map((item, index) => (_jsxs(Li, { layout: "flex-center", gap: "2", children: [item, index < items.length - 1 && (_jsx(Span, { className: "text-[var(--appkit-color-text-muted)]/90 select-none", color: "muted", "aria-hidden": "true", children: separator }))] }, index))) }) }));
|
|
19
19
|
}
|
|
20
20
|
export function BreadcrumbItem({ href, children, current = false, className = "", }) {
|
|
21
21
|
if (current || !href) {
|
|
22
22
|
return (_jsx(Span, { "aria-current": current ? "page" : undefined, className: `${className}`, color: "primary", children: children }));
|
|
23
23
|
}
|
|
24
|
-
return (_jsx(Link, { href: href, className: `text-
|
|
24
|
+
return (_jsx(Link, { href: href, className: `text-[var(--appkit-color-text-muted)] hover:text-zinc-950 dark:hover:text-white transition-colors ${className}`, children: children }));
|
|
25
25
|
}
|
|
@@ -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
|
|
11
|
+
return (_jsxs(BlockFooter, { id: id, className: "bg-zinc-50 bg-[var(--appkit-color-bg)] border-t border-[var(--appkit-color-border-subtle)]", children: [showTrustBar && visibleTrustItems.length > 0 && (_jsx(Div, { border: "subtle", className: "border-b", padding: "y-xl", children: _jsx(Div, { paddingX: "x-page", className: "container mx-auto 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, { textSize: "sm", gap: "sm", className: "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: "block", color: "primary", children: item.label }), item.subtitle && (_jsx(Span, { size: "xs", className: "block", color: "muted", children: item.subtitle }))] })] }) }, item.id ?? String(i)))) }) }) })), _jsxs(Div, { paddingX: "x-page", className: "container mx-auto max-w-[1920px] lg:py-14", padding: "y-2xl", children: [_jsxs(Div, { className: "grid grid-cols-1 lg:grid-cols-5 gap-10 lg:gap-16", children: [_jsxs(Stack, { className: "lg:col-span-2", gap: "md", children: [_jsx(Heading, { level: 5, size: "xl", weight: "bold", color: "primary", children: brandName }), _jsx(Text, { className: "leading-relaxed max-w-sm", color: "muted", size: "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-[var(--appkit-color-border)] text-[var(--appkit-color-text-muted)] 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, { padding: "t-xs", 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
|
-
"lg:grid-cols-5"}`, children: linkGroups.map((group, idx) => (_jsxs(Div, { children: [_jsxs(Button, { type: "button", variant: "ghost", onClick: () => toggleGroup(idx), className: "w-full justify-between border-b border-zinc-200 py-3 text-left text-sm font-semibold text-zinc-800 transition-colors hover:text-zinc-950
|
|
13
|
+
"lg:grid-cols-5"}`, children: linkGroups.map((group, idx) => (_jsxs(Div, { children: [_jsxs(Button, { type: "button", variant: "ghost", onClick: () => toggleGroup(idx), className: "w-full justify-between border-b border-zinc-200 py-3 text-left text-sm font-semibold text-zinc-800 transition-colors hover:text-zinc-950 border-[var(--appkit-color-border-subtle)] text-[var(--appkit-color-text)] 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-[var(--appkit-color-text-muted)] hover:text-primary dark:hover:text-secondary transition-colors", children: link.label }) }, link.href))) }), _jsxs(Div, { className: "hidden lg:block", children: [_jsx(Text, { className: "tracking-wider mb-3", color: "muted", size: "xs", weight: "semibold", transform: "uppercase", 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-[var(--appkit-color-text-muted)] hover:text-primary dark:hover:text-secondary transition-colors", children: link.label }) }, link.href))) })] })] }, idx))) })] }), _jsxs(Stack, { direction: "sm-row", color: "muted", textSize: "xs", justify: "between", border: "default", className: "mt-10 border-t border-[var(--appkit-color-border-subtle)] text-[var(--appkit-color-text-muted)]", padding: "t-lg", align: "center", gap: "3", children: [_jsx(Text, { size: "xs", color: "muted", 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-[var(--appkit-color-text-muted)] hover:text-primary dark:hover:text-secondary transition-colors underline-offset-2 hover:underline", children: link.label }) }, link.href))) }) })), madeInText && (_jsx(Text, { size: "xs", color: "muted", children: madeInText }))] })] })] }));
|
|
14
14
|
}
|
|
@@ -12,6 +12,6 @@ export function MainNavbar({ navItems, hiddenNavItems = [], inline = false, hasD
|
|
|
12
12
|
icon: item.icon,
|
|
13
13
|
highlighted: item.highlighted,
|
|
14
14
|
}));
|
|
15
|
-
const dashboardToggle = hasDashboardNav && onToggleDashboardNav ? (_jsx("button", { type: "button", onClick: onToggleDashboardNav, "aria-label": "Toggle dashboard navigation", className: "flex items-center justify-center w-8 h-8 rounded-lg text-
|
|
15
|
+
const dashboardToggle = hasDashboardNav && onToggleDashboardNav ? (_jsx("button", { type: "button", onClick: onToggleDashboardNav, "aria-label": "Toggle dashboard navigation", className: "flex items-center justify-center w-8 h-8 rounded-lg text-[var(--appkit-color-text-muted)] hover:bg-[var(--appkit-color-surface)] hover:bg-[var(--appkit-color-surface-elevated)] hover:text-zinc-800 dark:hover:text-zinc-100 transition-colors", children: _jsxs("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: "M3 5a2 2 0 012-2h14a2 2 0 012 2v14a2 2 0 01-2 2H5a2 2 0 01-2-2V5z" }), _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 3v18" })] }) })) : undefined;
|
|
16
16
|
return (_jsx(NavbarLayout, { items: items, activeHref: pathname, inline: inline, rightSlot: dashboardToggle }));
|
|
17
17
|
}
|
|
@@ -18,7 +18,7 @@ export function NavItem({ href, label, icon, isActive = false, variant = "horizo
|
|
|
18
18
|
}
|
|
19
19
|
if (highlighted) {
|
|
20
20
|
return (_jsxs(Link, { href: href, className: [
|
|
21
|
-
"flex items-center gap-2 px-3 py-1 rounded-full border border-primary-700/30 dark:border-primary/30 bg-primary-700/5 dark:bg-primary/5 text-
|
|
21
|
+
"flex items-center gap-2 px-3 py-1 rounded-full border border-primary-700/30 dark:border-primary/30 bg-primary-700/5 dark:bg-primary/5 text-[var(--appkit-color-text)] text-sm font-medium transition-all hover:bg-primary-700/10 dark:hover:bg-primary/10",
|
|
22
22
|
className,
|
|
23
23
|
]
|
|
24
24
|
.filter(Boolean)
|
|
@@ -11,8 +11,8 @@ function DefaultNavItem({ item, isActive, }) {
|
|
|
11
11
|
const activeClasses = item.highlighted
|
|
12
12
|
? "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"
|
|
13
13
|
: isActive
|
|
14
|
-
? "bg-primary-50
|
|
15
|
-
: "text-
|
|
14
|
+
? "bg-primary-50 bg-[var(--appkit-color-surface-elevated)] text-primary-800 dark:text-white font-semibold px-3 border-b-2 border-primary-500 dark:border-secondary-400 rounded-none pb-[6px] transition-colors duration-150"
|
|
15
|
+
: "text-[var(--appkit-color-text-muted)] hover:bg-[var(--appkit-color-surface)] hover:bg-[var(--appkit-color-surface-elevated)] hover:text-zinc-950 dark:hover:text-white transition-colors duration-150 px-3";
|
|
16
16
|
return (_jsxs(Link, { href: item.href, "aria-current": isActive ? "page" : undefined, className: `flex items-center gap-1.5 py-2 text-sm rounded-lg font-medium transition-colors duration-150 whitespace-nowrap ${activeClasses}`, children: [item.icon, _jsx(Span, { children: item.label })] }));
|
|
17
17
|
}
|
|
18
18
|
/**
|
|
@@ -51,5 +51,5 @@ export function NavbarLayout({ items, activeHref, id = "main-navbar", ariaLabel
|
|
|
51
51
|
if (inline) {
|
|
52
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))) }));
|
|
53
53
|
}
|
|
54
|
-
return (_jsx(Nav, { border: "subtle", id: id, "aria-label": ariaLabel, className: "hidden lg:block bg-white/95
|
|
54
|
+
return (_jsx(Nav, { border: "subtle", id: id, "aria-label": ariaLabel, className: "hidden lg:block bg-white/95 bg-[var(--appkit-color-bg)]/95 backdrop-blur-md border-b", children: _jsxs(Row, { className: "container mx-auto sm:px-6 lg:px-8 max-w-[1920px] h-10", padding: "x-md", align: "center", children: [_jsxs(Div, { className: `relative flex-1 ${__O.hidden}`, children: [canScrollLeft && (_jsx(NavbarChevron, { direction: "left", onClick: () => scroll("left") })), _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(NavbarChevron, { direction: "right", onClick: () => scroll("right") }))] }), rightSlot && _jsx(Div, { className: "shrink-0 ml-2", children: rightSlot })] }) }));
|
|
55
55
|
}
|
|
@@ -17,6 +17,6 @@ const __O = {
|
|
|
17
17
|
* to the rendered `aside` element.
|
|
18
18
|
*/
|
|
19
19
|
export const SidebarLayout = forwardRef(function SidebarLayout({ isOpen, ariaLabel, onClose, header, children, id = "secondary-sidebar" }, ref) {
|
|
20
|
-
return (_jsxs(_Fragment, { children: [isOpen && (_jsx(Div, { surface: "overlay-xs", className: "fixed inset-0 backdrop-blur-[2px] z-[var(--appkit-z-overlay)] transition-opacity duration-300", onClick: onClose, "aria-hidden": "true" })), _jsxs(Aside, { border: "default", ref: ref, id: id, "aria-label": ariaLabel, className: `fixed inset-y-0 right-0 w-80 bg-
|
|
20
|
+
return (_jsxs(_Fragment, { children: [isOpen && (_jsx(Div, { surface: "overlay-xs", className: "fixed inset-0 backdrop-blur-[2px] z-[var(--appkit-z-overlay)] transition-opacity duration-300", onClick: onClose, "aria-hidden": "true" })), _jsxs(Aside, { border: "default", ref: ref, id: id, "aria-label": ariaLabel, className: `fixed inset-y-0 right-0 w-80 bg-[var(--appkit-color-surface)] border-l border-[var(--appkit-color-border-subtle)] shadow-2xl transform duration-300 ease-in-out z-50 ${isOpen ? "translate-x-0" : "translate-x-full"} flex flex-col`, children: [_jsx(Div, { border: "default", className: "flex-shrink-0 py-5 border-b border-[var(--appkit-color-border-subtle)]", padding: "x-lg", surface: "muted", children: header }), _jsx(Div, { className: `flex-1 ${__O.yAuto} scrollbar-thin`, padding: "inlineLg", children: children })] })] }));
|
|
21
21
|
});
|
|
22
22
|
SidebarLayout.displayName = "SidebarLayout";
|