@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
|
@@ -53,7 +53,7 @@ function renderSectionElement(section, newsletterFormSlot, faqItems, slides, liv
|
|
|
53
53
|
}
|
|
54
54
|
case "categories": {
|
|
55
55
|
const cfg = config;
|
|
56
|
-
return (_jsx(ShopByCategorySection, { title: cleanTitle(cfg?.title) || "Shop by Category", viewMoreHref: ROUTES.PUBLIC.CATEGORIES, viewMoreLabel: "All categories \u2192", initialItems: sectionData.categories, cta: cfg?.cta, filters: cfg?.filters }));
|
|
56
|
+
return (_jsx(ShopByCategorySection, { title: cleanTitle(cfg?.title) || "Shop by Category", viewMoreHref: ROUTES.PUBLIC.CATEGORIES, viewMoreLabel: "All categories \u2192", initialItems: sectionData.categories, cta: cfg?.cta, filters: cfg?.filters, autoScroll: cfg?.autoScroll, scrollInterval: cfg?.scrollInterval, loop: cfg?.loop }));
|
|
57
57
|
}
|
|
58
58
|
case "stats": {
|
|
59
59
|
const cfg = config;
|
|
@@ -84,27 +84,27 @@ function renderSectionElement(section, newsletterFormSlot, faqItems, slides, liv
|
|
|
84
84
|
}
|
|
85
85
|
case "products": {
|
|
86
86
|
const cfg = config;
|
|
87
|
-
return (_jsx(FeaturedProductsSection, { title: cleanTitle(cfg?.title) || "Featured Products", viewMoreHref: ROUTES.PUBLIC.PRODUCTS, viewMoreLabel: "View all products \u2192", filterByBrand: cfg?.filterByBrand, initialItems: sectionData.products, rows: cfg?.rows, maxItems: cfg?.maxItems, autoScroll: cfg?.autoScroll, scrollInterval: cfg?.scrollInterval }));
|
|
87
|
+
return (_jsx(FeaturedProductsSection, { title: cleanTitle(cfg?.title) || "Featured Products", viewMoreHref: ROUTES.PUBLIC.PRODUCTS, viewMoreLabel: "View all products \u2192", filterByBrand: cfg?.filterByBrand, initialItems: sectionData.products, rows: cfg?.rows, maxItems: cfg?.maxItems, autoScroll: cfg?.autoScroll, scrollInterval: cfg?.scrollInterval, loop: cfg?.loop }));
|
|
88
88
|
}
|
|
89
89
|
case "auctions": {
|
|
90
90
|
const cfg = config;
|
|
91
|
-
return (_jsx(FeaturedAuctionsSection, { title: cleanTitle(cfg?.title) || "Live Auctions", viewMoreHref: ROUTES.PUBLIC.AUCTIONS, viewMoreLabel: "View all auctions \u2192", filterByBrand: cfg?.filterByBrand, initialItems: sectionData.auctions, rows: cfg?.rows, autoScroll: cfg?.autoScroll, scrollInterval: cfg?.scrollInterval }));
|
|
91
|
+
return (_jsx(FeaturedAuctionsSection, { title: cleanTitle(cfg?.title) || "Live Auctions", viewMoreHref: ROUTES.PUBLIC.AUCTIONS, viewMoreLabel: "View all auctions \u2192", filterByBrand: cfg?.filterByBrand, initialItems: sectionData.auctions, rows: cfg?.rows, autoScroll: cfg?.autoScroll, scrollInterval: cfg?.scrollInterval, loop: cfg?.loop }));
|
|
92
92
|
}
|
|
93
93
|
case "pre-orders": {
|
|
94
94
|
const cfg = config;
|
|
95
|
-
return (_jsx(FeaturedPreOrdersSection, { title: cleanTitle(cfg?.title) || "Reserve Before It Ships", viewMoreHref: ROUTES.PUBLIC.PRE_ORDERS, viewMoreLabel: "View all pre-orders \u2192", filterByBrand: cfg?.filterByBrand, initialItems: sectionData.preOrders, rows: cfg?.rows, autoScroll: cfg?.autoScroll, scrollInterval: cfg?.scrollInterval }));
|
|
95
|
+
return (_jsx(FeaturedPreOrdersSection, { title: cleanTitle(cfg?.title) || "Reserve Before It Ships", viewMoreHref: ROUTES.PUBLIC.PRE_ORDERS, viewMoreLabel: "View all pre-orders \u2192", filterByBrand: cfg?.filterByBrand, initialItems: sectionData.preOrders, rows: cfg?.rows, autoScroll: cfg?.autoScroll, scrollInterval: cfg?.scrollInterval, loop: cfg?.loop }));
|
|
96
96
|
}
|
|
97
97
|
case "stores": {
|
|
98
98
|
const cfg = config;
|
|
99
|
-
return (_jsx(FeaturedStoresSection, { title: cleanTitle(cfg?.title) || "Featured Stores", viewMoreHref: ROUTES.PUBLIC.STORES, viewMoreLabel: "View all stores \u2192", initialItems: sectionData.stores }));
|
|
99
|
+
return (_jsx(FeaturedStoresSection, { title: cleanTitle(cfg?.title) || "Featured Stores", viewMoreHref: ROUTES.PUBLIC.STORES, viewMoreLabel: "View all stores \u2192", initialItems: sectionData.stores, autoScroll: cfg?.autoScroll, scrollInterval: cfg?.scrollInterval, loop: cfg?.loop }));
|
|
100
100
|
}
|
|
101
101
|
case "events": {
|
|
102
102
|
const cfg = config;
|
|
103
|
-
return (_jsx(EventsSection, { title: cleanTitle(cfg?.title) || "Events & Offers", viewMoreHref: ROUTES.PUBLIC.EVENTS, viewMoreLabel: "View all events \u2192", initialItems: sectionData.events }));
|
|
103
|
+
return (_jsx(EventsSection, { title: cleanTitle(cfg?.title) || "Events & Offers", viewMoreHref: ROUTES.PUBLIC.EVENTS, viewMoreLabel: "View all events \u2192", initialItems: sectionData.events, autoScroll: cfg?.autoScroll, scrollInterval: cfg?.scrollInterval, loop: cfg?.loop }));
|
|
104
104
|
}
|
|
105
105
|
case "reviews": {
|
|
106
106
|
const cfg = config;
|
|
107
|
-
return (_jsx(HomepageCustomerReviewsSection, { title: cleanTitle(cfg?.title) || "What Our Customers Say", viewMoreHref: ROUTES.PUBLIC.REVIEWS, viewMoreLabel: "See all reviews \u2192" }));
|
|
107
|
+
return (_jsx(HomepageCustomerReviewsSection, { title: cleanTitle(cfg?.title) || "What Our Customers Say", viewMoreHref: ROUTES.PUBLIC.REVIEWS, viewMoreLabel: "See all reviews \u2192", autoScroll: cfg?.autoScroll, scrollInterval: cfg?.scrollInterval, loop: cfg?.loop }));
|
|
108
108
|
}
|
|
109
109
|
case "banner": {
|
|
110
110
|
const cfg = config;
|
|
@@ -156,7 +156,7 @@ function renderSectionElement(section, newsletterFormSlot, faqItems, slides, liv
|
|
|
156
156
|
}
|
|
157
157
|
case "brands": {
|
|
158
158
|
const cfg = config;
|
|
159
|
-
return (_jsx(BrandsSection, { title: cleanTitle(cfg?.title) || "Top Brands", subtitle: cfg?.subtitle, limit: cfg?.maxBrands || 12, viewMoreHref: ROUTES.PUBLIC.CATEGORIES, viewMoreLabel: "All brands \u2192", initialItems: sectionData.brands, cta: cfg?.cta, filters: cfg?.filters }));
|
|
159
|
+
return (_jsx(BrandsSection, { title: cleanTitle(cfg?.title) || "Top Brands", subtitle: cfg?.subtitle, limit: cfg?.maxBrands || 12, viewMoreHref: ROUTES.PUBLIC.CATEGORIES, viewMoreLabel: "All brands \u2192", initialItems: sectionData.brands, cta: cfg?.cta, filters: cfg?.filters, autoScroll: cfg?.autoScroll, scrollInterval: cfg?.scrollInterval, loop: cfg?.loop }));
|
|
160
160
|
}
|
|
161
161
|
case "social-feed": {
|
|
162
162
|
const cfg = config;
|
|
@@ -169,7 +169,7 @@ function renderSectionElement(section, newsletterFormSlot, faqItems, slides, liv
|
|
|
169
169
|
const cfg = config;
|
|
170
170
|
if (!cfg?.cards?.length)
|
|
171
171
|
return null;
|
|
172
|
-
return (_jsx(CustomCardsSection, { title: cleanTitle(cfg.title), layout: cfg.layout ?? "grid", columns: cfg.columns ?? 3, cards: cfg.cards, autoScroll: cfg.autoScroll, scrollIntervalMs: cfg.scrollIntervalMs }));
|
|
172
|
+
return (_jsx(CustomCardsSection, { title: cleanTitle(cfg.title), layout: cfg.layout ?? "grid", columns: cfg.columns ?? 3, cards: cfg.cards, autoScroll: cfg.autoScroll, scrollIntervalMs: cfg.scrollIntervalMs, loop: cfg.loop }));
|
|
173
173
|
}
|
|
174
174
|
case "google-reviews": {
|
|
175
175
|
const cfg = config;
|
|
@@ -196,6 +196,8 @@ export interface CategoriesSectionConfig {
|
|
|
196
196
|
maxCategories: 4;
|
|
197
197
|
autoScroll: boolean;
|
|
198
198
|
scrollInterval: number;
|
|
199
|
+
/** Circular auto-rotate at the carousel edges. Default: true. */
|
|
200
|
+
loop?: boolean;
|
|
199
201
|
/** Optional CTA button rendered below the scroller. */
|
|
200
202
|
cta?: SectionCTA;
|
|
201
203
|
/** Optional client-side filter chips above the scroller. */
|
|
@@ -213,6 +215,8 @@ export interface BrandsSectionConfig {
|
|
|
213
215
|
maxBrands: number;
|
|
214
216
|
autoScroll: boolean;
|
|
215
217
|
scrollInterval: number;
|
|
218
|
+
/** Circular auto-rotate at the carousel edges. Default: true. */
|
|
219
|
+
loop?: boolean;
|
|
216
220
|
/** Optional CTA button rendered below the scroller. */
|
|
217
221
|
cta?: SectionCTA;
|
|
218
222
|
/** Optional client-side filter chips above the scroller. */
|
|
@@ -306,6 +310,8 @@ export interface ReviewsSectionConfig {
|
|
|
306
310
|
mobileItemsPerView: 1;
|
|
307
311
|
autoScroll: boolean;
|
|
308
312
|
scrollInterval: number;
|
|
313
|
+
/** Circular auto-rotate at the carousel edges. Default: true. */
|
|
314
|
+
loop?: boolean;
|
|
309
315
|
source?: "platform" | "google";
|
|
310
316
|
placeId?: string;
|
|
311
317
|
}
|
|
@@ -496,6 +502,8 @@ export interface CustomCardsSectionConfig {
|
|
|
496
502
|
cards: CustomCardsCard[];
|
|
497
503
|
autoScroll?: boolean;
|
|
498
504
|
scrollIntervalMs?: number;
|
|
505
|
+
/** Circular auto-rotate at the carousel edges. Default: true. */
|
|
506
|
+
loop?: boolean;
|
|
499
507
|
}
|
|
500
508
|
export type CollectionCardType = "products" | "auctions" | "pre-orders" | "stores" | "events" | "blog-posts" | "reviews" | "brands" | "categories";
|
|
501
509
|
export interface CollectionCardsEntry {
|
|
@@ -8,7 +8,7 @@ export function FooterLayout({ brandName, brandDescription, socialLinks, linkGro
|
|
|
8
8
|
const [openGroups, setOpenGroups] = useState({});
|
|
9
9
|
const toggleGroup = (idx) => setOpenGroups((prev) => ({ ...prev, [idx]: !prev[idx] }));
|
|
10
10
|
const visibleTrustItems = trustBarItems.filter((item) => item.visible !== false);
|
|
11
|
-
return (_jsxs(BlockFooter, { id: id, className: "bg-
|
|
11
|
+
return (_jsxs(BlockFooter, { id: id, className: "bg-[var(--appkit-color-bg)] border-t border-[var(--appkit-color-border-subtle)]", children: [showTrustBar && visibleTrustItems.length > 0 && (_jsx(Div, { border: "subtle", className: "border-b", padding: "y-xl", children: _jsx(Div, { paddingX: "x-page", className: "container mx-auto max-w-[1920px]", children: _jsx(Row, { as: "ul", wrap: true, justify: "center", gap: "lg", className: "lg:gap-[var(--appkit-space-10)]", children: visibleTrustItems.map((item, i) => (_jsx(Li, { children: _jsxs(Row, { textSize: "sm", gap: "sm", className: "min-w-[160px]", children: [_jsx(Span, { className: "flex-shrink-0 text-primary-600 dark:text-secondary-400 w-5 h-5", children: item.icon }), _jsxs(Span, { children: [_jsx(Span, { size: "sm", weight: "bold", className: "block", color: "primary", children: item.label }), item.subtitle && (_jsx(Span, { size: "xs", className: "block", color: "muted", children: item.subtitle }))] })] }) }, item.id ?? String(i)))) }) }) })), _jsxs(Div, { paddingX: "x-page", className: "container mx-auto max-w-[1920px] lg:py-[var(--appkit-space-14)]", padding: "y-2xl", children: [_jsxs(Div, { className: "grid grid-cols-1 lg:grid-cols-5 gap-[var(--appkit-space-10)] lg:gap-[var(--appkit-space-16)]", children: [_jsxs(Stack, { className: "lg:col-span-2", gap: "md", children: [_jsx(Heading, { level: 5, size: "xl", weight: "bold", color: "primary", children: brandName }), _jsx(Text, { className: "leading-relaxed max-w-sm", color: "muted", size: "sm", children: brandDescription }), socialLinks.length > 0 && (_jsx(Row, { as: Ul, gap: "sm", children: socialLinks.map((link) => (_jsx(Li, { children: _jsx(Link, { href: link.href, "aria-label": link.ariaLabel, target: "_blank", rel: "noopener noreferrer", className: "flex items-center justify-center w-9 h-9 rounded-full border border-[var(--appkit-color-border)] text-[var(--appkit-color-text-muted)] hover:text-primary dark:hover:text-secondary hover:border-primary/40 dark:hover:border-secondary/40 transition-colors", children: link.icon }) }, link.platform))) })), newsletterEnabled && newsletterSlot && (_jsx(Div, { padding: "t-xs", children: newsletterSlot }))] }), _jsx(Div, { className: `lg:col-span-3 grid grid-cols-1 gap-[var(--appkit-space-0)] lg:gap-[var(--appkit-space-8)] ${linkGroups.length <= 3 ? "lg:grid-cols-3" :
|
|
12
12
|
linkGroups.length === 4 ? "lg:grid-cols-4" :
|
|
13
|
-
"lg:grid-cols-5"}`, children: linkGroups.map((group, idx) => (_jsxs(Div, { children: [_jsxs(Button, { type: "button", variant: "ghost", onClick: () => toggleGroup(idx), className: "w-full justify-between border-b
|
|
13
|
+
"lg:grid-cols-5"}`, children: linkGroups.map((group, idx) => (_jsxs(Div, { children: [_jsxs(Button, { type: "button", variant: "ghost", onClick: () => toggleGroup(idx), className: "w-full justify-between border-b py-[var(--appkit-space-3)] text-left text-[length:var(--appkit-text-sm)] font-semibold transition-colors border-[var(--appkit-color-border-subtle)] text-[var(--appkit-color-text)] hover:text-primary dark:hover:text-secondary lg:hidden", "aria-expanded": !!openGroups[idx], children: [group.heading, _jsx(ChevronDown, { className: `w-4 h-4 transition-transform duration-200 ${openGroups[idx] ? "rotate-180" : ""}` })] }), _jsx(Ul, { className: `lg:hidden overflow-hidden transition-all duration-200 ${openGroups[idx] ? "max-h-96 py-[var(--appkit-space-3)]" : "max-h-0"} space-y-2.5`, children: group.links.map((link) => (_jsx(Li, { children: _jsx(Link, { href: link.href, className: "text-[length:var(--appkit-text-sm)] text-[var(--appkit-color-text-muted)] hover:text-primary dark:hover:text-secondary transition-colors", children: link.label }) }, link.href))) }), _jsxs(Div, { className: "hidden lg:block", children: [_jsx(Text, { className: "tracking-wider mb-3", color: "muted", size: "xs", weight: "semibold", transform: "uppercase", children: group.heading }), _jsx(Ul, { className: "space-y-2.5", children: group.links.map((link) => (_jsx(Li, { children: _jsx(Link, { href: link.href, className: "text-[length:var(--appkit-text-sm)] text-[var(--appkit-color-text-muted)] hover:text-primary dark:hover:text-secondary transition-colors", children: link.label }) }, link.href))) })] })] }, idx))) })] }), _jsxs(Stack, { direction: "sm-row", color: "muted", textSize: "xs", justify: "between", border: "default", className: "mt-10 border-t border-[var(--appkit-color-border-subtle)] text-[var(--appkit-color-text-muted)]", padding: "t-lg", align: "center", gap: "3", children: [_jsx(Text, { size: "xs", color: "muted", children: copyrightText }), bottomLinks.length > 0 && (_jsx(Nav, { "aria-label": "Site utilities", children: _jsx(Ul, { className: "flex flex-wrap items-center gap-x-4 gap-y-1 justify-center", children: bottomLinks.map((link) => (_jsx(Li, { children: _jsx(Link, { href: link.href, className: "text-[length:var(--appkit-text-xs)] text-[var(--appkit-color-text-muted)] hover:text-primary dark:hover:text-secondary transition-colors underline-offset-2 hover:underline", children: link.label }) }, link.href))) }) })), madeInText && (_jsx(Text, { size: "xs", color: "muted", children: madeInText }))] })] })] }));
|
|
14
14
|
}
|
|
@@ -66,8 +66,8 @@ export declare const submitLotteryPullSchema: z.ZodEffects<z.ZodObject<{
|
|
|
66
66
|
purchasedItemNumber: z.ZodNumber;
|
|
67
67
|
userPhone: z.ZodString;
|
|
68
68
|
}, "strip", z.ZodTypeAny, {
|
|
69
|
-
userId: string;
|
|
70
69
|
transactionId: string;
|
|
70
|
+
userId: string;
|
|
71
71
|
userPhone: string;
|
|
72
72
|
sourceType: "product" | "event";
|
|
73
73
|
paymentTime: string;
|
|
@@ -77,8 +77,8 @@ export declare const submitLotteryPullSchema: z.ZodEffects<z.ZodObject<{
|
|
|
77
77
|
userDisplayName?: string | undefined;
|
|
78
78
|
eventId?: string | undefined;
|
|
79
79
|
}, {
|
|
80
|
-
userId: string;
|
|
81
80
|
transactionId: string;
|
|
81
|
+
userId: string;
|
|
82
82
|
userPhone: string;
|
|
83
83
|
sourceType: "product" | "event";
|
|
84
84
|
paymentTime: string;
|
|
@@ -88,8 +88,8 @@ export declare const submitLotteryPullSchema: z.ZodEffects<z.ZodObject<{
|
|
|
88
88
|
userDisplayName?: string | undefined;
|
|
89
89
|
eventId?: string | undefined;
|
|
90
90
|
}>, {
|
|
91
|
-
userId: string;
|
|
92
91
|
transactionId: string;
|
|
92
|
+
userId: string;
|
|
93
93
|
userPhone: string;
|
|
94
94
|
sourceType: "product" | "event";
|
|
95
95
|
paymentTime: string;
|
|
@@ -99,8 +99,8 @@ export declare const submitLotteryPullSchema: z.ZodEffects<z.ZodObject<{
|
|
|
99
99
|
userDisplayName?: string | undefined;
|
|
100
100
|
eventId?: string | undefined;
|
|
101
101
|
}, {
|
|
102
|
-
userId: string;
|
|
103
102
|
transactionId: string;
|
|
103
|
+
userId: string;
|
|
104
104
|
userPhone: string;
|
|
105
105
|
sourceType: "product" | "event";
|
|
106
106
|
paymentTime: string;
|
|
@@ -66,6 +66,10 @@ export interface PayoutDocument extends BaseDocument {
|
|
|
66
66
|
netAmount?: number;
|
|
67
67
|
requestedAt: Date;
|
|
68
68
|
processedAt?: Date;
|
|
69
|
+
/** UTR / UPI ref / bank transfer ID entered by admin when marking paid. */
|
|
70
|
+
transactionId?: string;
|
|
71
|
+
/** Seller-set personal follow-up flag — surfaced only to the owning seller, never mutated by admin. */
|
|
72
|
+
sellerReminderFlag?: boolean;
|
|
69
73
|
}
|
|
70
74
|
export declare const PAYOUT_COLLECTION: "payouts";
|
|
71
75
|
export declare const PAYOUT_INDEXED_FIELDS: readonly ["storeId", "status", "requestedAt", "createdAt"];
|
|
@@ -88,6 +92,8 @@ export declare const PAYOUT_FIELDS: {
|
|
|
88
92
|
};
|
|
89
93
|
export declare const PAYOUT_PUBLIC_FIELDS: readonly ["id", "storeId", "amount", "currency", "status", "paymentMethod", "requestedAt", "processedAt", "createdAt"];
|
|
90
94
|
export declare const PAYOUT_ADMIN_UPDATEABLE_FIELDS: readonly ["status", "adminNote", "processedAt"];
|
|
95
|
+
/** The only field a seller may write on their own payout doc. */
|
|
96
|
+
export declare const PAYOUT_SELLER_UPDATEABLE_FIELDS: readonly ["sellerReminderFlag"];
|
|
91
97
|
export type PayoutCreateInput = Omit<PayoutDocument, "id" | "createdAt" | "updatedAt" | "status" | "requestedAt">;
|
|
92
98
|
export type PayoutUpdateInput = Partial<Pick<PayoutDocument, (typeof PAYOUT_ADMIN_UPDATEABLE_FIELDS)[number]>>;
|
|
93
99
|
export declare const payoutQueryHelpers: {
|
|
@@ -52,6 +52,8 @@ export const PAYOUT_ADMIN_UPDATEABLE_FIELDS = [
|
|
|
52
52
|
"adminNote",
|
|
53
53
|
"processedAt",
|
|
54
54
|
];
|
|
55
|
+
/** The only field a seller may write on their own payout doc. */
|
|
56
|
+
export const PAYOUT_SELLER_UPDATEABLE_FIELDS = ["sellerReminderFlag"];
|
|
55
57
|
export const payoutQueryHelpers = {
|
|
56
58
|
byStore: (storeId) => ["storeId", "==", storeId],
|
|
57
59
|
byStatus: (status) => ["status", "==", status],
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
export interface SellerBundlesViewProps {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
}) => string;
|
|
3
|
+
/** Plain string with an `{id}` placeholder — safe to build in a Server Component page.tsx. */
|
|
4
|
+
editHrefTemplate: string;
|
|
6
5
|
newHref: string;
|
|
7
6
|
}
|
|
8
|
-
export declare function SellerBundlesView({
|
|
7
|
+
export declare function SellerBundlesView({ editHrefTemplate, newHref }: SellerBundlesViewProps): React.JSX.Element;
|
|
@@ -37,7 +37,7 @@ const COLUMNS = [
|
|
|
37
37
|
},
|
|
38
38
|
{ key: "updatedAt", header: "Updated", className: "w-28" },
|
|
39
39
|
];
|
|
40
|
-
export function SellerBundlesView({
|
|
40
|
+
export function SellerBundlesView({ editHrefTemplate, newHref }) {
|
|
41
41
|
const config = {
|
|
42
42
|
portal: "seller",
|
|
43
43
|
title: "Bundles",
|
|
@@ -78,7 +78,7 @@ export function SellerBundlesView({ getEditHref, newHref }) {
|
|
|
78
78
|
parts.push(sieveFilter("bundleStockStatus", SIEVE_OP.EQ, filterState.bundleStockStatus));
|
|
79
79
|
return parts.join(",") || undefined;
|
|
80
80
|
},
|
|
81
|
-
|
|
81
|
+
rowHrefTemplate: editHrefTemplate,
|
|
82
82
|
toolbarExtra: (_jsx(Button, { asChild: true, size: "sm", variant: "primary", children: _jsx(TextLink, { href: newHref, layout: "flex", align: "center", gap: "xs", children: "+ New Bundle" }) })),
|
|
83
83
|
// Rule #7: bulk-action array sourced from the SELLER_BULK_ACTIONS preset.
|
|
84
84
|
buildBulkActions: (selection) => {
|
|
@@ -1,7 +1,4 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import type { ListingLayoutProps } from "../../../ui";
|
|
3
|
-
export
|
|
4
|
-
|
|
5
|
-
onExportClick?: (id: string) => void;
|
|
6
|
-
}
|
|
7
|
-
export declare function SellerPayoutsView({ children, onViewClick, onExportClick, ...props }: SellerPayoutsViewProps): React.JSX.Element;
|
|
3
|
+
export type SellerPayoutsViewProps = ListingLayoutProps;
|
|
4
|
+
export declare function SellerPayoutsView({ children, ...props }: SellerPayoutsViewProps): React.JSX.Element;
|
|
@@ -1,18 +1,77 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { normalizeError } from "../../../errors/normalize";
|
|
3
4
|
import { sieveFilter, SIEVE_OP } from "@mohasinac/appkit";
|
|
4
5
|
import { sortBy } from "@mohasinac/appkit";
|
|
5
|
-
import React from "react";
|
|
6
|
-
import { FilterChipGroup, ListingLayout, RowActionMenu } from "../../../ui";
|
|
6
|
+
import React, { useState } from "react";
|
|
7
|
+
import { Badge, Div, FilterChipGroup, ListingLayout, Row, RowActionMenu, SideDrawer, Span, Stack, Text, Toggle, useToast } from "../../../ui";
|
|
7
8
|
import { SELLER_ENDPOINTS } from "../../../constants/api-endpoints";
|
|
8
9
|
import { ADMIN_PAYOUT_STATUS_TABS } from "../../admin/constants/filter-tabs";
|
|
9
10
|
import { ACTIONS } from "../../../_internal/shared/actions/action-registry";
|
|
11
|
+
import { buildBulkAction } from "../../../_internal/shared/actions/bulk-helpers";
|
|
12
|
+
import { apiClient } from "../../../http";
|
|
10
13
|
import { toRecordArray, toRelativeDate, toCurrency, toStringValue, } from "../../admin/hooks/useAdminListingData";
|
|
11
14
|
import { DataListingView } from "../../admin/components/DataListingView";
|
|
12
|
-
|
|
15
|
+
const PAYOUT_STAGES = ["pending", "processing", "paid"];
|
|
16
|
+
const PAYOUT_CYCLE_DAYS = 7;
|
|
17
|
+
function formatDate(value) {
|
|
18
|
+
if (!value)
|
|
19
|
+
return "—";
|
|
20
|
+
const d = new Date(value);
|
|
21
|
+
return Number.isNaN(d.getTime()) ? "—" : d.toLocaleDateString("en-IN", { day: "numeric", month: "short", year: "numeric" });
|
|
22
|
+
}
|
|
23
|
+
function StatusProgress({ status }) {
|
|
24
|
+
const normalized = status.toLowerCase();
|
|
25
|
+
if (normalized === "failed") {
|
|
26
|
+
return _jsx(Badge, { variant: "danger", children: "Failed" });
|
|
27
|
+
}
|
|
28
|
+
const currentIndex = PAYOUT_STAGES.indexOf(normalized);
|
|
29
|
+
return (_jsx(Row, { gap: "xs", align: "center", children: PAYOUT_STAGES.map((stage, i) => (_jsxs(React.Fragment, { children: [i > 0 && _jsx(Div, { className: `h-0.5 w-6 ${i <= currentIndex ? "bg-primary" : "bg-[var(--appkit-color-border)]"}` }), _jsx(Span, { size: "xs", weight: i === currentIndex ? "bold" : "medium", className: i <= currentIndex ? "text-primary" : "text-[var(--appkit-color-text-muted)]", children: stage[0].toUpperCase() + stage.slice(1) })] }, stage))) }));
|
|
30
|
+
}
|
|
31
|
+
export function SellerPayoutsView({ children, ...props }) {
|
|
32
|
+
const { showToast } = useToast();
|
|
33
|
+
const [selectedPayout, setSelectedPayout] = useState(null);
|
|
34
|
+
const [reminderPending, setReminderPending] = useState(false);
|
|
35
|
+
// Mirrors the raw API record per row id so the detail panel can open
|
|
36
|
+
// instantly from data already in memory (list already fetched it) —
|
|
37
|
+
// matches AdminProductsView's rawByIdRef pattern.
|
|
38
|
+
const rawByIdRef = React.useRef({});
|
|
13
39
|
if (React.Children.count(children) > 0) {
|
|
14
40
|
return (_jsx(ListingLayout, { portal: "seller", ...props, children: children }));
|
|
15
41
|
}
|
|
42
|
+
const handleExport = (rows) => {
|
|
43
|
+
const header = ["id", "amount", "currency", "status", "requestedAt", "processedAt", "transactionId"];
|
|
44
|
+
const lines = [header.join(",")];
|
|
45
|
+
for (const p of rows) {
|
|
46
|
+
lines.push(header.map((k) => JSON.stringify(p[k] ?? "")).join(","));
|
|
47
|
+
}
|
|
48
|
+
const blob = new Blob([lines.join("\n")], { type: "text/csv" });
|
|
49
|
+
const url = URL.createObjectURL(blob);
|
|
50
|
+
const a = document.createElement("a");
|
|
51
|
+
a.href = url;
|
|
52
|
+
a.download = `payouts-${new Date().toISOString().slice(0, 10)}.csv`;
|
|
53
|
+
a.click();
|
|
54
|
+
URL.revokeObjectURL(url);
|
|
55
|
+
};
|
|
56
|
+
const handleToggleReminder = async (next) => {
|
|
57
|
+
if (!selectedPayout)
|
|
58
|
+
return;
|
|
59
|
+
setReminderPending(true);
|
|
60
|
+
try {
|
|
61
|
+
await apiClient.patch(SELLER_ENDPOINTS.PAYOUT_BY_ID(String(selectedPayout.id)), {
|
|
62
|
+
sellerReminderFlag: next,
|
|
63
|
+
});
|
|
64
|
+
setSelectedPayout((prev) => (prev ? { ...prev, sellerReminderFlag: next } : prev));
|
|
65
|
+
showToast(next ? "Reminder set." : "Reminder cleared.", "success");
|
|
66
|
+
}
|
|
67
|
+
catch (err) {
|
|
68
|
+
void normalizeError(err);
|
|
69
|
+
showToast("Failed to update reminder.", "error");
|
|
70
|
+
}
|
|
71
|
+
finally {
|
|
72
|
+
setReminderPending(false);
|
|
73
|
+
}
|
|
74
|
+
};
|
|
16
75
|
const config = {
|
|
17
76
|
portal: "seller",
|
|
18
77
|
title: "Payouts",
|
|
@@ -26,29 +85,49 @@ export function SellerPayoutsView({ children, onViewClick, onExportClick, ...pro
|
|
|
26
85
|
{ value: sortBy("createdAt", "DESC"), label: "Newest" },
|
|
27
86
|
{ value: sortBy("createdAt", "ASC"), label: "Oldest" },
|
|
28
87
|
],
|
|
29
|
-
mapRows: (response) => toRecordArray(response.payouts).map((item, index) =>
|
|
30
|
-
id
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
88
|
+
mapRows: (response) => toRecordArray(response.payouts).map((item, index) => {
|
|
89
|
+
const id = toStringValue(item.id, `payout-${index}`);
|
|
90
|
+
rawByIdRef.current[id] = item;
|
|
91
|
+
return {
|
|
92
|
+
id,
|
|
93
|
+
primary: `Payout #${toStringValue(item.payoutNumber ?? item.id, "Unknown")}`,
|
|
94
|
+
secondary: [
|
|
95
|
+
toCurrency(item.amount ?? item.totalAmount),
|
|
96
|
+
`Requested: ${toRelativeDate(item.requestedAt ?? item.createdAt)}`,
|
|
97
|
+
].join(" · "),
|
|
98
|
+
status: toStringValue(item.status, "Pending"),
|
|
99
|
+
updatedAt: toRelativeDate(item.processedAt ?? item.updatedAt ?? item.createdAt),
|
|
100
|
+
};
|
|
101
|
+
}),
|
|
39
102
|
getTotal: (response, mappedRows) => typeof response.meta?.total === "number"
|
|
40
103
|
? response.meta.total
|
|
41
104
|
: mappedRows.length,
|
|
42
105
|
buildFilters: (state) => state.status && state.status !== "All" ? sieveFilter("status", SIEVE_OP.EQ, state.status) : undefined,
|
|
106
|
+
// Rule #7: bulk-action array sourced from the CTA registry, not inline objects.
|
|
107
|
+
buildBulkActions: (selection) => [
|
|
108
|
+
buildBulkAction(ACTIONS.STORE["export-payout"], () => {
|
|
109
|
+
const rows = selection.selectedIds
|
|
110
|
+
.map((id) => rawByIdRef.current[id])
|
|
111
|
+
.filter((r) => Boolean(r));
|
|
112
|
+
handleExport(rows);
|
|
113
|
+
selection.clearSelection();
|
|
114
|
+
}),
|
|
115
|
+
],
|
|
43
116
|
renderRowActions: (row) => (_jsx(RowActionMenu, { actions: [
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
: []),
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
: []
|
|
117
|
+
{
|
|
118
|
+
label: ACTIONS.STORE["view-payout"].label,
|
|
119
|
+
onClick: () => setSelectedPayout(rawByIdRef.current[row.id] ?? { id: row.id }),
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
label: ACTIONS.STORE["export-payout"].label,
|
|
123
|
+
onClick: () => handleExport([rawByIdRef.current[row.id] ?? { id: row.id }]),
|
|
124
|
+
},
|
|
50
125
|
] })),
|
|
51
126
|
renderFilterPanel: ({ pendingFilters, setPendingFilters }) => (_jsx(FilterChipGroup, { label: "Status", tabs: ADMIN_PAYOUT_STATUS_TABS, value: pendingFilters.status ?? "", onChange: (id) => setPendingFilters((p) => ({ ...p, status: id })) })),
|
|
52
127
|
};
|
|
53
|
-
|
|
128
|
+
const expectedByDate = selectedPayout?.requestedAt
|
|
129
|
+
? new Date(new Date(selectedPayout.requestedAt).getTime() + PAYOUT_CYCLE_DAYS * 24 * 60 * 60 * 1000)
|
|
130
|
+
: null;
|
|
131
|
+
const orderIds = Array.isArray(selectedPayout?.orderIds) ? selectedPayout.orderIds : [];
|
|
132
|
+
return (_jsxs(_Fragment, { children: [_jsx(DataListingView, { config: config }), _jsx(SideDrawer, { isOpen: Boolean(selectedPayout), onClose: () => setSelectedPayout(null), title: selectedPayout ? `Payout #${toStringValue(selectedPayout.payoutNumber ?? selectedPayout.id, "")}` : "Payout", mode: "view", children: selectedPayout && (_jsxs(Stack, { gap: "lg", children: [_jsx(StatusProgress, { status: toStringValue(selectedPayout.status, "pending") }), _jsxs(Stack, { gap: "xs", children: [_jsx(Text, { size: "xs", color: "muted", children: "Amount" }), _jsx(Text, { size: "xl", weight: "bold", children: toCurrency(selectedPayout.amount ?? selectedPayout.totalAmount) })] }), selectedPayout.transactionId ? (_jsxs(Stack, { gap: "xs", children: [_jsx(Text, { size: "xs", color: "muted", children: "Transaction / reference ID" }), _jsx(Text, { size: "sm", className: "font-mono", children: String(selectedPayout.transactionId) })] })) : null, _jsxs(Row, { gap: "lg", wrap: true, children: [_jsxs(Stack, { gap: "xs", children: [_jsx(Text, { size: "xs", color: "muted", children: "Requested" }), _jsx(Text, { size: "sm", children: formatDate(selectedPayout.requestedAt ?? selectedPayout.createdAt) })] }), selectedPayout.status === "paid" ? (_jsxs(Stack, { gap: "xs", children: [_jsx(Text, { size: "xs", color: "muted", children: "Paid on" }), _jsx(Text, { size: "sm", children: formatDate(selectedPayout.processedAt) })] })) : (_jsxs(Stack, { gap: "xs", children: [_jsx(Text, { size: "xs", color: "muted", children: "Expected by" }), _jsx(Text, { size: "sm", children: expectedByDate ? formatDate(expectedByDate.toISOString()) : "—" })] })), _jsxs(Stack, { gap: "xs", children: [_jsx(Text, { size: "xs", color: "muted", children: "Payment method" }), _jsx(Text, { size: "sm", className: "capitalize", children: toStringValue(selectedPayout.paymentMethod, "—").replace("_", " ") })] })] }), orderIds.length > 0 && (_jsxs(Stack, { gap: "xs", children: [_jsxs(Text, { size: "xs", color: "muted", children: ["Orders included (", orderIds.length, ")"] }), _jsx(Div, { className: "max-h-40", overflow: "y-auto", children: _jsx(Stack, { gap: "xs", children: orderIds.map((oid) => (_jsx(Text, { size: "xs", className: "font-mono", color: "muted", children: oid }, oid))) }) })] })), _jsxs(Row, { align: "center", justify: "between", border: "default", rounded: "lg", padding: "inline", children: [_jsxs(Stack, { gap: "none", children: [_jsx(Text, { size: "sm", weight: "medium", children: "Remind me" }), _jsx(Text, { size: "xs", color: "muted", children: "Flag this payout for a personal follow-up" })] }), _jsx(Toggle, { checked: Boolean(selectedPayout.sellerReminderFlag), onChange: handleToggleReminder, disabled: reminderPending, size: "md", "aria-label": ACTIONS.STORE["set-payout-reminder"].ariaLabel })] })] })) })] }));
|
|
54
133
|
}
|
|
@@ -111,7 +111,7 @@ export function SellerPreOrdersView({ children, onDelete, ...props }) {
|
|
|
111
111
|
const status = state.status && state.status !== "All" ? sieveFilter("status", SIEVE_OP.EQ, state.status) : null;
|
|
112
112
|
return ["listingType==pre-order", status].filter(Boolean).join(",");
|
|
113
113
|
},
|
|
114
|
-
|
|
114
|
+
rowHrefTemplate: String(ROUTES.STORE.PRE_ORDERS_EDIT("{id}")),
|
|
115
115
|
renderRowActions: (row) => (_jsx(RowActionMenu, { actions: [
|
|
116
116
|
{
|
|
117
117
|
label: ACTIONS.STORE["edit-listing"].label,
|
|
@@ -108,7 +108,7 @@ export function SellerPrizeDrawsView({ children, onDelete, ...props }) {
|
|
|
108
108
|
const status = state.status && state.status !== "All" ? sieveFilter("status", SIEVE_OP.EQ, state.status) : null;
|
|
109
109
|
return ["listingType==prize-draw", status].filter(Boolean).join(",");
|
|
110
110
|
},
|
|
111
|
-
|
|
111
|
+
rowHrefTemplate: String(ROUTES.STORE.PRIZE_DRAWS_EDIT("{id}")),
|
|
112
112
|
renderRowActions: (row) => (_jsx(RowActionMenu, { actions: [
|
|
113
113
|
{
|
|
114
114
|
label: ACTIONS.STORE["edit-listing"].label,
|
|
@@ -18,6 +18,7 @@ import { ROUTES } from "../../../constants";
|
|
|
18
18
|
import { normalizeListingType } from "../../products/utils/listing-type";
|
|
19
19
|
import { toRecordArray, toRelativeDate, toStringValue, useSellerListingData, } from "../hooks/useSellerListingData";
|
|
20
20
|
import { DataTable } from "../../admin/components/DataTable";
|
|
21
|
+
import { useDataViewMode } from "../../account/hooks/useDataViewMode";
|
|
21
22
|
import { ACTIONS } from "../../../_internal/shared/actions/action-registry";
|
|
22
23
|
import { buildBulkAction } from "../../../_internal/shared/actions/bulk-helpers";
|
|
23
24
|
import { useListingTypeFlags } from "../../../react/hooks/useListingTypeFlags";
|
|
@@ -114,7 +115,7 @@ const PRODUCT_COLUMNS = [
|
|
|
114
115
|
];
|
|
115
116
|
export function SellerProductsView({ onDeleteProduct, onCreateClick, children, ...props }) {
|
|
116
117
|
const hasChildren = React.Children.count(children) > 0;
|
|
117
|
-
const
|
|
118
|
+
const { view, setView } = useDataViewMode("table");
|
|
118
119
|
const dispatch = useActionDispatch();
|
|
119
120
|
const { showToast } = useToast();
|
|
120
121
|
const table = useUrlTable({ defaults: { pageSize: String(PAGE_SIZE), sort: DEFAULT_SORT } });
|
|
@@ -302,8 +303,11 @@ export function SellerProductsView({ onDeleteProduct, onCreateClick, children, .
|
|
|
302
303
|
{ label: "Show sold", active: showSold, onChange: (next) => table.set("showSold", next ? "true" : "") },
|
|
303
304
|
], extra: onCreateClick ? (_jsx(Button, { variant: "primary", size: "sm", onClick: onCreateClick, children: "+ New Listing" })) : null }), _jsx(TypeDropdown, { active: listingKind, onChange: handleKindChange }), totalPages > 1 && (_jsx(StickyToolbar, { offset: "header+pagination", tone: "default", border: true, padding: "sm", children: _jsx(Row, { justify: "center", children: _jsx(Pagination, { currentPage: currentPage, totalPages: totalPages, onPageChange: (p) => table.setPage(p) }) }) })), selection.selectedIds.length > 0 && (_jsx(StickyToolbar, { offset: "header+bulk-actions", tone: "default", border: true, padding: "sm", z: "above-toolbar", children: _jsx(BulkActionBar, { selectedCount: selection.selectedIds.length, onClearSelection: selection.clearSelection, actions: bulkActions }) })), _jsxs(Div, { paddingX: "x-sm-lg-md", padding: "y-md", children: [errorMessage && (_jsx(Alert, { variant: "error", className: "mb-4", children: errorMessage })), view !== "table" && (_jsx(SellerProductsCards, { view: view, rows: visibleRows, isLoading: isLoading, listingKind: listingKind, selectedIds: selection.selectedIdSet, toggle: selection.toggle, onEdit: handleEdit, onDuplicate: (row) => void handleDuplicate(row), onDelete: onDeleteProduct ? (row) => void handleDelete(row) : undefined })), view === "table" && (_jsx(DataTable, { columns: PRODUCT_COLUMNS, rows: visibleRows, isLoading: isLoading, emptyLabel: listingKind !== "all"
|
|
304
305
|
? `No ${listingKind} listings found`
|
|
305
|
-
: "No products listed yet", selectedIds: selection.selectedIdSet, onToggleSelect: selection.toggle, onToggleSelectAll: () => selection.toggleAll(),
|
|
306
|
+
: "No products listed yet", selectedIds: selection.selectedIdSet, onToggleSelect: selection.toggle, onToggleSelectAll: () => selection.toggleAll(), rowHrefTemplate: (row) =>
|
|
306
307
|
// S-STORE-2-D — row click → public detail/preview, not edit.
|
|
308
|
+
// A function is safe here: both this view and DataTable are
|
|
309
|
+
// already client components, and the target varies per row
|
|
310
|
+
// (not expressible as a single {id} template string).
|
|
307
311
|
row.listingKind === "auction"
|
|
308
312
|
? `/auctions/${row.id}`
|
|
309
313
|
: row.listingKind === "pre-order"
|
|
@@ -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 AdminShipmentsViewProps = ListingLayoutProps;
|
|
8
4
|
export declare function AdminShipmentsView({ children, ...props }: AdminShipmentsViewProps): React.JSX.Element;
|
package/dist/index.d.ts
CHANGED
|
@@ -132,8 +132,6 @@ export type { UseGestureOptions } from "./react/index";
|
|
|
132
132
|
export type { UseKeyPressOptions } from "./react/index";
|
|
133
133
|
export type { UsePullToRefreshOptions } from "./react/index";
|
|
134
134
|
export type { UsePullToRefreshReturn } from "./react/index";
|
|
135
|
-
export type { UseVisibleItemsOptions } from "./react/index";
|
|
136
|
-
export type { UseVisibleItemsResult } from "./react/index";
|
|
137
135
|
export { CONFIRMATION_MESSAGES } from "./values/index";
|
|
138
136
|
export { INFO_MESSAGES } from "./values/index";
|
|
139
137
|
export { deepClone } from "./utils/index";
|
|
@@ -3051,9 +3049,9 @@ export { Button } from "./ui/index";
|
|
|
3051
3049
|
export { Heading, Spinner, IconButton, Progress, IndeterminateProgress, Pagination, PageLoader } from "./ui/index";
|
|
3052
3050
|
export { ModalFooter, UnsavedChangesModal, ResponsiveView, Textarea, Checkbox } from "./ui/index";
|
|
3053
3051
|
export { ToastProvider, StarRating, StepperNav, ViewToggle, PriceDisplay, SummaryCard } from "./ui/index";
|
|
3054
|
-
export { CountdownDisplay, ItemRow, HorizontalScroller
|
|
3052
|
+
export { CountdownDisplay, ItemRow, HorizontalScroller } from "./ui/index";
|
|
3055
3053
|
export { CardBody, MenuTrigger, MenuContent, MenuSeparator, RoleBadge, SkipToMain } from "./ui/index";
|
|
3056
|
-
export { TabsList, TabsContent, PasswordStrengthIndicator, TablePagination } from "./ui/index";
|
|
3054
|
+
export { Tabs, TabsList, TabsTrigger, TabsContent, PasswordStrengthIndicator, TablePagination } from "./ui/index";
|
|
3057
3055
|
export { Stack, classNames, mergeTailwindClasses, SideModal, SideDrawer, RichText, RichTextRenderer } from "./ui/index";
|
|
3058
3056
|
export type { RichTextRendererProps } from "./ui/index";
|
|
3059
3057
|
export { SlottedListingView, DetailViewShell, StackedViewShell } from "./ui/index";
|
|
@@ -3067,7 +3065,7 @@ export { API_ENDPOINTS, API_ROUTES, LOGS_ENDPOINTS, AUTH_ENDPOINTS, ACCOUNT_ENDP
|
|
|
3067
3065
|
export { WishlistFullError } from "./features/wishlist/server";
|
|
3068
3066
|
export { useHistory, useHistoryMergeOnLogin, getGuestHistory, trackGuestHistory, removeGuestHistoryItem, clearGuestHistory, getGuestHistoryCount, type GuestHistoryItem, type GuestHistoryType, type UserHistoryItem, type HistoryProductType, type HistoryItemSnapshot, type TrackArgs as TrackHistoryArgs, } from "./features/history";
|
|
3069
3067
|
export { historyRepository, UserHistoryRepository, trackHistoryView, getHistoryForUser, removeHistoryItem, clearHistory, mergeGuestHistory, } from "./features/history/server";
|
|
3070
|
-
export { useMediaQuery, useBreakpoint, useClickOutside, useKeyPress, useLongPress, useGesture, useSwipe, useSession, useAuth, useCountdown, useCamera, useBulkSelection, useUrlTable, usePendingFilters, usePendingTable, useUnsavedChanges, UNSAVED_CHANGES_EVENT, useBulkAction, useEntityDelete, useContainerGrid, useMessage,
|
|
3068
|
+
export { useMediaQuery, useBreakpoint, useClickOutside, useKeyPress, useLongPress, useGesture, useSwipe, useSession, useAuth, useCountdown, useCamera, useBulkSelection, useUrlTable, usePendingFilters, usePendingTable, useUnsavedChanges, UNSAVED_CHANGES_EVENT, useBulkAction, useEntityDelete, useContainerGrid, useMessage, useModalStack, RTDBPayloadStatus, } from "./react/index";
|
|
3071
3069
|
export { RoleGate, ProtectedRoute, SocialAuthButtons, AuthStatusPanel, LoginForm, RegisterForm, ForgotPasswordView, ResetPasswordView, VerifyEmailView, OAuthLoadingView, } from "./features/auth/index";
|
|
3072
3070
|
export type { RoleGateProps, ProtectedRouteProps, AuthGuardUser, AuthRouteConfig, LoginFormProps, LoginFormValues, RegisterFormProps, RegisterFormValues, ForgotPasswordViewProps, ResetPasswordViewProps, VerifyEmailViewProps, } from "./features/auth/index";
|
|
3073
3071
|
export { CartItemRow, CartDrawer, CartView, CartSummary, ShippingPicker } from "./features/cart/index";
|
package/dist/index.js
CHANGED
|
@@ -5468,9 +5468,9 @@ export { Button } from "./ui/index";
|
|
|
5468
5468
|
export { Heading, Spinner, IconButton, Progress, IndeterminateProgress, Pagination, PageLoader } from "./ui/index";
|
|
5469
5469
|
export { ModalFooter, UnsavedChangesModal, ResponsiveView, Textarea, Checkbox } from "./ui/index";
|
|
5470
5470
|
export { ToastProvider, StarRating, StepperNav, ViewToggle, PriceDisplay, SummaryCard } from "./ui/index";
|
|
5471
|
-
export { CountdownDisplay, ItemRow, HorizontalScroller
|
|
5471
|
+
export { CountdownDisplay, ItemRow, HorizontalScroller } from "./ui/index";
|
|
5472
5472
|
export { CardBody, MenuTrigger, MenuContent, MenuSeparator, RoleBadge, SkipToMain } from "./ui/index";
|
|
5473
|
-
export { TabsList, TabsContent, PasswordStrengthIndicator, TablePagination } from "./ui/index";
|
|
5473
|
+
export { Tabs, TabsList, TabsTrigger, TabsContent, PasswordStrengthIndicator, TablePagination } from "./ui/index";
|
|
5474
5474
|
export { Stack, classNames, mergeTailwindClasses, SideModal, SideDrawer, RichText, RichTextRenderer } from "./ui/index";
|
|
5475
5475
|
export { SlottedListingView, DetailViewShell, StackedViewShell } from "./ui/index";
|
|
5476
5476
|
export { buildColumns, createColumnBuilder } from "./ui/index";
|
|
@@ -5486,7 +5486,7 @@ export { WishlistFullError } from "./features/wishlist/server";
|
|
|
5486
5486
|
export { useHistory, useHistoryMergeOnLogin, getGuestHistory, trackGuestHistory, removeGuestHistoryItem, clearGuestHistory, getGuestHistoryCount, } from "./features/history";
|
|
5487
5487
|
export { historyRepository, UserHistoryRepository, trackHistoryView, getHistoryForUser, removeHistoryItem, clearHistory, mergeGuestHistory, } from "./features/history/server";
|
|
5488
5488
|
// Missing React hooks and providers
|
|
5489
|
-
export { useMediaQuery, useBreakpoint, useClickOutside, useKeyPress, useLongPress, useGesture, useSwipe, useSession, useAuth, useCountdown, useCamera, useBulkSelection, useUrlTable, usePendingFilters, usePendingTable, useUnsavedChanges, UNSAVED_CHANGES_EVENT, useBulkAction, useEntityDelete, useContainerGrid, useMessage,
|
|
5489
|
+
export { useMediaQuery, useBreakpoint, useClickOutside, useKeyPress, useLongPress, useGesture, useSwipe, useSession, useAuth, useCountdown, useCamera, useBulkSelection, useUrlTable, usePendingFilters, usePendingTable, useUnsavedChanges, UNSAVED_CHANGES_EVENT, useBulkAction, useEntityDelete, useContainerGrid, useMessage, useModalStack, RTDBPayloadStatus, } from "./react/index";
|
|
5490
5490
|
// Missing core types (already exported above; skipped to avoid duplicates)
|
|
5491
5491
|
// Missing auth feature components
|
|
5492
5492
|
export { RoleGate, ProtectedRoute, SocialAuthButtons, AuthStatusPanel, LoginForm, RegisterForm, ForgotPasswordView, ResetPasswordView, VerifyEmailView, OAuthLoadingView, } from "./features/auth/index";
|
package/dist/react/index.d.ts
CHANGED
|
@@ -46,8 +46,6 @@ export type { BulkActionPayload, BulkActionResult, BulkActionSummary, BulkAction
|
|
|
46
46
|
export { useContainerGrid } from "./hooks/useContainerGrid";
|
|
47
47
|
export { useMessage } from "./hooks/useMessage";
|
|
48
48
|
export type { UseContainerGridOptions, UseContainerGridResult, } from "./hooks/useContainerGrid";
|
|
49
|
-
export { useVisibleItems } from "./hooks/useVisibleItems";
|
|
50
|
-
export type { UseVisibleItemsOptions, UseVisibleItemsResult, } from "./hooks/useVisibleItems";
|
|
51
49
|
export { useModalStack } from "./useModalStack";
|
|
52
50
|
export type { ModalEntry } from "./useModalStack";
|
|
53
51
|
export { ErrorBoundary } from "./ErrorBoundary";
|
package/dist/react/index.js
CHANGED
|
@@ -46,8 +46,6 @@ export { useBulkAction } from "./hooks/useBulkAction";
|
|
|
46
46
|
export { useContainerGrid } from "./hooks/useContainerGrid";
|
|
47
47
|
// Success/error message management
|
|
48
48
|
export { useMessage } from "./hooks/useMessage";
|
|
49
|
-
// Visible-items counter for tab strips and overflow scrollers
|
|
50
|
-
export { useVisibleItems } from "./hooks/useVisibleItems";
|
|
51
49
|
// Modal stack management
|
|
52
50
|
export { useModalStack } from "./useModalStack";
|
|
53
51
|
// Error boundary
|