@mohasinac/appkit 3.5.5 → 3.5.7

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.
Files changed (121) hide show
  1. package/dist/_internal/client/features/layout/DashboardLayoutClient.js +24 -3
  2. package/dist/_internal/client/features/tour/TourProvider.d.ts +11 -3
  3. package/dist/_internal/client/features/tour/TourProvider.js +93 -4
  4. package/dist/_internal/client/scaffolds/index.d.ts +0 -2
  5. package/dist/_internal/client/scaffolds/index.js +0 -1
  6. package/dist/_internal/server/features/checkout/actions.js +65 -11
  7. package/dist/_internal/server/features/orders/adapters.js +3 -0
  8. package/dist/_internal/shared/actions/action-registry.js +20 -0
  9. package/dist/_internal/shared/checkout/order-math.d.ts +21 -0
  10. package/dist/_internal/shared/checkout/order-math.js +24 -0
  11. package/dist/_internal/shared/features/orders/config.d.ts +1 -1
  12. package/dist/_internal/shared/features/orders/config.js +1 -1
  13. package/dist/_internal/shared/fees/calculator.d.ts +13 -0
  14. package/dist/_internal/shared/fees/calculator.js +8 -0
  15. package/dist/client-entry.d.ts +2 -2
  16. package/dist/client-entry.js +2 -2
  17. package/dist/client.d.ts +8 -0
  18. package/dist/client.js +8 -0
  19. package/dist/constants/api-endpoints.d.ts +9 -0
  20. package/dist/constants/api-endpoints.js +3 -0
  21. package/dist/features/account/components/UserSidebar.js +1 -1
  22. package/dist/features/admin/components/AdminBundleEditorView.d.ts +8 -1
  23. package/dist/features/admin/components/AdminBundleEditorView.js +15 -11
  24. package/dist/features/admin/components/AdminFeaturesView.js +1 -1
  25. package/dist/features/admin/components/AdminPayoutsView.js +41 -4
  26. package/dist/features/admin/components/AdminSidebar.js +1 -1
  27. package/dist/features/admin/components/AdminSiteSettingsView.js +49 -1
  28. package/dist/features/admin/components/DataTable.js +1 -1
  29. package/dist/features/admin/components/index.d.ts +0 -2
  30. package/dist/features/admin/components/index.js +0 -1
  31. package/dist/features/admin/schemas/firestore.d.ts +8 -0
  32. package/dist/features/admin/schemas/firestore.js +6 -0
  33. package/dist/features/auctions/components/MarketplaceAuctionCard.js +1 -1
  34. package/dist/features/before-after/components/BeforeAfterSlider.js +4 -0
  35. package/dist/features/blog/components/BlogFeaturedCard.js +1 -1
  36. package/dist/features/categories/components/BundleDynamicRuleEditor.js +2 -9
  37. package/dist/features/events/components/EventCard.js +1 -1
  38. package/dist/features/events/components/EventRafflesSection.d.ts +1 -1
  39. package/dist/features/events/components/EventRafflesSection.js +3 -3
  40. package/dist/features/homepage/components/BeforeAfterCard.js +5 -0
  41. package/dist/features/homepage/components/FeaturedBundlesSection.d.ts +1 -1
  42. package/dist/features/homepage/components/FeaturedBundlesSection.js +3 -1
  43. package/dist/features/homepage/components/GoogleReviewsSection.js +2 -2
  44. package/dist/features/homepage/components/HeroCarousel.js +1 -1
  45. package/dist/features/layout/NavbarLayout.js +1 -1
  46. package/dist/features/layout/TitleBarLayout.js +5 -5
  47. package/dist/features/media/MediaLightbox.js +7 -1
  48. package/dist/features/media/components/MediaSlider.js +4 -1
  49. package/dist/features/media/modals/ImageCropModal.js +1 -1
  50. package/dist/features/media/upload/ImageUpload.js +24 -12
  51. package/dist/features/messages/hooks/useConversations.d.ts +7 -1
  52. package/dist/features/messages/hooks/useConversations.js +7 -6
  53. package/dist/features/orders/actions/order-actions.d.ts +10 -0
  54. package/dist/features/orders/actions/order-actions.js +57 -4
  55. package/dist/features/orders/components/MarketplaceOrderCard.js +1 -1
  56. package/dist/features/orders/schemas/firestore.d.ts +16 -0
  57. package/dist/features/orders/types/index.d.ts +2 -0
  58. package/dist/features/pre-orders/components/MarketplacePreorderCard.js +1 -1
  59. package/dist/features/products/components/MarketplaceBundleCard.js +1 -1
  60. package/dist/features/products/components/MarketplacePrizeDrawCard.js +1 -1
  61. package/dist/features/products/components/PrizeDrawsSection.d.ts +1 -1
  62. package/dist/features/products/components/PrizeDrawsSection.js +3 -2
  63. package/dist/features/products/components/ProductForm.js +4 -9
  64. package/dist/features/products/components/ProductGrid.js +1 -1
  65. package/dist/features/products/schemas/firestore.d.ts +4 -0
  66. package/dist/features/promotions/components/CouponCard.js +1 -1
  67. package/dist/features/scams/actions/scam-actions.d.ts +12 -0
  68. package/dist/features/scams/actions/scam-actions.js +31 -0
  69. package/dist/features/scams/components/SellerTrustBadge.d.ts +16 -0
  70. package/dist/features/scams/components/SellerTrustBadge.js +21 -0
  71. package/dist/features/scams/components/index.d.ts +2 -0
  72. package/dist/features/scams/components/index.js +1 -0
  73. package/dist/features/seller/components/SellerBundlesView.d.ts +5 -5
  74. package/dist/features/seller/components/SellerBundlesView.js +81 -84
  75. package/dist/features/seller/components/SellerProductShell.d.ts +2 -0
  76. package/dist/features/seller/components/SellerProductShell.js +11 -5
  77. package/dist/features/seller/components/SellerSidebar.js +1 -1
  78. package/dist/features/shipments/components/ShipmentItemLinkModal.js +5 -5
  79. package/dist/features/stores/components/InteractiveStoreCard.js +1 -1
  80. package/dist/features/stores/components/StoreDetailLayoutView.d.ts +8 -1
  81. package/dist/features/stores/components/StoreDetailLayoutView.js +9 -3
  82. package/dist/features/stores/components/StoreHeader.d.ts +4 -1
  83. package/dist/features/stores/components/StoreHeader.js +3 -2
  84. package/dist/index.d.ts +7 -6
  85. package/dist/index.js +6 -5
  86. package/dist/jobs.d.ts +2 -0
  87. package/dist/jobs.js +6 -0
  88. package/dist/next/routing/route-map.d.ts +3 -0
  89. package/dist/next/routing/route-map.js +1 -0
  90. package/dist/react/hooks/useClickOutside.js +3 -0
  91. package/dist/security/rate-limit.d.ts +5 -0
  92. package/dist/security/rate-limit.js +2 -0
  93. package/dist/seed/categories-seed-data.js +180 -1
  94. package/dist/seed/grouped-listings-seed-data.d.ts +2 -0
  95. package/dist/seed/products-preorders-seed-data.d.ts +2 -0
  96. package/dist/seed/site-settings-seed-data.js +9 -2
  97. package/dist/server-entry.d.ts +2 -2
  98. package/dist/server-entry.js +1 -1
  99. package/dist/server.d.ts +4 -0
  100. package/dist/server.js +5 -0
  101. package/dist/styles.css +11 -4
  102. package/dist/tailwind-utilities.css +1 -1
  103. package/dist/tokens/themes/cobalt-night.d.ts +17 -0
  104. package/dist/tokens/themes/cobalt-night.js +50 -0
  105. package/dist/tokens/themes/index.d.ts +9 -1
  106. package/dist/tokens/themes/index.js +12 -1
  107. package/dist/tokens/themes/sunset.d.ts +18 -0
  108. package/dist/tokens/themes/sunset.js +51 -0
  109. package/dist/tokens/tokens.css +10 -3
  110. package/dist/ui/components/BaseListingCard.d.ts +2 -1
  111. package/dist/ui/components/BaseListingCard.js +4 -4
  112. package/dist/ui/components/Card.d.ts +1 -1
  113. package/dist/ui/components/Card.js +2 -2
  114. package/dist/ui/components/Div.js +2 -2
  115. package/dist/ui/components/Form.d.ts +1 -1
  116. package/dist/ui/components/Form.js +2 -2
  117. package/dist/ui/components/Input.js +1 -0
  118. package/dist/ui/components/ListingToolbar.js +1 -1
  119. package/dist/ui/components/QuickCreateModal.style.css +1 -1
  120. package/dist/ui/components/Slider.js +5 -1
  121. package/package.json +3 -2
