@mohasinac/appkit 3.2.8 → 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
|
@@ -222,7 +222,7 @@ export function PreOrdersIndexListing({ initialData, categorySlug, brandName })
|
|
|
222
222
|
setCompareIds(ids);
|
|
223
223
|
},
|
|
224
224
|
},
|
|
225
|
-
] }), totalPages > 1 && (_jsx(Row, { border: "bottom", className: "sticky top-[calc(var(--header-height,0px)+44px)] z-10 backdrop-blur-sm", surface: "default", padding: "toolbar", justify: "center", children: _jsx(Pagination, { currentPage: page, totalPages: totalPages, onPageChange: (p) => table.setPage(p) }) })), _jsx(Div, { padding: "y-lg", children: isLoading ? (_jsx(Div, { className: gridClass, children: Array.from({ length: 10 }).map((_, i) => (_jsxs(Div, { className: `${__O.hidden} animate-pulse`, border: "subtle", rounded: "xl", children: [_jsx(Div, { className: "aspect-square", surface: "subtle" }), _jsxs(Stack, { className: `${__P.p3}`, gap: "sm", children: [_jsx(Div, { className: "h-3 w-3/4", surface: "subtle", rounded: "default" }), _jsx(Div, { className: "h-3 w-1/2", surface: "subtle", rounded: "default" }), _jsx(Div, { className: "h-4 w-1/3", surface: "subtle", rounded: "default" }), _jsx(Div, { className: "h-8", surface: "subtle", rounded: "default" })] })] }, i))) })) : preOrders.length === 0 ? (_jsx(Text, { paddingY: "3xl", color: "muted", size: "sm", align: "center", children: "No pre-orders found." })) : view === "list" ? (_jsx(Stack, { className: "divide-y divide-zinc-100
|
|
225
|
+
] }), totalPages > 1 && (_jsx(Row, { border: "bottom", className: "sticky top-[calc(var(--header-height,0px)+44px)] z-10 backdrop-blur-sm", surface: "default", padding: "toolbar", justify: "center", children: _jsx(Pagination, { currentPage: page, totalPages: totalPages, onPageChange: (p) => table.setPage(p) }) })), _jsx(Div, { padding: "y-lg", children: isLoading ? (_jsx(Div, { className: gridClass, children: Array.from({ length: 10 }).map((_, i) => (_jsxs(Div, { className: `${__O.hidden} animate-pulse`, border: "subtle", rounded: "xl", children: [_jsx(Div, { className: "aspect-square", surface: "subtle" }), _jsxs(Stack, { className: `${__P.p3}`, gap: "sm", children: [_jsx(Div, { className: "h-3 w-3/4", surface: "subtle", rounded: "default" }), _jsx(Div, { className: "h-3 w-1/2", surface: "subtle", rounded: "default" }), _jsx(Div, { className: "h-4 w-1/3", surface: "subtle", rounded: "default" }), _jsx(Div, { className: "h-8", surface: "subtle", rounded: "default" })] })] }, i))) })) : preOrders.length === 0 ? (_jsx(Text, { paddingY: "3xl", color: "muted", size: "sm", align: "center", children: "No pre-orders found." })) : view === "list" ? (_jsx(Stack, { className: "divide-y divide-zinc-100 divide-[var(--appkit-color-border-subtle)]", border: "subtle", rounded: "xl", children: preOrders.map((product) => (_jsx(MarketplacePreorderCard, { product: product, variant: "list", hrefBuilder: (p) => String(ROUTES.PUBLIC.PRE_ORDER_DETAIL(p.id)), onAddToCart: handleAddToCart, wishlistActions: wishlistActions, selectable: selection.isSelecting, isSelected: selection.isSelected(product.id), onSelect: (id) => selection.toggle(id) }, product.id))) })) : (_jsx(Div, { className: gridClass, children: preOrders.map((product) => (_jsx(MarketplacePreorderCard, { product: product, variant: "grid", hrefBuilder: (p) => String(ROUTES.PUBLIC.PRE_ORDER_DETAIL(p.id)), onAddToCart: handleAddToCart, wishlistActions: wishlistActions, selectable: selection.isSelecting, isSelected: selection.isSelected(product.id), onSelect: (id) => selection.toggle(id) }, product.id))) })) }), _jsx(CompareOverlay, { isOpen: compareIds.length > 0, productIds: compareIds, productType: "preorder", onClose: () => {
|
|
226
226
|
setCompareIds([]);
|
|
227
227
|
selection.clearSelection();
|
|
228
228
|
}, onRemove: (id) => setCompareIds((ids) => ids.filter((i) => i !== id)) }), _jsx(FilterDrawer, { open: filterOpen, onOpen: openFilters, onClose: () => setFilterOpen(false), onApply: applyFilters, onReset: onFilterClear, activeCount: filterActiveCount, hideTrigger: true, children: _jsx(PreOrderFilters, { table: pendingTable, currencyPrefix: "\u20B9", categoryOptions: categoryOptions, brandOptions: brandOptions }) }), _jsx(LoginRequiredModal, { isOpen: modalOpen, onClose: closeModal, message: modalMessage })] }));
|
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
import { useQuery } from "@tanstack/react-query";
|
|
2
|
+
import { apiClient, ApiClientError } from "../../../http/ApiClient";
|
|
2
3
|
import { PREORDER_ENDPOINTS } from "../../../constants/api-endpoints";
|
|
3
4
|
export function usePreorders(opts) {
|
|
4
5
|
const endpoint = opts?.endpoint ?? PREORDER_ENDPOINTS.LIST;
|
|
5
6
|
return useQuery({
|
|
6
7
|
queryKey: ["preorders"],
|
|
7
|
-
queryFn:
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
throw new Error("Failed to fetch preorders");
|
|
11
|
-
return res.json();
|
|
12
|
-
},
|
|
8
|
+
queryFn: () => apiClient
|
|
9
|
+
.get(endpoint)
|
|
10
|
+
.then((res) => res.items ?? []),
|
|
13
11
|
staleTime: 2 * 60 * 1000,
|
|
14
12
|
});
|
|
15
13
|
}
|
|
@@ -20,12 +18,14 @@ export function usePreorder(slug, opts) {
|
|
|
20
18
|
if (!slug)
|
|
21
19
|
return null;
|
|
22
20
|
const endpoint = opts?.endpoint ?? PREORDER_ENDPOINTS.BY_SLUG(slug);
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
21
|
+
try {
|
|
22
|
+
return await apiClient.get(endpoint);
|
|
23
|
+
}
|
|
24
|
+
catch (err) {
|
|
25
|
+
if (err instanceof ApiClientError && err.status === 404)
|
|
26
|
+
return null;
|
|
27
|
+
throw err;
|
|
28
|
+
}
|
|
29
29
|
},
|
|
30
30
|
enabled: !!slug,
|
|
31
31
|
staleTime: 2 * 60 * 1000,
|
|
@@ -7,7 +7,7 @@ const __O = {
|
|
|
7
7
|
};
|
|
8
8
|
const STATUS_STYLES = {
|
|
9
9
|
published: "bg-success-surface text-success dark:bg-success-surface dark:text-success",
|
|
10
|
-
draft: "bg-
|
|
10
|
+
draft: "bg-[var(--appkit-color-surface)] text-zinc-700 bg-[var(--appkit-color-border)] text-[var(--appkit-color-text-muted)]",
|
|
11
11
|
out_of_stock: "bg-warning-surface text-warning dark:bg-warning-surface dark:text-warning",
|
|
12
12
|
discontinued: "bg-error-surface text-error dark:bg-error-surface dark:text-error",
|
|
13
13
|
sold: "bg-primary/10 dark:bg-primary/20 text-primary",
|
|
@@ -54,7 +54,7 @@ export function getProductTableColumns({ labels, onEdit, onDelete, currencyCode,
|
|
|
54
54
|
return (_jsx(Span, { className: [
|
|
55
55
|
"rounded px-2 py-1 text-xs font-medium",
|
|
56
56
|
STATUS_STYLES[status] ??
|
|
57
|
-
"bg-
|
|
57
|
+
"bg-[var(--appkit-color-surface)] text-zinc-700 bg-[var(--appkit-color-border)] text-[var(--appkit-color-text-muted)]",
|
|
58
58
|
].join(" "), children: status.replace("_", " ") }));
|
|
59
59
|
},
|
|
60
60
|
},
|
|
@@ -76,7 +76,7 @@ export function getProductTableColumns({ labels, onEdit, onDelete, currencyCode,
|
|
|
76
76
|
"rounded px-2 py-1 text-xs font-medium",
|
|
77
77
|
featured
|
|
78
78
|
? CLS_LOW_STOCK
|
|
79
|
-
: "bg-
|
|
79
|
+
: "bg-[var(--appkit-color-surface)] text-zinc-700 bg-[var(--appkit-color-border)] text-[var(--appkit-color-text-muted)]",
|
|
80
80
|
].join(" "), children: featured ? labels.yes : labels.no }));
|
|
81
81
|
},
|
|
82
82
|
},
|
|
@@ -30,5 +30,5 @@ export function BidHistory({ isLoading = false, isEmpty = false, renderList, ren
|
|
|
30
30
|
}
|
|
31
31
|
if (renderList)
|
|
32
32
|
return _jsx(Div, { className: className, children: renderList() });
|
|
33
|
-
return (_jsxs(Div, { className: className, children: [labels.title && (_jsx(Heading, { level: 3, className: "mb-3 tracking-wide", color: "muted", size: "sm", weight: "semibold", transform: "uppercase", children: labels.title })), _jsx(Stack, { gap: "sm", children: bids.map((bid, i) => renderBid ? (_jsx(React.Fragment, { children: renderBid(bid, i) }, bid.id)) : (_jsxs("div", { className: "flex items-center justify-between rounded-lg border border-
|
|
33
|
+
return (_jsxs(Div, { className: className, children: [labels.title && (_jsx(Heading, { level: 3, className: "mb-3 tracking-wide", color: "muted", size: "sm", weight: "semibold", transform: "uppercase", children: labels.title })), _jsx(Stack, { gap: "sm", children: bids.map((bid, i) => renderBid ? (_jsx(React.Fragment, { children: renderBid(bid, i) }, bid.id)) : (_jsxs("div", { className: "flex items-center justify-between rounded-lg border border-[var(--appkit-color-border-subtle)] bg-[var(--appkit-color-surface)] p-3 text-sm", "data-section": "bidhistory-div-422", children: [_jsx(Span, { weight: "bold", className: "text-primary-600 dark:text-primary-400", children: currency ? formatCurrency(bid.amount, currency) : bid.amount.toLocaleString() }), _jsx(Span, { size: "xs", color: "muted", children: formatBidDate(bid.placedAt) })] }, bid.id))) })] }));
|
|
34
34
|
}
|
|
@@ -9,7 +9,7 @@ const __O = {
|
|
|
9
9
|
hidden: "overflow-hidden",
|
|
10
10
|
};
|
|
11
11
|
const REL_NOOPENER = "noopener noreferrer";
|
|
12
|
-
const CLS_REMOVE_BTN = "shrink-0 rounded-full p-1 text-zinc-400 hover:bg-
|
|
12
|
+
const CLS_REMOVE_BTN = "shrink-0 rounded-full p-1 text-zinc-400 hover:bg-[var(--appkit-color-surface)] hover:text-error hover:bg-[var(--appkit-color-surface-elevated)]";
|
|
13
13
|
import Link from "next/link";
|
|
14
14
|
import { X } from "lucide-react";
|
|
15
15
|
import { Button, Div, Heading, Row, Span, Stack, Text } from "../../../ui";
|
|
@@ -33,11 +33,11 @@ const DEFAULT_LABELS = {
|
|
|
33
33
|
store: "Store",
|
|
34
34
|
},
|
|
35
35
|
};
|
|
36
|
-
const OVERLAY_CLASS = "fixed inset-0 flex flex-col bg-
|
|
37
|
-
const HEADER_CLASS = "flex items-center justify-between gap-3 border-b border-
|
|
38
|
-
const FIELD_LABEL_CLASS = "text-xs font-medium uppercase tracking-wider text-
|
|
39
|
-
const CHIP_CLASS = "inline-flex items-center rounded-full bg-
|
|
40
|
-
const COLUMN_CARD_CLASS = "flex flex-col gap-3 rounded-xl border border-
|
|
36
|
+
const OVERLAY_CLASS = "fixed inset-0 flex flex-col bg-[var(--appkit-color-bg)] overflow-hidden z-[var(--appkit-z-modal,60)]";
|
|
37
|
+
const HEADER_CLASS = "flex items-center justify-between gap-3 border-b border-[var(--appkit-color-border-subtle)] px-4 py-3";
|
|
38
|
+
const FIELD_LABEL_CLASS = "text-xs font-medium uppercase tracking-wider text-[var(--appkit-color-text-muted)]";
|
|
39
|
+
const CHIP_CLASS = "inline-flex items-center rounded-full bg-[var(--appkit-color-surface)] text-[var(--appkit-color-text-muted)] px-2 py-0.5 text-xs";
|
|
40
|
+
const COLUMN_CARD_CLASS = "flex flex-col gap-3 rounded-xl border border-[var(--appkit-color-border-subtle)] bg-[var(--appkit-color-surface)] p-3";
|
|
41
41
|
function detailHref(item, type) {
|
|
42
42
|
const id = item.slug ?? item.id;
|
|
43
43
|
if (type === "auction" || isAuctionListing(item)) {
|
|
@@ -59,7 +59,7 @@ function FieldRow({ label, children }) {
|
|
|
59
59
|
function CompareColumn({ item, productType, labels, onRemove, onClose }) {
|
|
60
60
|
const href = detailHref(item, productType);
|
|
61
61
|
const img = item.mainImage ?? item.images?.[0];
|
|
62
|
-
return (_jsxs(Stack, { gap: "md", className: COLUMN_CARD_CLASS, children: [_jsxs(Row, { justify: "between", align: "start", gap: "sm", children: [_jsx(Link, { href: href, target: "_blank", rel: REL_NOOPENER, className: "text-sm font-semibold text-
|
|
62
|
+
return (_jsxs(Stack, { gap: "md", className: COLUMN_CARD_CLASS, children: [_jsxs(Row, { justify: "between", align: "start", gap: "sm", children: [_jsx(Link, { href: href, target: "_blank", rel: REL_NOOPENER, className: "text-sm font-semibold text-[var(--appkit-color-text)] hover:underline line-clamp-2", children: item.title ?? item.id }), onRemove && (_jsx("button", { type: "button", onClick: () => onRemove(item.id), "aria-label": `${labels.remove} ${item.title ?? item.id}`, className: CLS_REMOVE_BTN, children: _jsx(X, { className: "h-4 w-4" }) }))] }), _jsx(FieldRow, { label: labels.field.image, children: _jsx(Link, { href: href, target: "_blank", rel: REL_NOOPENER, children: _jsx(Div, { className: `relative aspect-square ${__O.hidden}`, rounded: "lg", surface: "subtle", children: img ? (
|
|
63
63
|
// eslint-disable-next-line @next/next/no-img-element
|
|
64
64
|
_jsx("img", { src: img, alt: item.title ?? item.id, className: "h-full w-full object-cover" })) : null }) }) }), _jsx(FieldRow, { label: labels.field.price, children: _jsx(Text, { size: "base", weight: "semibold", color: "primary", children: priceLabel(item) }) }), _jsx(FieldRow, { label: labels.field.condition, children: _jsx(Text, { children: item.condition ? _jsx(Span, { className: CHIP_CLASS, children: item.condition }) : "—" }) }), _jsx(FieldRow, { label: labels.field.brand, children: _jsx(Text, { children: item.brand ? _jsx(Span, { className: CHIP_CLASS, children: item.brand }) : "—" }) }), _jsx(FieldRow, { label: labels.field.category, children: _jsx(Text, { children: (Array.isArray(item.categoryNames) ? item.categoryNames[0] : item.categoryName) || (Array.isArray(item.categorySlugs) ? item.categorySlugs[0] : item.category) ? (_jsx(Span, { className: CHIP_CLASS, children: (Array.isArray(item.categoryNames) ? item.categoryNames[0] : item.categoryName) ?? (Array.isArray(item.categorySlugs) ? item.categorySlugs[0] : item.category) })) : ("—") }) }), _jsx(FieldRow, { label: labels.field.store, children: _jsx(Text, { size: "sm", color: "muted", children: item.storeName ?? "—" }) }), _jsx(Button, { asChild: true, variant: "primary", size: "sm", className: "mt-auto", children: _jsx(Link, { href: href, target: "_blank", rel: REL_NOOPENER, onClick: onClose, children: labels.view }) })] }));
|
|
65
65
|
}
|
|
@@ -144,7 +144,7 @@ export function CompareOverlay({ isOpen, items: passedItems, productIds, product
|
|
|
144
144
|
}, [onRemove]);
|
|
145
145
|
if (!isOpen)
|
|
146
146
|
return null;
|
|
147
|
-
return (_jsxs(Div, { className: OVERLAY_CLASS, role: "dialog", "aria-modal": "true", "aria-label": labels.title, children: [_jsxs(Row, { justify: "between", align: "center", className: HEADER_CLASS, children: [_jsx(Heading, { level: 2, size: "base", weight: "semibold", children: labels.title }), _jsx("button", { type: "button", onClick: onClose, "aria-label": labels.close, className: "rounded-full p-2 text-
|
|
147
|
+
return (_jsxs(Div, { className: OVERLAY_CLASS, role: "dialog", "aria-modal": "true", "aria-label": labels.title, children: [_jsxs(Row, { justify: "between", align: "center", className: HEADER_CLASS, children: [_jsx(Heading, { level: 2, size: "base", weight: "semibold", children: labels.title }), _jsx("button", { type: "button", onClick: onClose, "aria-label": labels.close, className: "rounded-full p-2 text-[var(--appkit-color-text-muted)] hover:bg-[var(--appkit-color-surface-elevated)]", children: _jsx(X, { className: "h-5 w-5" }) })] }), _jsx(Div, { className: `flex-1 ${__O.auto} ${__P.p4}`, children: isLoading ? (_jsx(Text, { paddingY: "3xl", variant: "secondary", align: "center", children: "Loading\u00E2\u20AC\u00A6" })) : trimmed.length === 0 ? (_jsx(Text, { paddingY: "3xl", variant: "secondary", align: "center", children: labels.empty })) : (_jsxs(_Fragment, { children: [_jsx(Div, { ref: gridRef, gap: "4", className: "hidden md:grid", children: trimmed.map((item) => (_jsx(CompareColumn, { item: item, productType: productType, labels: labels, onRemove: onRemove ? handleRemove : undefined, onClose: onClose }, item.id))) }), _jsxs(Div, { className: "md:hidden", children: [_jsx(Div, { ref: swipeRef, className: "touch-pan-y", children: trimmed[activeIndex] && (_jsx(CompareColumn, { item: trimmed[activeIndex], productType: productType, labels: labels, onRemove: onRemove ? handleRemove : undefined, onClose: onClose })) }), trimmed.length > 1 && (_jsx(Row, { justify: "center", gap: "xs", className: "mt-4", children: trimmed.map((it, idx) => (_jsx("button", { type: "button", "aria-label": `Show item ${idx + 1}`, onClick: () => setActiveIndex(idx), className: `h-2 w-2 rounded-full transition-colors ${idx === activeIndex
|
|
148
148
|
? "bg-primary"
|
|
149
|
-
: "bg-
|
|
149
|
+
: "bg-[var(--appkit-color-border)]"}` }, it.id))) }))] })] })) })] }));
|
|
150
150
|
}
|
|
@@ -10,5 +10,5 @@ function renderFieldValue(f) {
|
|
|
10
10
|
export function CustomSectionTabContent({ section }) {
|
|
11
11
|
const html = section.text ? normalizeRichTextHtml(section.text) : null;
|
|
12
12
|
const fields = section.fields?.filter((f) => f.key && f.value) ?? [];
|
|
13
|
-
return (_jsxs(Stack, { gap: "md", children: [html && (_jsx(RichText, { html: html, proseClass: "prose prose-sm sm:prose max-w-none dark:prose-invert", className: "text-
|
|
13
|
+
return (_jsxs(Stack, { gap: "md", children: [html && (_jsx(RichText, { html: html, proseClass: "prose prose-sm sm:prose max-w-none dark:prose-invert", className: "text-[var(--appkit-color-text-muted)]" })), fields.length > 0 && (_jsx(Dl, { divide: "subtle", rounded: "xl", border: "subtle", className: "overflow-hidden", children: fields.map((f, i) => (_jsxs(Row, { gap: "md", oddEven: "zebra", surface: "default", padding: "inline", children: [_jsx(Dt, { weight: "medium", className: "w-36 flex-shrink-0 capitalize", color: "primary", children: f.key }), _jsx(Dd, { className: "flex-1", color: "muted", children: f.type === "url" ? (_jsx("a", { href: f.value, target: "_blank", rel: "noopener noreferrer", className: "text-primary-600 hover:underline dark:text-primary-400 break-all", children: f.value })) : (renderFieldValue(f)) })] }, i))) })), !html && fields.length === 0 && (_jsx(Text, { size: "sm", color: "faint", children: "No content in this section." }))] }));
|
|
14
14
|
}
|
|
@@ -24,5 +24,5 @@ export function CustomSectionsEditor({ sections, onChange, }) {
|
|
|
24
24
|
return;
|
|
25
25
|
onChange([...sections, emptySection()]);
|
|
26
26
|
}
|
|
27
|
-
return (_jsxs(Stack, { gap: "md", children: [sections.map((section, i) => (_jsxs(Stack, { gap: "3", surface: "muted", rounded: "xl", padding: "md", border: "default", children: [_jsxs(Row, { align: "center", justify: "between", gap: "sm", children: [_jsxs(Heading, { level: 4, size: "sm", weight: "semibold", color: "primary", children: ["Section ", i + 1] }), _jsx(Button, { type: "button", variant: "ghost", size: "sm", onClick: () => remove(i), className: CLS_REMOVE, children: "Remove" })] }), _jsxs(Div, { children: [_jsxs("label", { htmlFor: `${baseId}-title-${i}`, className: "mb-1 block text-xs font-medium text-
|
|
27
|
+
return (_jsxs(Stack, { gap: "md", children: [sections.map((section, i) => (_jsxs(Stack, { gap: "3", surface: "muted", rounded: "xl", padding: "md", border: "default", children: [_jsxs(Row, { align: "center", justify: "between", gap: "sm", children: [_jsxs(Heading, { level: 4, size: "sm", weight: "semibold", color: "primary", children: ["Section ", i + 1] }), _jsx(Button, { type: "button", variant: "ghost", size: "sm", onClick: () => remove(i), className: CLS_REMOVE, children: "Remove" })] }), _jsxs(Div, { children: [_jsxs("label", { htmlFor: `${baseId}-title-${i}`, className: "mb-1 block text-xs font-medium text-[var(--appkit-color-text-muted)]", children: ["Section title ", _jsx(Span, { className: "text-error", children: "*" })] }), _jsx(Input, { id: `${baseId}-title-${i}`, value: section.title, onChange: (e) => update(i, { title: e.target.value }), placeholder: 'e.g. "Box Contents", "Compatibility", "Grading Details"', maxLength: 80 })] }), _jsxs(Div, { children: [_jsxs("label", { htmlFor: `${baseId}-text-${i}`, className: "mb-1 block text-xs font-medium text-[var(--appkit-color-text-muted)]", children: ["Body text", " ", _jsx(Span, { weight: "normal", color: "faint", children: "(optional)" })] }), _jsx("textarea", { id: `${baseId}-text-${i}`, value: section.text ?? "", onChange: (e) => update(i, { text: e.target.value || undefined }), placeholder: "Additional details for this section\u2026", rows: 3, maxLength: 2000, 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:text-zinc-400 focus:outline-none focus:ring-2 focus:ring-primary-500 resize-y" })] }), _jsxs(Div, { children: [_jsxs(Text, { className: "mb-2", color: "muted", size: "xs", weight: "medium", children: ["Fields", " ", _jsx(Span, { weight: "normal", color: "faint", children: "(optional)" })] }), _jsx(CustomFieldsEditor, { fields: section.fields ?? [], onChange: (fields) => update(i, { fields: fields.length > 0 ? fields : undefined }), showUnit: true })] })] }, section.id))), _jsxs(Row, { align: "center", justify: "between", children: [_jsx(Button, { type: "button", variant: "ghost", size: "sm", onClick: add, disabled: sections.length >= MAX_CUSTOM_SECTIONS, className: "text-primary-600 dark:text-primary-400", children: "+ Add section" }), _jsxs(Text, { size: "xs", color: "faint", children: [sections.length, " / ", MAX_CUSTOM_SECTIONS, " sections"] })] })] }));
|
|
28
28
|
}
|
|
@@ -27,8 +27,8 @@ export const FEATURE_ICON_MAP = {
|
|
|
27
27
|
tag: Tag,
|
|
28
28
|
};
|
|
29
29
|
const ICON_SIZE_CLASS = "h-3 w-3";
|
|
30
|
-
const BADGE_BASE_CLASS = "inline-flex items-center gap-1 rounded-full border px-2 py-0.5 text-[var(--appkit-font-size-2xs,11px)] font-medium border-
|
|
31
|
-
const MORE_BADGE_CLASS = "inline-flex items-center rounded-full border border-
|
|
30
|
+
const BADGE_BASE_CLASS = "inline-flex items-center gap-1 rounded-full border px-2 py-0.5 text-[var(--appkit-font-size-2xs,11px)] font-medium border-[var(--appkit-color-border)]";
|
|
31
|
+
const MORE_BADGE_CLASS = "inline-flex items-center rounded-full border border-[var(--appkit-color-border)] px-2 py-0.5 text-[var(--appkit-font-size-2xs,11px)] font-medium text-[var(--appkit-color-text-muted)]";
|
|
32
32
|
function FeatureIcon({ icon, className = ICON_SIZE_CLASS, }) {
|
|
33
33
|
if (isFeatureIconPath(icon)) {
|
|
34
34
|
return (_jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round", className: className, "aria-hidden": "true", children: _jsx("path", { d: icon }) }));
|
|
@@ -215,9 +215,9 @@ export function GroupSettingsPanel({ productId, productSlug, groupId, isGroupPar
|
|
|
215
215
|
setOpen(next);
|
|
216
216
|
if (next && isGroupParent && children === null)
|
|
217
217
|
loadChildren();
|
|
218
|
-
}, className: "w-full flex items-center justify-between py-2 text-left group", "aria-expanded": open, children: [_jsx(Heading, { level: 3, size: "sm", weight: "semibold", color: "muted", children: "Group Settings" }), _jsx(Span, { size: "xs", className: "group-hover:text-[var(--appkit-color-text-muted)] dark:group-hover:text-[var(--appkit-color-text-faint)] transition-colors", color: "faint", children: open ? "▲" : "▼" })] }), open && (_jsxs(Stack, { gap: "sm", className: `mt-3 ${__P.p4}`, surface: "muted", rounded: "lg", border: "default", children: [!groupId && !groupParentSlug && (_jsxs(Stack, { gap: "xs", children: [_jsx(Text, { size: "xs", color: "muted", children: "Group related listings together \u2014 e.g. a set, bundle, or multi-part item. Parts can be sold individually but shown together." }), _jsx(Button, { type: "button", variant: "secondary", size: "sm", onClick: startGroup, isLoading: loading, children: "Start a group" })] })), isGroupParent && groupId && (_jsxs(Stack, { gap: "md", children: [_jsxs(Row, { align: "start", gap: "sm", wrap: true, children: [_jsx(Div, { className: "flex-1 min-w-[200px]", children: _jsx(FormField, { name: "groupTitle", label: "Group title", type: "text", value: editTitle, onChange: setEditTitle, placeholder: "e.g. Human Toy Complete Set" }) }), _jsx(Div, { padding: "t-lg", children: _jsx(Button, { type: "button", variant: "secondary", size: "sm", onClick: saveTitle, isLoading: loading, children: "Save title" }) })] }), _jsxs(Div, { children: [_jsxs(Text, { className: "mb-2", color: "muted", size: "xs", weight: "semibold", children: ["Members (", childSlugsCount + 1, " \u2014 including this listing)"] }), loading && !children ? (_jsx(Text, { size: "xs", color: "faint", children: "Loading\u2026" })) : (_jsxs(Div, { className: "divide-y divide-zinc-100
|
|
218
|
+
}, className: "w-full flex items-center justify-between py-2 text-left group", "aria-expanded": open, children: [_jsx(Heading, { level: 3, size: "sm", weight: "semibold", color: "muted", children: "Group Settings" }), _jsx(Span, { size: "xs", className: "group-hover:text-[var(--appkit-color-text-muted)] dark:group-hover:text-[var(--appkit-color-text-faint)] transition-colors", color: "faint", children: open ? "▲" : "▼" })] }), open && (_jsxs(Stack, { gap: "sm", className: `mt-3 ${__P.p4}`, surface: "muted", rounded: "lg", border: "default", children: [!groupId && !groupParentSlug && (_jsxs(Stack, { gap: "xs", children: [_jsx(Text, { size: "xs", color: "muted", children: "Group related listings together \u2014 e.g. a set, bundle, or multi-part item. Parts can be sold individually but shown together." }), _jsx(Button, { type: "button", variant: "secondary", size: "sm", onClick: startGroup, isLoading: loading, children: "Start a group" })] })), isGroupParent && groupId && (_jsxs(Stack, { gap: "md", children: [_jsxs(Row, { align: "start", gap: "sm", wrap: true, children: [_jsx(Div, { className: "flex-1 min-w-[200px]", children: _jsx(FormField, { name: "groupTitle", label: "Group title", type: "text", value: editTitle, onChange: setEditTitle, placeholder: "e.g. Human Toy Complete Set" }) }), _jsx(Div, { padding: "t-lg", children: _jsx(Button, { type: "button", variant: "secondary", size: "sm", onClick: saveTitle, isLoading: loading, children: "Save title" }) })] }), _jsxs(Div, { children: [_jsxs(Text, { className: "mb-2", color: "muted", size: "xs", weight: "semibold", children: ["Members (", childSlugsCount + 1, " \u2014 including this listing)"] }), loading && !children ? (_jsx(Text, { size: "xs", color: "faint", children: "Loading\u2026" })) : (_jsxs(Div, { className: "divide-y divide-zinc-100 divide-[var(--appkit-color-border-subtle)]", children: [_jsxs(Row, { align: "center", gap: "sm", padding: "y-xs", children: [_jsx(Span, { padding: "pill-2xs", weight: "semibold", className: "bg-[var(--appkit-color-primary)]/10 text-[var(--appkit-color-primary)] text-[10px]", rounded: "default", children: "Parent" }), _jsx(Text, { className: "flex-1", color: "primary", size: "sm", children: productSlug })] }), (children ?? []).filter((c) => c.id !== productId).map((child) => (_jsxs(Row, { align: "center", gap: "sm", padding: "y-xs", children: [child.images?.[0] ? (
|
|
219
219
|
// eslint-disable-next-line @next/next/no-img-element
|
|
220
|
-
_jsx("img", { src: child.images[0], alt: child.title, className: "w-8 h-8 rounded-full object-cover border border-
|
|
220
|
+
_jsx("img", { src: child.images[0], alt: child.title, className: "w-8 h-8 rounded-full object-cover border border-[var(--appkit-color-border)]" })) : (_jsx(Div, { className: "w-8 h-8", surface: "subtle", rounded: "full" })), _jsx(Text, { className: "flex-1 truncate", color: "primary", size: "sm", children: child.title }), _jsx(Button, { type: "button", variant: "ghost", size: "sm", onClick: () => requestUnlinkChild(child.id), isLoading: loading, className: `${CLS_DELETE_LINK} text-xs`, children: "Unlink" })] }, child.id)))] }))] }), _jsxs(Row, { gap: "sm", wrap: true, children: [_jsx(Button, { type: "button", variant: "secondary", size: "sm", onClick: () => setShowAddModal(true), children: "Add child listing" }), _jsx(Button, { type: "button", variant: "ghost", size: "sm", onClick: requestDissolveGroup, isLoading: loading, className: CLS_DELETE_LINK, children: "Dissolve group" })] })] })), !isGroupParent && groupParentSlug && (_jsxs(Stack, { gap: "xs", children: [_jsxs(Text, { size: "sm", color: "muted", children: ["Part of:", " ", _jsx(Span, { weight: "medium", color: "primary", children: groupTitle ?? groupParentSlug })] }), _jsxs(Text, { size: "xs", color: "muted", children: ["Parent listing: ", _jsx(Code, { className: "font-mono", children: groupParentSlug })] }), _jsx(Button, { type: "button", variant: "ghost", size: "sm", onClick: requestLeaveGroup, isLoading: loading, className: `${CLS_DELETE_LINK} w-fit`, children: "Leave group" })] }))] })), (groupChildSlugs?.length ?? 0) >= 4 ? (_jsx(SideDrawer, { isOpen: showAddModal, onClose: () => setShowAddModal(false), title: "Add child listing", children: _jsx(AddChildContent, { addTab: addTab, setAddTab: setAddTab, createForm: createForm, setCreateForm: setCreateForm, productSlug: productSlug, storeProductsEndpoint: storeProductsEndpoint, linkTargets: linkTargets, setLinkTargets: setLinkTargets, onAddCreate: addCreateChild, onAddLink: addLinkChild, loading: loading }) })) : (_jsx(Modal, { open: showAddModal, onClose: () => setShowAddModal(false), title: "Add child listing", size: "lg", children: _jsx(AddChildContent, { addTab: addTab, setAddTab: setAddTab, createForm: createForm, setCreateForm: setCreateForm, productSlug: productSlug, storeProductsEndpoint: storeProductsEndpoint, linkTargets: linkTargets, setLinkTargets: setLinkTargets, onAddCreate: addCreateChild, onAddLink: addLinkChild, loading: loading }) })), confirmAction && (_jsx(ConfirmDeleteModal, { isOpen: true, title: confirmAction.title, message: confirmAction.message, onConfirm: confirmAction.onConfirm, onClose: () => setConfirmAction(null), isDeleting: loading }))] }));
|
|
221
221
|
}
|
|
222
222
|
function AddChildContent({ addTab, setAddTab, createForm, setCreateForm, productSlug, storeProductsEndpoint, linkTargets, setLinkTargets, onAddCreate, onAddLink, loading, }) {
|
|
223
223
|
return (_jsx(Stack, { gap: "md", children: _jsxs(Tabs, { value: addTab, onChange: (v) => setAddTab(v), children: [_jsxs(TabsList, { children: [_jsx(TabsTrigger, { value: "create", children: "Create new child" }), _jsx(TabsTrigger, { value: "link", children: "Link existing" })] }), _jsx(TabsContent, { value: "create", children: _jsxs(Stack, { gap: "sm", className: "mt-4", children: [_jsx(FormField, { name: "childTitle", label: "Title *", type: "text", value: createForm.title, onChange: (v) => setCreateForm({ ...createForm, title: v }), placeholder: `${productSlug}-part` }), _jsx(FormField, { name: "childPrice", label: "Price (\u20B9) *", type: "number", value: createForm.price, onChange: (v) => setCreateForm({ ...createForm, price: v }), placeholder: "0" }), _jsx(Select, { label: "Condition", value: createForm.condition, onValueChange: (v) => setCreateForm({ ...createForm, condition: v }), options: CONDITION_OPTIONS }), _jsx(Text, { className: "dark:text-[var(--appkit-color-text-faint)]/80", color: "faint", size: "xs", children: "Other fields (category, brand, shipping, return policy) are inherited from this parent listing. Need more control? Edit the full listing after saving." }), _jsx(Button, { type: "button", onClick: onAddCreate, isLoading: loading, disabled: !createForm.title || !createForm.price, children: "Create and link child" })] }) }), _jsx(TabsContent, { value: "link", children: _jsxs(Stack, { gap: "sm", className: "mt-4", children: [_jsx(Text, { size: "xs", color: "muted", children: "Search your existing products or pre-orders. Auctions cannot be linked. Select multiple to bulk-link." }), _jsx(ProductInlineSelect, { scope: "store", endpoint: storeProductsEndpoint, filters: "listingType==standard", multiple: true, value: linkTargets, onChange: setLinkTargets, placeholder: "Search listings\u2026" }), _jsx(Button, { type: "button", onClick: onAddLink, isLoading: loading, disabled: linkTargets.length === 0, children: linkTargets.length > 1 ? `Link ${linkTargets.length} to group` : "Link to group" })] }) })] }) }));
|
|
@@ -40,7 +40,7 @@ function statusClass(s) {
|
|
|
40
40
|
case "open":
|
|
41
41
|
return "bg-success-surface text-success";
|
|
42
42
|
case "closed":
|
|
43
|
-
return "bg-zinc-200 text-zinc-700
|
|
43
|
+
return "bg-zinc-200 text-zinc-700 bg-[var(--appkit-color-border)] text-[var(--appkit-color-text-muted)]";
|
|
44
44
|
case "pending":
|
|
45
45
|
default:
|
|
46
46
|
return "bg-warning-surface text-warning";
|
|
@@ -118,5 +118,5 @@ export async function PrizeDrawDetailPageView({ id, initialPrizeDraw, currentUse
|
|
|
118
118
|
price: pricePerEntry,
|
|
119
119
|
storeId: typeof p.storeId === "string" ? p.storeId : undefined,
|
|
120
120
|
storeName: storeName ?? undefined,
|
|
121
|
-
} }), _jsxs(Container, { size: "xl", padding: "y-lg", children: [_jsxs(Row, { className: "mb-4", align: "center", justify: "between", gap: "sm", wrap: true, children: [_jsxs("nav", { "aria-label": "Breadcrumb", className: "flex items-center gap-1.5 text-xs text-
|
|
121
|
+
} }), _jsxs(Container, { size: "xl", padding: "y-lg", children: [_jsxs(Row, { className: "mb-4", align: "center", justify: "between", gap: "sm", wrap: true, children: [_jsxs("nav", { "aria-label": "Breadcrumb", className: "flex items-center gap-1.5 text-xs text-[var(--appkit-color-text-muted)] flex-wrap", children: [_jsx(Link, { href: String(ROUTES.HOME), className: "hover:text-primary-600 transition-colors", children: "Home" }), _jsx(Span, { "aria-hidden": true, children: "/" }), _jsx(Link, { href: String(ROUTES.PUBLIC.PRIZE_DRAWS), className: "hover:text-primary-600 transition-colors", children: "Prize Draws" }), _jsx(Span, { "aria-hidden": true, children: "/" }), _jsx(Span, { className: "truncate max-w-[200px]", color: "muted", children: title })] }), _jsx(ShareButton, { title: title })] }), _jsx(PreOrderDetailView, { renderGallery: () => (_jsx(PrizeDrawCollage, { items: items, hideWonState: true })), renderInfo: () => (_jsxs(Stack, { gap: "md", children: [_jsxs(Div, { children: [_jsxs(Row, { gap: "xs", wrap: true, className: "mb-2", children: [_jsx(Span, { size: "xs", weight: "semibold", className: CLS_PRIZE_BADGE, children: "Prize Draw" }), _jsx(Span, { size: "xs", weight: "semibold", className: `inline-block ${statusClass(revealStatus)}`, padding: "pill-sm", rounded: "full", children: statusLabel(revealStatus) }), maxPerUser !== null && (_jsxs(Span, { size: "xs", weight: "medium", className: "inline-block", padding: "pill-sm", rounded: "full", surface: "subtle", color: "muted", children: ["Limit: ", maxPerUser, " entries per customer"] })), maxPerUser !== null && userEntriesUsed !== null && (_jsxs(Span, { size: "xs", weight: "semibold", className: CLS_PRIZE_BADGE, children: ["You have used ", userEntriesUsed, "/", maxPerUser] }))] }), _jsx(Heading, { level: 1, className: "leading-snug", smSize: "2xl", color: "primary", size: "xl", weight: "bold", children: title })] }), _jsx(Div, { className: `${__P.p4}`, border: "subtle", rounded: "xl", surface: "muted", children: _jsxs(Stack, { gap: "sm", children: [_jsxs(Row, { justify: "between", align: "center", children: [_jsx(Text, { className: "text-[var(--appkit-color-text-muted)]", size: "sm", children: "Entries" }), _jsxs(Text, { size: "sm", weight: "semibold", children: [current, " / ", max, " (", remaining, " left)"] })] }), revealStart && (_jsxs(Row, { justify: "between", align: "center", children: [_jsx(Text, { className: "text-[var(--appkit-color-text-muted)]", size: "sm", children: "Reveal window opens" }), _jsx(Text, { size: "sm", weight: "medium", children: revealStart.toLocaleString() })] })), revealEnd && (_jsxs(Row, { justify: "between", align: "center", children: [_jsx(Text, { className: "text-[var(--appkit-color-text-muted)]", size: "sm", children: "Reveal window closes" }), _jsx(Text, { size: "sm", weight: "medium", children: revealEnd.toLocaleString() })] }))] }) }), descriptionHtml && (_jsx(RichText, { html: descriptionHtml, proseClass: "prose prose-sm max-w-none dark:prose-invert prose-p:my-0", className: "text-sm leading-relaxed text-[var(--appkit-color-text-muted)] line-clamp-4" })), safeSeller && (_jsx(Div, { className: `${__P.p3}`, border: "subtle", rounded: "xl", surface: "muted", children: _jsxs(Row, { justify: "between", align: "center", children: [_jsxs(Div, { children: [_jsx(Text, { className: "text-[10px] tracking-wide mb-0.5", color: "faint", transform: "uppercase", children: "Sold by" }), _jsx(Text, { size: "sm", weight: "semibold", color: "primary", children: safeSeller })] }), storeHref && (_jsx(Link, { href: storeHref, className: "shrink-0 rounded-lg bg-primary/10 dark:bg-primary/20 px-3 py-1.5 text-xs font-semibold text-primary-700 dark:text-primary-300 hover:bg-primary/20 dark:hover:bg-primary/30 transition-colors", children: "Visit Store \u2192" }))] }) }))] })), renderTabs: () => (_jsx(ProductTabsShell, { descriptionContent: descriptionHtml ? (_jsx(RichText, { html: descriptionHtml, proseClass: "prose prose-sm sm:prose max-w-none dark:prose-invert", className: "text-[var(--appkit-color-text-muted)]" })) : undefined })), renderBuyBar: () => (_jsx(Div, { padding: "5", id: "prize-draw-buy-bar", border: "subtle", surface: "muted", rounded: "xl", children: _jsx(PrizeDrawEntryActions, { productId: String(product.id), productSlug: slug, title: title, thumb: thumb, pricePerEntry: pricePerEntry, currency: currency, remainingEntries: remaining, revealStatus: revealStatus, prizeGithubFileUrl: githubUrl, storeId: typeof p.storeId === "string" ? p.storeId : undefined, storeName: storeName ?? undefined }) })) }), _jsx(PrizeDrawBottomActions, { pricePerEntry: pricePerEntry, currency: currency, closed: revealStatus === "closed" || remaining === 0 })] })] }));
|
|
122
122
|
}
|
|
@@ -86,5 +86,5 @@ export function PrizeDrawsIndexListing({ initialData, categorySlug, brandName, s
|
|
|
86
86
|
return;
|
|
87
87
|
setView(v);
|
|
88
88
|
table.set(TABLE_KEYS.VIEW, v);
|
|
89
|
-
}, onResetAll: resetAll, hasActiveState: hasActiveState, extra: _jsxs(Label, { layout: "flex", gap: "xs", className: "cursor-pointer select-none shrink-0", children: [_jsx(Span, { size: "xs", className: "hidden sm:inline whitespace-nowrap", color: "muted", children: "Show closed" }), _jsx("button", { type: "button", role: "switch", "aria-checked": showClosed, onClick: () => table.set("showClosed", showClosed ? "" : "true"), className: `relative inline-flex h-5 w-9 flex-shrink-0 items-center rounded-full transition-colors duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-1 ${showClosed ? "bg-primary" : "bg-zinc-300 dark:bg-slate-600"}`, children: _jsx(Span, { className: `inline-block h-3.5 w-3.5 transform transition-transform duration-200 ${showClosed ? "translate-x-[19px]" : "translate-x-[3px]"}`, rounded: "full", surface: "default", shadow: "sm" }) })] }) }), totalPages > 1 && (_jsx(Row, { border: "bottom", className: "sticky top-[calc(var(--header-height,0px)+44px)] z-10 backdrop-blur-sm", surface: "default", padding: "toolbar", justify: "center", children: _jsx(Pagination, { currentPage: page, totalPages: totalPages, onPageChange: (p) => table.setPage(p) }) })), _jsx(Div, { padding: "y-lg", children: isLoading ? (_jsx(Div, { className: gridClass, children: Array.from({ length: 8 }).map((_, i) => (_jsxs(Div, { className: "overflow-hidden animate-pulse", border: "subtle", rounded: "xl", children: [_jsx(Div, { className: "aspect-square", surface: "subtle" }), _jsxs(Stack, { className: `${__P.p3}`, gap: "sm", children: [_jsx(Div, { className: "h-3 w-3/4", surface: "subtle", rounded: "default" }), _jsx(Div, { className: "h-3 w-1/2", surface: "subtle", rounded: "default" }), _jsx(Div, { className: "h-8", surface: "subtle", rounded: "default" })] })] }, i))) })) : filteredDraws.length === 0 ? (_jsx(Text, { paddingY: "3xl", color: "muted", size: "sm", align: "center", children: "No prize draws found." })) : (_jsx(Div, { className: gridClass, children: filteredDraws.map((product) => (_jsx(MarketplacePrizeDrawCard, { product: product, variant: view }, product.id))) })) }), _jsx(FilterDrawer, { open: filterOpen, onOpen: openFilters, onClose: () => setFilterOpen(false), onApply: applyFilters, onReset: onFilterClear, activeCount: filterActiveCount, hideTrigger: true, children: _jsxs(Stack, { gap: "md", children: [_jsxs(_Fragment, { children: [_jsx("label", { htmlFor: "prizeRevealStatusFilter", className: "block text-xs font-semibold text-
|
|
89
|
+
}, onResetAll: resetAll, hasActiveState: hasActiveState, extra: _jsxs(Label, { layout: "flex", gap: "xs", className: "cursor-pointer select-none shrink-0", children: [_jsx(Span, { size: "xs", className: "hidden sm:inline whitespace-nowrap", color: "muted", children: "Show closed" }), _jsx("button", { type: "button", role: "switch", "aria-checked": showClosed, onClick: () => table.set("showClosed", showClosed ? "" : "true"), className: `relative inline-flex h-5 w-9 flex-shrink-0 items-center rounded-full transition-colors duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-1 ${showClosed ? "bg-primary" : "bg-zinc-300 dark:bg-slate-600"}`, children: _jsx(Span, { className: `inline-block h-3.5 w-3.5 transform transition-transform duration-200 ${showClosed ? "translate-x-[19px]" : "translate-x-[3px]"}`, rounded: "full", surface: "default", shadow: "sm" }) })] }) }), totalPages > 1 && (_jsx(Row, { border: "bottom", className: "sticky top-[calc(var(--header-height,0px)+44px)] z-10 backdrop-blur-sm", surface: "default", padding: "toolbar", justify: "center", children: _jsx(Pagination, { currentPage: page, totalPages: totalPages, onPageChange: (p) => table.setPage(p) }) })), _jsx(Div, { padding: "y-lg", children: isLoading ? (_jsx(Div, { className: gridClass, children: Array.from({ length: 8 }).map((_, i) => (_jsxs(Div, { className: "overflow-hidden animate-pulse", border: "subtle", rounded: "xl", children: [_jsx(Div, { className: "aspect-square", surface: "subtle" }), _jsxs(Stack, { className: `${__P.p3}`, gap: "sm", children: [_jsx(Div, { className: "h-3 w-3/4", surface: "subtle", rounded: "default" }), _jsx(Div, { className: "h-3 w-1/2", surface: "subtle", rounded: "default" }), _jsx(Div, { className: "h-8", surface: "subtle", rounded: "default" })] })] }, i))) })) : filteredDraws.length === 0 ? (_jsx(Text, { paddingY: "3xl", color: "muted", size: "sm", align: "center", children: "No prize draws found." })) : (_jsx(Div, { className: gridClass, children: filteredDraws.map((product) => (_jsx(MarketplacePrizeDrawCard, { product: product, variant: view }, product.id))) })) }), _jsx(FilterDrawer, { open: filterOpen, onOpen: openFilters, onClose: () => setFilterOpen(false), onApply: applyFilters, onReset: onFilterClear, activeCount: filterActiveCount, hideTrigger: true, children: _jsxs(Stack, { gap: "md", children: [_jsxs(_Fragment, { children: [_jsx("label", { htmlFor: "prizeRevealStatusFilter", className: "block text-xs font-semibold text-[var(--appkit-color-text-muted)] mb-1.5", children: "Reveal status" }), _jsxs("select", { id: "prizeRevealStatusFilter", value: pendingTable.get(TABLE_KEYS.PRIZE_REVEAL_STATUS) ?? "", onChange: (e) => pendingTable.set(TABLE_KEYS.PRIZE_REVEAL_STATUS, e.target.value), className: "w-full rounded border border-[var(--appkit-color-border)] bg-[var(--appkit-color-surface)] px-2 py-1.5 text-sm", children: [_jsx("option", { value: "", children: "Any" }), _jsx("option", { value: "pending", children: "Reveal pending" }), _jsx("option", { value: "open", children: "Reveal open" }), _jsx("option", { value: "closed", children: "Closed" })] })] }), _jsx(ProductFilters, { table: pendingTable, currencyPrefix: "\u20B9", categoryOptions: categoryOptions, brandOptions: brandOptions })] }) })] }));
|
|
90
90
|
}
|
|
@@ -9,7 +9,7 @@ const CLS_BREADCRUMB_LINK = "hover:text-primary-600 transition-colors";
|
|
|
9
9
|
const ACTION_NOT_WIRED = "Action not wired";
|
|
10
10
|
const CLS_STAR_FULL = "text-warning text-sm";
|
|
11
11
|
const CLS_STAR_HALF = "text-warning text-sm";
|
|
12
|
-
const CLS_STAR_EMPTY = "text-
|
|
12
|
+
const CLS_STAR_EMPTY = "text-[var(--appkit-color-text-faint)] text-sm";
|
|
13
13
|
const CLS_STOCK_IN = "bg-success-surface text-success dark:bg-success-surface dark:text-success";
|
|
14
14
|
const CLS_STOCK_OUT = "bg-error-surface text-error dark:bg-error-surface dark:text-error";
|
|
15
15
|
const CLS_BUNDLE_PILL = "inline-flex items-center gap-1 rounded-full border border-success bg-success-surface px-2.5 py-1 text-xs font-semibold text-success transition-colors hover:border-success hover:bg-success-surface dark:border-success/60 dark:bg-success-surface dark:text-success dark:hover:border-success dark:hover:bg-success-surface";
|
|
@@ -262,7 +262,7 @@ export async function ProductDetailPageView({ slug, initialProduct, renderOfferA
|
|
|
262
262
|
? ` — only ${effectiveStock} left`
|
|
263
263
|
: ""] })] })) : (_jsxs(Span, { layout: "inline-flex", gap: "xs", className: `w-fit .5 ${inStock ? CLS_STOCK_IN : CLS_STOCK_OUT}`, rounded: "full", padding: "pill-md", size: "xs", weight: "medium", children: [inStock ? "✓ In Stock" : "✗ Out of Stock", inStock && effectiveStock !== null && effectiveStock <= 10
|
|
264
264
|
? ` — only ${effectiveStock} left`
|
|
265
|
-
: ""] })), (categorySlugs.length > 0 || subcategory || brand) && (_jsxs(Row, { gap: "sm", wrap: true, children: [categorySlugs.map((slug, i) => (_jsx(Link, { href: String(ROUTES.PUBLIC.CATEGORY_DETAIL(slug)), className: "inline-flex items-center rounded-full border border-
|
|
265
|
+
: ""] })), (categorySlugs.length > 0 || subcategory || brand) && (_jsxs(Row, { gap: "sm", wrap: true, children: [categorySlugs.map((slug, i) => (_jsx(Link, { href: String(ROUTES.PUBLIC.CATEGORY_DETAIL(slug)), className: "inline-flex items-center rounded-full border border-[var(--appkit-color-border)] bg-[var(--appkit-color-surface)] px-2.5 py-1 text-xs font-medium text-[var(--appkit-color-text-muted)] transition-colors hover:border-primary-300 hover:bg-primary-50 hover:text-primary-700 dark:hover:border-primary-700/60 dark:hover:bg-primary-900/20 dark:hover:text-primary-400", children: categoryNames[i] ?? slug }, slug))), subcategory && (_jsx(Span, { layout: "inline-flex", size: "xs", weight: "medium", border: "subtle", rounded: "full", padding: "pill-sm-tall", surface: "muted", color: "muted", transform: "capitalize", children: subcategory })), brand && brandSlug && (_jsx(Link, { href: String(ROUTES.PUBLIC.BRAND_DETAIL(brandSlug)), className: "inline-flex items-center rounded-full border border-[var(--appkit-color-border)] bg-[var(--appkit-color-surface)] px-2.5 py-1 text-xs font-medium text-[var(--appkit-color-text-muted)] transition-colors hover:border-primary-300 hover:bg-primary-50 hover:text-primary-700 dark:hover:border-primary-700/60 dark:hover:bg-primary-900/20 dark:hover:text-primary-400", children: brand })), brand && !brandSlug && (_jsx(Span, { layout: "inline-flex", size: "xs", weight: "medium", border: "subtle", rounded: "full", padding: "pill-sm-tall", surface: "muted", color: "muted", children: brand }))] })), bundleMemberships.length > 0 && (_jsx(Row, { gap: "sm", wrap: true, children: bundleMemberships.map((b) => (_jsxs(Link, { href: String(ROUTES.PUBLIC.BUNDLE_DETAIL(b.id)), className: CLS_BUNDLE_PILL, children: [_jsx(Span, { "aria-hidden": "true", children: "\uD83D\uDCE6" }), "In bundle: ", b.title] }, b.id))) })), _jsx(ProductFeatureBadges, { featured: featured, freeShipping: freeShipping, condition: condition ?? undefined, returnable: returnPolicy != null && returnPolicy.length > 0, labels: {
|
|
266
266
|
featured: "Featured",
|
|
267
267
|
fasterDelivery: "Faster Delivery",
|
|
268
268
|
ratedSeller: "Rated Seller",
|
|
@@ -276,7 +276,7 @@ export async function ProductDetailPageView({ slug, initialProduct, renderOfferA
|
|
|
276
276
|
codAvailable: "Cash on Delivery",
|
|
277
277
|
wishlistCount: (n) => `${n} wishlisted`,
|
|
278
278
|
categoryProductCount: (n, cat) => `${n} in ${cat}`,
|
|
279
|
-
} }), productFeatures && features.length > 0 && (_jsx(FeatureBadgeList, { productFeatureIds: features, features: productFeatures })), !productFeatures && features.length > 0 && (_jsxs(Div, { border: "subtle", surface: "muted", padding: "inline", rounded: "xl", children: [_jsx(Text, { className: "mb-2 tracking-wide", color: "muted", size: "xs", weight: "semibold", transform: "uppercase", children: "About this product" }), _jsx(Ul, { spacing: "comfortable", size: "sm", color: "primary", children: features.map((f, i) => (_jsxs(Li, { layout: "flex-start", gap: "2", children: [_jsx(Span, { className: "mt-0.5 flex-shrink-0 text-primary-500", children: "\u2022" }), f] }, i))) })] })), descriptionHtml && (_jsx(RichText, { html: descriptionHtml, proseClass: "prose prose-sm max-w-none dark:prose-invert prose-p:my-0", className: "text-sm leading-relaxed text-
|
|
279
|
+
} }), productFeatures && features.length > 0 && (_jsx(FeatureBadgeList, { productFeatureIds: features, features: productFeatures })), !productFeatures && features.length > 0 && (_jsxs(Div, { border: "subtle", surface: "muted", padding: "inline", rounded: "xl", children: [_jsx(Text, { className: "mb-2 tracking-wide", color: "muted", size: "xs", weight: "semibold", transform: "uppercase", children: "About this product" }), _jsx(Ul, { spacing: "comfortable", size: "sm", color: "primary", children: features.map((f, i) => (_jsxs(Li, { layout: "flex-start", gap: "2", children: [_jsx(Span, { className: "mt-0.5 flex-shrink-0 text-primary-500", children: "\u2022" }), f] }, i))) })] })), descriptionHtml && (_jsx(RichText, { html: descriptionHtml, proseClass: "prose prose-sm max-w-none dark:prose-invert prose-p:my-0", className: "text-sm leading-relaxed text-[var(--appkit-color-text-muted)] line-clamp-4" })), safeSeller && (_jsx(Div, { className: `${__P.p3}`, border: "subtle", rounded: "xl", surface: "muted", children: _jsxs(Row, { justify: "between", align: "center", children: [_jsxs(Div, { children: [_jsx(Text, { className: "text-[10px] tracking-wide mb-0.5", color: "faint", transform: "uppercase", children: "Sold by" }), _jsx(Text, { size: "sm", weight: "semibold", color: "primary", children: safeSeller }), typeof p.storeRating === "number" && p.storeRating > 0 && (_jsx(Row, { gap: "xs", align: "center", className: "mt-0.5", children: _jsxs(Text, { size: "xs", color: "muted", children: [_jsx(Span, { className: "text-warning", "aria-hidden": "true", children: "\u2605" }), " ", p.storeRating.toFixed(1), typeof p.storeReviewCount === "number" &&
|
|
280
280
|
p.storeReviewCount > 0 &&
|
|
281
281
|
` · ${p.storeReviewCount} reviews`] }) }))] }), storeHref && (_jsx(Link, { href: storeHref, className: "shrink-0 rounded-lg bg-primary/10 dark:bg-primary/20 px-3 py-1.5 text-xs font-semibold text-primary-700 dark:text-primary-300 hover:bg-primary/20 dark:hover:bg-primary/30 transition-colors", children: "Visit Store \u2192" }))] }) }))] })), renderActions: () => (_jsxs(Stack, { className: `${__P.p5}`, border: "subtle", gap: "md", rounded: "xl", surface: "muted", children: [formattedPrice && (_jsxs(Div, { children: [_jsxs(Row, { align: "baseline", gap: "sm", wrap: true, children: [_jsx(Text, { size: "2xl", weight: "bold", color: "primary", children: formattedPrice }), formattedOriginal && discount && (_jsxs(_Fragment, { children: [_jsx(Span, { size: "sm", className: "line-through", color: "faint", children: formattedOriginal }), _jsxs(Span, { size: "xs", weight: "bold", className: CLS_DISCOUNT_BADGE, children: ["-", discount, "%"] })] }))] }), inStock && effectiveStock !== null && effectiveStock <= 10 && (_jsxs(Text, { className: "mt-1 text-warning", size: "xs", children: ["Only ", effectiveStock, " left \u2014 order soon!"] }))] })), _jsxs(Stack, { gap: "sm", children: [renderPrimaryActions ? (renderPrimaryActions({
|
|
282
282
|
productId: product.id,
|
|
@@ -302,7 +302,7 @@ export async function ProductDetailPageView({ slug, initialProduct, renderOfferA
|
|
|
302
302
|
? () => (_jsx(SublistingCarouselSection, { sublistingCategoryId: sublistingCategoryId, currentListingId: String(product.id) }))
|
|
303
303
|
: undefined, renderGroupSection: groupId
|
|
304
304
|
? () => (_jsx(ShowGroupSection, { groupId: groupId, currentSlug: String(p.slug ?? product.id), isParent: isGroupParent, groupTitle: groupTitle }))
|
|
305
|
-
: undefined, renderTabs: () => (_jsx(ProductTabsShell, { descriptionContent: descriptionHtml ? (_jsx(RichText, { html: descriptionHtml, proseClass: "prose prose-sm sm:prose max-w-none dark:prose-invert", className: "text-
|
|
305
|
+
: undefined, renderTabs: () => (_jsx(ProductTabsShell, { descriptionContent: descriptionHtml ? (_jsx(RichText, { html: descriptionHtml, proseClass: "prose prose-sm sm:prose max-w-none dark:prose-invert", className: "text-[var(--appkit-color-text-muted)]" })) : undefined, specsContent: allSpecs.length > 0 ? (_jsx(Dl, { divide: "subtle", rounded: "xl", border: "subtle", className: "overflow-hidden", children: allSpecs.map((s, i) => (_jsxs(Row, { gap: "md", oddEven: "zebra", surface: "default", padding: "inline", children: [_jsx(Dt, { className: "w-36 flex-shrink-0", color: "primary", weight: "medium", children: s.name }), _jsxs(Dd, { className: "flex-1", color: "muted", children: [s.value, s.unit ? ` ${s.unit}` : ""] })] }, i))) })) : undefined, ingredientsContent: ingredients.length > 0 ? (_jsx(Ul, { spacing: "comfortable", children: ingredients.map((item, i) => (_jsxs(Li, { layout: "flex-start", gap: "2", children: [_jsx(Span, { className: "mt-1 flex-shrink-0 h-1.5 w-1.5 bg-primary-400", rounded: "full" }), item] }, i))) })) : undefined, howToUseContent: howToUse.length > 0 ? (_jsx(Ol, { spacing: "loose", children: howToUse.map((step, i) => (_jsxs(Li, { layout: "flex-start", gap: "3", textSize: "sm", color: "muted", children: [_jsx(Span, { layout: "flex-center", size: "xs", weight: "bold", className: "flex-shrink-0 h-6 w-6 bg-primary-100 dark:bg-primary-900/30 text-primary-700 dark:text-primary-300", rounded: "full", children: i + 1 }), step] }, i))) })) : undefined, reviewsContent: _jsx(ReviewsList, { reviews: reviews, context: "listing", emptyLabel: "No reviews yet \u2014 be the first to review this product." }), customTabs: customSections.map((s) => ({
|
|
306
306
|
id: s.id,
|
|
307
307
|
label: s.title,
|
|
308
308
|
content: _jsx(CustomSectionTabContent, { section: s }),
|
|
@@ -91,9 +91,9 @@ export function ProductFeatureBadges({ featured, fasterDelivery, ratedSeller, co
|
|
|
91
91
|
key: "categoryCount",
|
|
92
92
|
icon: _jsx(Span, { size: "xs", children: "\u25A6" }),
|
|
93
93
|
label: labels.categoryProductCount(formattedCount, categoryName),
|
|
94
|
-
colorClass: "text-
|
|
94
|
+
colorClass: "text-[var(--appkit-color-text-muted)]",
|
|
95
95
|
bgClass: categoryBadgeClassName ??
|
|
96
|
-
"bg-
|
|
96
|
+
"bg-[var(--appkit-color-surface)] border-[var(--appkit-color-border)]",
|
|
97
97
|
});
|
|
98
98
|
}
|
|
99
99
|
if (badges.length === 0)
|
|
@@ -7,13 +7,13 @@ import { apiClient } from "../../../http";
|
|
|
7
7
|
import { ADMIN_ENDPOINTS } from "../../../constants/api-endpoints";
|
|
8
8
|
import { PRODUCT_FEATURE_QUERY_STALE_MS } from "../constants/product-features.constants";
|
|
9
9
|
import { MAX_FEATURES_PER_PRODUCT, } from "../schemas/product-features";
|
|
10
|
-
const SECTION_LABEL_CLASS = "text-[var(--appkit-font-size-2xs,11px)] font-semibold uppercase tracking-wide text-
|
|
10
|
+
const SECTION_LABEL_CLASS = "text-[var(--appkit-font-size-2xs,11px)] font-semibold uppercase tracking-wide text-[var(--appkit-color-text-muted)] mb-2";
|
|
11
11
|
const ROW_BASE_CLASS = "flex items-start gap-2 rounded-lg border px-3 py-2 text-xs cursor-pointer transition-colors";
|
|
12
12
|
const ROW_CHECKED_CLASS = "border-primary bg-primary/5 dark:bg-primary/10";
|
|
13
|
-
const ROW_DISABLED_CLASS = "border-
|
|
14
|
-
const ROW_DEFAULT_CLASS = "border-
|
|
13
|
+
const ROW_DISABLED_CLASS = "border-[var(--appkit-color-border)] opacity-50 cursor-not-allowed";
|
|
14
|
+
const ROW_DEFAULT_CLASS = "border-[var(--appkit-color-border)] hover:bg-zinc-50 hover:bg-[var(--appkit-color-surface-elevated)]";
|
|
15
15
|
const OVER_LIMIT_BANNER_CLASS = "rounded-lg border border-error/20 bg-error-surface px-3 py-2 text-xs text-error";
|
|
16
|
-
const EMPTY_STATE_CLASS = "rounded-lg border border-
|
|
16
|
+
const EMPTY_STATE_CLASS = "rounded-lg border border-[var(--appkit-color-border)] bg-[var(--appkit-color-surface)] px-3 py-4 text-xs text-[var(--appkit-color-text-muted)] text-center";
|
|
17
17
|
function applyProductType(list, productType) {
|
|
18
18
|
if (productType === "all")
|
|
19
19
|
return list;
|
|
@@ -20,7 +20,7 @@ export function ProductGalleryClient({ images, productName }) {
|
|
|
20
20
|
return (_jsx(Div, { className: `${__O.hidden}`, border: "subtle", rounded: "xl", surface: "muted", children: _jsx(Row, { className: "aspect-square text-[var(--appkit-color-border)] dark:text-[var(--appkit-color-border-subtle)]", align: "center", justify: "center", children: _jsx(PlaceholderSvg, {}) }) }));
|
|
21
21
|
}
|
|
22
22
|
const mainImage = images[activeIndex] ?? images[0];
|
|
23
|
-
return (_jsxs(Stack, { gap: "3", children: [_jsx("div", { className: "overflow-hidden rounded-xl border border-
|
|
23
|
+
return (_jsxs(Stack, { gap: "3", children: [_jsx("div", { className: "overflow-hidden rounded-xl border border-[var(--appkit-color-border-subtle)] cursor-zoom-in aspect-square w-full", onClick: () => setLightboxIndex(activeIndex), role: "button", tabIndex: 0, onKeyDown: (e) => {
|
|
24
24
|
if (e.key === "Enter" || e.key === " ")
|
|
25
25
|
setLightboxIndex(activeIndex);
|
|
26
26
|
}, "aria-label": `View ${productName ?? "product"} image in full screen`, children: _jsx(MediaImage, { src: mainImage, alt: productName ? `${productName} — image ${activeIndex + 1}` : `Product image ${activeIndex + 1}`, size: "gallery", className: "transition-transform duration-300 hover:scale-105" }) }), images.length > 1 && (_jsx(Div, { layout: "flex", gap: "2", className: `${__O.xAuto}`, padding: "b-2xs", children: images.map((src, i) => (_jsx("button", { type: "button", onClick: () => setActiveIndex(i), className: `flex-shrink-0 h-16 w-16 overflow-hidden rounded-lg border-2 transition-all${i === activeIndex
|
|
@@ -25,14 +25,14 @@ const CLS_BADGE_SALE = "rounded-full bg-success-surface px-2 py-0.5 text-[10px]
|
|
|
25
25
|
const CLS_BADGE_TRENDING = "rounded-full bg-indigo-600 px-2 py-0.5 text-[10px] font-bold text-white shadow-sm";
|
|
26
26
|
const CLS_BADGE_LIMITED = "rounded-full bg-info-surface px-2 py-0.5 text-[10px] font-bold text-white shadow-sm";
|
|
27
27
|
const CLS_HEART_ACTIVE = "bg-error-surface text-white hover:bg-error-surface";
|
|
28
|
-
const CLS_HEART_IDLE = "bg-white/90
|
|
28
|
+
const CLS_HEART_IDLE = "bg-white/90 bg-[var(--appkit-color-surface-elevated)]/90 text-[var(--appkit-color-text-muted)] hover:text-error hover:bg-[var(--appkit-color-surface)] hover:bg-[var(--appkit-color-surface-elevated)]";
|
|
29
29
|
const CLS_STAR = "text-[11px] text-warning";
|
|
30
30
|
const CLS_DISCOUNT_TEXT = "mt-1 text-[11px] font-semibold text-error";
|
|
31
31
|
const CLS_DISCOUNT_TEXT_BARE = "text-[10px] text-error";
|
|
32
32
|
const CLS_STAR_BARE = "text-warning";
|
|
33
33
|
const CLS_BID_TEXT = "text-[11px] text-error";
|
|
34
34
|
const CLS_HEART_ROSE_ACTIVE = "text-error";
|
|
35
|
-
const CLS_HEART_ROSE_IDLE = "text-zinc-300 dark:text-
|
|
35
|
+
const CLS_HEART_ROSE_IDLE = "text-zinc-300 dark:text-[var(--appkit-color-text-muted)] hover:text-error";
|
|
36
36
|
export function ProductCard({ product, href, onClick, onAddToWishlist, isWishlisted, onAddToCart, onBuyNow, className = "", selectionMode = false, isSelected = false, onSelect, }) {
|
|
37
37
|
const discount = product.originalPrice && product.originalPrice > product.price
|
|
38
38
|
? Math.round(((product.originalPrice - product.price) / product.originalPrice) *
|
|
@@ -57,13 +57,13 @@ export function ProductCard({ product, href, onClick, onAddToWishlist, isWishlis
|
|
|
57
57
|
? (e) => (e.key === "Enter" || e.key === " ") && onClick(product)
|
|
58
58
|
: undefined, onClick: handleCardClick, ...(!selectionMode ? longPress : {}), className: [
|
|
59
59
|
"group relative flex h-full flex-col overflow-hidden",
|
|
60
|
-
"rounded-2xl border bg-
|
|
60
|
+
"rounded-2xl border bg-[var(--appkit-color-surface)]",
|
|
61
61
|
"shadow-sm transition-all duration-200",
|
|
62
62
|
isSelected
|
|
63
63
|
? "border-primary ring-2 ring-primary/30 shadow-md"
|
|
64
64
|
: "border-zinc-200/80 hover:shadow-lg hover:border-primary/30 hover:-translate-y-0.5",
|
|
65
|
-
"
|
|
66
|
-
isSelected ? "dark:border-primary dark:ring-primary/30" : "
|
|
65
|
+
"bg-[var(--appkit-color-surface)]",
|
|
66
|
+
isSelected ? "dark:border-primary dark:ring-primary/30" : "border-[var(--appkit-color-border)]/60",
|
|
67
67
|
selectionMode || onClick || href ? "cursor-pointer" : "",
|
|
68
68
|
className,
|
|
69
69
|
]
|
|
@@ -131,11 +131,11 @@ function ProductListRow({ product, onClick, onAddToWishlist, isWishlisted, }) {
|
|
|
131
131
|
? (e) => (e.key === "Enter" || e.key === " ") && onClick(product)
|
|
132
132
|
: undefined, onClick: onClick ? () => onClick(product) : undefined, className: [
|
|
133
133
|
"flex items-center gap-3 p-2 sm:p-3",
|
|
134
|
-
"hover:bg-
|
|
134
|
+
"hover:bg-[var(--appkit-color-surface)]/60 transition-colors",
|
|
135
135
|
onClick ? "cursor-pointer" : "",
|
|
136
136
|
]
|
|
137
137
|
.filter(Boolean)
|
|
138
|
-
.join(" "), children: [_jsx(Div, { className: `flex-shrink-0 w-16 h-16 sm:w-20 sm:h-20 ${__O.hidden} bg-
|
|
138
|
+
.join(" "), children: [_jsx(Div, { className: `flex-shrink-0 w-16 h-16 sm:w-20 sm:h-20 ${__O.hidden} bg-[var(--appkit-color-surface)]`, rounded: "lg", children: product.mainImage ? (_jsx(MediaImage, { src: product.mainImage, alt: product.title, size: "thumbnail" })) : (_jsx(Div, { className: "w-full h-full bg-neutral-200" })) }), _jsxs(Stack, { className: "flex-1 min-w-0 gap-[2px]", children: [_jsx(Text, { size: "sm", weight: "medium", color: "primary", truncate: 2, children: product.title }), (product.categoryName || product.brand) && (_jsx(Span, { className: "text-[11px] truncate", color: "faint", children: [product.categoryName, product.brand].filter(Boolean).join(" · ") })), _jsxs(Row, { className: "mt-0.5", align: "center", gap: "sm", wrap: true, children: [_jsx(Span, { size: "sm", weight: "semibold", className: "text-primary", children: formatCurrency(product.price, getDefaultCurrency()) }), discount && (_jsxs(Span, { weight: "bold", className: CLS_DISCOUNT_TEXT_BARE, children: ["-", discount, "%"] })), product.rating !== undefined && (_jsxs(Span, { layout: "flex", gap: "2xs", className: "text-[11px]", color: "faint", children: [_jsx(Span, { className: CLS_STAR_BARE, children: "\u2605" }), product.rating.toFixed(1)] })), (() => {
|
|
139
139
|
const stock = product.stockCount ?? product.stockQuantity ?? product.availableQuantity;
|
|
140
140
|
if (stock === undefined)
|
|
141
141
|
return null;
|
|
@@ -188,7 +188,7 @@ export function ProductGrid({ products, renderCard, onProductClick, getProductHr
|
|
|
188
188
|
}
|
|
189
189
|
const renderItems = () => {
|
|
190
190
|
if (view === "list") {
|
|
191
|
-
return (_jsx(Stack, { className: `divide-y divide-zinc-100
|
|
191
|
+
return (_jsx(Stack, { className: `divide-y divide-zinc-100 divide-[var(--appkit-color-border-subtle)] ${className}`, border: "subtle", rounded: "xl", children: products.map((p) => (_jsx(ProductListRow, { product: p, onClick: onProductClick, onAddToWishlist: onWishlistToggle, isWishlisted: wishlistedIds?.has(p.id) ?? false }, p.id))) }));
|
|
192
192
|
}
|
|
193
193
|
if (view === "fluid") {
|
|
194
194
|
return (_jsx(Grid, { cols: "productCardsCompact", className: className, children: products.map((p, i) => {
|
|
@@ -21,5 +21,5 @@ export function ProductTabs({ renderDescription, renderSpecs, renderReviews, ext
|
|
|
21
21
|
const tabs = allTabs.length > 0 ? allTabs : DEFAULT_TABS;
|
|
22
22
|
return (_jsxs(Div, { className: className, children: [renderTabBar ? (renderTabBar(activeTab, setActiveTab, tabs)) : (_jsx(Row, { gap: "md", className: "border-b mb-4", children: tabs.map((t) => (_jsx("button", { onClick: () => setActiveTab(t.value), className: `pb-2 text-sm font-medium border-b-2 transition-colors ${activeTab === t.value
|
|
23
23
|
? "border-current text-current"
|
|
24
|
-
: "border-transparent text-
|
|
24
|
+
: "border-transparent text-[var(--appkit-color-text-muted)]"}`, children: t.label }, t.value))) })), activeTab === "description" && renderDescription?.(), activeTab === "specs" && renderSpecs?.(), activeTab === "reviews" && renderReviews?.(), renderExtraTab?.(activeTab)] }));
|
|
25
25
|
}
|
|
@@ -41,5 +41,5 @@ export function ProductTabsShell({ descriptionContent, specsContent, gradingCont
|
|
|
41
41
|
const activeContent = allTabs.find((t) => t.id === activeId)?.content;
|
|
42
42
|
return (_jsxs(Div, { className: `mt-8 ${className}`, children: [_jsx(Div, { layout: "flex", gap: "1", border: "default", className: `mb-6 ${__O.xAuto} border-b pb-px`, children: allTabs.map((t) => (_jsx("button", { type: "button", onClick: () => setActiveId(t.id), className: `flex-shrink-0 -mb-px pb-3 px-4 text-sm font-medium border-b-2 transition-colors ${activeId === t.id
|
|
43
43
|
? "border-[var(--appkit-color-primary)] text-[var(--appkit-color-primary)]"
|
|
44
|
-
: "border-transparent text-
|
|
44
|
+
: "border-transparent text-[var(--appkit-color-text-muted)] hover:text-[var(--appkit-color-text-muted)]"}`, children: t.label }, t.id))) }), _jsx("div", { children: activeContent })] }));
|
|
45
45
|
}
|
|
@@ -18,5 +18,5 @@ export function ShareButton({ title, text, className = "" }) {
|
|
|
18
18
|
setCopied(true);
|
|
19
19
|
setTimeout(() => setCopied(false), 2000);
|
|
20
20
|
};
|
|
21
|
-
return (_jsxs("button", { type: "button", onClick: handleShare, className: `inline-flex items-center gap-1.5 rounded-lg border border-
|
|
21
|
+
return (_jsxs("button", { type: "button", onClick: handleShare, className: `inline-flex items-center gap-1.5 rounded-lg border border-[var(--appkit-color-border)] px-3 py-1.5 text-sm font-medium text-[var(--appkit-color-text-muted)] hover:bg-[var(--appkit-color-surface)] transition-colors ${className}`, "aria-label": "Share this page", children: ["\uD83D\uDD17 ", copied ? "Link Copied!" : "Share"] }));
|
|
22
22
|
}
|
|
@@ -23,7 +23,7 @@ function MemberThumb({ member, isCurrent }) {
|
|
|
23
23
|
const price = formatCurrency(member.price, member.currency ?? "INR");
|
|
24
24
|
return (_jsxs(Link, { href: href, "aria-label": member.title, className: "flex flex-col items-center gap-1.5 flex-shrink-0 w-16 group", children: [_jsxs("div", { className: `relative w-14 h-14 rounded-full overflow-hidden border-2 transition-all ${isCurrent
|
|
25
25
|
? "border-[var(--appkit-color-primary)] ring-2 ring-[var(--appkit-color-primary)]/30"
|
|
26
|
-
: "border-
|
|
26
|
+
: "border-[var(--appkit-color-border)] group-hover:border-[var(--appkit-color-primary)]"}`, children: [_jsx(MediaImage, { src: image, alt: member.title, size: "card" }), member.isGroupParent && (_jsx(Span, { color: "inverse", rounded: "sm", className: "absolute bottom-0 right-0 bg-[var(--appkit-color-primary)] text-[8px] leading-none px-[0.25rem] py-[0.125rem]", children: "Set" }))] }), _jsx(Text, { className: "text-[10px] leading-tight line-clamp-2 w-full", color: "muted", align: "center", children: member.title }), _jsx(Text, { className: "text-[10px]", color: "primary", weight: "semibold", children: price })] }));
|
|
27
27
|
}
|
|
28
28
|
function GroupTableRow({ member }) {
|
|
29
29
|
const href = memberHref(member);
|
|
@@ -52,7 +52,7 @@ export function ShowGroupSection({ groupId, currentSlug, isParent, groupTitle })
|
|
|
52
52
|
const parentLabel = isParent ? `Parts in this group: ${label}` : `Part of: ${label}`;
|
|
53
53
|
const useDrawer = members.length >= 5;
|
|
54
54
|
const tableContent = (_jsx(Div, { className: `${__O.xAuto}`, children: _jsxs(Table, { className: "text-left min-w-[400px]", children: [_jsx(Thead, { children: _jsxs(Tr, { border: "default", children: [_jsx(Th, { paddingY: "sm", paddingSide: "pr-sm", color: "muted", size: "xs", weight: "semibold", children: "Image" }), _jsx(Th, { paddingY: "sm", paddingSide: "pr-sm", color: "muted", size: "xs", weight: "semibold", children: "Name" }), _jsx(Th, { paddingY: "sm", paddingSide: "pr-sm", color: "muted", size: "xs", weight: "semibold", children: "Price" }), _jsx(Th, { paddingY: "sm", paddingSide: "pr-sm", color: "muted", size: "xs", weight: "semibold", children: "Condition" }), _jsx(Th, { paddingY: "sm", paddingSide: "pb-sm", color: "muted", size: "xs", weight: "semibold" })] }) }), _jsx(Tbody, { children: members.map((m) => _jsx(GroupTableRow, { member: m }, m.id)) })] }) }));
|
|
55
|
-
return (_jsxs(_Fragment, { children: [_jsxs(Div, { className: `${__O.hidden}`, surface: "muted", rounded: "xl", border: "default", children: [_jsxs("button", { type: "button", onClick: () => setOpen((v) => !v), className: "w-full flex items-center justify-between px-4 py-3 text-left hover:bg-
|
|
55
|
+
return (_jsxs(_Fragment, { children: [_jsxs(Div, { className: `${__O.hidden}`, surface: "muted", rounded: "xl", border: "default", children: [_jsxs("button", { type: "button", onClick: () => setOpen((v) => !v), className: "w-full flex items-center justify-between px-4 py-3 text-left hover:bg-[var(--appkit-color-surface)]/70 hover:bg-[var(--appkit-color-surface-elevated)]/70 transition-colors", "aria-expanded": open, children: [_jsxs(Row, { align: "center", gap: "xs", children: [_jsx(Span, { size: "xs", className: "mr-1", color: "faint", children: open ? "â–¼" : "â–¶" }), _jsx(Text, { size: "sm", weight: "medium", color: "primary", children: parentLabel }), _jsx(Span, { size: "xs", className: "ml-1", rounded: "full", padding: "pill-xs", surface: "subtle", color: "muted", children: members.length })] }), _jsx(Button, { type: "button", variant: "ghost", size: "sm", onClick: (e) => { e.stopPropagation(); setShowAll(true); }, className: "text-xs text-[var(--appkit-color-primary)] hover:underline ml-3 flex-shrink-0", children: "View whole group \u00E2\u2020\u2019" })] }), open && (_jsx(Div, { className: `pb-[1rem] pt-[0.25rem] ${__O.xAuto}`, padding: "x-md", children: _jsx(Row, { gap: "3", className: "min-w-0", children: [...members]
|
|
56
56
|
.sort((a, b) => (b.isGroupParent ? 1 : 0) - (a.isGroupParent ? 1 : 0))
|
|
57
57
|
.map((m) => (_jsx(MemberThumb, { member: m, isCurrent: m.slug === currentSlug || m.id === currentSlug }, m.id))) }) }))] }), useDrawer ? (_jsx(SideDrawer, { isOpen: showAll, onClose: () => setShowAll(false), title: label, children: tableContent })) : (_jsx(Modal, { open: showAll, onClose: () => setShowAll(false), title: label, children: tableContent }))] }));
|
|
58
58
|
}
|