@mohasinac/appkit 4.3.0 → 4.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_internal/client/features/layout/navActive.d.ts +17 -0
- package/dist/_internal/client/features/layout/navActive.js +33 -0
- package/dist/_internal/server/features/products/service.d.ts +1 -1
- package/dist/_internal/server/features/products/service.js +3 -3
- package/dist/_internal/server/jobs/core/prizeDrawExpiryReveal.js +1 -1
- package/dist/_internal/server/jobs/core/prizeDrawSoldOutReveal.js +1 -1
- package/dist/features/account/components/UserSidebar.js +21 -9
- package/dist/features/admin/components/AdminGuideHubView.js +15 -1
- package/dist/features/admin/components/AdminPaymentsGuideView.d.ts +2 -0
- package/dist/features/admin/components/AdminPaymentsGuideView.js +36 -0
- package/dist/features/admin/components/AdminSidebar.js +18 -9
- package/dist/features/admin/components/AdminWhatsAppGuideView.d.ts +2 -0
- package/dist/features/admin/components/AdminWhatsAppGuideView.js +35 -0
- package/dist/features/auctions/components/CollapsibleBidHistory.d.ts +10 -10
- package/dist/features/auctions/components/CollapsibleBidHistory.js +3 -2
- package/dist/features/events/components/EventCard.js +2 -2
- package/dist/features/homepage/components/SectionCarousel.js +1 -1
- package/dist/features/layout/AppLayoutShell.js +43 -9
- package/dist/features/pre-orders/components/MarketplacePreorderCard.js +1 -1
- package/dist/features/products/components/MarketplaceBundleCard.js +1 -1
- package/dist/features/products/components/ProductGalleryClient.js +2 -2
- package/dist/features/products/constants/action-defs.d.ts +1 -2
- package/dist/features/products/constants/action-defs.js +0 -3
- package/dist/features/products/schemas/firestore.d.ts +4 -3
- package/dist/features/seller/components/SellerSidebar.js +20 -9
- package/dist/features/stores/components/StoreGuideHubView.js +7 -1
- package/dist/features/stores/components/StoreNavTabs.js +4 -3
- package/dist/features/stores/components/StoreWhatsAppGuideView.d.ts +3 -0
- package/dist/features/stores/components/StoreWhatsAppGuideView.js +12 -0
- package/dist/features/stores/components/index.d.ts +2 -0
- package/dist/features/stores/components/index.js +1 -0
- package/dist/features/tester/seed-data/products-tester-seed-data.js +4 -3
- package/dist/features/tester/seed-data/tester-checklist-seed-data.js +8 -6
- package/dist/index.d.ts +4 -0
- package/dist/index.js +6 -0
- package/dist/next/routing/route-map.d.ts +7 -2
- package/dist/next/routing/route-map.js +3 -1
- package/dist/seed/products-standard-seed-data.js +2 -4
- package/dist/styles.css +1 -1
- package/dist/tailwind-utilities.css +1 -1
- package/package.json +1 -1
|
@@ -64,5 +64,5 @@ export function MarketplacePreorderCard({ product, className = "", variant = "gr
|
|
|
64
64
|
/* ── Compact list layout ── */
|
|
65
65
|
_jsxs(_Fragment, { children: [_jsxs(Row, { className: "min-w-0", align: "start", justify: "between", gap: "sm", children: [_jsx(TextLink, { href: detailHref, className: "min-w-0 flex-1", children: _jsx(Text, { size: "sm", weight: "medium", color: "primary", truncate: 2, children: product.title }) }), wishlistActions && (_jsx(Button, { type: "button", variant: "ghost", size: "sm", className: `shrink-0 p-[0.25rem] leading-none ${inWishlist ? "text-primary" : "text-[var(--appkit-color-text-faint)]"}`, onClick: handleWishlist, "aria-label": inWishlist ? mergedLabels.removeFromWishlist : mergedLabels.addToWishlist, children: inWishlist ? "♥" : "♡" }))] }), _jsxs(Row, { align: "center", gap: "sm", wrap: true, children: [_jsx(Text, { className: "text-primary", size: "sm", weight: "bold", children: formatCurrency(product.price, getDefaultCurrency()) }), shipDate && _jsx(PreorderBadge, { shipDate: shipDate })] }), _jsx(Button, { type: "button", variant: "primary", size: "sm", textSize: "xs", className: "self-start mt-0.5", onClick: handleNavigate, children: mergedLabels.reserveNow })] })) : (
|
|
66
66
|
/* ── Full grid layout ── */
|
|
67
|
-
_jsxs(_Fragment, { children: [_jsx(TextLink, { href: detailHref, children: _jsx(Text, { size: "sm", weight: "medium", color: "primary", truncate: 2, children: product.title }) }), product.description ? (_jsx(RichText, { html: normalizeRichTextHtml(product.description), proseClass: "prose prose-sm max-w-none dark:prose-invert prose-p:my-0", className: "line-clamp-2 text-[length:var(--appkit-text-xs)] text-[var(--appkit-color-text-muted)]" })) : null, _jsxs(Row, { justify: "between", className: "mt-1", gap: "sm", children: [_jsx(Text, { size: "sm", weight: "semibold", color: "primary", children: formatCurrency(product.price, getDefaultCurrency()) }), shipDate && _jsx(PreorderBadge, { shipDate: shipDate })] }), _jsxs(Row, { justify: "between", className: "mt-auto pt-2", gap: "sm", children: [_jsx(Button, { type: "button", variant: "primary", size: "sm", textSize: "xs", className: "flex-1", onClick: handleNavigate, children: mergedLabels.reserveNow }), onAddToCart ? (_jsx(Button, { type: "button", variant: "outline", size: "sm", textSize: "xs", className: "flex-1", onClick: (e) => { e.stopPropagation(); onAddToCart(product); }, children: mergedLabels.addToCart })) : null, wishlistActions ? (_jsx(Button, { type: "button", variant: "ghost", size: "sm", className: `${inWishlist ? "text-primary" : "text-[var(--appkit-color-text-muted)]"}`, onClick: handleWishlist, "aria-label": inWishlist ? mergedLabels.removeFromWishlist : mergedLabels.addToWishlist, children: inWishlist ? "♥" : "♡" })) : null] })] })) })] }));
|
|
67
|
+
_jsxs(_Fragment, { children: [_jsx(TextLink, { href: detailHref, children: _jsx(Text, { size: "sm", weight: "medium", color: "primary", truncate: 2, children: product.title }) }), product.description ? (_jsx(RichText, { html: normalizeRichTextHtml(product.description), proseClass: "prose prose-sm max-w-none dark:prose-invert prose-p:my-0", className: "line-clamp-2 text-[length:var(--appkit-text-xs)] text-[var(--appkit-color-text-muted)]" })) : null, _jsxs(Row, { justify: "between", className: "mt-1", gap: "sm", children: [_jsx(Text, { size: "sm", weight: "semibold", color: "primary", children: formatCurrency(product.price, getDefaultCurrency()) }), shipDate && _jsx(PreorderBadge, { shipDate: shipDate })] }), _jsxs(Row, { justify: "between", className: "mt-auto pt-[var(--appkit-space-2)]", gap: "sm", children: [_jsx(Button, { type: "button", variant: "primary", size: "sm", textSize: "xs", className: "flex-1", onClick: handleNavigate, children: mergedLabels.reserveNow }), onAddToCart ? (_jsx(Button, { type: "button", variant: "outline", size: "sm", textSize: "xs", className: "flex-1", onClick: (e) => { e.stopPropagation(); onAddToCart(product); }, children: mergedLabels.addToCart })) : null, wishlistActions ? (_jsx(Button, { type: "button", variant: "ghost", size: "sm", className: `${inWishlist ? "text-primary" : "text-[var(--appkit-color-text-muted)]"}`, onClick: handleWishlist, "aria-label": inWishlist ? mergedLabels.removeFromWishlist : mergedLabels.addToWishlist, children: inWishlist ? "♥" : "♡" })) : null] })] })) })] }));
|
|
68
68
|
}
|
|
@@ -49,7 +49,7 @@ export function MarketplaceBundleCard({ bundle, className = "", variant = "grid"
|
|
|
49
49
|
}
|
|
50
50
|
router.push(String(detailHref));
|
|
51
51
|
}, [detailHref, onNavigate, router]);
|
|
52
|
-
return (_jsxs(BaseListingCard, { isSelected: isSelected, variant: variant, className: className, onMouseDown: !isSelected ? longPress.onMouseDown : undefined, onMouseUp: !isSelected ? longPress.onMouseUp : undefined, onMouseLeave: !isSelected ? longPress.onMouseLeave : undefined, onTouchStart: !isSelected ? longPress.onTouchStart : undefined, onTouchEnd: !isSelected ? longPress.onTouchEnd : undefined, onTouchCancel: !isSelected ? longPress.onTouchCancel : undefined, children: [_jsxs(BaseListingCard.Hero, { aspect: "square", variant: variant, children: [_jsx(TextLink, { href: String(detailHref), className: "absolute inset-0 block", children: showCollage ? (_jsx(Div, { layout: "grid", className: `h-full w-full gap-[0.125rem] bg-[var(--appkit-color-surface-muted)] ${collageTiles.length === 2 ? "grid-cols-2 grid-rows-1" : "grid-cols-2 grid-rows-2"}`, children: collageTiles.map((tile, i) => (_jsxs(Div, { className: "relative overflow-hidden bg-[var(--appkit-color-surface-muted)]", children: [_jsx(MediaImage, { src: tile.imageURL, alt: tile.title ?? `${bundle.name} item ${i + 1}`, size: "card" }), i === collageTiles.length - 1 && overflow > 0 && (_jsxs(Row, { textWeight: "semibold", textSize: "sm", surface: "overlay-md", className: "absolute inset-0 text-white", align: "center", justify: "center", children: ["+", overflow] }))] }, `${tile.productId}-${i}`))) })) : cover ? (_jsx(Div, { className: "absolute inset-0 bg-[var(--appkit-color-surface-muted)]", children: _jsx(MediaImage, { src: cover, alt: bundle.name, size: "card" }) })) : (_jsx(Row, { className: "absolute inset-0 bg-[var(--appkit-color-surface-muted)]", align: "center", justify: "center", children: _jsx(Text, { className: "text-[var(--appkit-color-text-muted)]", size: "xs", children: "No image" }) })) }), discount && (_jsx(Span, { size: "xs", weight: "bold", color: "inverse", className: "absolute left-2 top-2
|
|
52
|
+
return (_jsxs(BaseListingCard, { isSelected: isSelected, variant: variant, className: className, onMouseDown: !isSelected ? longPress.onMouseDown : undefined, onMouseUp: !isSelected ? longPress.onMouseUp : undefined, onMouseLeave: !isSelected ? longPress.onMouseLeave : undefined, onTouchStart: !isSelected ? longPress.onTouchStart : undefined, onTouchEnd: !isSelected ? longPress.onTouchEnd : undefined, onTouchCancel: !isSelected ? longPress.onTouchCancel : undefined, children: [_jsxs(BaseListingCard.Hero, { aspect: "square", variant: variant, children: [_jsx(TextLink, { href: String(detailHref), className: "absolute inset-0 block", children: showCollage ? (_jsx(Div, { layout: "grid", className: `h-full w-full gap-[0.125rem] bg-[var(--appkit-color-surface-muted)] ${collageTiles.length === 2 ? "grid-cols-2 grid-rows-1" : "grid-cols-2 grid-rows-2"}`, children: collageTiles.map((tile, i) => (_jsxs(Div, { className: "relative overflow-hidden bg-[var(--appkit-color-surface-muted)]", children: [_jsx(MediaImage, { src: tile.imageURL, alt: tile.title ?? `${bundle.name} item ${i + 1}`, size: "card" }), i === collageTiles.length - 1 && overflow > 0 && (_jsxs(Row, { textWeight: "semibold", textSize: "sm", surface: "overlay-md", className: "absolute inset-0 text-white", align: "center", justify: "center", children: ["+", overflow] }))] }, `${tile.productId}-${i}`))) })) : cover ? (_jsx(Div, { className: "absolute inset-0 bg-[var(--appkit-color-surface-muted)]", children: _jsx(MediaImage, { src: cover, alt: bundle.name, size: "card" }) })) : (_jsx(Row, { className: "absolute inset-0 bg-[var(--appkit-color-surface-muted)]", align: "center", justify: "center", children: _jsx(Text, { className: "text-[var(--appkit-color-text-muted)]", size: "xs", children: "No image" }) })) }), discount && (_jsx(Span, { size: "xs", weight: "bold", color: "inverse", surface: "success-surface", className: "absolute left-2 top-2", rounded: "full", padding: "pill-xs", children: BUNDLE_COPY.detail.discountBadge(discount.percent) })), _jsxs(Stack, { className: "absolute right-2 top-2", align: "end", gap: "xs", children: [_jsx(Span, { size: "xs", weight: "medium", className: CLS_BUNDLE_PILL, children: mergedLabels.bundleBadge }), _jsx(Span, { layout: "inline-flex", color: "inverse", className: `${stock === "out_of_stock" ? "bg-neutral-500 " : CLS_STOCK_OK}`, rounded: "full", padding: "pill-xs", size: "xs", weight: "medium", children: stock === "out_of_stock" ? mergedLabels.outOfStockBadge : mergedLabels.inStockBadge })] }), stock === "out_of_stock" && (_jsx(Row, { surface: "overlay-xs", className: "absolute inset-0", align: "center", justify: "center", children: _jsx(Span, { color: "inverse", size: "xs", weight: "bold", className: "bg-neutral-900/80 tracking-wider", rounded: "default", padding: "pill-md", transform: "uppercase", children: mergedLabels.outOfStockBadge }) })), onSelect && (_jsx(BaseListingCard.Checkbox, { selected: isSelected, onSelect: (event) => {
|
|
53
53
|
event.stopPropagation();
|
|
54
54
|
onSelect(bundle.id, !isSelected);
|
|
55
55
|
}, className: selectable || isSelected
|
|
@@ -42,9 +42,9 @@ export function ProductGalleryClient({ images, video, productName }) {
|
|
|
42
42
|
: "Product video"
|
|
43
43
|
: productName
|
|
44
44
|
? `${productName} — image ${activeIndex + 1}`
|
|
45
|
-
: `Product image ${activeIndex + 1}`, size: "gallery", className: "transition-transform duration-300 hover:scale-105" }), activeSlide.kind === "video" && (_jsx(Row, { className: "absolute inset-0 pointer-events-none", align: "center", justify: "center", children: _jsx(Row, { className: "h-16 w-16
|
|
45
|
+
: `Product image ${activeIndex + 1}`, size: "gallery", className: "transition-transform duration-300 hover:scale-105" }), activeSlide.kind === "video" && (_jsx(Row, { className: "absolute inset-0 pointer-events-none", align: "center", justify: "center", children: _jsx(Row, { surface: "overlay-sm", rounded: "full", className: "h-16 w-16 text-white", align: "center", justify: "center", children: _jsx(Play, { className: "h-7 w-7 fill-current", "aria-hidden": "true" }) }) }))] }), slides.length > 1 && (_jsx(Div, { layout: "flex", gap: "2", className: `${__O.xAuto}`, padding: "b-2xs", children: slides.map((slide, i) => (_jsxs(Button, { variant: "ghost", type: "button", onClick: () => setActiveIndex(i), rounded: "lg", paddingX: "none", paddingY: "none", className: `relative flex-shrink-0 h-16 w-16 overflow-hidden border-2 transition-all${i === activeIndex
|
|
46
46
|
? " border-primary-500"
|
|
47
|
-
: " border-transparent opacity-60 hover:opacity-100"}`, "aria-label": slide.kind === "video" ? "View video" : `View image ${i + 1}`, "aria-current": i === activeIndex ? "true" : undefined, children: [_jsx(MediaImage, { src: slide.kind === "video" ? slide.poster : slide.src, alt: slide.kind === "video" ? "Video thumbnail" : `Thumbnail ${i + 1}`, size: "thumbnail" }), slide.kind === "video" && (_jsx(Row, { className: "absolute inset-0 pointer-events-none
|
|
47
|
+
: " border-transparent opacity-60 hover:opacity-100"}`, "aria-label": slide.kind === "video" ? "View video" : `View image ${i + 1}`, "aria-current": i === activeIndex ? "true" : undefined, children: [_jsx(MediaImage, { src: slide.kind === "video" ? slide.poster : slide.src, alt: slide.kind === "video" ? "Video thumbnail" : `Thumbnail ${i + 1}`, size: "thumbnail" }), slide.kind === "video" && (_jsx(Row, { surface: "overlay-xs", className: "absolute inset-0 pointer-events-none", align: "center", justify: "center", children: _jsx(Play, { className: "h-5 w-5 text-white fill-current", "aria-hidden": "true" }) }))] }, i))) })), slides.length > 1 && (
|
|
48
48
|
// audit-content-alignment-ok: functional image-counter label under the gallery, not page content
|
|
49
49
|
_jsxs(Text, { size: "xs", align: "center", color: "faint", children: [activeIndex + 1, " / ", slides.length] })), _jsx(ImageLightbox, { images: lightboxImages, activeIndex: lightboxIndex, onClose: () => setLightboxIndex(null), onNavigate: (i) => setLightboxIndex(i) })] }));
|
|
50
50
|
}
|
|
@@ -286,7 +286,6 @@ export declare const DASHBOARD_QUICK_ACTION_ID: {
|
|
|
286
286
|
readonly ADMIN_EVENTS: "dqa-admin-events";
|
|
287
287
|
readonly ADMIN_SUPPORT: "dqa-admin-support";
|
|
288
288
|
readonly ADMIN_MODERATION: "dqa-admin-moderation";
|
|
289
|
-
readonly ADMIN_INTEGRATION_GUIDES: "dqa-admin-integration-guides";
|
|
290
289
|
readonly ADMIN_USERS: "dqa-admin-users";
|
|
291
290
|
readonly ADMIN_CATEGORIES: "dqa-admin-categories";
|
|
292
291
|
readonly ADMIN_REVIEWS: "dqa-admin-reviews";
|
|
@@ -333,7 +332,7 @@ export interface DashboardQuickActionMeta {
|
|
|
333
332
|
}
|
|
334
333
|
export declare const DASHBOARD_QUICK_ACTION_META: Record<DashboardQuickActionId, DashboardQuickActionMeta>;
|
|
335
334
|
export declare const DASHBOARD_QUICK_ACTIONS: {
|
|
336
|
-
readonly admin: readonly ["dqa-admin-add-product", "dqa-admin-add-user", "dqa-admin-add-store", "dqa-admin-add-coupon", "dqa-admin-add-event", "dqa-admin-add-blog", "dqa-admin-users", "dqa-admin-stores", "dqa-admin-orders", "dqa-admin-payouts", "dqa-admin-analytics", "dqa-admin-categories", "dqa-admin-reviews", "dqa-admin-events", "dqa-admin-faqs", "dqa-admin-carousel", "dqa-admin-sections", "dqa-admin-support", "dqa-admin-moderation", "dqa-admin-
|
|
335
|
+
readonly admin: readonly ["dqa-admin-add-product", "dqa-admin-add-user", "dqa-admin-add-store", "dqa-admin-add-coupon", "dqa-admin-add-event", "dqa-admin-add-blog", "dqa-admin-users", "dqa-admin-stores", "dqa-admin-orders", "dqa-admin-payouts", "dqa-admin-analytics", "dqa-admin-categories", "dqa-admin-reviews", "dqa-admin-events", "dqa-admin-faqs", "dqa-admin-carousel", "dqa-admin-sections", "dqa-admin-support", "dqa-admin-moderation", "dqa-admin-settings"];
|
|
337
336
|
readonly seller: readonly ["dqa-seller-add-product", "dqa-seller-products", "dqa-seller-view-orders", "dqa-seller-analytics", "dqa-seller-add-coupon", "dqa-seller-auctions", "dqa-seller-payout-request", "dqa-seller-shipping", "dqa-seller-messages", "dqa-seller-whatsapp", "dqa-seller-reviews", "dqa-seller-storefront", "dqa-seller-settings"];
|
|
338
337
|
readonly user: readonly ["dqa-user-view-orders", "dqa-user-view-wishlist", "dqa-user-edit-profile", "dqa-user-add-address", "dqa-user-recently-viewed", "dqa-user-my-catalogue", "dqa-user-my-coupons"];
|
|
339
338
|
};
|
|
@@ -356,7 +356,6 @@ export const DASHBOARD_QUICK_ACTION_ID = {
|
|
|
356
356
|
ADMIN_EVENTS: "dqa-admin-events",
|
|
357
357
|
ADMIN_SUPPORT: "dqa-admin-support",
|
|
358
358
|
ADMIN_MODERATION: "dqa-admin-moderation",
|
|
359
|
-
ADMIN_INTEGRATION_GUIDES: "dqa-admin-integration-guides",
|
|
360
359
|
ADMIN_USERS: "dqa-admin-users",
|
|
361
360
|
ADMIN_CATEGORIES: "dqa-admin-categories",
|
|
362
361
|
ADMIN_REVIEWS: "dqa-admin-reviews",
|
|
@@ -402,7 +401,6 @@ export const DASHBOARD_QUICK_ACTION_META = {
|
|
|
402
401
|
[DASHBOARD_QUICK_ACTION_ID.ADMIN_EVENTS]: { id: DASHBOARD_QUICK_ACTION_ID.ADMIN_EVENTS, label: "Events", variant: "outline", iconName: "Calendar", requiresAuth: true, requiredRole: "admin", requiredPermission: "events.read" },
|
|
403
402
|
[DASHBOARD_QUICK_ACTION_ID.ADMIN_SUPPORT]: { id: DASHBOARD_QUICK_ACTION_ID.ADMIN_SUPPORT, label: "Support Tickets", variant: "outline", iconName: "LifeBuoy", requiresAuth: true, requiredRole: "admin", requiredPermission: "support.read" },
|
|
404
403
|
[DASHBOARD_QUICK_ACTION_ID.ADMIN_MODERATION]: { id: DASHBOARD_QUICK_ACTION_ID.ADMIN_MODERATION, label: "Moderation", variant: "outline", iconName: "ShieldAlert", requiresAuth: true, requiredRole: "admin", requiredPermission: "moderation.read" },
|
|
405
|
-
[DASHBOARD_QUICK_ACTION_ID.ADMIN_INTEGRATION_GUIDES]: { id: DASHBOARD_QUICK_ACTION_ID.ADMIN_INTEGRATION_GUIDES, label: "Integration Guides", variant: "ghost", iconName: "BookOpen", requiresAuth: true, requiredRole: "admin", requiredPermission: "admin:site:read" },
|
|
406
404
|
[DASHBOARD_QUICK_ACTION_ID.ADMIN_USERS]: { id: DASHBOARD_QUICK_ACTION_ID.ADMIN_USERS, label: "Users", variant: "outline", iconName: "Users", requiresAuth: true, requiredRole: "admin", requiredPermission: "admin.users.read" },
|
|
407
405
|
[DASHBOARD_QUICK_ACTION_ID.ADMIN_CATEGORIES]: { id: DASHBOARD_QUICK_ACTION_ID.ADMIN_CATEGORIES, label: "Categories", variant: "outline", iconName: "Tag", requiresAuth: true, requiredRole: "admin", requiredPermission: "categories.read" },
|
|
408
406
|
[DASHBOARD_QUICK_ACTION_ID.ADMIN_REVIEWS]: { id: DASHBOARD_QUICK_ACTION_ID.ADMIN_REVIEWS, label: "Reviews", variant: "outline", iconName: "Star", requiresAuth: true, requiredRole: "admin", requiredPermission: "reviews.read" },
|
|
@@ -452,7 +450,6 @@ export const DASHBOARD_QUICK_ACTIONS = {
|
|
|
452
450
|
DASHBOARD_QUICK_ACTION_ID.ADMIN_SECTIONS,
|
|
453
451
|
DASHBOARD_QUICK_ACTION_ID.ADMIN_SUPPORT,
|
|
454
452
|
DASHBOARD_QUICK_ACTION_ID.ADMIN_MODERATION,
|
|
455
|
-
DASHBOARD_QUICK_ACTION_ID.ADMIN_INTEGRATION_GUIDES,
|
|
456
453
|
DASHBOARD_QUICK_ACTION_ID.ADMIN_SETTINGS,
|
|
457
454
|
],
|
|
458
455
|
seller: [
|
|
@@ -241,7 +241,7 @@ export interface ProductDocument extends BaseDocument {
|
|
|
241
241
|
sublistingIcon?: string;
|
|
242
242
|
/**
|
|
243
243
|
* Required since Phase 4 dropped the legacy `isAuction` / `isPreOrder`
|
|
244
|
-
* booleans. Every product document carries this
|
|
244
|
+
* booleans. Every product document carries this — queries route through
|
|
245
245
|
* `where("listingType", "==", X)` against the `listingType+...` composite
|
|
246
246
|
* indexes in `appkit/firebase/base/firestore.indexes.json`.
|
|
247
247
|
* SB-UNI-F — extended with classified | digital-code | live.
|
|
@@ -272,9 +272,10 @@ export interface ProductDocument extends BaseDocument {
|
|
|
272
272
|
prizeRevealWindowEnd?: Date;
|
|
273
273
|
/**
|
|
274
274
|
* "pending" is legacy-only (no longer written by new listings — reveal is
|
|
275
|
-
* fully automatic, there's no seller-facing delayed-start concept anymore
|
|
275
|
+
* fully automatic, there's no seller-facing delayed-start concept anymore —
|
|
276
276
|
* draft→published is how a seller holds a draw back). New listings go
|
|
277
|
-
* straight to "open"
|
|
277
|
+
* straight to "open", flipping to "closed" once every eligible order has
|
|
278
|
+
* been revealed.
|
|
278
279
|
*/
|
|
279
280
|
prizeRevealStatus?: "pending" | "open" | "closed";
|
|
280
281
|
/**
|
|
@@ -8,6 +8,7 @@ import { MediaImage } from "../../media/MediaImage";
|
|
|
8
8
|
import { BottomSheet } from "../../layout/BottomSheet";
|
|
9
9
|
import { SidebarCollapseToggle } from "../../../_internal/client/features/layout/SidebarCollapseToggle";
|
|
10
10
|
import { useSidebarSearch } from "../../../_internal/client/features/layout/useSidebarSearch";
|
|
11
|
+
import { findActiveNavGroup, findActiveNavItem } from "../../../_internal/client/features/layout/navActive";
|
|
11
12
|
const __O = {
|
|
12
13
|
hidden: "overflow-hidden",
|
|
13
14
|
yAuto: "overflow-y-auto",
|
|
@@ -18,26 +19,36 @@ const CLS_STORE_NAME = "text-[length:var(--appkit-text-sm)] font-semibold text-[
|
|
|
18
19
|
const CLS_NAV_ACTIVE = "bg-warning-surface dark:bg-warning-surface text-warning dark:text-warning";
|
|
19
20
|
const CLS_NAV_BADGE = "shrink-0 rounded-full bg-warning-surface px-[var(--appkit-space-1-5)] py-[var(--appkit-space-0-5)] text-[10px] text-white leading-none";
|
|
20
21
|
const CLS_NAV_ICON_ACTIVE = "text-warning dark:text-warning";
|
|
21
|
-
function isNavItemActive(item, activeHref) {
|
|
22
|
-
return activeHref === item.href;
|
|
23
|
-
}
|
|
24
22
|
function NavLink({ item, isActive, onClick }) {
|
|
25
23
|
return (_jsxs(Link, { href: item.href, onClick: onClick, className: `flex items-center justify-end gap-[var(--appkit-space-2-5)] rounded-lg px-[var(--appkit-space-3)] py-[var(--appkit-space-2)] text-[0.8125rem] font-medium leading-tight transition-colors ${isActive
|
|
26
24
|
? CLS_NAV_ACTIVE
|
|
27
25
|
: "text-[var(--appkit-color-text-muted)] hover:bg-zinc-50 hover:bg-[var(--appkit-color-surface-elevated)]/60 hover:text-zinc-800 hover:text-[var(--appkit-color-text-muted)]"}`, children: [item.icon && _jsx(Span, { size: "base", className: "shrink-0 opacity-60", children: item.icon }), _jsx(Span, { className: "truncate", children: item.label }), item.badge != null && item.badge > 0 && (_jsx(Span, { weight: "bold", className: CLS_NAV_BADGE, children: item.badge }))] }));
|
|
28
26
|
}
|
|
29
27
|
function FlatContent({ items, activeHref, storeName, storeLogoURL, onItemClick, }) {
|
|
28
|
+
const activeItem = findActiveNavItem(items, activeHref);
|
|
30
29
|
return (_jsxs(_Fragment, { children: [storeName && (_jsxs(Row, { border: "bottom-subtle", gap: "3", padding: "inline", children: [storeLogoURL ? (_jsx(Div, { className: CLS_STORE_AVATAR, children: _jsx(MediaImage, { src: storeLogoURL, alt: storeName, size: "thumbnail" }) })) : (_jsx(Div, { className: CLS_STORE_FALLBACK, children: storeName[0]?.toUpperCase() })), _jsx(Text, { className: CLS_STORE_NAME, children: storeName })] })), _jsx(Nav, { "aria-label": "Store navigation", padding: "y-sm", children: _jsx(Ul, { paddingX: "x-sm", spacing: "2xs", children: items.map((item) => {
|
|
31
|
-
const isActive =
|
|
30
|
+
const isActive = activeItem?.href === item.href;
|
|
32
31
|
return (_jsx(Li, { children: _jsx(NavLink, { item: item, isActive: isActive, onClick: onItemClick }) }, item.href));
|
|
33
32
|
}) }) })] }));
|
|
34
33
|
}
|
|
35
34
|
function GroupsContent({ groups, activeHref, storeName, storeLogoURL, onItemClick, }) {
|
|
36
|
-
// Accordion — only one group open at a time.
|
|
35
|
+
// Accordion — only one group open at a time. Initial pick: the group
|
|
36
|
+
// containing the active path, else the first group with defaultOpen.
|
|
37
37
|
const [openGroup, setOpenGroup] = useState(() => {
|
|
38
|
-
const
|
|
39
|
-
|
|
38
|
+
const active = findActiveNavGroup(groups, activeHref);
|
|
39
|
+
if (active)
|
|
40
|
+
return active.title;
|
|
41
|
+
return groups.find((g) => g.defaultOpen)?.title ?? null;
|
|
40
42
|
});
|
|
43
|
+
// Re-sync whenever the route changes — the sidebar stays mounted across
|
|
44
|
+
// client-side navigation, so the lazy initializer above only fires once.
|
|
45
|
+
useEffect(() => {
|
|
46
|
+
const active = findActiveNavGroup(groups, activeHref);
|
|
47
|
+
if (active)
|
|
48
|
+
setOpenGroup(active.title);
|
|
49
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
50
|
+
}, [activeHref]);
|
|
51
|
+
const activeItem = findActiveNavItem(groups.flatMap((g) => g.items), activeHref);
|
|
41
52
|
const { query, setQuery, isSearching, filteredGroups } = useSidebarSearch(groups);
|
|
42
53
|
const toggle = useCallback((title) => {
|
|
43
54
|
if (isSearching)
|
|
@@ -46,10 +57,10 @@ function GroupsContent({ groups, activeHref, storeName, storeLogoURL, onItemClic
|
|
|
46
57
|
}, [isSearching]);
|
|
47
58
|
return (_jsxs(_Fragment, { children: [storeName && (_jsxs(Row, { border: "bottom-subtle", gap: "3", padding: "inline", children: [storeLogoURL ? (_jsx(Div, { className: CLS_STORE_AVATAR, children: _jsx(MediaImage, { src: storeLogoURL, alt: storeName, size: "thumbnail" }) })) : (_jsx(Div, { className: CLS_STORE_FALLBACK, children: storeName[0]?.toUpperCase() })), _jsx(Text, { className: CLS_STORE_NAME, children: storeName })] })), _jsxs(Nav, { "aria-label": "Store navigation", padding: "y-xs", children: [_jsx(Div, { padding: "x-md", paddingY: "y-sm", children: _jsx(Input, { value: query, onChange: (e) => setQuery(e.target.value), placeholder: "Search navigation\u2026", "aria-label": "Search navigation" }) }), isSearching && filteredGroups.length === 0 && (_jsx(Div, { padding: "x-md", paddingY: "y-sm", children: _jsxs(Span, { size: "xs", color: "muted", children: ["No matches for \u201C", query, "\u201D."] }) })), filteredGroups.map((group) => {
|
|
48
59
|
const isOpen = isSearching || openGroup === group.title;
|
|
49
|
-
const hasActive = group.items
|
|
60
|
+
const hasActive = !!findActiveNavItem(group.items, activeHref);
|
|
50
61
|
return (_jsxs(Div, { className: "mb-0.5", children: [_jsx(Button, { type: "button", variant: "ghost", onClick: () => toggle(group.title), paddingX: "md", paddingY: "sm", weight: "semibold", rounded: "none", className: `w-full text-[0.6875rem] uppercase tracking-widest transition-colors ${hasActive && !isOpen
|
|
51
62
|
? CLS_NAV_ICON_ACTIVE
|
|
52
|
-
: "text-[var(--appkit-color-text-faint)] hover:text-[var(--appkit-color-text-muted)]"}`, children: _jsxs(Row, { align: "center", justify: "between", className: "w-full", children: [_jsx(Span, { children: group.title }), _jsx("svg", { className: `w-3 h-3 transition-transform duration-150 ${isOpen ? "rotate-180" : ""}`, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", "aria-hidden": "true", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2.5, d: "M19 9l-7 7-7-7" }) })] }) }), isOpen && (_jsx(Ul, { paddingX: "x-sm", paddingY: "y-bottom-xs", spacing: "2xs", children: group.items.map((item) => (_jsx(Li, { children: _jsx(NavLink, { item: item, isActive:
|
|
63
|
+
: "text-[var(--appkit-color-text-faint)] hover:text-[var(--appkit-color-text-muted)]"}`, children: _jsxs(Row, { align: "center", justify: "between", className: "w-full", children: [_jsx(Span, { children: group.title }), _jsx("svg", { className: `w-3 h-3 transition-transform duration-150 ${isOpen ? "rotate-180" : ""}`, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", "aria-hidden": "true", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2.5, d: "M19 9l-7 7-7-7" }) })] }) }), isOpen && (_jsx(Ul, { paddingX: "x-sm", paddingY: "y-bottom-xs", spacing: "2xs", children: group.items.map((item) => (_jsx(Li, { children: _jsx(NavLink, { item: item, isActive: activeItem?.href === item.href, onClick: onItemClick }) }, item.href))) }))] }, group.title));
|
|
53
64
|
})] })] }));
|
|
54
65
|
}
|
|
55
66
|
function DrawerPanel({ title, onClose, children }) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { Package, ShoppingBag, Wallet, Settings, Shield, Headphones, CheckCircle2, Circle, BookOpen, } from "lucide-react";
|
|
2
|
+
import { Package, ShoppingBag, Wallet, Settings, Shield, Headphones, CheckCircle2, Circle, BookOpen, MessageSquare, } from "lucide-react";
|
|
3
3
|
import { Div, Heading, Progress, Row, Section, Stack, Text, TextLink } from "../../../ui";
|
|
4
4
|
import { ROUTES } from "../../../next/routing/route-map";
|
|
5
5
|
const CLS_CHECK_ICON = "w-5 h-5 flex-shrink-0 text-emerald-500";
|
|
@@ -36,6 +36,12 @@ const GUIDE_CARDS = [
|
|
|
36
36
|
description: "Admin-granted feature flags — auctions, pre-orders, lower commissions, and more.",
|
|
37
37
|
href: String(ROUTES.STORE.GUIDE_CAPABILITIES),
|
|
38
38
|
},
|
|
39
|
+
{
|
|
40
|
+
Icon: MessageSquare,
|
|
41
|
+
title: "WhatsApp Catalog Sync",
|
|
42
|
+
description: "Push your product catalog to Meta Commerce Manager for WhatsApp, Facebook, and Instagram Shops.",
|
|
43
|
+
href: String(ROUTES.STORE.GUIDE_WHATSAPP),
|
|
44
|
+
},
|
|
39
45
|
{
|
|
40
46
|
Icon: Headphones,
|
|
41
47
|
title: "Support",
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { useRouter } from "next/navigation";
|
|
4
4
|
import { Button, Div, Select, TextLink } from "../../../ui";
|
|
5
|
+
const CLS_ACTIVE_TAB = "border-primary text-primary";
|
|
5
6
|
export function StoreNavTabs({ tabs, dropdownTabs = [], dropdownPlaceholder = "Browse listings", activeValue, onTabChange, renderTabBar, className = "", }) {
|
|
6
7
|
const router = useRouter();
|
|
7
8
|
const handleChange = (v) => onTabChange?.(v);
|
|
@@ -17,9 +18,9 @@ export function StoreNavTabs({ tabs, dropdownTabs = [], dropdownPlaceholder = "B
|
|
|
17
18
|
router.push(tab.href);
|
|
18
19
|
handleChange(tab.value);
|
|
19
20
|
};
|
|
20
|
-
return (_jsxs(Div, { layout: "flex", gap: "2", role: "tablist", border: "bottom", className: `
|
|
21
|
-
?
|
|
21
|
+
return (_jsxs(Div, { layout: "flex", gap: "2", align: "center", role: "tablist", border: "bottom", className: `overflow-x-auto ${className}`, children: [dropdownTabs.length > 0 && (_jsx(Select, { bare: true, "aria-label": dropdownPlaceholder, options: dropdownTabs.map((tab) => ({ value: tab.value, label: tab.label })), value: activeDropdownTab?.value ?? "", placeholder: activeDropdownTab ? undefined : dropdownPlaceholder, onValueChange: handleDropdownChange, className: `max-w-[12rem] flex-shrink-0 whitespace-nowrap ${activeDropdownTab ? CLS_ACTIVE_TAB : ""}` })), tabs.map((tab) => tab.href ? (_jsx(TextLink, { variant: "bare", href: tab.href, role: "tab", "aria-selected": activeValue === tab.value, paddingX: "md", paddingY: "xs", size: "sm", weight: "medium", className: `whitespace-nowrap border-b-2 -mb-px transition-colors ${activeValue === tab.value
|
|
22
|
+
? CLS_ACTIVE_TAB
|
|
22
23
|
: "border-transparent text-[var(--appkit-color-text-muted)] text-[var(--appkit-color-text-muted)] hover:text-neutral-800 hover:text-[var(--appkit-color-text-muted)]"}`, children: tab.label }, tab.value)) : (_jsx(Button, { variant: "ghost", type: "button", role: "tab", "aria-selected": activeValue === tab.value, onClick: () => handleChange(tab.value), paddingX: "md", paddingY: "sm", textSize: "sm", weight: "medium", rounded: "none", className: `whitespace-nowrap border-b-2 -mb-px transition-colors ${activeValue === tab.value
|
|
23
|
-
?
|
|
24
|
+
? CLS_ACTIVE_TAB
|
|
24
25
|
: "border-transparent text-[var(--appkit-color-text-muted)] text-[var(--appkit-color-text-muted)] hover:text-neutral-800 hover:text-[var(--appkit-color-text-muted)]"}`, children: tab.label }, tab.value)))] }));
|
|
25
26
|
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { ArrowLeft } from "lucide-react";
|
|
3
|
+
import { Alert, Code, Div, Heading, Li, Section, Span, Stack, Text, TextLink, Ul } from "../../../ui";
|
|
4
|
+
import { ROUTES } from "../../../next/routing/route-map";
|
|
5
|
+
function GuideSection({ title, children, }) {
|
|
6
|
+
return (_jsxs(Section, { className: "border border-[var(--appkit-color-border)] bg-[var(--appkit-color-surface)]", rounded: "xl", shadow: "sm", padding: "lg", children: [_jsx(Heading, { level: 2, className: "mb-4 text-[var(--appkit-color-text)]", size: "lg", weight: "semibold", children: title }), children] }));
|
|
7
|
+
}
|
|
8
|
+
const LIST_DISC = "list-disc leading-relaxed";
|
|
9
|
+
const TEXT_MUTED = "leading-relaxed text-[var(--appkit-color-text-muted)]";
|
|
10
|
+
export function StoreWhatsAppGuideView(_props) {
|
|
11
|
+
return (_jsxs(Stack, { gap: "lg", padding: "b-2xl", children: [_jsxs(TextLink, { variant: "bare", href: String(ROUTES.STORE.GUIDE), size: "sm", layout: "inline-flex", align: "center", gap: "sm", className: "text-[var(--appkit-color-text-muted)] hover:text-[var(--appkit-color-text)] transition-colors", children: [_jsx(ArrowLeft, { className: "h-4 w-4" }), "Back to Seller Guide"] }), _jsxs(Div, { children: [_jsx(Heading, { level: 1, className: "text-[var(--appkit-color-text)]", size: "2xl", weight: "bold", children: "WhatsApp Catalog Sync" }), _jsx(Text, { className: "mt-1 text-[var(--appkit-color-text-muted)]", size: "sm", children: "Push your product catalog to Meta's Commerce Manager for WhatsApp catalog messages and Facebook/Instagram Shops \u2014 and import products back the other way." })] }), _jsx(GuideSection, { title: "1. Create a Commerce Manager catalog", children: _jsxs(Ul, { spacing: "tight", indent: "lg", children: [_jsxs(Li, { className: LIST_DISC, textSize: "sm", color: "muted", children: ["At ", _jsx(Span, { weight: "bold", children: "business.facebook.com/commerce" }), ", create a new catalog for the store (or use an existing one)."] }), _jsxs(Li, { className: LIST_DISC, textSize: "sm", color: "muted", children: ["Note the ", _jsx(Span, { weight: "bold", children: "Catalog ID" }), " shown in the catalog's settings."] })] }) }), _jsx(GuideSection, { title: "2. Generate a catalog-scoped access token", children: _jsxs(Text, { className: TEXT_MUTED, size: "sm", children: ["You need a Meta access token with ", _jsx(Code, { size: "xs", padding: "xs", rounded: "default", surface: "subtle", children: "catalog_management" }), " permission, scoped to that catalog. This is generated the same way as the platform-level WhatsApp System User token (ask your admin \u2014 Admin Guide \u2192 WhatsApp Integration, step 3) but assigned to the ", _jsx(Span, { weight: "bold", children: "catalog" }), " asset instead of the WhatsApp Business Account asset."] }) }), _jsxs(GuideSection, { title: "3. Enter credentials in the seller dashboard", children: [_jsxs(Text, { className: "mb-2 leading-relaxed text-[var(--appkit-color-text-muted)]", size: "sm", children: [_jsx(Span, { weight: "bold", children: "Store \u2192 WhatsApp" }), " settings page:"] }), _jsxs(Ul, { spacing: "tight", indent: "lg", children: [_jsx(Li, { className: LIST_DISC, textSize: "sm", color: "muted", children: "Catalog ID" }), _jsx(Li, { className: LIST_DISC, textSize: "sm", color: "muted", children: "Access Token" })] }), _jsxs(Text, { className: "mt-3 leading-relaxed text-[var(--appkit-color-text-muted)]", size: "sm", children: ["This is a store capability \u2014 it must be enabled for the store (", _jsx(Code, { size: "xs", padding: "xs", rounded: "default", surface: "subtle", children: "whatsapp_catalog_sync" }), " capability) before the settings page and sync actions are available."] })] }), _jsx(GuideSection, { title: "4. Push products to the catalog", children: _jsxs(Text, { className: TEXT_MUTED, size: "sm", children: ["Once connected, trigger a sync that batches published ", _jsx(Code, { size: "xs", padding: "xs", rounded: "default", surface: "subtle", children: "standard" }), "-listing products (up to 50 per API call) to the Meta catalog via the Commerce API ", _jsx(Code, { size: "xs", padding: "xs", rounded: "default", surface: "subtle", children: "items_batch" }), " endpoint \u2014 title, description, price, image, availability, and condition."] }) }), _jsx(GuideSection, { title: "5. Import products from the catalog", children: _jsxs(Text, { className: TEXT_MUTED, size: "sm", children: ["The reverse flow fetches products already in the Meta catalog and creates them as local ", _jsx(Span, { weight: "bold", children: "draft" }), " listings, deduplicating against existing products by slug/retailer-id matching."] }) }), _jsxs(Alert, { variant: "info", children: ["This is unrelated to the platform-level WhatsApp order-notification credentials \u2014 those are for sending order-status messages to buyers, not catalog sync. Only published ", _jsx(Span, { weight: "bold", children: "standard" }), " listings sync \u2014 auctions, pre-orders, and other listing types are not included."] })] }));
|
|
12
|
+
}
|
|
@@ -47,3 +47,5 @@ export { StoreCapabilitiesGuideView } from "./StoreCapabilitiesGuideView";
|
|
|
47
47
|
export type { StoreCapabilitiesGuideViewProps } from "./StoreCapabilitiesGuideView";
|
|
48
48
|
export { StoreSettingsGuideView } from "./StoreSettingsGuideView";
|
|
49
49
|
export type { StoreSettingsGuideViewProps } from "./StoreSettingsGuideView";
|
|
50
|
+
export { StoreWhatsAppGuideView } from "./StoreWhatsAppGuideView";
|
|
51
|
+
export type { StoreWhatsAppGuideViewProps } from "./StoreWhatsAppGuideView";
|
|
@@ -20,3 +20,4 @@ export { StoreOrdersGuideView } from "./StoreOrdersGuideView";
|
|
|
20
20
|
export { StoreFinanceGuideView } from "./StoreFinanceGuideView";
|
|
21
21
|
export { StoreCapabilitiesGuideView } from "./StoreCapabilitiesGuideView";
|
|
22
22
|
export { StoreSettingsGuideView } from "./StoreSettingsGuideView";
|
|
23
|
+
export { StoreWhatsAppGuideView } from "./StoreWhatsAppGuideView";
|
|
@@ -25,6 +25,7 @@ import { seedExtMedia } from "../../../seed/_helpers/media";
|
|
|
25
25
|
import { testDataExpiresAt } from "./tester-ttl";
|
|
26
26
|
const TESTER_STORE_ID = "store-tester-sandbox";
|
|
27
27
|
const TESTER_STORE_NAME = "Tester Sandbox Store";
|
|
28
|
+
const TESTER_GROUP_TITLE = "Tester Sandbox Bundle";
|
|
28
29
|
const GADGETS_CATEGORY_SLUGS = ["category-tester-gadgets", "category-tester-sandbox"];
|
|
29
30
|
const GADGETS_CATEGORY_NAMES = ["Test Gadgets", "Tester Sandbox"];
|
|
30
31
|
const COLLECTIBLES_CATEGORY_SLUGS = ["category-tester-collectibles", "category-tester-sandbox"];
|
|
@@ -71,7 +72,7 @@ export const productsTesterSeedData = [
|
|
|
71
72
|
// resolvable and ShowGroupSection renders nothing (members.length <= 1).
|
|
72
73
|
groupId: "group-tester-sandbox-bundle",
|
|
73
74
|
groupParentSlug: "group-tester-sandbox-bundle",
|
|
74
|
-
groupTitle:
|
|
75
|
+
groupTitle: TESTER_GROUP_TITLE,
|
|
75
76
|
createdAt: new Date(),
|
|
76
77
|
updatedAt: new Date(),
|
|
77
78
|
}),
|
|
@@ -100,7 +101,7 @@ export const productsTesterSeedData = [
|
|
|
100
101
|
isOnSale: false,
|
|
101
102
|
groupId: "group-tester-sandbox-bundle",
|
|
102
103
|
groupParentSlug: "group-tester-sandbox-bundle",
|
|
103
|
-
groupTitle:
|
|
104
|
+
groupTitle: TESTER_GROUP_TITLE,
|
|
104
105
|
createdAt: new Date(),
|
|
105
106
|
updatedAt: new Date(),
|
|
106
107
|
}),
|
|
@@ -492,7 +493,7 @@ export const productsTesterSeedData = [
|
|
|
492
493
|
isOnSale: false,
|
|
493
494
|
isGroupParent: true,
|
|
494
495
|
groupId: "group-tester-sandbox-bundle",
|
|
495
|
-
groupTitle:
|
|
496
|
+
groupTitle: TESTER_GROUP_TITLE,
|
|
496
497
|
groupChildSlugs: ["product-tester-standard-1", "product-tester-standard-2"],
|
|
497
498
|
createdAt: new Date(),
|
|
498
499
|
updatedAt: new Date(),
|
|
@@ -18,6 +18,8 @@
|
|
|
18
18
|
* @tag sideEffects:none
|
|
19
19
|
*/
|
|
20
20
|
import { assignDefaultPhases } from "../utils/phases";
|
|
21
|
+
const ADMIN_TESTING_GROUP_LABEL = "Admin (Testing)";
|
|
22
|
+
const BUG_HUNTER_REWARDS_PAGE_LABEL = "Bug Hunter Rewards";
|
|
21
23
|
function group(groupKey, groupLabel, pages, opts) {
|
|
22
24
|
const items = [];
|
|
23
25
|
pages.forEach((page, pageIdx) => {
|
|
@@ -676,7 +678,7 @@ const rawTesterChecklistItems = [
|
|
|
676
678
|
],
|
|
677
679
|
},
|
|
678
680
|
]),
|
|
679
|
-
...group("admin",
|
|
681
|
+
...group("admin", ADMIN_TESTING_GROUP_LABEL, [
|
|
680
682
|
{
|
|
681
683
|
pageKey: "catalog-listings",
|
|
682
684
|
pageLabel: "Catalog & Listings",
|
|
@@ -853,7 +855,7 @@ const rawTesterChecklistItems = [
|
|
|
853
855
|
},
|
|
854
856
|
{
|
|
855
857
|
pageKey: "bug-hunter-rewards",
|
|
856
|
-
pageLabel:
|
|
858
|
+
pageLabel: BUG_HUNTER_REWARDS_PAGE_LABEL,
|
|
857
859
|
cases: [
|
|
858
860
|
{
|
|
859
861
|
key: "confirm-bug",
|
|
@@ -888,9 +890,9 @@ const rawTesterChecklistItems = [
|
|
|
888
890
|
{
|
|
889
891
|
id: "checklist-admin-bug-hunter-rewards-demo-fixture",
|
|
890
892
|
groupKey: "admin",
|
|
891
|
-
groupLabel:
|
|
893
|
+
groupLabel: ADMIN_TESTING_GROUP_LABEL,
|
|
892
894
|
pageKey: "bug-hunter-rewards",
|
|
893
|
-
pageLabel:
|
|
895
|
+
pageLabel: BUG_HUNTER_REWARDS_PAGE_LABEL,
|
|
894
896
|
label: "Demo fixture — reported bug, already confirmed and reopened (v1, disabled)",
|
|
895
897
|
description: "Seed-only fixture demonstrating a confirmed bug: this v1 case is disabled (isActive:false) and credited to \"Mock User 18\". Its retest is \"Demo fixture — reported bug, already confirmed and reopened (v2, active)\" in this same page.",
|
|
896
898
|
order: 100,
|
|
@@ -906,9 +908,9 @@ const rawTesterChecklistItems = [
|
|
|
906
908
|
{
|
|
907
909
|
id: "checklist-admin-bug-hunter-rewards-demo-fixture-v2",
|
|
908
910
|
groupKey: "admin",
|
|
909
|
-
groupLabel:
|
|
911
|
+
groupLabel: ADMIN_TESTING_GROUP_LABEL,
|
|
910
912
|
pageKey: "bug-hunter-rewards",
|
|
911
|
-
pageLabel:
|
|
913
|
+
pageLabel: BUG_HUNTER_REWARDS_PAGE_LABEL,
|
|
912
914
|
label: "Demo fixture — reported bug, already confirmed and reopened (v2, active)",
|
|
913
915
|
description: "Seed-only fixture — the retest version reopened from the disabled v1 case in this same page. Active and answerable again; a fresh \"No\" answer here can be used to try Mark as Bug end-to-end.",
|
|
914
916
|
order: 101,
|
package/dist/index.d.ts
CHANGED
|
@@ -2900,6 +2900,8 @@ export { AdminSiteConfigGuideView } from "./features/admin/components/AdminSiteC
|
|
|
2900
2900
|
export { AdminTeamGuideView } from "./features/admin/components/AdminTeamGuideView";
|
|
2901
2901
|
export { AdminAnalyticsGuideView } from "./features/admin/components/AdminAnalyticsGuideView";
|
|
2902
2902
|
export { AdminTrustGuideView } from "./features/admin/components/AdminTrustGuideView";
|
|
2903
|
+
export { AdminWhatsAppGuideView } from "./features/admin/components/AdminWhatsAppGuideView";
|
|
2904
|
+
export { AdminPaymentsGuideView } from "./features/admin/components/AdminPaymentsGuideView";
|
|
2903
2905
|
export { BuyerShoppingGuideView } from "./features/account/components/BuyerShoppingGuideView";
|
|
2904
2906
|
export { BuyerAuctionsGuideView } from "./features/account/components/BuyerAuctionsGuideView";
|
|
2905
2907
|
export { BuyerOrdersGuideView } from "./features/account/components/BuyerOrdersGuideView";
|
|
@@ -2916,6 +2918,8 @@ export { StoreCapabilitiesGuideView } from "./features/stores/components/StoreCa
|
|
|
2916
2918
|
export type { StoreCapabilitiesGuideViewProps } from "./features/stores/components/StoreCapabilitiesGuideView";
|
|
2917
2919
|
export { StoreSettingsGuideView } from "./features/stores/components/StoreSettingsGuideView";
|
|
2918
2920
|
export type { StoreSettingsGuideViewProps } from "./features/stores/components/StoreSettingsGuideView";
|
|
2921
|
+
export { StoreWhatsAppGuideView } from "./features/stores/components/StoreWhatsAppGuideView";
|
|
2922
|
+
export type { StoreWhatsAppGuideViewProps } from "./features/stores/components/StoreWhatsAppGuideView";
|
|
2919
2923
|
export { StorePreOrdersListing } from "./features/stores/components/StorePreOrdersListing";
|
|
2920
2924
|
export type { StorePreOrdersListingProps } from "./features/stores/components/StorePreOrdersListing";
|
|
2921
2925
|
export { buildStoreColumns } from "./features/stores/index";
|
package/dist/index.js
CHANGED
|
@@ -5218,6 +5218,10 @@ export { AdminTeamGuideView } from "./features/admin/components/AdminTeamGuideVi
|
|
|
5218
5218
|
export { AdminAnalyticsGuideView } from "./features/admin/components/AdminAnalyticsGuideView";
|
|
5219
5219
|
// [CLIENT-SSR]-Admin trust & safety guide — static view, no firebase-admin.
|
|
5220
5220
|
export { AdminTrustGuideView } from "./features/admin/components/AdminTrustGuideView";
|
|
5221
|
+
// [CLIENT-SSR]-Admin WhatsApp integration guide — static view, no firebase-admin.
|
|
5222
|
+
export { AdminWhatsAppGuideView } from "./features/admin/components/AdminWhatsAppGuideView";
|
|
5223
|
+
// [CLIENT-SSR]-Admin payments (Razorpay) guide — static view, no firebase-admin.
|
|
5224
|
+
export { AdminPaymentsGuideView } from "./features/admin/components/AdminPaymentsGuideView";
|
|
5221
5225
|
// [CLIENT-SSR]-Buyer shopping guide — static view, no firebase-admin.
|
|
5222
5226
|
export { BuyerShoppingGuideView } from "./features/account/components/BuyerShoppingGuideView";
|
|
5223
5227
|
// [CLIENT-SSR]-Buyer auctions & pre-orders guide — static view, no firebase-admin.
|
|
@@ -5238,6 +5242,8 @@ export { StoreFinanceGuideView } from "./features/stores/components/StoreFinance
|
|
|
5238
5242
|
export { StoreCapabilitiesGuideView } from "./features/stores/components/StoreCapabilitiesGuideView";
|
|
5239
5243
|
// [CLIENT-SSR]-Store settings guide — static view, no firebase-admin.
|
|
5240
5244
|
export { StoreSettingsGuideView } from "./features/stores/components/StoreSettingsGuideView";
|
|
5245
|
+
// [CLIENT-SSR]-Store WhatsApp catalog sync guide — static view, no firebase-admin.
|
|
5246
|
+
export { StoreWhatsAppGuideView } from "./features/stores/components/StoreWhatsAppGuideView";
|
|
5241
5247
|
export { StorePreOrdersListing } from "./features/stores/components/StorePreOrdersListing";
|
|
5242
5248
|
// [CLIENT-SSR]-Runs in both SSR and browser â€" React component or hook that does not depend on browser-only APIs.
|
|
5243
5249
|
// buildStoreColumns - Helper for build store columns.
|
|
@@ -238,6 +238,7 @@ export declare const DEFAULT_ROUTE_MAP: {
|
|
|
238
238
|
readonly GUIDE_FINANCE: "/store/guide/finance";
|
|
239
239
|
readonly GUIDE_CAPABILITIES: "/store/guide/capabilities";
|
|
240
240
|
readonly GUIDE_SETTINGS: "/store/guide/settings";
|
|
241
|
+
readonly GUIDE_WHATSAPP: "/store/guide/whatsapp";
|
|
241
242
|
};
|
|
242
243
|
readonly ADMIN: {
|
|
243
244
|
readonly DASHBOARD: "/admin/dashboard";
|
|
@@ -249,7 +250,6 @@ export declare const DEFAULT_ROUTE_MAP: {
|
|
|
249
250
|
readonly CATALOGUE_APPROVALS: "/admin/catalogue-approvals";
|
|
250
251
|
readonly USERS: "/admin/users";
|
|
251
252
|
readonly SITE: "/admin/site";
|
|
252
|
-
readonly INTEGRATION_GUIDES: "/admin/integration-guides";
|
|
253
253
|
readonly CAROUSEL: "/admin/carousel";
|
|
254
254
|
readonly CAROUSEL_NEW: "/admin/carousel/new";
|
|
255
255
|
readonly CAROUSEL_EDIT: (id: string) => string;
|
|
@@ -360,6 +360,8 @@ export declare const DEFAULT_ROUTE_MAP: {
|
|
|
360
360
|
readonly GUIDE_TEAM: "/admin/guide/team";
|
|
361
361
|
readonly GUIDE_ANALYTICS: "/admin/guide/analytics";
|
|
362
362
|
readonly GUIDE_TRUST: "/admin/guide/trust";
|
|
363
|
+
readonly GUIDE_WHATSAPP: "/admin/guide/whatsapp";
|
|
364
|
+
readonly GUIDE_PAYMENTS: "/admin/guide/payments";
|
|
363
365
|
readonly BANNED_ADDRESSES: "/admin/banned-addresses";
|
|
364
366
|
readonly ADDRESS_CLUSTERS: "/admin/address-clusters";
|
|
365
367
|
readonly PAYMENT_METHODS: "/admin/payment-methods";
|
|
@@ -599,6 +601,7 @@ export declare const ROUTES: {
|
|
|
599
601
|
readonly GUIDE_FINANCE: "/store/guide/finance";
|
|
600
602
|
readonly GUIDE_CAPABILITIES: "/store/guide/capabilities";
|
|
601
603
|
readonly GUIDE_SETTINGS: "/store/guide/settings";
|
|
604
|
+
readonly GUIDE_WHATSAPP: "/store/guide/whatsapp";
|
|
602
605
|
};
|
|
603
606
|
readonly ADMIN: {
|
|
604
607
|
readonly DASHBOARD: "/admin/dashboard";
|
|
@@ -610,7 +613,6 @@ export declare const ROUTES: {
|
|
|
610
613
|
readonly CATALOGUE_APPROVALS: "/admin/catalogue-approvals";
|
|
611
614
|
readonly USERS: "/admin/users";
|
|
612
615
|
readonly SITE: "/admin/site";
|
|
613
|
-
readonly INTEGRATION_GUIDES: "/admin/integration-guides";
|
|
614
616
|
readonly CAROUSEL: "/admin/carousel";
|
|
615
617
|
readonly CAROUSEL_NEW: "/admin/carousel/new";
|
|
616
618
|
readonly CAROUSEL_EDIT: (id: string) => string;
|
|
@@ -721,6 +723,8 @@ export declare const ROUTES: {
|
|
|
721
723
|
readonly GUIDE_TEAM: "/admin/guide/team";
|
|
722
724
|
readonly GUIDE_ANALYTICS: "/admin/guide/analytics";
|
|
723
725
|
readonly GUIDE_TRUST: "/admin/guide/trust";
|
|
726
|
+
readonly GUIDE_WHATSAPP: "/admin/guide/whatsapp";
|
|
727
|
+
readonly GUIDE_PAYMENTS: "/admin/guide/payments";
|
|
724
728
|
readonly BANNED_ADDRESSES: "/admin/banned-addresses";
|
|
725
729
|
readonly ADDRESS_CLUSTERS: "/admin/address-clusters";
|
|
726
730
|
readonly PAYMENT_METHODS: "/admin/payment-methods";
|
|
@@ -815,6 +819,7 @@ export declare const SELLER_ROUTES: {
|
|
|
815
819
|
readonly GUIDE_FINANCE: "/store/guide/finance";
|
|
816
820
|
readonly GUIDE_CAPABILITIES: "/store/guide/capabilities";
|
|
817
821
|
readonly GUIDE_SETTINGS: "/store/guide/settings";
|
|
822
|
+
readonly GUIDE_WHATSAPP: "/store/guide/whatsapp";
|
|
818
823
|
};
|
|
819
824
|
export declare const PUBLIC_ROUTES: readonly ["/", string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, "/unauthorized", "/auth/login", "/auth/register", "/auth/forgot-password", "/auth/reset-password", "/auth/verify-email"];
|
|
820
825
|
export declare const PROTECTED_ROUTES: readonly [string, string, string, string, string, string, string];
|
|
@@ -237,6 +237,7 @@ export const DEFAULT_ROUTE_MAP = {
|
|
|
237
237
|
GUIDE_FINANCE: "/store/guide/finance",
|
|
238
238
|
GUIDE_CAPABILITIES: "/store/guide/capabilities",
|
|
239
239
|
GUIDE_SETTINGS: "/store/guide/settings",
|
|
240
|
+
GUIDE_WHATSAPP: "/store/guide/whatsapp",
|
|
240
241
|
},
|
|
241
242
|
ADMIN: {
|
|
242
243
|
DASHBOARD: "/admin/dashboard",
|
|
@@ -248,7 +249,6 @@ export const DEFAULT_ROUTE_MAP = {
|
|
|
248
249
|
CATALOGUE_APPROVALS: "/admin/catalogue-approvals",
|
|
249
250
|
USERS: "/admin/users",
|
|
250
251
|
SITE: "/admin/site",
|
|
251
|
-
INTEGRATION_GUIDES: "/admin/integration-guides",
|
|
252
252
|
CAROUSEL: "/admin/carousel",
|
|
253
253
|
CAROUSEL_NEW: "/admin/carousel/new",
|
|
254
254
|
CAROUSEL_EDIT: (id) => `/admin/carousel/${id}/edit`,
|
|
@@ -364,6 +364,8 @@ export const DEFAULT_ROUTE_MAP = {
|
|
|
364
364
|
GUIDE_TEAM: "/admin/guide/team",
|
|
365
365
|
GUIDE_ANALYTICS: "/admin/guide/analytics",
|
|
366
366
|
GUIDE_TRUST: "/admin/guide/trust",
|
|
367
|
+
GUIDE_WHATSAPP: "/admin/guide/whatsapp",
|
|
368
|
+
GUIDE_PAYMENTS: "/admin/guide/payments",
|
|
367
369
|
BANNED_ADDRESSES: "/admin/banned-addresses",
|
|
368
370
|
ADDRESS_CLUSTERS: "/admin/address-clusters",
|
|
369
371
|
PAYMENT_METHODS: "/admin/payment-methods",
|
|
@@ -290,8 +290,7 @@ const _rawProductsStandardSeedData = [
|
|
|
290
290
|
seedExtMedia("https://picsum.photos/seed/product-image-beyblade-original-dragoon-f-video-demo-2-20260819/900/900"),
|
|
291
291
|
],
|
|
292
292
|
video: {
|
|
293
|
-
// audit-seed-external-url-ok: raw <video> src, /api/media/ext is image-only (Root Cause #27)
|
|
294
|
-
url: "https://storage.googleapis.com/gtv-videos-bucket/sample/ForBiggerBlazes.mp4",
|
|
293
|
+
url: "https://storage.googleapis.com/gtv-videos-bucket/sample/ForBiggerBlazes.mp4", // audit-seed-external-url-ok: raw <video> src, /api/media/ext is image-only (Root Cause #27)
|
|
295
294
|
thumbnailUrl: seedExtMedia("https://picsum.photos/seed/product-video-thumb-beyblade-original-dragoon-f-video-demo-20260819/800/450"),
|
|
296
295
|
duration: 15,
|
|
297
296
|
},
|
|
@@ -324,8 +323,7 @@ const _rawProductsStandardSeedData = [
|
|
|
324
323
|
seedExtMedia("https://picsum.photos/seed/product-image-beyblade-x-dran-sword-video-demo-2-20260819/900/900"),
|
|
325
324
|
],
|
|
326
325
|
video: {
|
|
327
|
-
// audit-seed-external-url-ok: raw <video> src, /api/media/ext is image-only (Root Cause #27)
|
|
328
|
-
url: "https://storage.googleapis.com/gtv-videos-bucket/sample/ElephantsDream.mp4",
|
|
326
|
+
url: "https://storage.googleapis.com/gtv-videos-bucket/sample/ElephantsDream.mp4", // audit-seed-external-url-ok: raw <video> src, /api/media/ext is image-only (Root Cause #27)
|
|
329
327
|
thumbnailUrl: seedExtMedia("https://picsum.photos/seed/product-video-thumb-beyblade-x-dran-sword-video-demo-20260819/800/450"),
|
|
330
328
|
duration: 20,
|
|
331
329
|
},
|