@@ -22,7 +22,7 @@ export function InteractiveStoreCard({ store, href, selectable, isSelected = fal
22
22
  ? "border-[var(--appkit-color-primary,theme(colors.violet.600))] outline outline-2 outline-[var(--appkit-color-primary,theme(colors.violet.600))]"
23
23
  : "border-[var(--appkit-color-border)]",
24
24
  className,
25
- ].join(" "), 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, children: [onSelect && (_jsx(BaseListingCard.Checkbox, { selected: isSelected, onSelect: (e) => {
25
+ ].join(" "), 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: [onSelect && (_jsx(BaseListingCard.Checkbox, { selected: isSelected, onSelect: (e) => {
26
26
  e.preventDefault();
27
27
  onSelect(store.id, !isSelected);
28
28
  }, label: isSelected ? "Deselect store" : "Select store", position: "top-2 left-2", className: selectable || isSelected ? "opacity-100" : "opacity-0 group-hover:opacity-100 transition-opacity" })), _jsxs(Link, { href: href, className: "flex flex-col flex-1 min-h-0", children: [_jsxs(Div, { surface: "muted", className: `relative aspect-video w-full ${__O.hidden} flex-shrink-0`, children: [hasBanner ? (_jsx(MediaImage, { src: store.storeBannerURL, alt: `${store.storeName} banner`, size: "banner", className: "h-full w-full object-cover transition-transform duration-500 group-hover:scale-105" })) : (_jsx(Row, { className: "absolute inset-0", align: "center", justify: "center", children: _jsx(Span, { className: "opacity-20 select-none", size: "5xl", "aria-hidden": "true", children: "\uD83C\uDFEA" }) })), _jsx(Scrim, { direction: "bottom-up", intensity: "subtle", className: "absolute inset-x-0 bottom-0 h-12" }), store.averageRating != null && store.averageRating > 0 && (_jsxs(Div, { className: CLS_RATING_BADGE, children: ["\u2605 ", store.averageRating.toFixed(1)] }))] }), _jsxs(Stack, { paddingY: "b-md", className: "flex-1", padding: "x-md", children: [_jsx(Row, { className: "-mt-5 mb-2", align: "end", justify: "between", children: _jsx(Div, { className: "flex-shrink-0", children: hasLogo ? (_jsx(Div, { className: "relative h-10 w-10 border-2 border-white border-[var(--appkit-color-border-subtle)] bg-[var(--appkit-color-surface)]", rounded: "lg", shadow: "md", overflow: "hidden", children: _jsx(MediaImage, { src: store.storeLogoURL, alt: store.storeName, size: "thumbnail", onError: () => setLogoBroken(true) }) })) : (_jsx(Row, { textWeight: "bold", textSize: "base", className: "h-10 w-10 border-2 border-white bg-primary/10 dark:bg-primary/20 text-primary", align: "center", justify: "center", rounded: "lg", shadow: "md", children: initial })) }) }), _jsx(Heading, { level: 3, className: `group-hover:text-primary transition-colors`, truncate: true, size: "sm", weight: "bold", color: "primary", children: store.storeName }), store.storeDescription ? (_jsx(RichText, { html: normalizeRichTextHtml(store.storeDescription), proseClass: "prose prose-sm max-w-none dark:prose-invert prose-p:my-0", className: "mt-1 line-clamp-2 text-[length:var(--appkit-text-xs)] text-[var(--appkit-color-text-muted)] flex-1" })) : (_jsx(Div, { className: "flex-1" })), _jsxs(Row, { color: "muted", textSize: "xs", gap: "sm", className: "mt-2.5", wrap: true, children: [store.totalProducts != null && store.totalProducts > 0 && (_jsxs(Span, { layout: "flex", gap: "2xs", children: [_jsx(Span, { "aria-hidden": "true", children: "\uD83D\uDCE6" }), " ", store.totalProducts, " ", labels.products ?? "products"] })), store.itemsSold != null && store.itemsSold > 0 && (_jsxs(Span, { layout: "flex", gap: "2xs", children: [_jsx(Span, { "aria-hidden": "true", children: "\uD83D\uDECD\uFE0F" }), " ", store.itemsSold, " ", labels.sold ?? "sold"] }))] }), _jsxs(Row, { border: "top-subtle", paddingY: "y-xs-tall", className: "mt-3", align: "center", justify: "between", children: [_jsxs(Span, { size: "xs", weight: "semibold", className: "text-primary group-hover:underline transition-colors", children: [labels.visitStore ?? "Visit store", " \u2192"] }), store.totalReviews != null && store.totalReviews > 0 && (_jsxs(Span, { size: "xs", color: "muted", children: [store.totalReviews, " ", labels.reviews ?? "reviews"] }))] })] })] })] }));
@@ -6,5 +6,12 @@ export interface StoreDetailLayoutViewProps {
6
6
  /** The current active tab value: "products" | "auctions" | "reviews" | "about" */
7
7
  activeTab: string;
8
8
  children: ReactNode;
9
+ /**
10
+ * P-12 — gates the trust badge behind the same FEATURE_SCAM_REGISTRY flag
11
+ * that gates the registry itself (pending legal sign-off). Consumer passes
12
+ * `getFlag("SCAM_REGISTRY")`; appkit has no access to that env reader.
13
+ * Defaults to `false` — off unless the consumer explicitly opts in.
14
+ */
15
+ scamRegistryEnabled?: boolean;
9
16
  }
10
- export declare function StoreDetailLayoutView({ storeSlug, activeTab, children, }: StoreDetailLayoutViewProps): Promise<React.JSX.Element>;
17
+ export declare function StoreDetailLayoutView({ storeSlug, activeTab, children, scamRegistryEnabled, }: StoreDetailLayoutViewProps): Promise<React.JSX.Element>;
@@ -6,6 +6,7 @@ import { ROUTES } from "../../../next";
6
6
  import { Container, Main, Section, Text } from "../../../ui";
7
7
  import { STORE_PAGE_TABS } from "../../products/constants/listing-tabs";
8
8
  import { isListingTypeEnabled, isCategoryTypeEnabled } from "../../../_internal/shared/listing-types/feature-flags";
9
+ import { getSellerTrustStatus } from "../../scams/actions/scam-actions";
9
10
  import { StoreHeader } from "./StoreHeader";
10
11
  import { StoreNavTabs } from "./StoreNavTabs";
11
12
  const STORE_LISTING_HREF = {
@@ -28,13 +29,18 @@ function tabLabel(base, count) {
28
29
  return base;
29
30
  return `${base} (${count.toLocaleString()})`;
30
31
  }
31
- export async function StoreDetailLayoutView({ storeSlug, activeTab, children, }) {
32
+ export async function StoreDetailLayoutView({ storeSlug, activeTab, children, scamRegistryEnabled = false, }) {
32
33
  const store = await getStoreBySlug(storeSlug);
33
34
  if (!store) {
34
35
  return (_jsx(Main, { children: _jsx(Section, { padding: "y-5xl", children: _jsx(Container, { size: "md", children: _jsx(Text, { align: "start", color: "muted", children: "Store not found." }) }) }) }));
35
36
  }
36
37
  const storeId = store?.id;
37
- const settings = await siteSettingsRepository.findById("global").catch(() => null);
38
+ const [settings, trust] = await Promise.all([
39
+ siteSettingsRepository.findById("global").catch(() => null),
40
+ scamRegistryEnabled && storeId
41
+ ? getSellerTrustStatus(storeId).catch(() => undefined)
42
+ : Promise.resolve(undefined),
43
+ ]);
38
44
  const [productsCount, auctionsCount, preOrdersCount, prizeDrawsCount, bundlesCount, classifiedsCount, digitalCodesCount, liveCount, artCount, stickersCount, couponsCount, reviewsCount] = storeId
39
45
  ? await Promise.all([
40
46
  productRepository
@@ -128,5 +134,5 @@ export async function StoreDetailLayoutView({ storeSlug, activeTab, children, })
128
134
  { value: "reviews", label: tabLabel("Reviews", reviewsCount), href: String(ROUTES.PUBLIC.STORE_REVIEWS(storeSlug)) },
129
135
  { value: "about", label: "About", href: String(ROUTES.PUBLIC.STORE_ABOUT(storeSlug)) },
130
136
  ];
131
- return (_jsxs(Main, { children: [_jsx(StoreHeader, { store: store }), _jsxs(Container, { size: "xl", className: "mt-6", children: [_jsx(StoreNavTabs, { tabs: tabs, activeValue: activeTab }), _jsx(Section, { padding: "t-lg", children: children })] })] }));
137
+ return (_jsxs(Main, { children: [_jsx(StoreHeader, { store: store, trust: trust }), _jsxs(Container, { size: "xl", className: "mt-6", children: [_jsx(StoreNavTabs, { tabs: tabs, activeValue: activeTab }), _jsx(Section, { padding: "t-lg", children: children })] })] }));
132
138
  }
@@ -1,3 +1,4 @@
1
+ import type { SellerTrustResult } from "../../scams/actions/scam-actions";
1
2
  import type { StoreDetail } from "../types";
2
3
  interface StoreHeaderProps {
3
4
  store: StoreDetail;
@@ -10,6 +11,8 @@ interface StoreHeaderProps {
10
11
  };
11
12
  onFollow?: (storeSlug: string) => void;
12
13
  className?: string;
14
+ /** P-12 — omitted (undefined) when the scam registry feature is off; no badge renders. */
15
+ trust?: SellerTrustResult;
13
16
  }
14
- export declare function StoreHeader({ store, labels, onFollow, className, }: StoreHeaderProps): import("react").JSX.Element;
17
+ export declare function StoreHeader({ store, labels, onFollow, className, trust, }: StoreHeaderProps): import("react").JSX.Element;
15
18
  export {};
@@ -4,6 +4,7 @@ import { MediaImage } from "../../media/MediaImage";
4
4
  import { normalizeRichTextHtml } from "../../../utils/string.formatter";
5
5
  import { ShareButton } from "../../products/components/ShareButton";
6
6
  import { StoreScopedSearch } from "./StoreScopedSearch";
7
+ import { SellerTrustBadge } from "../../scams/components/SellerTrustBadge";
7
8
  const __O = {
8
9
  hidden: "overflow-hidden",
9
10
  };
@@ -11,8 +12,8 @@ const CLS_AVATAR = "-mt-8 h-16 w-16 rounded-xl border-2 border-white border-[var
11
12
  const CLS_STARS = "inline-flex items-center gap-[var(--appkit-space-1)] text-warning";
12
13
  const CLS_FOLLOW_BTN = "rounded-lg border border-warning px-[var(--appkit-space-4)] py-[var(--appkit-space-2)] text-[length:var(--appkit-text-sm)] font-medium text-warning hover:bg-warning-surface transition-colors";
13
14
  const CLS_WARN_BANNER = "mt-3 rounded-lg bg-warning-surface dark:bg-warning-surface border border-warning dark:border-warning px-[var(--appkit-space-3)] py-[var(--appkit-space-2)] text-[length:var(--appkit-text-sm)] text-warning dark:text-warning";
14
- export function StoreHeader({ store, labels = {}, onFollow, className = "", }) {
15
- return (_jsxs(Section, { surface: "default", border: "bottom", className: className, children: [store.storeBannerURL && (_jsx(Div, { className: `relative h-40 md:h-56 ${__O.hidden} bg-[var(--appkit-color-surface)] bg-[var(--appkit-color-surface-elevated)]`, children: _jsx(MediaImage, { src: store.storeBannerURL, alt: `${store.storeName} banner`, size: "banner" }) })), _jsxs(Div, { paddingX: "x-page", className: "max-w-7xl mx-auto", padding: "y-md", children: [_jsxs(Row, { align: "end", gap: "md", children: [store.storeLogoURL ? (_jsx(Div, { className: "relative -mt-8 h-16 w-16 border-2 border-white", rounded: "xl", shadow: "sm", overflow: "hidden", children: _jsx(MediaImage, { src: store.storeLogoURL, alt: store.storeName, size: "avatar" }) })) : (_jsx(Div, { className: CLS_AVATAR, children: store.storeName[0]?.toUpperCase() })), _jsxs(Div, { className: "flex-1 min-w-0", children: [_jsxs(Row, { className: "mb-0.5", align: "center", gap: "sm", wrap: true, children: [_jsx(Heading, { level: 1, className: "text-[var(--appkit-color-text)]", size: "xl", weight: "bold", children: store.storeName }), store.averageRating != null && store.averageRating > 0 && (_jsxs(Span, { size: "sm", weight: "medium", className: CLS_STARS, children: ["\u2605 ", store.averageRating.toFixed(1)] }))] }), _jsxs(Row, { textSize: "xs", className: "text-[var(--appkit-color-text-muted)] mb-0.5", gap: "3", children: [store.category && _jsx(Span, { transform: "capitalize", children: store.category }), store.totalProducts != null && store.totalProducts > 0 && (_jsxs(Span, { children: [store.totalProducts, " ", labels.products ?? "products"] })), store.totalReviews != null && store.totalReviews > 0 && (_jsxs(Span, { children: [store.totalReviews, " ", labels.reviews ?? "reviews"] })), store.itemsSold != null && store.itemsSold > 0 && (_jsxs(Span, { children: [store.itemsSold, " ", labels.sold ?? "sold"] }))] }), store.storeDescription && (_jsx(RichText, { html: normalizeRichTextHtml(store.storeDescription), copyableCode: true, className: "mt-0.5" }))] }), _jsxs(Row, { gap: "sm", align: "center", className: "shrink-0", children: [_jsx(ShareButton, { title: store.storeName }), onFollow && (_jsx(Button, { type: "button", variant: "outline", size: "sm", onClick: () => onFollow(store.storeSlug), className: CLS_FOLLOW_BTN, children: labels.follow ?? "Follow" }))] })] }), store.isVacationMode && (_jsx(Text, { className: CLS_WARN_BANNER, children: store.vacationMessage ??
15
+ export function StoreHeader({ store, labels = {}, onFollow, className = "", trust, }) {
16
+ return (_jsxs(Section, { surface: "default", border: "bottom", className: className, children: [store.storeBannerURL && (_jsx(Div, { className: `relative h-40 md:h-56 ${__O.hidden} bg-[var(--appkit-color-surface)] bg-[var(--appkit-color-surface-elevated)]`, children: _jsx(MediaImage, { src: store.storeBannerURL, alt: `${store.storeName} banner`, size: "banner" }) })), _jsxs(Div, { paddingX: "x-page", className: "max-w-7xl mx-auto", padding: "y-md", children: [_jsxs(Row, { align: "end", gap: "md", children: [store.storeLogoURL ? (_jsx(Div, { className: "relative -mt-8 h-16 w-16 border-2 border-white", rounded: "xl", shadow: "sm", overflow: "hidden", children: _jsx(MediaImage, { src: store.storeLogoURL, alt: store.storeName, size: "avatar" }) })) : (_jsx(Div, { className: CLS_AVATAR, children: store.storeName[0]?.toUpperCase() })), _jsxs(Div, { className: "flex-1 min-w-0", children: [_jsxs(Row, { className: "mb-0.5", align: "center", gap: "sm", wrap: true, children: [_jsx(Heading, { level: 1, className: "text-[var(--appkit-color-text)]", size: "xl", weight: "bold", children: store.storeName }), store.averageRating != null && store.averageRating > 0 && (_jsxs(Span, { size: "sm", weight: "medium", className: CLS_STARS, children: ["\u2605 ", store.averageRating.toFixed(1)] })), trust && _jsx(SellerTrustBadge, { trust: trust })] }), _jsxs(Row, { textSize: "xs", className: "text-[var(--appkit-color-text-muted)] mb-0.5", gap: "3", children: [store.category && _jsx(Span, { transform: "capitalize", children: store.category }), store.totalProducts != null && store.totalProducts > 0 && (_jsxs(Span, { children: [store.totalProducts, " ", labels.products ?? "products"] })), store.totalReviews != null && store.totalReviews > 0 && (_jsxs(Span, { children: [store.totalReviews, " ", labels.reviews ?? "reviews"] })), store.itemsSold != null && store.itemsSold > 0 && (_jsxs(Span, { children: [store.itemsSold, " ", labels.sold ?? "sold"] }))] }), store.storeDescription && (_jsx(RichText, { html: normalizeRichTextHtml(store.storeDescription), copyableCode: true, className: "mt-0.5" }))] }), _jsxs(Row, { gap: "sm", align: "center", className: "shrink-0", children: [_jsx(ShareButton, { title: store.storeName }), onFollow && (_jsx(Button, { type: "button", variant: "outline", size: "sm", onClick: () => onFollow(store.storeSlug), className: CLS_FOLLOW_BTN, children: labels.follow ?? "Follow" }))] })] }), store.isVacationMode && (_jsx(Text, { className: CLS_WARN_BANNER, children: store.vacationMessage ??
16
17
  labels.vacationMode ??
17
18
  "Store is on vacation mode" })), _jsx(Div, { className: "mt-3", children: _jsx(StoreScopedSearch, { storeId: store.storeSlug, storeName: store.storeName }) })] })] }));
18
19
  }
package/dist/index.d.ts CHANGED
@@ -1198,7 +1198,6 @@ export { NOTIFICATIONS_COLLECTION } from "./features/admin/index";
1198
1198
  export { NOTIFICATIONS_INDEXED_FIELDS } from "./features/admin/index";
1199
1199
  export { NOTIFICATION_FIELDS } from "./features/admin/index";
1200
1200
  export { NOTIFICATION_PUBLIC_FIELDS } from "./features/admin/index";
1201
- export { QuickActionsPanel } from "./features/admin/index";
1202
1201
  export { SITE_SETTINGS_COLLECTION } from "./features/admin/index";
1203
1202
  export { SITE_SETTINGS_INDEXED_FIELDS } from "./features/admin/index";
1204
1203
  export { SITE_SETTINGS_PUBLIC_FIELDS } from "./features/admin/index";
@@ -1283,8 +1282,6 @@ export type { NotificationPriority } from "./features/admin/index";
1283
1282
  export type { NotificationUpdateInput } from "./features/admin/index";
1284
1283
  export type { SendNotificationInput } from "./features/admin/server";
1285
1284
  export type { SendNotificationResult } from "./features/admin/server";
1286
- export type { QuickActionItem } from "./features/admin/index";
1287
- export type { QuickActionsPanelProps } from "./features/admin/index";
1288
1285
  export type { SiteSettingsCredentials } from "./features/admin/index";
1289
1286
  export type { SiteSettingsCredentialsMasked } from "./features/admin/index";
1290
1287
  export type { SiteSettingsDocument } from "./features/admin/index";
@@ -2282,6 +2279,7 @@ export type { PaymentGateway } from "./features/orders/index";
2282
2279
  export type { RefundStatus } from "./features/orders/index";
2283
2280
  export type { ShippingMethod } from "./features/orders/index";
2284
2281
  export { cancelOrderForUser } from "./features/orders/server";
2282
+ export { cancelOrderItemsForUser } from "./features/orders/server";
2285
2283
  export { getOrderByIdForUser } from "./features/orders/server";
2286
2284
  export { getOrderTrackingHandler } from "./features/orders/server";
2287
2285
  export { getTrackingInfo } from "./features/orders/server";
@@ -2453,8 +2451,8 @@ export { actionTracker, setActionTrackerSink, resetActionTrackerSink, type Actio
2453
2451
  export { cartRequiresShipping, cartIsDigitalOnly, cartIsChatOnly, } from "./_internal/shared/listing-types/cart-shipping";
2454
2452
  export { ACTIONS, action, act, canPerformAction, actionsForListingType, actionLabel, type ActionDef, type ActionKind, type ActionResource, type ActionTree, type ActionConfirmation, } from "./_internal/shared/actions/action-registry";
2455
2453
  export { buildBulkAction } from "./_internal/shared/actions/bulk-helpers";
2456
- export { computeCheckoutFees, computePayoutDeduction, computeCodHandlingFee, } from "./_internal/shared/fees/calculator";
2457
- export type { FeeCommissionRates, CheckoutFees, PayoutDeduction, CodHandlingFeeRates, } from "./_internal/shared/fees/calculator";
2454
+ export { computeCheckoutFees, computePayoutDeduction, computeCodHandlingFee, calculateGst, } from "./_internal/shared/fees/calculator";
2455
+ export type { FeeCommissionRates, CheckoutFees, PayoutDeduction, CodHandlingFeeRates, GstBreakdown, } from "./_internal/shared/fees/calculator";
2458
2456
  export { checkEmiEligibility, computeEmiSchedule } from "./_internal/shared/features/emi/schedule";
2459
2457
  export type { EmiSettings, EmiIneligibleReason, EmiEligibility, EmiInstallmentPlan, EmiScheduleResult, } from "./_internal/shared/features/emi/schedule";
2460
2458
  export { isAdminUser, isSellerUser, isModeratorUser, isEmployeeUser, isBuyerUser, } from "./features/auth/role-predicates";
@@ -3145,9 +3143,12 @@ export { ScamProfileView } from "./features/scams/components/ScamProfileView";
3145
3143
  export type { ScamProfileViewProps } from "./features/scams/components/ScamProfileView";
3146
3144
  export { ScamAwarenessModal } from "./features/scams/components/ScamAwarenessModal";
3147
3145
  export type { ScamAwarenessModalProps } from "./features/scams/components/ScamAwarenessModal";
3148
- export { listVerifiedScammers, getPublicScammerById, getScammerProfilePageData, } from "./features/scams/actions/scam-actions";
3146
+ export { SellerTrustBadge } from "./features/scams/components/SellerTrustBadge";
3147
+ export type { SellerTrustBadgeProps } from "./features/scams/components/SellerTrustBadge";
3148
+ export { listVerifiedScammers, getPublicScammerById, getScammerProfilePageData, getSellerTrustStatus, } from "./features/scams/actions/scam-actions";
3149
3149
  export type { ScammerProfilePageData } from "./features/scams/actions/scam-actions";
3150
3150
  export type { ScammerListResult } from "./features/scams/actions/scam-actions";
3151
+ export type { SellerTrustResult, SellerTrustStatus } from "./features/scams/actions/scam-actions";
3151
3152
  export { SellerProductShell } from "./features/seller/components/SellerProductShell";
3152
3153
  export type { SellerProductShellProps, SellerProductDraft, ProductListingMode } from "./features/seller/components/SellerProductShell";
3153
3154
  export { CategoryInlineSelect } from "./features/seller/components/CategoryInlineSelect";
package/dist/index.js CHANGED
@@ -2342,9 +2342,6 @@ export { NOTIFICATION_FIELDS } from "./features/admin/index";
2342
2342
  // [SCHEMA]-Schema / data-shape constant â€" Zod validator, default-value object, or Firestore collection/field name constant.
2343
2343
  // NOTIFICATION_PUBLIC_FIELDS - Constant used across modules.
2344
2344
  export { NOTIFICATION_PUBLIC_FIELDS } from "./features/admin/index";
2345
- // [CLIENT-SSR]-Runs in both SSR and browser â€" React component or hook that does not depend on browser-only APIs.
2346
- // QuickActionsPanel - Shared export for quick actions panel.
2347
- export { QuickActionsPanel } from "./features/admin/index";
2348
2345
  // [SCHEMA]-Schema / data-shape constant â€" Zod validator, default-value object, or Firestore collection/field name constant.
2349
2346
  // SITE_SETTINGS_COLLECTION - Constant used across modules.
2350
2347
  export { SITE_SETTINGS_COLLECTION } from "./features/admin/index";
@@ -4225,6 +4222,9 @@ export { useTrackOrder } from "./features/orders/index";
4225
4222
  // cancelOrderForUser - Shared export for cancel order for user.
4226
4223
  export { cancelOrderForUser } from "./features/orders/server";
4227
4224
  // [SERVER-ONLY]-Server-only â€" uses Node.js, Next.js server internals, or third-party server SDKs (auth, email, payment, shipping).
4225
+ // cancelOrderItemsForUser - Cancels a subset of line items on an order and continues with the rest.
4226
+ export { cancelOrderItemsForUser } from "./features/orders/server";
4227
+ // [SERVER-ONLY]-Server-only â€" uses Node.js, Next.js server internals, or third-party server SDKs (auth, email, payment, shipping).
4228
4228
  // getOrderByIdForUser - Helper for get order by id for user.
4229
4229
  export { getOrderByIdForUser } from "./features/orders/server";
4230
4230
  // [SERVER-ONLY]-Server-only â€" uses Node.js, Next.js server internals, or third-party server SDKs (auth, email, payment, shipping).
@@ -4520,7 +4520,7 @@ export { cartRequiresShipping, cartIsDigitalOnly, cartIsChatOnly, } from "./_int
4520
4520
  export { ACTIONS, action, act, canPerformAction, actionsForListingType, actionLabel, } from "./_internal/shared/actions/action-registry";
4521
4521
  export { buildBulkAction } from "./_internal/shared/actions/bulk-helpers";
4522
4522
  // Shared fee calculator — platform/gateway/GST/COD handling fee math (pure, client-safe).
4523
- export { computeCheckoutFees, computePayoutDeduction, computeCodHandlingFee, } from "./_internal/shared/fees/calculator";
4523
+ export { computeCheckoutFees, computePayoutDeduction, computeCodHandlingFee, calculateGst, } from "./_internal/shared/fees/calculator";
4524
4524
  // EMI eligibility + schedule computation (pure, client-safe — used for checkout quotes).
4525
4525
  export { checkEmiEligibility, computeEmiSchedule } from "./_internal/shared/features/emi/schedule";
4526
4526
  // User-role predicates â€" SB-UNI-E 2026-05-13.
@@ -5598,8 +5598,9 @@ export { SCAM_TYPES, SCAM_CATEGORIES, SCAM_TYPE_LABELS, SCAM_CATEGORY_LABELS, ge
5598
5598
  export { ScamRegistryView } from "./features/scams/components/ScamRegistryView";
5599
5599
  export { ScamProfileView } from "./features/scams/components/ScamProfileView";
5600
5600
  export { ScamAwarenessModal } from "./features/scams/components/ScamAwarenessModal";
5601
+ export { SellerTrustBadge } from "./features/scams/components/SellerTrustBadge";
5601
5602
  // Scam server actions
5602
- export { listVerifiedScammers, getPublicScammerById, getScammerProfilePageData, } from "./features/scams/actions/scam-actions";
5603
+ export { listVerifiedScammers, getPublicScammerById, getScammerProfilePageData, getSellerTrustStatus, } from "./features/scams/actions/scam-actions";
5603
5604
  // --- Shell primitives (UX1/UX2/UX3/UX6) ----------------------------------------
5604
5605
  // [CLIENT] SellerProductShell â€" full-flow create/edit shell for standard, auction, and pre-order listings.
5605
5606
  export { SellerProductShell } from "./features/seller/components/SellerProductShell";
package/dist/jobs.d.ts CHANGED
@@ -22,5 +22,7 @@
22
22
  */
23
23
  export { couponExpiryHandler, offerExpiryHandler, cartPruneHandler, notificationPruneHandler, dailyDataCleanupHandler, cleanupRtdbEventsHandler, auctionSettlementHandler, autoPayoutEligibilityHandler, countersReconcileHandler, onOrderCreateHandler, onOrderStatusChangeHandler, onBidPlacedHandler, onReviewWriteHandler, promotionsHandler, mediaTmpCleanupHandler, pendingOrderTimeoutHandler, productStatsSyncHandler, positionsReconcileHandler, payoutBatchHandler, weeklyPayoutEligibilityHandler, onCategoryWriteHandler, onProductWriteHandler, onStoreWriteHandler, adminAnalyticsHandler, storeAnalyticsHandler, listingProcessorHandler, supportedListingCollections, prizeRevealOpenHandler, prizeRevealCloseHandler, prizeRevealExpiryHandler, prizeRevealReminderHandler, bundleStockSyncHandler, onProductStockChangeHandler, triggerEventRaffleHandler, assignSpinPrizeHandler, draftPruneHandler, onSupportTicketCreateHandler, onSupportTicketUpdateHandler, onUserBanChangeHandler, onScamReportCreateHandler, onScamReportUpdateHandler, bindSchedule, bindDocumentWritten, bindDocumentCreated, bindDocumentUpdated, bindCallable, bindHttps, bindToFirebase, } from "./_internal/server/jobs/index.js";
24
24
  export { defineFunction, mergeFunctionRegistries, bindAllFromRegistry, APPKIT_FUNCTIONS, APPKIT_FUNCTIONS_BY_NAME, } from "./_internal/server/functions/index.js";
25
+ export { orderRepository, siteSettingsRepository } from "./repositories/index.js";
26
+ export type { OrderDocument, OrderDocumentItem } from "./features/orders/index.js";
25
27
  export type { PromotionsCallableResult, AdminAnalyticsResult, StoreAnalyticsInput, StoreAnalyticsResult, ListingRequestBody, ListingResponseBody, JobContext, JobLogger, JobHandlers, ScheduleHandler, FirestoreTriggerHandler, FirestoreTriggerEvent, CallableHandler, BindHttpsOptions, } from "./_internal/server/jobs/index.js";
26
28
  export type { DocumentCreatedTrigger, DocumentTriggerFunctionDefinition, DocumentUpdatedTrigger, DocumentWrittenTrigger, FunctionDefinition, FunctionMemory, FunctionOptions, FunctionTrigger, HttpsFunctionDefinition, HttpsTrigger, ScheduledFunctionDefinition, ScheduleTrigger, } from "./_internal/server/functions/index.js";
package/dist/jobs.js CHANGED
@@ -40,3 +40,9 @@ bindSchedule, bindDocumentWritten, bindDocumentCreated, bindDocumentUpdated, bin
40
40
  // mergeFunctionRegistries(...) and binding the result with
41
41
  // bindAllFromRegistry(...).
42
42
  export { defineFunction, mergeFunctionRegistries, bindAllFromRegistry, APPKIT_FUNCTIONS, APPKIT_FUNCTIONS_BY_NAME, } from "./_internal/server/functions/index.js";
43
+ // Narrow repository re-export for consumer Firebase Functions (e.g. invoice
44
+ // PDF generation) — imports directly from the repositories barrel rather
45
+ // than `index.ts`/`server.ts`, whose much broader module graphs pull in
46
+ // Next.js OG-rendering code that fails to bundle under tsup/esbuild's CJS
47
+ // output for the Functions runtime.
48
+ export { orderRepository, siteSettingsRepository } from "./repositories/index.js";
@@ -154,6 +154,7 @@ export declare const DEFAULT_ROUTE_MAP: {
154
154
  };
155
155
  readonly STORE: {
156
156
  readonly DASHBOARD: "/store";
157
+ readonly MESSAGES: "/store/messages";
157
158
  readonly PRODUCTS: "/store/products";
158
159
  readonly PRODUCTS_NEW: "/store/products/new";
159
160
  readonly PRODUCTS_EDIT: (id: string) => string;
@@ -513,6 +514,7 @@ export declare const ROUTES: {
513
514
  };
514
515
  readonly STORE: {
515
516
  readonly DASHBOARD: "/store";
517
+ readonly MESSAGES: "/store/messages";
516
518
  readonly PRODUCTS: "/store/products";
517
519
  readonly PRODUCTS_NEW: "/store/products/new";
518
520
  readonly PRODUCTS_EDIT: (id: string) => string;
@@ -731,6 +733,7 @@ export declare const ROUTES: {
731
733
  /** @deprecated Use ROUTES.STORE instead */
732
734
  export declare const SELLER_ROUTES: {
733
735
  readonly DASHBOARD: "/store";
736
+ readonly MESSAGES: "/store/messages";
734
737
  readonly PRODUCTS: "/store/products";
735
738
  readonly PRODUCTS_NEW: "/store/products/new";
736
739
  readonly PRODUCTS_EDIT: (id: string) => string;
@@ -142,6 +142,7 @@ export const DEFAULT_ROUTE_MAP = {
142
142
  },
143
143
  STORE: {
144
144
  DASHBOARD: "/store",
145
+ MESSAGES: "/store/messages",
145
146
  PRODUCTS: "/store/products",
146
147
  PRODUCTS_NEW: "/store/products/new",
147
148
  PRODUCTS_EDIT: (id) => `/store/products/${id}/edit`,
@@ -46,6 +46,9 @@ export function useClickOutside(ref, callback, options = {}) {
46
46
  }
47
47
  };
48
48
  // Add event listeners for both mouse and touch
49
+ // audit-touch-handler-ok: single-shot "did a touch start outside this
50
+ // element" detection, no gesture-in-progress state to leave stale if the
51
+ // touch is later cancelled.
49
52
  document.addEventListener(eventType, handleClickOutside);
50
53
  document.addEventListener("touchstart", handleClickOutside);
51
54
  return () => {
@@ -68,6 +68,11 @@ export declare const RateLimitPresets: {
68
68
  readonly limit: 10;
69
69
  readonly window: 60;
70
70
  };
71
+ /** P-11 — chat message send: 100 per hour per user. */
72
+ readonly CHAT: {
73
+ readonly limit: 100;
74
+ readonly window: 3600;
75
+ };
71
76
  };
72
77
  /** For testing only: clear the in-memory store. */
73
78
  export declare function clearRateLimitStore(): void;
@@ -113,6 +113,8 @@ export const RateLimitPresets = {
113
113
  PASSWORD_RESET: { limit: 3, window: 3600 },
114
114
  EMAIL_VERIFICATION: { limit: 5, window: 3600 },
115
115
  OAUTH: { limit: 10, window: 60 },
116
+ /** P-11 — chat message send: 100 per hour per user. */
117
+ CHAT: { limit: 100, window: 3600 },
116
118
  };
117
119
  /** For testing only: clear the in-memory store. */
118
120
  export function clearRateLimitStore() {
@@ -227,14 +227,193 @@ const brandRows = [
227
227
  seo: { title: "Beyblade | LetItRip", description: "Shop Beyblade — Original, X, Burst, Metal Fight tops and stadiums.", keywords: ["beyblade", "beyblade x", "beyblade burst", "spinning top battle"] },
228
228
  },
229
229
  ];
230
+ // P-17 — 5 bundle rows (categoryType:"bundle") grouping the Beyblade-minimal
231
+ // standard products by generation, plus one cross-generation starter pack.
232
+ // Every bundle references real seeded product ids (products-standard-seed-data.ts),
233
+ // all currently under store-beyblade-arena.
234
+ const bundleRows = [
235
+ {
236
+ id: "bundle-original-collectors-set",
237
+ name: "Original Collector's Set",
238
+ slug: "bundle-original-collectors-set",
239
+ description: "Both original-generation Beyblades — Dranzer S and Driger V — bundled at a discount.",
240
+ categoryType: "bundle",
241
+ bundleKind: "special",
242
+ bundlePriceInPaise: 299900,
243
+ bundleQueryRule: {
244
+ type: "static",
245
+ productIds: ["product-beyblade-original-dranzer-s", "product-beyblade-original-driger-v", "product-beyblade-metal-storm-pegasus"],
246
+ },
247
+ bundleProductIds: ["product-beyblade-original-dranzer-s", "product-beyblade-original-driger-v", "product-beyblade-metal-storm-pegasus"],
248
+ bundleStockStatus: "in_stock",
249
+ display: { coverImage: seedExtMedia("https://picsum.photos/seed/bundle-original-collectors-set-20260101/1200/900"), showInFooter: false },
250
+ isActive: true,
251
+ isSearchable: true,
252
+ isFeatured: true,
253
+ order: 0,
254
+ rootId: "bundle-original-collectors-set",
255
+ parentIds: [],
256
+ childrenIds: [],
257
+ tier: 0,
258
+ path: "bundle-original-collectors-set",
259
+ position: 0,
260
+ subtreeSize: 1,
261
+ metrics: { productCount: 0, productIds: [], auctionCount: 0, auctionIds: [], totalProductCount: 0, totalAuctionCount: 0, totalItemCount: 0, lastUpdated: NOW },
262
+ createdBy: "user-admin-letitrip",
263
+ createdByType: "admin",
264
+ createdAt: daysAgo(20),
265
+ updatedAt: daysAgo(5),
266
+ },
267
+ {
268
+ id: "bundle-metal-fusion-duo",
269
+ name: "Metal Fusion Duo",
270
+ slug: "bundle-metal-fusion-duo",
271
+ description: "Storm Pegasus and Flame Sagittario — the classic Metal Fight rivalry, together.",
272
+ categoryType: "bundle",
273
+ bundleKind: "special",
274
+ bundlePriceInPaise: 349900,
275
+ bundleQueryRule: {
276
+ type: "static",
277
+ productIds: ["product-beyblade-metal-storm-pegasus", "product-beyblade-metal-flame-sagittario", "product-beyblade-original-dranzer-s"],
278
+ },
279
+ bundleProductIds: ["product-beyblade-metal-storm-pegasus", "product-beyblade-metal-flame-sagittario", "product-beyblade-original-dranzer-s"],
280
+ bundleStockStatus: "in_stock",
281
+ display: { coverImage: seedExtMedia("https://picsum.photos/seed/bundle-metal-fusion-duo-20260101/1200/900"), showInFooter: false },
282
+ isActive: true,
283
+ isSearchable: true,
284
+ isFeatured: false,
285
+ order: 1,
286
+ rootId: "bundle-metal-fusion-duo",
287
+ parentIds: [],
288
+ childrenIds: [],
289
+ tier: 0,
290
+ path: "bundle-metal-fusion-duo",
291
+ position: 0,
292
+ subtreeSize: 1,
293
+ metrics: { productCount: 0, productIds: [], auctionCount: 0, auctionIds: [], totalProductCount: 0, totalAuctionCount: 0, totalItemCount: 0, lastUpdated: NOW },
294
+ createdBy: "user-admin-letitrip",
295
+ createdByType: "admin",
296
+ createdAt: daysAgo(18),
297
+ updatedAt: daysAgo(4),
298
+ },
299
+ {
300
+ id: "bundle-burst-battlers-pack",
301
+ name: "Burst Battlers Pack",
302
+ slug: "bundle-burst-battlers-pack",
303
+ description: "Valkyrie and Regalia Genesis — top-tier Burst-era attackers in one set.",
304
+ categoryType: "bundle",
305
+ bundleKind: "special",
306
+ bundlePriceInPaise: 379900,
307
+ bundleQueryRule: {
308
+ type: "static",
309
+ productIds: ["product-beyblade-burst-valkyrie", "product-beyblade-burst-regalia-genesis", "product-beyblade-metal-flame-sagittario"],
310
+ },
311
+ bundleProductIds: ["product-beyblade-burst-valkyrie", "product-beyblade-burst-regalia-genesis", "product-beyblade-metal-flame-sagittario"],
312
+ bundleStockStatus: "in_stock",
313
+ display: { coverImage: seedExtMedia("https://picsum.photos/seed/bundle-burst-battlers-pack-20260101/1200/900"), showInFooter: false },
314
+ isActive: true,
315
+ isSearchable: true,
316
+ isFeatured: true,
317
+ order: 2,
318
+ rootId: "bundle-burst-battlers-pack",
319
+ parentIds: [],
320
+ childrenIds: [],
321
+ tier: 0,
322
+ path: "bundle-burst-battlers-pack",
323
+ position: 0,
324
+ subtreeSize: 1,
325
+ metrics: { productCount: 0, productIds: [], auctionCount: 0, auctionIds: [], totalProductCount: 0, totalAuctionCount: 0, totalItemCount: 0, lastUpdated: NOW },
326
+ createdBy: "user-admin-letitrip",
327
+ createdByType: "admin",
328
+ createdAt: daysAgo(15),
329
+ updatedAt: daysAgo(3),
330
+ },
331
+ {
332
+ id: "bundle-x-series-starter",
333
+ name: "X-Series Starter Set",
334
+ slug: "bundle-x-series-starter",
335
+ description: "Wizard Arrow and Knife Shinobi — the newest X-series tops for new battlers.",
336
+ categoryType: "bundle",
337
+ bundleKind: "special",
338
+ bundlePriceInPaise: 249900,
339
+ bundleQueryRule: {
340
+ type: "static",
341
+ productIds: ["product-beyblade-x-wizard-arrow", "product-beyblade-x-knife-shinobi", "product-beyblade-burst-valkyrie"],
342
+ },
343
+ bundleProductIds: ["product-beyblade-x-wizard-arrow", "product-beyblade-x-knife-shinobi", "product-beyblade-burst-valkyrie"],
344
+ bundleStockStatus: "in_stock",
345
+ display: { coverImage: seedExtMedia("https://picsum.photos/seed/bundle-x-series-starter-20260101/1200/900"), showInFooter: false },
346
+ isActive: true,
347
+ isSearchable: true,
348
+ isFeatured: false,
349
+ order: 3,
350
+ rootId: "bundle-x-series-starter",
351
+ parentIds: [],
352
+ childrenIds: [],
353
+ tier: 0,
354
+ path: "bundle-x-series-starter",
355
+ position: 0,
356
+ subtreeSize: 1,
357
+ metrics: { productCount: 0, productIds: [], auctionCount: 0, auctionIds: [], totalProductCount: 0, totalAuctionCount: 0, totalItemCount: 0, lastUpdated: NOW },
358
+ createdBy: "user-admin-letitrip",
359
+ createdByType: "admin",
360
+ createdAt: daysAgo(12),
361
+ updatedAt: daysAgo(2),
362
+ },
363
+ {
364
+ id: "bundle-every-generation-starter-pack",
365
+ name: "Every Generation Starter Pack",
366
+ slug: "bundle-every-generation-starter-pack",
367
+ description: "One top from every Beyblade generation — Original, Metal Fight, Burst, and X — the ultimate collector's starter pack.",
368
+ categoryType: "bundle",
369
+ bundleKind: "special",
370
+ bundlePriceInPaise: 599900,
371
+ bundleQueryRule: {
372
+ type: "static",
373
+ productIds: [
374
+ "product-beyblade-original-driger-v",
375
+ "product-beyblade-metal-storm-pegasus",
376
+ "product-beyblade-burst-valkyrie",
377
+ "product-beyblade-x-wizard-arrow",
378
+ ],
379
+ },
380
+ bundleProductIds: [
381
+ "product-beyblade-original-driger-v",
382
+ "product-beyblade-metal-storm-pegasus",
383
+ "product-beyblade-burst-valkyrie",
384
+ "product-beyblade-x-wizard-arrow",
385
+ ],
386
+ bundleStockStatus: "in_stock",
387
+ display: { coverImage: seedExtMedia("https://picsum.photos/seed/bundle-every-generation-starter-pack-20260101/1200/900"), showInFooter: false },
388
+ isActive: true,
389
+ isSearchable: true,
390
+ isFeatured: true,
391
+ order: 4,
392
+ rootId: "bundle-every-generation-starter-pack",
393
+ parentIds: [],
394
+ childrenIds: [],
395
+ tier: 0,
396
+ path: "bundle-every-generation-starter-pack",
397
+ position: 0,
398
+ subtreeSize: 1,
399
+ metrics: { productCount: 0, productIds: [], auctionCount: 0, auctionIds: [], totalProductCount: 0, totalAuctionCount: 0, totalItemCount: 0, lastUpdated: NOW },
400
+ createdBy: "user-admin-letitrip",
401
+ createdByType: "admin",
402
+ createdAt: daysAgo(10),
403
+ updatedAt: daysAgo(1),
404
+ },
405
+ ];
230
406
  export const categoriesSeedData = [
231
407
  ...rawCategories.map((c) => ({ ancestors: [], ...c, createdByType: "admin" })),
232
408
  ...sublistingRows.map((s) => ({ ancestors: [], ...s, createdByType: "admin" })),
233
409
  ...brandRows.map((b) => ({ ancestors: [], ...b, createdByType: "admin" })),
410
+ ...bundleRows.map((b) => ({ ancestors: [], ...b })),
234
411
  ];
235
- // P-1 default seed: identical to categoriesSeedData now that bundle rows have been removed.
412
+ // P-1 default seed: identical to categoriesSeedData (bundle rows included P-17
413
+ // re-added them 2026-08-15 after the earlier removal referenced below).
236
414
  export const categoriesP1SeedData = [
237
415
  ...rawCategories.map((c) => ({ ancestors: [], ...c, createdByType: "admin" })),
238
416
  ...sublistingRows.map((s) => ({ ancestors: [], ...s, createdByType: "admin" })),
239
417
  ...brandRows.map((b) => ({ ancestors: [], ...b, createdByType: "admin" })),
418
+ ...bundleRows.map((b) => ({ ancestors: [], ...b })),
240
419
  ];
@@ -67,6 +67,8 @@ export declare const groupedListingsSeedData: {
67
67
  isOnSale?: boolean | undefined;
68
68
  isSold?: boolean | undefined;
69
69
  allowShipBeforeEmiComplete?: boolean | undefined;
70
+ gstRate?: 0 | 5 | 12 | 18 | 28 | undefined;
71
+ hsnCode?: string | undefined;
70
72
  printMeta?: import("../features/products").ProductPrintMeta | undefined;
71
73
  promotionEndDate?: Date | undefined;
72
74
  pickupAddressId?: string | undefined;
@@ -68,6 +68,8 @@ export declare const productsPreordersSeedData: {
68
68
  isOnSale?: boolean | undefined;
69
69
  isSold?: boolean | undefined;
70
70
  allowShipBeforeEmiComplete?: boolean | undefined;
71
+ gstRate?: 0 | 5 | 12 | 18 | 28 | undefined;
72
+ hsnCode?: string | undefined;
71
73
  printMeta?: import("../features/products").ProductPrintMeta | undefined;
72
74
  promotionEndDate?: Date | undefined;
73
75
  pickupAddressId?: string | undefined;
@@ -907,7 +907,14 @@ export const siteSettingsSeedData = {
907
907
  },
908
908
  },
909
909
  ],
910
- defaultLightThemeId: "crimson-warrior",
911
- defaultDarkThemeId: "shadow-abyss",
910
+ // Reverted 2026-08-15 — the live site had drifted onto the "Teal Tide" /
911
+ // "Teal Depths" custom pair (added in a prior session's theme-experiment
912
+ // sweep), which is not the brand's cobalt+lime/hot-pink identity. The
913
+ // custom themes above stay available as selectable options (nothing
914
+ // deleted); this just restores the appkit built-ins as what's live by
915
+ // default. buildThemeRegistry() always resolves "default-light"/
916
+ // "default-dark" to the true built-in records regardless of this list.
917
+ defaultLightThemeId: "default-light",
918
+ defaultDarkThemeId: "default-dark",
912
919
  },
913
920
  };
@@ -70,8 +70,8 @@ export { processRefundAction, type ProcessRefundInput, } from "./_internal/serve
70
70
  export { createPaymentIntentAction, verifyPaymentSignatureAction, resolvePaymentFee, PAYMENTS_DEFAULT_PLATFORM_FEE_PERCENT, PAYMENTS_DEFAULT_GST_PERCENT, PAYMENTS_RECEIPT_PREFIX, type CreatePaymentIntentInput, type CreatePaymentIntentResult, type VerifyPaymentSignatureInput, type ResolvedPaymentFee, } from "./_internal/server/features/payments/index";
71
71
  export { getSublistingCategoryForDetail } from "./_internal/server/features/sublisting-categories/index";
72
72
  export { getStoreForDetail, listStoreProductsInitial, listStoreAuctionsInitial, listStorePreOrdersInitial, listSitemapStores, STORES_PAGE_SIZE, STORES_PRODUCTS_PAGE_SIZE, STORES_SITEMAP_LIMIT, STORES_FEATURED_LIMIT, } from "./_internal/server/features/stores/index";
73
- export { AppShell, DashboardScaffold } from "./_internal/client/scaffolds/index";
74
- export type { AppShellProps, AppShellRenderContext, DashboardScaffoldProps, DashboardScaffoldRenderContext, } from "./_internal/client/scaffolds/index";
73
+ export { AppShell } from "./_internal/client/scaffolds/index";
74
+ export type { AppShellProps, AppShellRenderContext, } from "./_internal/client/scaffolds/index";
75
75
  export { toClient, clientInitial } from "./_internal/shared/serialization/index";
76
76
  export * as accountServer from "./_internal/server/features/account/index";
77
77
  export * as authServer from "./_internal/server/features/auth/index";
@@ -108,7 +108,7 @@ export { getStoreForDetail, listStoreProductsInitial, listStoreAuctionsInitial,
108
108
  // Next.js lambdas. Consumers that need them (i.e. `functions/src/index.ts`)
109
109
  // import directly from `@mohasinac/appkit/jobs`.
110
110
  // S6: client scaffolds (server-side type-aware import; runtime is "use client")
111
- export { AppShell, DashboardScaffold } from "./_internal/client/scaffolds/index";
111
+ export { AppShell } from "./_internal/client/scaffolds/index";
112
112
  // CC-3: hydration helpers
113
113
  export { toClient, clientInitial } from "./_internal/shared/serialization/index";
114
114
  // S7 server feature shims (data + actions) — canonical _internal/ entries
package/dist/server.d.ts CHANGED
@@ -333,6 +333,7 @@ export { finalizeStagedMediaObject } from "./features/media/server";
333
333
  export { finalizeStagedMediaObjectArray } from "./features/media/server";
334
334
  export { finalizeStagedMediaUrl } from "./features/media/server";
335
335
  export { cancelOrderForUser } from "./features/orders/server";
336
+ export { cancelOrderItemsForUser } from "./features/orders/server";
336
337
  export { getOrderByIdForUser } from "./features/orders/server";
337
338
  export { getOrderTrackingHandler } from "./features/orders/server";
338
339
  export { getTrackingInfo } from "./features/orders/server";
@@ -437,6 +438,9 @@ export { getWishlistForUser } from "./features/wishlist/server";
437
438
  export { removeFromWishlist } from "./features/wishlist/server";
438
439
  export { siteSettingsRepository } from "./repositories/index";
439
440
  export { storeRepository } from "./repositories/index";
441
+ export { orderRepository } from "./repositories/index";
442
+ export type { OrderDocument } from "./features/orders/index";
443
+ export type { OrderDocumentItem } from "./features/orders/index";
440
444
  export { serverLogger } from "./monitoring/index";
441
445
  export { withRetry } from "./http/retry";
442
446
  export { safeFireAndForget } from "./utils/safe-fire-forget";
package/dist/server.js CHANGED
@@ -968,6 +968,9 @@ export { finalizeStagedMediaUrl } from "./features/media/server";
968
968
  // cancelOrderForUser - Shared export for cancel order for user.
969
969
  export { cancelOrderForUser } from "./features/orders/server";
970
970
  // [SERVER-ONLY]-Server-only — uses Node.js, Next.js server internals, or third-party server SDKs (auth, email, payment, shipping).
971
+ // cancelOrderItemsForUser - Cancels a subset of line items on an order and continues with the rest.
972
+ export { cancelOrderItemsForUser } from "./features/orders/server";
973
+ // [SERVER-ONLY]-Server-only — uses Node.js, Next.js server internals, or third-party server SDKs (auth, email, payment, shipping).
971
974
  // getOrderByIdForUser - Helper for get order by id for user.
972
975
  export { getOrderByIdForUser } from "./features/orders/server";
973
976
  // [SERVER-ONLY]-Server-only — uses Node.js, Next.js server internals, or third-party server SDKs (auth, email, payment, shipping).
@@ -1274,6 +1277,8 @@ export { removeFromWishlist } from "./features/wishlist/server";
1274
1277
  export { siteSettingsRepository } from "./repositories/index";
1275
1278
  // storeRepository - Shared export for store repository.
1276
1279
  export { storeRepository } from "./repositories/index";
1280
+ // orderRepository - Shared export for order repository (needed by consumer Firebase Functions, e.g. invoice PDF generation).
1281
+ export { orderRepository } from "./repositories/index";
1277
1282
  // SB-UNI-V — bundlesRepository deleted; use categoriesRepository with categoryType:"bundle".
1278
1283
  // -- Monitoring --------------------------------------------------------------
1279
1284
  // serverLogger - Structured server-side logger.