@mohasinac/appkit 3.9.0 → 4.0.0
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/shared/actions/action-registry.js +8 -0
- package/dist/client.d.ts +2 -2
- package/dist/client.js +1 -4
- package/dist/constants/api-endpoints.d.ts +3 -0
- package/dist/constants/api-endpoints.js +1 -0
- package/dist/features/account/hooks/useDataViewMode.d.ts +17 -0
- package/dist/features/account/hooks/useDataViewMode.js +55 -0
- package/dist/features/account/hooks/useProfile.d.ts +2 -0
- package/dist/features/admin/components/AdminBundlesView.d.ts +3 -4
- package/dist/features/admin/components/AdminBundlesView.js +2 -2
- package/dist/features/admin/components/AdminCarouselView.js +1 -1
- package/dist/features/admin/components/AdminCategoriesView.d.ts +2 -6
- package/dist/features/admin/components/AdminCategoriesView.js +1 -1
- package/dist/features/admin/components/AdminFaqsView.d.ts +0 -2
- package/dist/features/admin/components/AdminPrizeDrawsView.js +1 -1
- package/dist/features/admin/components/AdminSectionsView.js +4 -4
- package/dist/features/admin/components/DataListingView.d.ts +8 -2
- package/dist/features/admin/components/DataListingView.js +7 -3
- package/dist/features/admin/components/DataTable.d.ts +10 -2
- package/dist/features/admin/components/DataTable.js +4 -2
- package/dist/features/admin/components/sections/adminSectionsBuildParse.js +13 -5
- package/dist/features/admin/components/sections/adminSectionsTypes.d.ts +4 -0
- package/dist/features/admin/components/sections/adminSectionsTypes.js +9 -5
- package/dist/features/admin/hooks/useAdminListing.d.ts +2 -2
- package/dist/features/admin/hooks/useAdminListing.js +6 -1
- package/dist/features/categories/components/BrandDetailTabs.js +2 -12
- package/dist/features/categories/components/CategoryDetailTabs.js +2 -12
- package/dist/features/events/components/AdminEventsView.d.ts +1 -5
- package/dist/features/faq/components/FAQAccordion.js +3 -2
- package/dist/features/faq/components/RelatedFAQs.js +1 -1
- package/dist/features/homepage/components/BrandsSection.d.ts +4 -1
- package/dist/features/homepage/components/BrandsSection.js +2 -2
- package/dist/features/homepage/components/CustomCardsSection.js +3 -3
- package/dist/features/homepage/components/CustomerReviewsSection.d.ts +4 -1
- package/dist/features/homepage/components/CustomerReviewsSection.js +2 -2
- package/dist/features/homepage/components/EventsSection.d.ts +4 -1
- package/dist/features/homepage/components/EventsSection.js +2 -2
- package/dist/features/homepage/components/FAQSection.js +3 -3
- package/dist/features/homepage/components/FeaturedAuctionsSection.d.ts +2 -1
- package/dist/features/homepage/components/FeaturedAuctionsSection.js +2 -2
- package/dist/features/homepage/components/FeaturedPreOrdersSection.d.ts +2 -1
- package/dist/features/homepage/components/FeaturedPreOrdersSection.js +2 -2
- package/dist/features/homepage/components/FeaturedProductsSection.d.ts +2 -1
- package/dist/features/homepage/components/FeaturedProductsSection.js +2 -2
- package/dist/features/homepage/components/FeaturedStoresSection.d.ts +4 -1
- package/dist/features/homepage/components/FeaturedStoresSection.js +2 -2
- package/dist/features/homepage/components/HomepageCustomerReviewsSection.d.ts +4 -1
- package/dist/features/homepage/components/HomepageCustomerReviewsSection.js +2 -2
- package/dist/features/homepage/components/SectionCarousel.d.ts +3 -1
- package/dist/features/homepage/components/SectionCarousel.js +2 -2
- package/dist/features/homepage/components/ShopByCategorySection.d.ts +4 -1
- package/dist/features/homepage/components/ShopByCategorySection.js +2 -2
- package/dist/features/homepage/lib/section-renderer.js +9 -9
- package/dist/features/homepage/schemas/firestore.d.ts +8 -0
- package/dist/features/layout/FooterLayout.js +2 -2
- package/dist/features/lottery/schemas/zod.d.ts +4 -4
- package/dist/features/payments/schemas/firestore.d.ts +6 -0
- package/dist/features/payments/schemas/firestore.js +2 -0
- package/dist/features/seller/components/SellerBundlesView.d.ts +3 -4
- package/dist/features/seller/components/SellerBundlesView.js +2 -2
- package/dist/features/seller/components/SellerPayoutsView.d.ts +2 -5
- package/dist/features/seller/components/SellerPayoutsView.js +100 -21
- package/dist/features/seller/components/SellerPreOrdersView.js +1 -1
- package/dist/features/seller/components/SellerPrizeDrawsView.js +1 -1
- package/dist/features/seller/components/SellerProductsView.js +6 -2
- package/dist/features/shipments/components/AdminShipmentsView.d.ts +1 -5
- package/dist/index.d.ts +3 -5
- package/dist/index.js +3 -3
- package/dist/react/index.d.ts +0 -2
- package/dist/react/index.js +0 -2
- package/dist/seed/faq-seed-data.js +11 -11
- package/dist/seed/homepage-sections-seed-data.js +11 -1
- package/dist/styles.css +30 -99
- package/dist/tailwind-utilities.css +1 -1
- package/dist/ui/DataTable.js +1 -1
- package/dist/ui/DataTable.style.css +10 -0
- package/dist/ui/components/DetailPageTabs.d.ts +1 -1
- package/dist/ui/components/DetailPageTabs.js +6 -30
- package/dist/ui/components/HorizontalScroller.js +3 -0
- package/dist/ui/components/Tabs.d.ts +9 -1
- package/dist/ui/components/Tabs.js +13 -8
- package/dist/ui/components/Tabs.style.css +19 -0
- package/dist/ui/components/index.style.css +0 -1
- package/dist/ui/index.d.ts +0 -2
- package/dist/ui/index.js +0 -1
- package/package.json +1 -1
|
@@ -42,7 +42,7 @@ export const DEFAULT_PRODUCTS_BUILDER = {
|
|
|
42
42
|
manualResourceIds: "",
|
|
43
43
|
filterByCategory: "",
|
|
44
44
|
maxCount: 10,
|
|
45
|
-
loop:
|
|
45
|
+
loop: true,
|
|
46
46
|
};
|
|
47
47
|
export const DEFAULT_AUCTIONS_BUILDER = {
|
|
48
48
|
title: "Live Auctions",
|
|
@@ -57,7 +57,7 @@ export const DEFAULT_AUCTIONS_BUILDER = {
|
|
|
57
57
|
manualResourceIds: "",
|
|
58
58
|
filterByCategory: "",
|
|
59
59
|
maxCount: 10,
|
|
60
|
-
loop:
|
|
60
|
+
loop: true,
|
|
61
61
|
};
|
|
62
62
|
const DEFAULT_STAT_ROW = {
|
|
63
63
|
source: "static",
|
|
@@ -89,7 +89,7 @@ export const DEFAULT_PRE_ORDERS_BUILDER = {
|
|
|
89
89
|
manualResourceIds: "",
|
|
90
90
|
filterByCategory: "",
|
|
91
91
|
maxCount: 10,
|
|
92
|
-
loop:
|
|
92
|
+
loop: true,
|
|
93
93
|
};
|
|
94
94
|
export const DEFAULT_STORES_BUILDER = {
|
|
95
95
|
title: "Featured Stores",
|
|
@@ -105,7 +105,7 @@ export const DEFAULT_STORES_BUILDER = {
|
|
|
105
105
|
manualResourceIds: "",
|
|
106
106
|
filterByCategory: "",
|
|
107
107
|
maxCount: 10,
|
|
108
|
-
loop:
|
|
108
|
+
loop: true,
|
|
109
109
|
};
|
|
110
110
|
export const DEFAULT_EVENTS_BUILDER = {
|
|
111
111
|
title: "Events & Offers",
|
|
@@ -121,7 +121,7 @@ export const DEFAULT_EVENTS_BUILDER = {
|
|
|
121
121
|
manualResourceIds: "",
|
|
122
122
|
filterByCategory: "",
|
|
123
123
|
maxCount: 10,
|
|
124
|
-
loop:
|
|
124
|
+
loop: true,
|
|
125
125
|
};
|
|
126
126
|
export const DEFAULT_SOCIAL_FEED_BUILDER = {
|
|
127
127
|
title: "",
|
|
@@ -156,6 +156,7 @@ export const DEFAULT_CATEGORIES_BUILDER = {
|
|
|
156
156
|
maxCategories: 8,
|
|
157
157
|
autoScroll: false,
|
|
158
158
|
scrollInterval: 5000,
|
|
159
|
+
loop: true,
|
|
159
160
|
};
|
|
160
161
|
export const DEFAULT_BRANDS_BUILDER = {
|
|
161
162
|
title: "Top Brands",
|
|
@@ -163,6 +164,7 @@ export const DEFAULT_BRANDS_BUILDER = {
|
|
|
163
164
|
maxBrands: 13,
|
|
164
165
|
autoScroll: true,
|
|
165
166
|
scrollInterval: 4000,
|
|
167
|
+
loop: true,
|
|
166
168
|
};
|
|
167
169
|
export const DEFAULT_BANNER_BUILDER = {
|
|
168
170
|
height: "lg",
|
|
@@ -187,6 +189,7 @@ export const DEFAULT_REVIEWS_BUILDER = {
|
|
|
187
189
|
itemsPerView: 3,
|
|
188
190
|
autoScroll: true,
|
|
189
191
|
scrollInterval: 5000,
|
|
192
|
+
loop: true,
|
|
190
193
|
source: "platform",
|
|
191
194
|
placeId: "",
|
|
192
195
|
};
|
|
@@ -237,6 +240,7 @@ export const DEFAULT_CUSTOM_CARDS_BUILDER = {
|
|
|
237
240
|
columns: 3,
|
|
238
241
|
autoScroll: false,
|
|
239
242
|
scrollIntervalMs: 4000,
|
|
243
|
+
loop: true,
|
|
240
244
|
cards: [],
|
|
241
245
|
};
|
|
242
246
|
export const DEFAULT_GOOGLE_REVIEWS_BUILDER = {
|
|
@@ -14,8 +14,8 @@ export interface AdminListingConfig<TResponse, TRow extends {
|
|
|
14
14
|
export declare function useAdminListing<TResponse, TRow extends {
|
|
15
15
|
id: string;
|
|
16
16
|
}>(config: AdminListingConfig<TResponse, TRow>): {
|
|
17
|
-
view: "
|
|
18
|
-
setView: import("
|
|
17
|
+
view: import("../../account/hooks/useDataViewMode").DataViewMode;
|
|
18
|
+
setView: (next: import("../../account/hooks/useDataViewMode").DataViewMode) => void;
|
|
19
19
|
table: {
|
|
20
20
|
params: URLSearchParams;
|
|
21
21
|
get: (key: string) => string;
|
|
@@ -3,10 +3,15 @@ import { useState, useCallback } from "react";
|
|
|
3
3
|
import { useUrlTable } from "../../../react/hooks/useUrlTable";
|
|
4
4
|
import { useBulkSelection } from "../../../react/hooks/useBulkSelection";
|
|
5
5
|
import { usePanelUrlSync } from "../../../react/hooks/use-panel-url-sync";
|
|
6
|
+
import { useDataViewMode } from "../../account/hooks/useDataViewMode";
|
|
6
7
|
import { useAdminListingData } from "./useAdminListingData";
|
|
7
8
|
export function useAdminListing(config) {
|
|
8
9
|
const { filterKeys, defaultSort, pageSize: defaultPageSize = 25, queryKey, endpoint, mapRows, getTotal, buildFilters, } = config;
|
|
9
|
-
|
|
10
|
+
// Persisted, viewport-aware view-mode: below 768px defaults to "list"
|
|
11
|
+
// (AdminViewCards' one-full-width-card-per-row layout) unless the caller
|
|
12
|
+
// explicitly pins hideTableView (grid-only views like coupons); the user's
|
|
13
|
+
// own explicit choice, once made, always wins and persists across visits.
|
|
14
|
+
const { view, setView } = useDataViewMode(config.initialView ?? "table");
|
|
10
15
|
const table = useUrlTable({ defaults: { pageSize: String(defaultPageSize), sort: defaultSort } });
|
|
11
16
|
// Reactive — table.getNumber reads the URL param, so a page-size selector
|
|
12
17
|
// (Pagination's pageSize/onPageSizeChange) actually takes effect instead
|
|
@@ -1,21 +1,13 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { useState } from "react";
|
|
4
|
-
import {
|
|
4
|
+
import { Tabs, TabsList, TabsTrigger } from "../../../ui";
|
|
5
5
|
import { CategoryProductsListing } from "./CategoryProductsListing";
|
|
6
6
|
import { AuctionsIndexListing } from "../../products/components/AuctionsIndexListing";
|
|
7
7
|
import { PreOrdersIndexListing } from "../../pre-orders/components/PreOrdersIndexListing";
|
|
8
8
|
import { PrizeDrawsIndexListing } from "../../products/components/PrizeDrawsIndexListing";
|
|
9
9
|
import { CategoryBundlesListing } from "./CategoryBundlesListing";
|
|
10
10
|
import { CATEGORY_PAGE_TABS } from "../../products/constants/listing-tabs";
|
|
11
|
-
const __O = {
|
|
12
|
-
xAuto: "overflow-x-auto",
|
|
13
|
-
};
|
|
14
|
-
function tabLabel(label, count) {
|
|
15
|
-
if (!count)
|
|
16
|
-
return label;
|
|
17
|
-
return `${label} (${count.toLocaleString()})`;
|
|
18
|
-
}
|
|
19
11
|
const TAB_TYPE_MAP = {
|
|
20
12
|
products: { kind: "listing", type: "standard" },
|
|
21
13
|
auctions: { kind: "listing", type: "auction" },
|
|
@@ -48,7 +40,5 @@ export function BrandDetailTabs({ brandName, initialProductsData, initialBundles
|
|
|
48
40
|
default: return undefined;
|
|
49
41
|
}
|
|
50
42
|
};
|
|
51
|
-
return (_jsxs(_Fragment, { children: [_jsx(
|
|
52
|
-
? "border-primary text-primary"
|
|
53
|
-
: "border-transparent text-[var(--appkit-color-text-muted)] hover:text-zinc-900 dark:hover:text-zinc-100"}`, children: tabLabel(t.label, countFor(t.id)) }, t.id))) }), activeTab === "products" && (_jsx(CategoryProductsListing, { categorySlug: "", brandName: brandName, initialData: initialProductsData })), activeTab === "auctions" && (_jsx(AuctionsIndexListing, { brandName: brandName })), activeTab === "pre-orders" && (_jsx(PreOrdersIndexListing, { brandName: brandName })), activeTab === "prize-draws" && (_jsx(PrizeDrawsIndexListing, { brandName: brandName })), activeTab === "bundles" && (_jsx(CategoryBundlesListing, { initialBundles: initialBundles, brandName: brandName }))] }));
|
|
43
|
+
return (_jsxs(_Fragment, { children: [_jsx(Tabs, { value: activeTab, onChange: (v) => setActiveTab(v), className: "mb-6", children: _jsx(TabsList, { children: visibleTabs.map((t) => (_jsx(TabsTrigger, { value: t.id, badge: countFor(t.id), children: t.label }, t.id))) }) }), activeTab === "products" && (_jsx(CategoryProductsListing, { categorySlug: "", brandName: brandName, initialData: initialProductsData })), activeTab === "auctions" && (_jsx(AuctionsIndexListing, { brandName: brandName })), activeTab === "pre-orders" && (_jsx(PreOrdersIndexListing, { brandName: brandName })), activeTab === "prize-draws" && (_jsx(PrizeDrawsIndexListing, { brandName: brandName })), activeTab === "bundles" && (_jsx(CategoryBundlesListing, { initialBundles: initialBundles, brandName: brandName }))] }));
|
|
54
44
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { useState } from "react";
|
|
4
|
-
import {
|
|
4
|
+
import { Tabs, TabsList, TabsTrigger } from "../../../ui";
|
|
5
5
|
import { CategoryProductsListing } from "./CategoryProductsListing";
|
|
6
6
|
import { AuctionsIndexListing } from "../../products/components/AuctionsIndexListing";
|
|
7
7
|
import { PreOrdersIndexListing } from "../../pre-orders/components/PreOrdersIndexListing";
|
|
@@ -9,14 +9,6 @@ import { PrizeDrawsIndexListing } from "../../products/components/PrizeDrawsInde
|
|
|
9
9
|
import { CategoryBundlesListing } from "./CategoryBundlesListing";
|
|
10
10
|
import { CategoryStoresListing } from "./CategoryStoresListing";
|
|
11
11
|
import { CATEGORY_PAGE_TABS } from "../../products/constants/listing-tabs";
|
|
12
|
-
const __O = {
|
|
13
|
-
xAuto: "overflow-x-auto",
|
|
14
|
-
};
|
|
15
|
-
function tabLabel(label, count) {
|
|
16
|
-
if (!count)
|
|
17
|
-
return label;
|
|
18
|
-
return `${label} (${count.toLocaleString()})`;
|
|
19
|
-
}
|
|
20
12
|
/** Maps CATEGORY_PAGE_TABS id → listing type / category type key for flag filtering. */
|
|
21
13
|
const TAB_TYPE_MAP = {
|
|
22
14
|
products: { kind: "listing", type: "standard" },
|
|
@@ -54,7 +46,5 @@ export function CategoryDetailTabs({ categorySlug, categoryId, initialProductsDa
|
|
|
54
46
|
default: return undefined;
|
|
55
47
|
}
|
|
56
48
|
};
|
|
57
|
-
return (_jsxs(_Fragment, { children: [_jsx(
|
|
58
|
-
? "border-primary text-primary"
|
|
59
|
-
: "border-transparent text-[var(--appkit-color-text-muted)] hover:text-zinc-900 dark:hover:text-zinc-100"}`, children: tabLabel(t.label, countFor(t.id)) }, t.id))) }), activeTab === "products" && (_jsx(CategoryProductsListing, { categorySlug: categorySlug, categoryId: categoryId, initialData: initialProductsData })), activeTab === "auctions" && (_jsx(AuctionsIndexListing, { categorySlug: categorySlug })), activeTab === "pre-orders" && (_jsx(PreOrdersIndexListing, { categorySlug: categorySlug })), activeTab === "prize-draws" && (_jsx(PrizeDrawsIndexListing, { categorySlug: categorySlug })), activeTab === "bundles" && (_jsx(CategoryBundlesListing, { initialBundles: initialBundles })), activeTab === "stores" && (_jsx(CategoryStoresListing, { stores: initialStores }))] }));
|
|
49
|
+
return (_jsxs(_Fragment, { children: [_jsx(Tabs, { value: activeTab, onChange: (v) => setActiveTab(v), className: "mb-6", children: _jsx(TabsList, { children: visibleTabs.map((t) => (_jsx(TabsTrigger, { value: t.id, badge: countFor(t.id), children: t.label }, t.id))) }) }), activeTab === "products" && (_jsx(CategoryProductsListing, { categorySlug: categorySlug, categoryId: categoryId, initialData: initialProductsData })), activeTab === "auctions" && (_jsx(AuctionsIndexListing, { categorySlug: categorySlug })), activeTab === "pre-orders" && (_jsx(PreOrdersIndexListing, { categorySlug: categorySlug })), activeTab === "prize-draws" && (_jsx(PrizeDrawsIndexListing, { categorySlug: categorySlug })), activeTab === "bundles" && (_jsx(CategoryBundlesListing, { initialBundles: initialBundles })), activeTab === "stores" && (_jsx(CategoryStoresListing, { stores: initialStores }))] }));
|
|
60
50
|
}
|
|
@@ -1,8 +1,4 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import type { ListingLayoutProps } from "../../../ui";
|
|
3
|
-
export
|
|
4
|
-
getRowHref?: (row: {
|
|
5
|
-
id: string;
|
|
6
|
-
}) => string;
|
|
7
|
-
}
|
|
3
|
+
export type AdminEventsViewProps = ListingLayoutProps;
|
|
8
4
|
export declare function AdminEventsView({ children, ...props }: AdminEventsViewProps): React.JSX.Element;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { useState } from "react";
|
|
4
|
-
import { Button, Div, RichText, Row, Span, Text } from "../../../ui";
|
|
4
|
+
import { Button, Div, RichText, Row, Span, Tabs, TabsList, TabsTrigger, Text } from "../../../ui";
|
|
5
5
|
function FAQAccordionItem({ faq, isOpen, onToggle, renderExpandedFooter, }) {
|
|
6
6
|
return (_jsxs(Div, { className: "border-b border-neutral-200 last:border-0", children: [_jsxs(Button, { variant: "ghost", onClick: onToggle, "aria-expanded": isOpen, className: "w-full justify-[space-between] gap-[1rem] py-[1rem] text-left text-[0.875rem] font-[500] text-[var(--appkit-color-text)] dark:text-[var(--appkit-color-text)] transition hover:text-primary", children: [_jsx(Span, { children: faq.question }), _jsx(Span, { className: `flex-shrink-0 transition-transform ${isOpen ? "rotate-180" : ""}`, children: _jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: _jsx("path", { d: "M4 6l4 4 4-4", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) }) })] }), isOpen && (_jsxs(Div, { textSize: "sm", className: "text-[var(--appkit-color-text-muted)]", padding: "b-md", children: [faq.tags && faq.tags.length > 0 && (_jsx(Row, { wrap: true, gap: "sm", className: "mb-3", children: faq.tags.map((tag) => (_jsx(Span, { className: "bg-[var(--appkit-color-surface)] py-[0.25rem] text-[var(--appkit-color-text-muted)]", rounded: "md", padding: "x-xs", size: "xs", children: tag }, tag))) })), faq.answer.format === "html" ? (_jsx(RichText, { html: faq.answer.text, className: "prose-sm" })) : (_jsx(Text, { className: "whitespace-pre-line", children: faq.answer.text })), renderExpandedFooter?.(faq)] }))] }));
|
|
7
7
|
}
|
|
@@ -12,6 +12,7 @@ export function FAQAccordion({ faqs, className = "", renderExpandedFooter, label
|
|
|
12
12
|
}
|
|
13
13
|
return (_jsx(Div, { surface: "card", className: `divide-y divide-neutral-100 divide-[var(--appkit-color-border)] ${className}`, padding: "x-md", children: faqs.map((faq) => (_jsx(FAQAccordionItem, { faq: faq, isOpen: openId === faq.id, onToggle: () => setOpenId(openId === faq.id ? null : faq.id), renderExpandedFooter: renderExpandedFooter }, faq.id))) }));
|
|
14
14
|
}
|
|
15
|
+
const ALL_TAB_VALUE = "__all__";
|
|
15
16
|
export function FAQCategoryTabs({ categories, active, onSelect, labels = {}, }) {
|
|
16
|
-
return (
|
|
17
|
+
return (_jsx(Tabs, { value: active ?? ALL_TAB_VALUE, onChange: (next) => onSelect(next === ALL_TAB_VALUE ? null : next), children: _jsxs(TabsList, { children: [_jsx(TabsTrigger, { value: ALL_TAB_VALUE, children: labels.all ?? "All" }), categories.map((cat) => (_jsx(TabsTrigger, { value: cat, children: labels[cat] ?? cat.replace(/_/g, " ") }, cat)))] }) }));
|
|
17
18
|
}
|
|
@@ -4,5 +4,5 @@ export function RelatedFAQs({ relatedFAQs, hrefForFaq, labels, }) {
|
|
|
4
4
|
if (!relatedFAQs || relatedFAQs.length === 0) {
|
|
5
5
|
return null;
|
|
6
6
|
}
|
|
7
|
-
return (_jsxs(Card, { variant: "outlined", padding: "lg", children: [_jsx(Heading, { level: 3, className: "mb-4", size: "lg", weight: "semibold", children: labels?.title ?? "Related Questions" }), _jsx(Stack, { gap: "
|
|
7
|
+
return (_jsxs(Card, { variant: "outlined", padding: "lg", children: [_jsx(Heading, { level: 3, className: "mb-4", size: "lg", weight: "semibold", children: labels?.title ?? "Related Questions" }), _jsx(Stack, { gap: "none", className: "divide-y divide-[var(--appkit-color-border)]", children: relatedFAQs.map((faq) => (_jsx(TextLink, { href: hrefForFaq ? hrefForFaq(faq) : `/faqs#${faq.id}`, className: "group block p-[1rem] transition-colors hover:bg-[var(--appkit-color-surface-elevated)]", children: _jsxs(Row, { align: "start", gap: "3", children: [_jsx("svg", { className: "mt-0.5 h-5 w-5 flex-shrink-0 text-[var(--appkit-color-text-muted)]", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M8.228 9c.549-1.165 2.03-2 3.772-2 2.21 0 4 1.343 4 3 0 1.4-1.278 2.575-3.006 2.907-.542.104-.994.54-.994 1.093m0 3h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" }) }), _jsx(Text, { className: "transition-colors group-hover:text-primary", color: "primary", size: "sm", children: faq.question }), _jsx("svg", { className: "ml-auto mt-0.5 h-4 w-4 flex-shrink-0 text-[var(--appkit-color-text-muted)] opacity-0 transition-opacity group-hover:opacity-100 text-[var(--appkit-color-text-muted)]", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 5l7 7-7 7" }) })] }) }, faq.id))) })] }));
|
|
8
8
|
}
|
|
@@ -13,5 +13,8 @@ export interface BrandsSectionProps {
|
|
|
13
13
|
featuredOnly?: boolean;
|
|
14
14
|
byCountry?: string;
|
|
15
15
|
};
|
|
16
|
+
autoScroll?: boolean;
|
|
17
|
+
scrollInterval?: number;
|
|
18
|
+
loop?: boolean;
|
|
16
19
|
}
|
|
17
|
-
export declare function BrandsSection({ title, subtitle, limit, viewMoreHref, viewMoreLabel, className, initialItems, cta, filters, }: BrandsSectionProps): import("react").JSX.Element | null;
|
|
20
|
+
export declare function BrandsSection({ title, subtitle, limit, viewMoreHref, viewMoreLabel, className, initialItems, cta, filters, autoScroll, scrollInterval, loop, }: BrandsSectionProps): import("react").JSX.Element | null;
|
|
@@ -29,7 +29,7 @@ function BrandLogo({ brand }) {
|
|
|
29
29
|
const initial = brand.name[0]?.toUpperCase() ?? "?";
|
|
30
30
|
return (_jsxs(Link, { href: ROUTES.PUBLIC.CATEGORY_DETAIL(brand.slug), className: "flex h-32 w-36 flex-col items-center justify-center gap-[var(--appkit-space-2)] rounded-xl border border-zinc-200 bg-[var(--appkit-color-surface)] p-[var(--appkit-space-3)] shadow-sm transition-all hover:border-primary-300 hover:shadow-md border-[var(--appkit-color-border)] bg-[var(--appkit-color-surface)] md:h-40", children: [iconSrc || coverImage ? (_jsx(Image, { src: iconSrc ?? coverImage, alt: brand.name, width: 64, height: 64, className: "h-16 w-16 rounded object-contain" })) : (_jsx(Row, { textWeight: "bold", textSize: "sm", className: "h-16 w-16 bg-primary-100 text-primary-700 dark:bg-primary-900 dark:text-primary-300", align: "center", justify: "center", rounded: "lg", children: initial })), _jsx(Text, { className: "w-full truncate", color: "muted", size: "xs", weight: "medium", align: "start", children: brand.name })] }));
|
|
31
31
|
}
|
|
32
|
-
export function BrandsSection({ title = "Top Brands", subtitle, limit = 12, viewMoreHref, viewMoreLabel = "All brands →", className = "", initialItems, cta, filters, }) {
|
|
32
|
+
export function BrandsSection({ title = "Top Brands", subtitle, limit = 12, viewMoreHref, viewMoreLabel = "All brands →", className = "", initialItems, cta, filters, autoScroll = true, scrollInterval = 4000, loop = true, }) {
|
|
33
33
|
const themed = { textPrimary: THEMED_TEXT_PRIMARY };
|
|
34
34
|
const { data: allBrands = [], isLoading } = useTopBrands(limit, { initialData: initialItems });
|
|
35
35
|
const [activeFilter, setActiveFilter] = useState("all");
|
|
@@ -42,5 +42,5 @@ export function BrandsSection({ title = "Top Brands", subtitle, limit = 12, view
|
|
|
42
42
|
});
|
|
43
43
|
if (!isLoading && allBrands.length === 0)
|
|
44
44
|
return null;
|
|
45
|
-
return (_jsx(Section, { className: `${className}`, surface: "subtle", paddingY: "y-3xl", paddingX: "x-md", children: _jsxs(Div, { className: "mx-auto max-w-7xl", children: [_jsxs(Row, { className: "mb-6", align: "center", justify: "between", children: [_jsxs(_Fragment, { children: [_jsx(Heading, { level: 2, className: themed.textPrimary, size: "2xl", mdSize: "3xl", weight: "bold", children: title }), subtitle && (_jsx(Text, { variant: "secondary", className: "mt-1", size: "sm", children: subtitle }))] }), !cta && viewMoreHref && (_jsx(Link, { href: viewMoreHref, className: "text-[length:var(--appkit-text-sm)] font-medium text-[var(--appkit-color-primary)] hover:underline", children: viewMoreLabel }))] }), showFeaturedChip && !isLoading && (_jsxs(Row, { wrap: true, gap: "sm", className: "mb-4", children: [_jsx(BrandFilterChip, { label: "All", active: activeFilter === "all", onClick: () => setActiveFilter("all") }), _jsx(BrandFilterChip, { label: "Featured", active: activeFilter === "featured", onClick: () => setActiveFilter(activeFilter === "featured" ? "all" : "featured") })] })), isLoading ? (_jsx(Div, { layout: "flex", gap: "3", className: `${__O.hidden}`, children: Array.from({ length: 8 }).map((_, i) => (_jsx(Div, { className: "h-32 w-36 flex-none animate-pulse md:h-40", surface: "subtle", rounded: "xl" }, i))) })) : (_jsx(HorizontalScroller, { items: brands, renderItem: (brand) => _jsx(BrandLogo, { brand: brand }), keyExtractor: (brand) => brand.id, gap: 12, showArrows: true, showScrollbar: false,
|
|
45
|
+
return (_jsx(Section, { className: `${className}`, surface: "subtle", paddingY: "y-3xl", paddingX: "x-md", children: _jsxs(Div, { className: "mx-auto max-w-7xl", children: [_jsxs(Row, { className: "mb-6", align: "center", justify: "between", children: [_jsxs(_Fragment, { children: [_jsx(Heading, { level: 2, className: themed.textPrimary, size: "2xl", mdSize: "3xl", weight: "bold", children: title }), subtitle && (_jsx(Text, { variant: "secondary", className: "mt-1", size: "sm", children: subtitle }))] }), !cta && viewMoreHref && (_jsx(Link, { href: viewMoreHref, className: "text-[length:var(--appkit-text-sm)] font-medium text-[var(--appkit-color-primary)] hover:underline", children: viewMoreLabel }))] }), showFeaturedChip && !isLoading && (_jsxs(Row, { wrap: true, gap: "sm", className: "mb-4", children: [_jsx(BrandFilterChip, { label: "All", active: activeFilter === "all", onClick: () => setActiveFilter("all") }), _jsx(BrandFilterChip, { label: "Featured", active: activeFilter === "featured", onClick: () => setActiveFilter(activeFilter === "featured" ? "all" : "featured") })] })), isLoading ? (_jsx(Div, { layout: "flex", gap: "3", className: `${__O.hidden}`, children: Array.from({ length: 8 }).map((_, i) => (_jsx(Div, { className: "h-32 w-36 flex-none animate-pulse md:h-40", surface: "subtle", rounded: "xl" }, i))) })) : (_jsx(HorizontalScroller, { items: brands, renderItem: (brand) => _jsx(BrandLogo, { brand: brand }), keyExtractor: (brand) => brand.id, gap: 12, showArrows: true, showScrollbar: false, autoScroll: autoScroll, autoScrollInterval: scrollInterval, pauseOnHover: true, loop: loop })), cta && !isLoading && (_jsx(Div, { className: "mt-6 text-left", children: _jsx(Link, { href: cta.href, className: CTA_CLASSES[cta.variant], children: cta.label }) }))] }) }));
|
|
46
46
|
}
|
|
@@ -55,16 +55,16 @@ function SectionHeader({ title }) {
|
|
|
55
55
|
return (_jsx(Div, { className: "mb-6", children: _jsx(Heading, { level: 2, className: themed.textPrimary, children: title }) }));
|
|
56
56
|
}
|
|
57
57
|
export function CustomCardsSection(config) {
|
|
58
|
-
const { title, layout, columns = 3, cards, autoScroll, scrollIntervalMs } = config;
|
|
58
|
+
const { title, layout, columns = 3, cards, autoScroll, scrollIntervalMs, loop = true } = config;
|
|
59
59
|
if (!cards?.length)
|
|
60
60
|
return null;
|
|
61
61
|
// autoScroll: wrap all cards in SectionCarousel (client carousel)
|
|
62
62
|
if (autoScroll) {
|
|
63
|
-
return (_jsx(Section, { padding: "y-3xl", surface: "muted", children: _jsx(Div, { className: CLS_CONTAINER, children: _jsx(SectionCarousel, { title: title ?? "", items: cards, renderItem: (card) => _jsx(CardItem, { card: card }), keyExtractor: (card) => card.id, autoScroll: true, autoScrollInterval: scrollIntervalMs ?? 3500, perView: { base: 1, sm: 2, md: columns } }) }) }));
|
|
63
|
+
return (_jsx(Section, { padding: "y-3xl", surface: "muted", children: _jsx(Div, { className: CLS_CONTAINER, children: _jsx(SectionCarousel, { title: title ?? "", items: cards, renderItem: (card) => _jsx(CardItem, { card: card }), keyExtractor: (card) => card.id, autoScroll: true, autoScrollInterval: scrollIntervalMs ?? 3500, loop: loop, perView: { base: 1, sm: 2, md: columns } }) }) }));
|
|
64
64
|
}
|
|
65
65
|
// Row layout: horizontal scroller
|
|
66
66
|
if (layout === "row") {
|
|
67
|
-
return (_jsx(Section, { padding: "y-3xl", surface: "muted", children: _jsxs(Div, { className: CLS_CONTAINER, children: [_jsx(SectionHeader, { title: title }), _jsx(HorizontalScroller, { gap: 16, showArrows: true, snapToItems: true, loop:
|
|
67
|
+
return (_jsx(Section, { padding: "y-3xl", surface: "muted", children: _jsxs(Div, { className: CLS_CONTAINER, children: [_jsx(SectionHeader, { title: title }), _jsx(HorizontalScroller, { gap: 16, showArrows: true, snapToItems: true, loop: loop, items: cards, keyExtractor: (card) => card.id, renderItem: (card) => (_jsx(Div, { className: "w-72 flex-shrink-0", children: _jsx(CardItem, { card: card }) })) })] }) }));
|
|
68
68
|
}
|
|
69
69
|
// Masonry layout: CSS columns
|
|
70
70
|
if (layout === "masonry") {
|
|
@@ -9,5 +9,8 @@ export interface CustomerReviewsSectionProps<T = unknown> {
|
|
|
9
9
|
isLoading?: boolean;
|
|
10
10
|
keyExtractor?: (item: T) => string;
|
|
11
11
|
className?: string;
|
|
12
|
+
autoScroll?: boolean;
|
|
13
|
+
scrollInterval?: number;
|
|
14
|
+
loop?: boolean;
|
|
12
15
|
}
|
|
13
|
-
export declare function CustomerReviewsSection<T = unknown>({ title, subtitle, items, renderItem, viewMoreHref, viewMoreLabel, isLoading, keyExtractor, className, }: CustomerReviewsSectionProps<T>): React.JSX.Element | null;
|
|
16
|
+
export declare function CustomerReviewsSection<T = unknown>({ title, subtitle, items, renderItem, viewMoreHref, viewMoreLabel, isLoading, keyExtractor, className, autoScroll, scrollInterval, loop, }: CustomerReviewsSectionProps<T>): React.JSX.Element | null;
|
|
@@ -10,12 +10,12 @@ const __O = {
|
|
|
10
10
|
hidden: "overflow-hidden",
|
|
11
11
|
};
|
|
12
12
|
// --- Section -----------------------------------------------------------------
|
|
13
|
-
export function CustomerReviewsSection({ title, subtitle, items, renderItem, viewMoreHref, viewMoreLabel = "See all reviews", isLoading = false, keyExtractor, className = "", }) {
|
|
13
|
+
export function CustomerReviewsSection({ title, subtitle, items, renderItem, viewMoreHref, viewMoreLabel = "See all reviews", isLoading = false, keyExtractor, className = "", autoScroll = true, scrollInterval = 4500, loop = true, }) {
|
|
14
14
|
const themed = { textPrimary: THEMED_TEXT_PRIMARY, textSecondary: THEMED_TEXT_SECONDARY };
|
|
15
15
|
if (isLoading) {
|
|
16
16
|
return (_jsx(Section, { className: `${__P.p8} ${className}`, surface: "muted", children: _jsxs(Div, { className: "w-full max-w-7xl mx-auto", children: [_jsx(Div, { className: `h-8 ${skeleton.base} mb-8 max-w-xs mx-auto` }), _jsx(Div, { layout: "flex", gap: "6", className: `${__O.hidden}`, children: [...Array(3)].map((_, i) => (_jsx(Div, { className: `${skeleton.card} h-[clamp(180px,26vh,260px)] min-w-[clamp(150px,18vw,260px)] max-w-[clamp(240px,36vw,380px)] flex-none` }, i))) })] }) }));
|
|
17
17
|
}
|
|
18
18
|
if (items.length === 0)
|
|
19
19
|
return null;
|
|
20
|
-
return (_jsx(Section, { className: `${className}`, surface: "muted", padding: "y-3xl", children: _jsxs(Div, { className: "w-full max-w-7xl mx-auto md:px-[2rem]", padding: "x-md", children: [_jsxs(Div, { className: "text-left mb-10", children: [_jsx(Heading, { level: 2, className: `${themed.textPrimary} mb-3`, size: "3xl", mdSize: "4xl", weight: "bold", children: title }), subtitle && (_jsx(Text, { className: `${themed.textSecondary}`, size: "base", children: subtitle }))] }), _jsx(HorizontalScroller, { items: items, renderItem: (item) => renderItem(item), perView: CAROUSEL_PER_VIEW.reviews, gap: 24, autoScroll:
|
|
20
|
+
return (_jsx(Section, { className: `${className}`, surface: "muted", padding: "y-3xl", children: _jsxs(Div, { className: "w-full max-w-7xl mx-auto md:px-[2rem]", padding: "x-md", children: [_jsxs(Div, { className: "text-left mb-10", children: [_jsx(Heading, { level: 2, className: `${themed.textPrimary} mb-3`, size: "3xl", mdSize: "4xl", weight: "bold", children: title }), subtitle && (_jsx(Text, { className: `${themed.textSecondary}`, size: "base", children: subtitle }))] }), _jsx(HorizontalScroller, { items: items, renderItem: (item) => renderItem(item), perView: CAROUSEL_PER_VIEW.reviews, gap: 24, autoScroll: autoScroll, autoScrollInterval: scrollInterval, pauseOnHover: true, snapToItems: true, showArrows: true, keyExtractor: keyExtractor, loop: loop }), viewMoreHref && (_jsx(Div, { className: "text-left mt-8", children: _jsx(TextLink, { href: viewMoreHref, className: "text-primary hover:text-primary/80", size: "sm", weight: "medium", children: viewMoreLabel }) }))] }) }));
|
|
21
21
|
}
|
|
@@ -8,5 +8,8 @@ export interface EventsSectionProps {
|
|
|
8
8
|
limit?: number;
|
|
9
9
|
className?: string;
|
|
10
10
|
initialItems?: EventItem[];
|
|
11
|
+
autoScroll?: boolean;
|
|
12
|
+
scrollInterval?: number;
|
|
13
|
+
loop?: boolean;
|
|
11
14
|
}
|
|
12
|
-
export declare function EventsSection({ title, description, viewMoreHref, viewMoreLabel, limit, className, initialItems, }: EventsSectionProps): React.JSX.Element;
|
|
15
|
+
export declare function EventsSection({ title, description, viewMoreHref, viewMoreLabel, limit, className, initialItems, autoScroll, scrollInterval, loop, }: EventsSectionProps): React.JSX.Element;
|
|
@@ -4,7 +4,7 @@ import { SectionCarousel } from "./SectionCarousel";
|
|
|
4
4
|
import { useHomepageEvents } from "../hooks/useHomepageEvents";
|
|
5
5
|
import { EventCard } from "../../events/components/EventCard";
|
|
6
6
|
import { CAROUSEL_PER_VIEW } from "../constants/carousel-per-view";
|
|
7
|
-
export function EventsSection({ title = "Events & Offers", description, viewMoreHref, viewMoreLabel = "View all events →", limit = 6, className = "", initialItems, }) {
|
|
7
|
+
export function EventsSection({ title = "Events & Offers", description, viewMoreHref, viewMoreLabel = "View all events →", limit = 6, className = "", initialItems, autoScroll = false, scrollInterval = 5000, loop = true, }) {
|
|
8
8
|
const { data: items = [], isLoading } = useHomepageEvents(limit, { initialData: initialItems });
|
|
9
|
-
return (_jsx(SectionCarousel, { title: title, description: description, pillLabel: "Events & Offers", headingVariant: "editorial", viewMoreHref: viewMoreHref, viewMoreLabel: viewMoreLabel, items: items, isLoading: isLoading, skeletonCount: 3, perView: CAROUSEL_PER_VIEW.events, gap: 16, keyExtractor: (event) => event.id, renderItem: (event) => (_jsx(EventCard, { event: event })), className: className }));
|
|
9
|
+
return (_jsx(SectionCarousel, { title: title, description: description, pillLabel: "Events & Offers", headingVariant: "editorial", viewMoreHref: viewMoreHref, viewMoreLabel: viewMoreLabel, items: items, isLoading: isLoading, skeletonCount: 3, perView: CAROUSEL_PER_VIEW.events, gap: 16, autoScroll: autoScroll, autoScrollInterval: scrollInterval, loop: loop, keyExtractor: (event) => event.id, renderItem: (event) => (_jsx(EventCard, { event: event })), className: className }));
|
|
10
10
|
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { useState, useMemo } from "react";
|
|
4
4
|
import { THEMED_BG_PRIMARY, THEMED_BG_TERTIARY, THEMED_BORDER, THEMED_TEXT_PRIMARY, THEMED_TEXT_SECONDARY, FLEX_BETWEEN } from "../../../_internal/shared/styles/themed";
|
|
5
|
-
import { Button, Div, Heading, RichText,
|
|
5
|
+
import { Button, Div, Heading, RichText, Section, Span, Stack, Tabs, TabsList, TabsTrigger, Text, TextLink } from "../../../ui";
|
|
6
6
|
import { ChevronDown } from "lucide-react";
|
|
7
7
|
const __O = {
|
|
8
8
|
hidden: "overflow-hidden",
|
|
@@ -67,8 +67,8 @@ export function FAQSection({ title, subtitle, items, tabs: tabsProp, showCategor
|
|
|
67
67
|
return items;
|
|
68
68
|
return items.filter((i) => (i.category ?? "general") === activeTab);
|
|
69
69
|
}, [items, showTabs, activeTab]);
|
|
70
|
-
return (_jsx(Section, { paddingX: "x-md-2xl", className: className, surface: "subtle", paddingY: "y-4xl", children: _jsxs(Div, { className: "w-full max-w-4xl mx-auto", children: [_jsxs(Div, { className: "text-left mb-10", children: [_jsx(Heading, { level: 2, variant: "none", gradient: "brand", className: "mb-3", mdSize: "4xl", size: "3xl", weight: "bold", children: title }), subtitle && (_jsx(Text, { className: `max-w-xl ${themed.textSecondary}`, size: "base", children: subtitle }))] }), showTabs && (
|
|
70
|
+
return (_jsx(Section, { paddingX: "x-md-2xl", className: className, surface: "subtle", paddingY: "y-4xl", children: _jsxs(Div, { className: "w-full max-w-4xl mx-auto", children: [_jsxs(Div, { className: "text-left mb-10", children: [_jsx(Heading, { level: 2, variant: "none", gradient: "brand", className: "mb-3", mdSize: "4xl", size: "3xl", weight: "bold", children: title }), subtitle && (_jsx(Text, { className: `max-w-xl ${themed.textSecondary}`, size: "base", children: subtitle }))] }), showTabs && (_jsx(Tabs, { value: activeTab, onChange: setActiveTab, className: "mb-8", children: _jsxs(TabsList, { children: [_jsx(TabsTrigger, { value: "all", children: "All" }), derivedTabs.map((tab) => (_jsx(TabsTrigger, { value: tab.value, children: tab.label }, tab.value)))] }) })), _jsxs(Stack, { gap: "none", rounded: "xl", className: `${themed.bgPrimary} ${__O.hidden} border ${themed.border}`, children: [visibleItems.length === 0 && (_jsx(Text, { paddingY: "3xl", align: "start", className: themed.textSecondary, children: "No FAQs in this category yet." })), visibleItems.map((faq, index) => {
|
|
71
71
|
const isOpen = openIds.has(faq.id);
|
|
72
|
-
return (_jsxs(Div, { className:
|
|
72
|
+
return (_jsxs(Div, { className: `transition-colors duration-200 ${index < visibleItems.length - 1 ? "border-b border-[var(--appkit-color-border)]" : ""} ${isOpen ? "bg-[var(--appkit-color-surface-elevated)]" : ""}`, children: [_jsxs(Button, { variant: "ghost", rounded: "none", className: `w-full text-left px-[1.25rem] py-[1rem] ${flex.between} gap-[1rem] hover:${themed.bgTertiary} transition-colors`, onClick: () => toggle(faq.id), "aria-expanded": isOpen, children: [_jsx(Span, { size: "sm", weight: "medium", className: `flex-1 leading-snug ${isOpen ? "text-primary" : themed.textPrimary}`, children: faq.question }), _jsx(ChevronDown, { className: `w-4 h-4 flex-shrink-0 transition-transform duration-250 ${isOpen ? "rotate-180 text-primary" : themed.textSecondary}` })] }), _jsx(Div, { layout: "grid", className: `transition-all duration-300 ease-out ${isOpen ? "grid-rows-[1fr] opacity-100" : "grid-rows-[0fr] opacity-0"}`, children: _jsx(Div, { className: `${__O.hidden}`, children: _jsx(Div, { paddingY: "b-md-lg", padding: "x-md", children: isHtml(faq.answer) ? (_jsx(RichText, { html: faq.answer, proseClass: "prose prose-sm max-w-none dark:prose-invert" })) : (_jsx(Text, { className: `leading-relaxed ${themed.textSecondary}`, size: "sm", children: faq.answer })) }) }) })] }, faq.id));
|
|
73
73
|
})] }), viewMoreHref && (_jsx(Div, { className: "text-left mt-10", children: _jsxs(TextLink, { rounded: "full", paddingX: "xl", paddingY: "sm", href: viewMoreHref, className: "inline-flex items-[center] gap-[0.5rem] bg-primary/10 text-primary hover:bg-primary/20 dark:bg-primary/15 transition-colors", size: "sm", weight: "medium", children: [viewMoreLabel, hasMore && moreCount > 0 && (_jsxs(Span, { color: "inverse", size: "xs", className: "bg-primary", rounded: "full", padding: "pill-xs", children: ["+", moreCount] }))] }) }))] }) }));
|
|
74
74
|
}
|
|
@@ -11,5 +11,6 @@ export interface FeaturedAuctionsSectionProps {
|
|
|
11
11
|
rows?: number;
|
|
12
12
|
autoScroll?: boolean;
|
|
13
13
|
scrollInterval?: number;
|
|
14
|
+
loop?: boolean;
|
|
14
15
|
}
|
|
15
|
-
export declare function FeaturedAuctionsSection({ title, description, viewMoreHref, viewMoreLabel, className, filterByBrand, initialItems, rows, autoScroll, scrollInterval, }: FeaturedAuctionsSectionProps): React.JSX.Element;
|
|
16
|
+
export declare function FeaturedAuctionsSection({ title, description, viewMoreHref, viewMoreLabel, className, filterByBrand, initialItems, rows, autoScroll, scrollInterval, loop, }: FeaturedAuctionsSectionProps): React.JSX.Element;
|
|
@@ -4,7 +4,7 @@ import { SectionCarousel } from "./SectionCarousel";
|
|
|
4
4
|
import { useFeaturedAuctions } from "../hooks/useFeaturedAuctions";
|
|
5
5
|
import { MarketplaceAuctionCard } from "../../auctions/components/MarketplaceAuctionCard";
|
|
6
6
|
import { CAROUSEL_PER_VIEW } from "../constants/carousel-per-view";
|
|
7
|
-
export function FeaturedAuctionsSection({ title = "Live Auctions", description, viewMoreHref, viewMoreLabel = "View all auctions →", className = "", filterByBrand, initialItems, rows = 1, autoScroll = false, scrollInterval = 5000, }) {
|
|
7
|
+
export function FeaturedAuctionsSection({ title = "Live Auctions", description, viewMoreHref, viewMoreLabel = "View all auctions →", className = "", filterByBrand, initialItems, rows = 1, autoScroll = false, scrollInterval = 5000, loop = true, }) {
|
|
8
8
|
const { data: items = [], isLoading } = useFeaturedAuctions({ filterByBrand, initialData: initialItems });
|
|
9
|
-
return (_jsx(SectionCarousel, { title: title, description: description, pillLabel: "Live Auctions", headingVariant: "editorial", viewMoreHref: viewMoreHref, viewMoreLabel: viewMoreLabel, items: items, isLoading: isLoading, skeletonCount: 4, perView: CAROUSEL_PER_VIEW.standard, gap: 16, rows: Math.min(Math.max(rows, 1), 4), autoScroll: autoScroll, autoScrollInterval: scrollInterval, keyExtractor: (product) => product.id, renderItem: (product) => (_jsx(MarketplaceAuctionCard, { product: product })), className: className }));
|
|
9
|
+
return (_jsx(SectionCarousel, { title: title, description: description, pillLabel: "Live Auctions", headingVariant: "editorial", viewMoreHref: viewMoreHref, viewMoreLabel: viewMoreLabel, items: items, isLoading: isLoading, skeletonCount: 4, perView: CAROUSEL_PER_VIEW.standard, gap: 16, rows: Math.min(Math.max(rows, 1), 4), autoScroll: autoScroll, autoScrollInterval: scrollInterval, loop: loop, keyExtractor: (product) => product.id, renderItem: (product) => (_jsx(MarketplaceAuctionCard, { product: product })), className: className }));
|
|
10
10
|
}
|
|
@@ -11,5 +11,6 @@ export interface FeaturedPreOrdersSectionProps {
|
|
|
11
11
|
rows?: number;
|
|
12
12
|
autoScroll?: boolean;
|
|
13
13
|
scrollInterval?: number;
|
|
14
|
+
loop?: boolean;
|
|
14
15
|
}
|
|
15
|
-
export declare function FeaturedPreOrdersSection({ title, description, viewMoreHref, viewMoreLabel, className, filterByBrand, initialItems, rows, autoScroll, scrollInterval, }: FeaturedPreOrdersSectionProps): React.JSX.Element;
|
|
16
|
+
export declare function FeaturedPreOrdersSection({ title, description, viewMoreHref, viewMoreLabel, className, filterByBrand, initialItems, rows, autoScroll, scrollInterval, loop, }: FeaturedPreOrdersSectionProps): React.JSX.Element;
|
|
@@ -4,7 +4,7 @@ import { SectionCarousel } from "./SectionCarousel";
|
|
|
4
4
|
import { useFeaturedPreOrders } from "../hooks/useFeaturedPreOrders";
|
|
5
5
|
import { MarketplacePreorderCard } from "../../pre-orders/components/MarketplacePreorderCard";
|
|
6
6
|
import { CAROUSEL_PER_VIEW } from "../constants/carousel-per-view";
|
|
7
|
-
export function FeaturedPreOrdersSection({ title = "Reserve Before It Ships", description, viewMoreHref, viewMoreLabel = "View all pre-orders →", className = "", filterByBrand, initialItems, rows = 1, autoScroll = false, scrollInterval = 5000, }) {
|
|
7
|
+
export function FeaturedPreOrdersSection({ title = "Reserve Before It Ships", description, viewMoreHref, viewMoreLabel = "View all pre-orders →", className = "", filterByBrand, initialItems, rows = 1, autoScroll = false, scrollInterval = 5000, loop = true, }) {
|
|
8
8
|
const { data: items = [], isLoading } = useFeaturedPreOrders({ filterByBrand, initialData: initialItems });
|
|
9
|
-
return (_jsx(SectionCarousel, { title: title, description: description, pillLabel: "Pre-Order Incoming", headingVariant: "editorial", viewMoreHref: viewMoreHref, viewMoreLabel: viewMoreLabel, items: items, isLoading: isLoading, skeletonCount: 4, perView: CAROUSEL_PER_VIEW.standard, gap: 16, rows: Math.min(Math.max(rows, 1), 4), autoScroll: autoScroll, autoScrollInterval: scrollInterval, keyExtractor: (product) => product.id, renderItem: (product) => (_jsx(MarketplacePreorderCard, { product: product })), className: className }));
|
|
9
|
+
return (_jsx(SectionCarousel, { title: title, description: description, pillLabel: "Pre-Order Incoming", headingVariant: "editorial", viewMoreHref: viewMoreHref, viewMoreLabel: viewMoreLabel, items: items, isLoading: isLoading, skeletonCount: 4, perView: CAROUSEL_PER_VIEW.standard, gap: 16, rows: Math.min(Math.max(rows, 1), 4), autoScroll: autoScroll, autoScrollInterval: scrollInterval, loop: loop, keyExtractor: (product) => product.id, renderItem: (product) => (_jsx(MarketplacePreorderCard, { product: product })), className: className }));
|
|
10
10
|
}
|
|
@@ -11,5 +11,6 @@ export interface FeaturedProductsSectionProps {
|
|
|
11
11
|
maxItems?: number;
|
|
12
12
|
autoScroll?: boolean;
|
|
13
13
|
scrollInterval?: number;
|
|
14
|
+
loop?: boolean;
|
|
14
15
|
}
|
|
15
|
-
export declare function FeaturedProductsSection({ title, description, viewMoreHref, viewMoreLabel, className, filterByBrand, initialItems, rows, autoScroll, scrollInterval, }: FeaturedProductsSectionProps): import("react").JSX.Element;
|
|
16
|
+
export declare function FeaturedProductsSection({ title, description, viewMoreHref, viewMoreLabel, className, filterByBrand, initialItems, rows, autoScroll, scrollInterval, loop, }: FeaturedProductsSectionProps): import("react").JSX.Element;
|
|
@@ -5,7 +5,7 @@ import { useFeaturedProducts } from "../hooks/useFeaturedProducts";
|
|
|
5
5
|
import { InteractiveProductCard } from "../../products/components/InteractiveProductCard";
|
|
6
6
|
import { ROUTES } from "../../../next";
|
|
7
7
|
import { CAROUSEL_PER_VIEW } from "../constants/carousel-per-view";
|
|
8
|
-
export function FeaturedProductsSection({ title = "Featured Products", description, viewMoreHref, viewMoreLabel = "View all products →", className = "", filterByBrand, initialItems, rows = 1, autoScroll = false, scrollInterval = 5000, }) {
|
|
8
|
+
export function FeaturedProductsSection({ title = "Featured Products", description, viewMoreHref, viewMoreLabel = "View all products →", className = "", filterByBrand, initialItems, rows = 1, autoScroll = false, scrollInterval = 5000, loop = true, }) {
|
|
9
9
|
const { data, isLoading } = useFeaturedProducts({
|
|
10
10
|
filterByBrand,
|
|
11
11
|
initialData: initialItems?.length
|
|
@@ -13,5 +13,5 @@ export function FeaturedProductsSection({ title = "Featured Products", descripti
|
|
|
13
13
|
: undefined,
|
|
14
14
|
});
|
|
15
15
|
const items = data?.items ?? [];
|
|
16
|
-
return (_jsx(SectionCarousel, { title: title, description: description, pillLabel: "Featured Products", headingVariant: "editorial", viewMoreHref: viewMoreHref, viewMoreLabel: viewMoreLabel, items: items, isLoading: isLoading, skeletonCount: 4, perView: CAROUSEL_PER_VIEW.standard, gap: 16, rows: Math.min(Math.max(rows, 1), 4), autoScroll: autoScroll, autoScrollInterval: scrollInterval, keyExtractor: (product) => product.id, renderItem: (product) => (_jsx(InteractiveProductCard, { product: product, href: String(ROUTES.PUBLIC.PRODUCT_DETAIL(product.slug ?? product.id ?? "")) })), className: className }));
|
|
16
|
+
return (_jsx(SectionCarousel, { title: title, description: description, pillLabel: "Featured Products", headingVariant: "editorial", viewMoreHref: viewMoreHref, viewMoreLabel: viewMoreLabel, items: items, isLoading: isLoading, skeletonCount: 4, perView: CAROUSEL_PER_VIEW.standard, gap: 16, rows: Math.min(Math.max(rows, 1), 4), autoScroll: autoScroll, autoScrollInterval: scrollInterval, loop: loop, keyExtractor: (product) => product.id, renderItem: (product) => (_jsx(InteractiveProductCard, { product: product, href: String(ROUTES.PUBLIC.PRODUCT_DETAIL(product.slug ?? product.id ?? "")) })), className: className }));
|
|
17
17
|
}
|
|
@@ -8,5 +8,8 @@ export interface FeaturedStoresSectionProps {
|
|
|
8
8
|
limit?: number;
|
|
9
9
|
className?: string;
|
|
10
10
|
initialItems?: StoreListItem[];
|
|
11
|
+
autoScroll?: boolean;
|
|
12
|
+
scrollInterval?: number;
|
|
13
|
+
loop?: boolean;
|
|
11
14
|
}
|
|
12
|
-
export declare function FeaturedStoresSection({ title, description, viewMoreHref, viewMoreLabel, limit, className, initialItems, }: FeaturedStoresSectionProps): React.JSX.Element;
|
|
15
|
+
export declare function FeaturedStoresSection({ title, description, viewMoreHref, viewMoreLabel, limit, className, initialItems, autoScroll, scrollInterval, loop, }: FeaturedStoresSectionProps): React.JSX.Element;
|
|
@@ -5,7 +5,7 @@ import { useFeaturedStores } from "../hooks/useFeaturedStores";
|
|
|
5
5
|
import { InteractiveStoreCard } from "../../stores/components/InteractiveStoreCard";
|
|
6
6
|
import { ROUTES } from "../../../next";
|
|
7
7
|
import { CAROUSEL_PER_VIEW } from "../constants/carousel-per-view";
|
|
8
|
-
export function FeaturedStoresSection({ title = "Featured Stores", description, viewMoreHref, viewMoreLabel = "View all stores →", limit = 8, className = "", initialItems, }) {
|
|
8
|
+
export function FeaturedStoresSection({ title = "Featured Stores", description, viewMoreHref, viewMoreLabel = "View all stores →", limit = 8, className = "", initialItems, autoScroll = false, scrollInterval = 5000, loop = true, }) {
|
|
9
9
|
const { data: items = [], isLoading } = useFeaturedStores(limit, { initialData: initialItems });
|
|
10
|
-
return (_jsx(SectionCarousel, { title: title, description: description, pillLabel: "Top Stores", headingVariant: "editorial", viewMoreHref: viewMoreHref, viewMoreLabel: viewMoreLabel, items: items, isLoading: isLoading, skeletonCount: 4, perView: CAROUSEL_PER_VIEW.standard, gap: 16, keyExtractor: (store) => store.id, renderItem: (store) => (_jsx(InteractiveStoreCard, { store: store, href: ROUTES.PUBLIC.STORE_DETAIL(store.storeSlug) })), className: className }));
|
|
10
|
+
return (_jsx(SectionCarousel, { title: title, description: description, pillLabel: "Top Stores", headingVariant: "editorial", viewMoreHref: viewMoreHref, viewMoreLabel: viewMoreLabel, items: items, isLoading: isLoading, skeletonCount: 4, perView: CAROUSEL_PER_VIEW.standard, gap: 16, autoScroll: autoScroll, autoScrollInterval: scrollInterval, loop: loop, keyExtractor: (store) => store.id, renderItem: (store) => (_jsx(InteractiveStoreCard, { store: store, href: ROUTES.PUBLIC.STORE_DETAIL(store.storeSlug) })), className: className }));
|
|
11
11
|
}
|
|
@@ -5,5 +5,8 @@ export interface HomepageCustomerReviewsSectionProps {
|
|
|
5
5
|
viewMoreHref?: string;
|
|
6
6
|
viewMoreLabel?: string;
|
|
7
7
|
className?: string;
|
|
8
|
+
autoScroll?: boolean;
|
|
9
|
+
scrollInterval?: number;
|
|
10
|
+
loop?: boolean;
|
|
8
11
|
}
|
|
9
|
-
export declare function HomepageCustomerReviewsSection({ title, subtitle, viewMoreHref, viewMoreLabel, className, }: HomepageCustomerReviewsSectionProps): React.JSX.Element;
|
|
12
|
+
export declare function HomepageCustomerReviewsSection({ title, subtitle, viewMoreHref, viewMoreLabel, className, autoScroll, scrollInterval, loop, }: HomepageCustomerReviewsSectionProps): React.JSX.Element;
|
|
@@ -3,7 +3,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
3
3
|
import { CustomerReviewsSection } from "./CustomerReviewsSection";
|
|
4
4
|
import { useHomepageReviews } from "../hooks/useHomepageReviews";
|
|
5
5
|
import { ReviewCard } from "../../reviews/components";
|
|
6
|
-
export function HomepageCustomerReviewsSection({ title = "What Our Customers Say", subtitle, viewMoreHref, viewMoreLabel = "See all reviews →", className = "", }) {
|
|
6
|
+
export function HomepageCustomerReviewsSection({ title = "What Our Customers Say", subtitle, viewMoreHref, viewMoreLabel = "See all reviews →", className = "", autoScroll = true, scrollInterval = 4500, loop = true, }) {
|
|
7
7
|
const { data: reviews = [], isLoading } = useHomepageReviews();
|
|
8
|
-
return (_jsx(CustomerReviewsSection, { title: title, subtitle: subtitle, items: reviews, renderItem: (review) => (_jsx(ReviewCard, { review: review, className: "h-full border-zinc-200 shadow-sm border-[var(--appkit-color-border)]" })), viewMoreHref: viewMoreHref, viewMoreLabel: viewMoreLabel, isLoading: isLoading, keyExtractor: (review) => review.id, className: className }));
|
|
8
|
+
return (_jsx(CustomerReviewsSection, { title: title, subtitle: subtitle, items: reviews, renderItem: (review) => (_jsx(ReviewCard, { review: review, className: "h-full border-zinc-200 shadow-sm border-[var(--appkit-color-border)]" })), viewMoreHref: viewMoreHref, viewMoreLabel: viewMoreLabel, isLoading: isLoading, keyExtractor: (review) => review.id, className: className, autoScroll: autoScroll, scrollInterval: scrollInterval, loop: loop }));
|
|
9
9
|
}
|
|
@@ -41,6 +41,8 @@ export interface SectionCarouselProps<T = unknown> {
|
|
|
41
41
|
autoScroll?: boolean;
|
|
42
42
|
/** Interval between auto-scroll steps in ms. Default: 3500 */
|
|
43
43
|
autoScrollInterval?: number;
|
|
44
|
+
/** Circular auto-rotate at the carousel edges. Default: true */
|
|
45
|
+
loop?: boolean;
|
|
44
46
|
/** Key extractor for the HorizontalScroller. */
|
|
45
47
|
keyExtractor?: (item: T, index: number) => string;
|
|
46
48
|
/**
|
|
@@ -72,4 +74,4 @@ export interface SectionCarouselProps<T = unknown> {
|
|
|
72
74
|
*/
|
|
73
75
|
minItemWidth?: number;
|
|
74
76
|
}
|
|
75
|
-
export declare function SectionCarousel<T = unknown>({ title, description, headingVariant, pillLabel, backgroundImage, viewMoreHref, viewMoreLabel, items, renderItem, perView, gap, autoScroll, autoScrollInterval, keyExtractor, rows, className, isLoading, skeletonCount, lightText, showPeek: _showPeek, minItemWidth, }: SectionCarouselProps<T>): React.JSX.Element | null;
|
|
77
|
+
export declare function SectionCarousel<T = unknown>({ title, description, headingVariant, pillLabel, backgroundImage, viewMoreHref, viewMoreLabel, items, renderItem, perView, gap, autoScroll, autoScrollInterval, loop, keyExtractor, rows, className, isLoading, skeletonCount, lightText, showPeek: _showPeek, minItemWidth, }: SectionCarouselProps<T>): React.JSX.Element | null;
|
|
@@ -12,7 +12,7 @@ function CarouselSkeleton({ count }) {
|
|
|
12
12
|
return (_jsx(Div, { layout: "flex", gap: "4", className: `${__O.hidden}`, padding: "x-md", children: Array.from({ length: count }).map((_, i) => (_jsxs(Stack, { className: "flex-none min-w-[clamp(150px,18vw,260px)] max-w-[clamp(240px,36vw,380px)] h-[clamp(180px,26vh,260px)]", gap: "sm", children: [_jsx(Div, { className: `aspect-square ${skeleton.image}`, rounded: "xl" }), _jsx(Div, { className: `${skeleton.text} w-3/4` }), _jsx(Div, { className: `${skeleton.text} w-1/2` })] }, i))) }));
|
|
13
13
|
}
|
|
14
14
|
// --- Component ---------------------------------------------------------------
|
|
15
|
-
export function SectionCarousel({ title, description, headingVariant = "editorial", pillLabel, backgroundImage, viewMoreHref, viewMoreLabel = "View all →", items, renderItem, perView = CAROUSEL_PER_VIEW.standard, gap = 16, autoScroll = false, autoScrollInterval = 3500, keyExtractor, rows = 1, className = "", isLoading = false, skeletonCount = 4, lightText, showPeek: _showPeek = false, minItemWidth = 220, }) {
|
|
15
|
+
export function SectionCarousel({ title, description, headingVariant = "editorial", pillLabel, backgroundImage, viewMoreHref, viewMoreLabel = "View all →", items, renderItem, perView = CAROUSEL_PER_VIEW.standard, gap = 16, autoScroll = false, autoScrollInterval = 3500, loop = true, keyExtractor, rows = 1, className = "", isLoading = false, skeletonCount = 4, lightText, showPeek: _showPeek = false, minItemWidth = 220, }) {
|
|
16
16
|
if (!isLoading && items.length === 0)
|
|
17
17
|
return null;
|
|
18
18
|
const hasBg = Boolean(backgroundImage);
|
|
@@ -41,5 +41,5 @@ export function SectionCarousel({ title, description, headingVariant = "editoria
|
|
|
41
41
|
headingClass,
|
|
42
42
|
]
|
|
43
43
|
.filter(Boolean)
|
|
44
|
-
.join(" "), children: title }), headingVariant === "editorial" && (_jsxs(Row, { align: "center", justify: "center", gap: "sm", textSize: "xs", color: "faint", className: "mt-1 select-none", "aria-hidden": "true", children: [_jsx(Span, { className: "h-px w-6 bg-current" }), _jsx(Span, { size: "xs", children: "\u2736" }), _jsx(Span, { className: "h-px w-6 bg-current" })] })), description && (_jsx(Text, { className: `${descVariant} mt-2`, size: "base", children: description }))] }), isLoading ? (_jsx(CarouselSkeleton, { count: skeletonCount })) : (_jsx(HorizontalScroller, { items: items, renderItem: renderItem, perView: perView, gap: gap, autoScroll: autoScroll, autoScrollInterval: autoScrollInterval, loop:
|
|
44
|
+
.join(" "), children: title }), headingVariant === "editorial" && (_jsxs(Row, { align: "center", justify: "center", gap: "sm", textSize: "xs", color: "faint", className: "mt-1 select-none", "aria-hidden": "true", children: [_jsx(Span, { className: "h-px w-6 bg-current" }), _jsx(Span, { size: "xs", children: "\u2736" }), _jsx(Span, { className: "h-px w-6 bg-current" })] })), description && (_jsx(Text, { className: `${descVariant} mt-2`, size: "base", children: description }))] }), isLoading ? (_jsx(CarouselSkeleton, { count: skeletonCount })) : (_jsx(HorizontalScroller, { items: items, renderItem: renderItem, perView: perView, gap: gap, autoScroll: autoScroll, autoScrollInterval: autoScrollInterval, loop: loop, keyExtractor: keyExtractor, rows: rows, minItemWidth: minItemWidth, showArrows: true, snapToItems: true, showFadeEdges: true, showScrollbar: false, pauseOnHover: true })), viewMoreHref && !isLoading && (_jsx(Row, { className: "mt-6", justify: "start", children: _jsx(TextLink, { rounded: "lg", paddingX: "xl", paddingY: "sm", href: viewMoreHref, className: `inline-flex items-[center] gap-[0.375rem] border transition-colors ${useLightText ? "border-white/40 text-white hover:bg-[rgba(255,255,255,0.1)]" : "border-[var(--appkit-color-border)] text-[var(--appkit-color-text-muted)] hover:bg-[var(--appkit-color-surface-elevated)]"}`, size: "sm", weight: "medium", children: viewMoreLabel }) }))] })] }));
|
|
45
45
|
}
|
|
@@ -14,5 +14,8 @@ export interface ShopByCategorySectionProps {
|
|
|
14
14
|
rootOnly?: boolean;
|
|
15
15
|
rootCategoryId?: string;
|
|
16
16
|
};
|
|
17
|
+
autoScroll?: boolean;
|
|
18
|
+
scrollInterval?: number;
|
|
19
|
+
loop?: boolean;
|
|
17
20
|
}
|
|
18
|
-
export declare function ShopByCategorySection({ title, subtitle, limit, viewMoreHref, viewMoreLabel, className, initialItems, cta, filters, }: ShopByCategorySectionProps): import("react").JSX.Element | null;
|
|
21
|
+
export declare function ShopByCategorySection({ title, subtitle, limit, viewMoreHref, viewMoreLabel, className, initialItems, cta, filters, autoScroll, scrollInterval, loop, }: ShopByCategorySectionProps): import("react").JSX.Element | null;
|
|
@@ -37,7 +37,7 @@ function FilterChip({ label, active, onClick, }) {
|
|
|
37
37
|
: "border-[var(--appkit-color-border)] bg-[var(--appkit-color-surface-elevated)] text-[var(--appkit-color-text-muted)] hover:border-[var(--appkit-color-primary)]",
|
|
38
38
|
].join(" "), children: label }));
|
|
39
39
|
}
|
|
40
|
-
export function ShopByCategorySection({ title = "Shop by Category", subtitle, limit = 12, viewMoreHref, viewMoreLabel = "View all categories →", className = "", initialItems, cta, filters, }) {
|
|
40
|
+
export function ShopByCategorySection({ title = "Shop by Category", subtitle, limit = 12, viewMoreHref, viewMoreLabel = "View all categories →", className = "", initialItems, cta, filters, autoScroll = true, scrollInterval = 3500, loop = true, }) {
|
|
41
41
|
const themed = { textPrimary: THEMED_TEXT_PRIMARY };
|
|
42
42
|
const { data: allCategories = [], isLoading } = useTopCategories(limit, { initialData: initialItems });
|
|
43
43
|
const [activeFilter, setActiveFilter] = useState("all");
|
|
@@ -68,5 +68,5 @@ export function ShopByCategorySection({ title = "Shop by Category", subtitle, li
|
|
|
68
68
|
if (!cat)
|
|
69
69
|
return null;
|
|
70
70
|
return (_jsx(FilterChip, { label: cat.name, active: activeFilter === id, onClick: () => setActiveFilter(activeFilter === id ? "all" : id) }, id));
|
|
71
|
-
})] })), isLoading ? (_jsx(Div, { layout: "flex", gap: "3", className: `${__O.hidden} px-[0.25rem]`, children: Array.from({ length: 6 }).map((_, i) => (_jsx(Div, { className: "flex-none h-[104px] w-[108px] animate-pulse", surface: "subtle", rounded: "xl" }, i))) })) : (_jsx(HorizontalScroller, { items: categories, renderItem: (cat) => _jsx(CategoryChip, { category: cat }), perView: CAROUSEL_PER_VIEW.standard, gap: 16, keyExtractor: (cat) => cat.id, autoScroll:
|
|
71
|
+
})] })), isLoading ? (_jsx(Div, { layout: "flex", gap: "3", className: `${__O.hidden} px-[0.25rem]`, children: Array.from({ length: 6 }).map((_, i) => (_jsx(Div, { className: "flex-none h-[104px] w-[108px] animate-pulse", surface: "subtle", rounded: "xl" }, i))) })) : (_jsx(HorizontalScroller, { items: categories, renderItem: (cat) => _jsx(CategoryChip, { category: cat }), perView: CAROUSEL_PER_VIEW.standard, gap: 16, keyExtractor: (cat) => cat.id, autoScroll: autoScroll, autoScrollInterval: scrollInterval, showArrows: true, snapToItems: true, showFadeEdges: true, showScrollbar: false, loop: loop, pauseOnHover: true })), cta && !isLoading && (_jsx(Div, { className: "mt-6 text-left", children: _jsx(Link, { href: cta.href, className: CTA_CLASSES[cta.variant], children: cta.label }) })), !cta && viewMoreHref && !isLoading && (_jsx(Div, { className: "mt-6 text-left", children: _jsx(Link, { href: viewMoreHref, className: "inline-flex items-center gap-[var(--appkit-space-1)] text-[length:var(--appkit-text-sm)] font-medium text-[var(--appkit-color-primary)] hover:opacity-80", children: viewMoreLabel }) }))] }) }));
|
|
72
72
|
}
|