@mohasinac/appkit 3.3.3 → 3.3.5

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 (97) hide show
  1. package/dist/_internal/client/features/lottery/LotteryAdminSlotView.js +1 -1
  2. package/dist/_internal/client/features/lottery/LotteryDetailView.js +2 -1
  3. package/dist/_internal/client/features/lottery/PrizeDrawLotteryDetailView.js +2 -1
  4. package/dist/_internal/server/features/auth/permissions.js +4 -3
  5. package/dist/_internal/server/features/cart/actions.js +1 -1
  6. package/dist/_internal/server/features/lottery/data.d.ts +2 -3
  7. package/dist/_internal/server/features/products/actions.js +1 -1
  8. package/dist/features/about/components/AboutView.js +1 -1
  9. package/dist/features/about/components/PolicyPageView.js +1 -1
  10. package/dist/features/about/components/TrackOrderView.js +1 -1
  11. package/dist/features/account/components/AddressesIndexListing.js +1 -1
  12. package/dist/features/admin/components/AdminBlogEditorView.js +1 -1
  13. package/dist/features/admin/components/AdminCarouselEditorView.js +2 -1
  14. package/dist/features/admin/components/AdminCarouselView.js +1 -1
  15. package/dist/features/admin/components/AdminNavEditorView.js +2 -1
  16. package/dist/features/admin/components/AdminProductsView.js +2 -2
  17. package/dist/features/admin/components/AdminSectionsView.js +11 -7
  18. package/dist/features/admin/components/AdminSiteSettingsView.js +2 -1
  19. package/dist/features/admin/components/DrawerFormFooter.js +2 -2
  20. package/dist/features/admin/components/QuickEditMenu.js +1 -1
  21. package/dist/features/admin/components/analytics/AdminAnalyticsCharts.js +1 -1
  22. package/dist/features/admin/components/sections/adminSectionsTypes.js +3 -2
  23. package/dist/features/admin/constants/filter-tabs.js +11 -0
  24. package/dist/features/auctions/columns/index.js +1 -1
  25. package/dist/features/auctions/components/AuctionBidsTable.js +1 -1
  26. package/dist/features/auctions/schemas/index.d.ts +2 -2
  27. package/dist/features/auth/hooks/useRBAC.js +6 -1
  28. package/dist/features/blog/columns/index.js +1 -1
  29. package/dist/features/cart/components/CartDrawer.js +2 -2
  30. package/dist/features/categories/components/BrandDetailPageView.js +1 -1
  31. package/dist/features/categories/components/BreadcrumbTrail.js +2 -1
  32. package/dist/features/categories/schemas/firestore.d.ts +1 -1
  33. package/dist/features/contact/email.js +0 -1
  34. package/dist/features/events/components/EventBanner.js +2 -1
  35. package/dist/features/events/components/EventLeaderboard.js +1 -1
  36. package/dist/features/faq/components/FAQCategorySidebar.js +2 -1
  37. package/dist/features/forms/Slider.js +5 -2
  38. package/dist/features/forms/Toggle.js +4 -1
  39. package/dist/features/homepage/components/AdSlot.js +2 -2
  40. package/dist/features/homepage/components/BeforeAfterCard.js +1 -1
  41. package/dist/features/homepage/components/CTABannerSection.js +2 -1
  42. package/dist/features/homepage/components/CharacterHotspot.js +2 -1
  43. package/dist/features/homepage/components/FAQSection.js +1 -1
  44. package/dist/features/homepage/components/FeaturedBundlesSection.js +1 -1
  45. package/dist/features/homepage/components/HowItWorksInfoView.js +1 -1
  46. package/dist/features/homepage/components/HowItWorksSection.js +1 -1
  47. package/dist/features/homepage/components/NewsletterBanner.js +1 -1
  48. package/dist/features/homepage/components/SecurityHighlightsSection.js +1 -1
  49. package/dist/features/homepage/components/SiteFeaturesSection.js +1 -1
  50. package/dist/features/homepage/components/TrustFeaturesSection.js +1 -1
  51. package/dist/features/homepage/components/TrustIndicatorsSection.js +1 -1
  52. package/dist/features/layout/BottomActions.js +29 -2
  53. package/dist/features/layout/BottomActionsContext.d.ts +36 -0
  54. package/dist/features/layout/BottomActionsContext.js +36 -0
  55. package/dist/features/orders/components/MarketplaceOrderCard.js +2 -2
  56. package/dist/features/orders/schemas/index.d.ts +2 -2
  57. package/dist/features/payments/schemas/index.d.ts +4 -4
  58. package/dist/features/products/components/BidHistory.js +1 -1
  59. package/dist/features/products/components/MarketplaceBundleCard.js +1 -1
  60. package/dist/features/products/components/ProductGalleryClient.js +1 -1
  61. package/dist/features/products/components/ShowGroupSection.js +1 -1
  62. package/dist/features/products/components/SublistingCarouselSection.js +1 -1
  63. package/dist/features/products/repository/products.repository.js +1 -1
  64. package/dist/features/products/schemas/product-features.validators.d.ts +6 -6
  65. package/dist/features/promotions/repository/claimed-coupons.repository.js +1 -1
  66. package/dist/features/reviews/columns/index.js +1 -1
  67. package/dist/features/scams/components/ScamAwarenessModal.js +1 -1
  68. package/dist/features/search/components/Search.js +1 -1
  69. package/dist/features/search/schemas/index.d.ts +2 -2
  70. package/dist/features/seller/actions/seller-actions.d.ts +2 -2
  71. package/dist/features/seller/components/SellerCouponEditorView.js +1 -1
  72. package/dist/features/seller/components/SellerGoogleReviewsView.js +1 -1
  73. package/dist/features/seller/components/SellerOrdersView.js +4 -1
  74. package/dist/features/seller/components/SellerPayoutMethodsView.js +1 -1
  75. package/dist/features/seller/components/SellerProductsView.js +35 -31
  76. package/dist/features/seller/components/SellerReviewsView.js +1 -1
  77. package/dist/features/seller/schemas/index.d.ts +2 -2
  78. package/dist/features/shell/QuickFormDrawer.js +1 -1
  79. package/dist/features/stores/columns/index.js +1 -1
  80. package/dist/features/stores/components/StoresIndexListing.js +20 -15
  81. package/dist/features/wishlist/actions/wishlist-actions.js +1 -1
  82. package/dist/next/ErrorBoundary.js +2 -1
  83. package/dist/next/components/NotFoundView.js +17 -0
  84. package/dist/next/components/UnauthorizedView.js +13 -0
  85. package/dist/schemas/registry.d.ts +93 -94
  86. package/dist/schemas/webhooks/razorpay.d.ts +86 -86
  87. package/dist/seed/carousel-slides-seed-data.js +3 -2
  88. package/dist/seed/defaults/homepage-sections.js +2 -1
  89. package/dist/seed/factories/carousel.factory.js +2 -1
  90. package/dist/seed/homepage-sections-seed-data.js +4 -3
  91. package/dist/seed/notifications-seed-data.js +2 -1
  92. package/dist/seed/site-settings-seed-data.js +3 -2
  93. package/dist/seo/metadata.js +2 -1
  94. package/dist/ui/columns/column-renderers.js +1 -1
  95. package/dist/ui/components/Accordion.js +10 -6
  96. package/dist/ui/components/ListingLayout.js +6 -2
  97. package/package.json +1 -1
@@ -6,5 +6,5 @@ import { Div, Grid, Heading, Row, Section, Span, Text } from "../../../ui";
6
6
  export function HowItWorksInfoView({ title, subtitle, heroClass = "", stepsTitle, steps, detailsSectionTitle, details = [], renderDiagram, renderFooter, accentClass = "bg-info-surface dark:bg-info-surface text-info dark:text-info", className = "", }) {
7
7
  const themed = { bgSecondary: THEMED_BG_SECONDARY, border: THEMED_BORDER };
8
8
  const spacing = { stack: SPACING_STACK };
9
- return (_jsxs(Div, { className: `-mx-4 md:-mx-6 lg:-mx-8 -mt-6 sm:-mt-8 lg:-mt-10 ${className}`, children: [_jsx(Section, { color: "inverse", tone: "accent-banner", className: heroClass, paddingY: "y-5xl", children: _jsxs(Div, { paddingX: "x-page", className: "max-w-4xl mx-auto text-center", children: [_jsx(Heading, { color: "inverse", level: 1, variant: "none", className: "mb-4", children: title }), subtitle && (_jsx(Text, { color: "inverse", variant: "none", className: "/80 max-w-2xl mx-auto", children: subtitle }))] }) }), _jsxs(Div, { paddingX: "x-page", className: "max-w-4xl mx-auto", padding: "content-banner", children: [renderDiagram?.(), stepsTitle && (_jsx(Heading, { level: 2, className: "mb-6", children: stepsTitle })), _jsx(Div, { className: `${spacing.stack} mb-14`, children: steps.map(({ number, icon, title: stepTitle, text, accentClass: stepAccent, textClass, }) => (_jsxs(Section, { layout: "flex", gap: "md", align: "start", border: "default", surface: "subtle", rounded: "xl", padding: "lg", children: [_jsx(Row, { textWeight: "bold", align: "center", justify: "center", textSize: "sm", className: `shrink-0 w-10 h-10 ${stepAccent ?? accentClass}`, rounded: "xl", children: _jsx(Span, { className: textClass, children: number }) }), _jsxs(Div, { children: [_jsxs(Heading, { level: 3, className: "mb-1", weight: "semibold", children: [icon, " ", stepTitle] }), _jsx(Text, { variant: "secondary", size: "sm", className: "leading-relaxed", children: text })] })] }, number))) }), details.length > 0 && (_jsxs(_Fragment, { children: [detailsSectionTitle && (_jsx(Heading, { level: 2, className: "mb-6", children: detailsSectionTitle })), _jsx(Grid, { className: "grid-cols-1 sm:grid-cols-2 xl:grid-cols-2 2xl:grid-cols-3 mb-12", children: details.map(({ title: dt, text: dx }) => (_jsxs("div", { className: `${themed.bgSecondary} border ${themed.border} rounded-xl p-5`, children: [_jsx(Heading, { level: 3, className: "mb-2", weight: "semibold", children: dt }), _jsx(Text, { variant: "secondary", size: "sm", className: "leading-relaxed", children: dx })] }, dt))) })] })), renderFooter?.()] })] }));
9
+ return (_jsxs(Div, { className: `-mx-4 md:-mx-6 lg:-mx-8 -mt-6 sm:-mt-8 lg:-mt-10 ${className}`, children: [_jsx(Section, { color: "inverse", tone: "accent-banner", className: heroClass, paddingY: "y-5xl", children: _jsxs(Div, { paddingX: "x-page", className: "max-w-4xl mx-auto text-center", children: [_jsx(Heading, { color: "inverse", level: 1, variant: "none", className: "mb-4", children: title }), subtitle && (_jsx(Text, { color: "inverse", variant: "none", className: "/80 max-w-2xl mx-auto", children: subtitle }))] }) }), _jsxs(Div, { paddingX: "x-page", className: "max-w-4xl mx-auto", padding: "content-banner", children: [renderDiagram?.(), stepsTitle && (_jsx(Heading, { level: 2, className: "mb-6", children: stepsTitle })), _jsx(Div, { className: `${spacing.stack} mb-14`, children: steps.map(({ number, icon, title: stepTitle, text, accentClass: stepAccent, textClass, }) => (_jsxs(Section, { layout: "flex", gap: "md", align: "start", border: "default", surface: "subtle", rounded: "xl", padding: "lg", children: [_jsx(Row, { textWeight: "bold", align: "center", justify: "center", textSize: "sm", className: `shrink-0 w-10 h-10 ${stepAccent ?? accentClass}`, rounded: "xl", children: _jsx(Span, { className: textClass, children: number }) }), _jsxs(Div, { children: [_jsxs(Heading, { level: 3, className: "mb-1", weight: "semibold", children: [icon, " ", stepTitle] }), _jsx(Text, { variant: "secondary", size: "sm", className: "leading-relaxed", children: text })] })] }, number))) }), details.length > 0 && (_jsxs(_Fragment, { children: [detailsSectionTitle && (_jsx(Heading, { level: 2, className: "mb-6", children: detailsSectionTitle })), _jsx(Grid, { className: "grid-cols-1 sm:grid-cols-2 xl:grid-cols-2 2xl:grid-cols-3 mb-12", children: details.map(({ title: dt, text: dx }) => (_jsxs(Div, { className: `${themed.bgSecondary} border ${themed.border} rounded-xl p-5`, children: [_jsx(Heading, { level: 3, className: "mb-2", weight: "semibold", children: dt }), _jsx(Text, { variant: "secondary", size: "sm", className: "leading-relaxed", children: dx })] }, dt))) })] })), renderFooter?.()] })] }));
10
10
  }
@@ -9,7 +9,7 @@ const STEP_DELAYS = ["delay-0", "delay-150", "delay-300", "delay-[450ms]"];
9
9
  // --- Single step card ---------------------------------------------------------
10
10
  function StepCard({ step, visible, delayClass, }) {
11
11
  const { badgeBg = "bg-primary", iconColor = "text-primary", iconBg = "bg-primary/5 dark:bg-primary/10", } = step;
12
- return (_jsxs("div", { className: [
12
+ return (_jsxs(Div, { className: [
13
13
  "relative rounded-3xl p-8",
14
14
  "bg-[var(--appkit-color-surface)]",
15
15
  "shadow-md group hover:-translate-y-2 hover:shadow-xl",
@@ -2,7 +2,7 @@
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { normalizeError } from "../../../errors/normalize";
4
4
  import { useState } from "react";
5
- import { Button, Div, Heading, Span, Text, } from "../../../ui";
5
+ import { Button, Div, Heading, Span, Text } from "../../../ui";
6
6
  import { DynamicBgDiv } from "../../../ui/components/DynamicBgDiv";
7
7
  import { Form } from "../../../ui/components/Form";
8
8
  import { FieldInput } from "../../../ui/forms/FieldInput";
@@ -10,7 +10,7 @@ function SecurityCard({ item, visible, delayClass, }) {
10
10
  const colorClass = item.colorClass ??
11
11
  "bg-primary/5 border-primary/20 dark:bg-primary/10 dark:border-primary/30";
12
12
  const iconColorClass = item.iconColorClass ?? "text-primary";
13
- return (_jsxs("div", { className: [
13
+ return (_jsxs(Div, { className: [
14
14
  "rounded-xl border p-5 transition-all duration-500",
15
15
  colorClass,
16
16
  delayClass,
@@ -7,5 +7,5 @@ const __P = {
7
7
  // --- Section -----------------------------------------------------------------
8
8
  export function SiteFeaturesSection({ title, subtitle, features, className = "", }) {
9
9
  const themed = { textPrimary: THEMED_TEXT_PRIMARY, textSecondary: THEMED_TEXT_SECONDARY };
10
- return (_jsx(Section, { className: `${__P.p8} ${className}`, surface: "subtle", children: _jsxs(Div, { className: "w-full", children: [_jsxs(Div, { className: "text-center mb-12", children: [_jsx(Heading, { level: 2, className: `${themed.textPrimary} mb-3`, size: "3xl", mdSize: "4xl", weight: "bold", children: title }), subtitle && (_jsx(Text, { className: `${themed.textSecondary} max-w-2xl mx-auto`, size: "base", children: subtitle }))] }), _jsx(Grid, { gap: "section", className: "grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4", children: features.map((feature) => (_jsxs("div", { className: "p-6 text-center hover:shadow-lg transition-all group rounded-2xl bg-[var(--appkit-color-surface)] border border-zinc-100 border-[var(--appkit-color-border-subtle)]", children: [_jsx(Div, { className: "text-[3.75rem] mb-4 group-hover:scale-110 transition-transform", children: feature.icon }), _jsx(Heading, { level: 3, className: `${themed.textPrimary} mb-2`, size: "base", weight: "bold", children: feature.title }), _jsx(Text, { className: `${themed.textSecondary}`, size: "base", children: feature.description })] }, feature.id))) })] }) }));
10
+ return (_jsx(Section, { className: `${__P.p8} ${className}`, surface: "subtle", children: _jsxs(Div, { className: "w-full", children: [_jsxs(Div, { className: "text-center mb-12", children: [_jsx(Heading, { level: 2, className: `${themed.textPrimary} mb-3`, size: "3xl", mdSize: "4xl", weight: "bold", children: title }), subtitle && (_jsx(Text, { className: `${themed.textSecondary} max-w-2xl mx-auto`, size: "base", children: subtitle }))] }), _jsx(Grid, { gap: "section", className: "grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4", children: features.map((feature) => (_jsxs(Div, { className: "p-6 text-center hover:shadow-lg transition-all group rounded-2xl bg-[var(--appkit-color-surface)] border border-zinc-100 border-[var(--appkit-color-border-subtle)]", children: [_jsx(Div, { className: "text-[3.75rem] mb-4 group-hover:scale-110 transition-transform", children: feature.icon }), _jsx(Heading, { level: 3, className: `${themed.textPrimary} mb-2`, size: "base", weight: "bold", children: feature.title }), _jsx(Text, { className: `${themed.textSecondary}`, size: "base", children: feature.description })] }, feature.id))) })] }) }));
11
11
  }
@@ -6,7 +6,7 @@ import { Div, Grid, Heading, Row, Section, Span, Text } from "../../../ui";
6
6
  const CARD_DELAYS = ["delay-0", "delay-100", "delay-200", "delay-300", "delay-[400ms]", "delay-500"];
7
7
  // --- Single cards-variant card -----------------------------------------------
8
8
  function TrustFeatureCard({ item, visible, delayClass, }) {
9
- return (_jsxs("div", { className: [
9
+ return (_jsxs(Div, { className: [
10
10
  "flex flex-col items-center text-center p-4",
11
11
  "transition-all duration-500",
12
12
  delayClass,
@@ -7,5 +7,5 @@ const __P = {
7
7
  // --- Section -----------------------------------------------------------------
8
8
  export function TrustIndicatorsSection({ items, className = "", }) {
9
9
  const themed = { textPrimary: THEMED_TEXT_PRIMARY, textSecondary: THEMED_TEXT_SECONDARY };
10
- return (_jsx(Section, { className: `${__P.p6} ${className}`, surface: "subtle", children: _jsx(Div, { className: "w-full", children: _jsx(Grid, { gap: "section", className: "grid-cols-2 sm:grid-cols-3 md:grid-cols-4 xl:grid-cols-4 2xl:grid-cols-4", children: items.map((indicator, index) => (_jsxs("div", { className: "text-center p-4 rounded-2xl bg-[var(--appkit-color-surface)] border border-zinc-100 border-[var(--appkit-color-border-subtle)] hover:shadow-md transition-shadow", children: [_jsx(Div, { className: "text-[2.25rem] md:text-[3rem] mb-2 md:mb-3", children: indicator.icon }), _jsx(Heading, { level: 3, className: `${themed.textPrimary} mb-1 md:mb-2`, size: "sm", weight: "semibold", children: indicator.title }), _jsx(Text, { className: `${themed.textSecondary}`, size: "xs", children: indicator.description })] }, index))) }) }) }));
10
+ return (_jsx(Section, { className: `${__P.p6} ${className}`, surface: "subtle", children: _jsx(Div, { className: "w-full", children: _jsx(Grid, { gap: "section", className: "grid-cols-2 sm:grid-cols-3 md:grid-cols-4 xl:grid-cols-4 2xl:grid-cols-4", children: items.map((indicator, index) => (_jsxs(Div, { className: "text-center p-4 rounded-2xl bg-[var(--appkit-color-surface)] border border-zinc-100 border-[var(--appkit-color-border-subtle)] hover:shadow-md transition-shadow", children: [_jsx(Div, { className: "text-[2.25rem] md:text-[3rem] mb-2 md:mb-3", children: indicator.icon }), _jsx(Heading, { level: 3, className: `${themed.textPrimary} mb-1 md:mb-2`, size: "sm", weight: "semibold", children: indicator.title }), _jsx(Text, { className: `${themed.textSecondary}`, size: "xs", children: indicator.description })] }, index))) }) }) }));
11
11
  }
@@ -1,5 +1,32 @@
1
1
  "use client";
2
2
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
+ /**
4
+ * BottomActions Component
5
+ *
6
+ * A fixed-bottom mobile action bar rendered **above** BottomNavbar (bottom-14).
7
+ * Reads from `BottomActionsContext` — features register their actions via the
8
+ * `useBottomActions` hook; this component just renders whatever is registered.
9
+ *
10
+ * Two modes:
11
+ * - **Page mode** — shows registered page-level actions inline (Add to Cart,
12
+ * Buy Now, Place Bid, Proceed to Checkout, etc.) with an optional info label.
13
+ * - **Bulk mode** — activates when sieveFilter("bulk.selectedCount", SIEVE_OP.GT, "0"); shows:
14
+ * • Selection count pill on the left (tap to deselect all)
15
+ * • An upward-opening type-picker dropdown (middle, flex-1) — tap to
16
+ * choose WHICH action to run; the chosen label is always visible.
17
+ * • An "Apply" submit button on the right — executes the selected action,
18
+ * styled with the selected action's variant (danger = red, etc.).
19
+ *
20
+ * Layout rules:
21
+ * - Hidden on lg+ screens (`lg:hidden`) — desktop shows inline action panels.
22
+ * - The bar slides up with a 300 ms ease-out transition; `pointer-events-none`
23
+ * while off-screen.
24
+ *
25
+ * @component
26
+ * @example
27
+ * // Automatically rendered by LayoutClient — no manual usage required.
28
+ * // Features use `useBottomActions` to register their actions.
29
+ */
3
30
  import { useState, useRef, useEffect } from "react";
4
31
  import { X, ChevronUp, ChevronDown, Check } from "lucide-react";
5
32
  import { useBottomActionsContext } from "./BottomActionsContext";
@@ -13,7 +40,7 @@ const FLEX_CENTER = "flex items-center justify-center";
13
40
  const CLS_COUNT_BADGE = "bg-error-surface text-white";
14
41
  // ─── Sub-components ───────────────────────────────────────────────────────────
15
42
  function BulkPickerPanel({ bulkActions, selectedActionId, pickerOpen, onSelect, }) {
16
- return (_jsx("div", { role: "listbox", "aria-label": "Bulk actions", className: [
43
+ return (_jsx(Div, { role: "listbox", "aria-label": "Bulk actions", className: [
17
44
  "absolute bottom-full left-0 right-0 overflow-hidden",
18
45
  BOTTOM_NAV_BG,
19
46
  "border-t border-zinc-200/80 border-[var(--appkit-color-border)]/80",
@@ -91,7 +118,7 @@ export default function BottomActions() {
91
118
  bulkCallbacksRef.current.get(selectedActionId)?.();
92
119
  setPickerOpen(false);
93
120
  };
94
- return (_jsxs("div", { ref: containerRef, role: "toolbar", "aria-label": isBulkMode ? "Bulk actions" : "Page actions", "aria-hidden": !isVisible, className: [
121
+ return (_jsxs(Div, { ref: containerRef, role: "toolbar", "aria-label": isBulkMode ? "Bulk actions" : "Page actions", "aria-hidden": !isVisible, className: [
95
122
  "fixed bottom-14 left-0 right-0 lg:hidden",
96
123
  Z_BOTTOM_ACTIONS,
97
124
  BOTTOM_NAV_BG,
@@ -1,3 +1,39 @@
1
+ /**
2
+ * BottomActionsContext
3
+ *
4
+ * Provides a context for registering page-level mobile action bars.
5
+ * Features call `useBottomActions` to push actions; the `<BottomActions>`
6
+ * layout component reads this context and renders the bar above BottomNavbar.
7
+ *
8
+ * Supports two modes:
9
+ * - Page mode: primary page actions (Add to Cart, Buy Now, Place Bid, etc.)
10
+ * - Bulk mode: activated when sieveFilter("bulk.selectedCount", SIEVE_OP.GT, "0") — shows selection
11
+ * count + custom bulk action buttons (Delete, Archive, Export, etc.)
12
+ *
13
+ * @example — product detail page
14
+ * ```tsx
15
+ * useBottomActions({
16
+ * actions: [
17
+ * { id: "wishlist", icon: <Heart className="w-4 h-4" />, label: t("wishlist"), variant: "ghost", grow: false, onClick: handleWishlist },
18
+ * { id: "cart", label: t("addToCart"), variant: "outline", onClick: handleAddToCart },
19
+ * { id: "buy", label: t("buyNow"), variant: "primary", onClick: handleBuyNow },
20
+ * ],
21
+ * });
22
+ * ```
23
+ *
24
+ * @example — admin listing with bulk select
25
+ * ```tsx
26
+ * useBottomActions({
27
+ * bulk: {
28
+ * selectedCount: selectedIds.length,
29
+ * onClearSelection: () => setSelectedIds([]),
30
+ * actions: [
31
+ * { id: "delete", label: t("bulkDelete", { count: selectedIds.length }), variant: "danger", onClick: handleBulkDelete },
32
+ * ],
33
+ * },
34
+ * });
35
+ * ```
36
+ */
1
37
  import React from "react";
2
38
  import type { ButtonProps } from "../../ui";
3
39
  export interface BottomAction {
@@ -1,5 +1,41 @@
1
1
  "use client";
2
2
  import { jsx as _jsx } from "react/jsx-runtime";
3
+ /**
4
+ * BottomActionsContext
5
+ *
6
+ * Provides a context for registering page-level mobile action bars.
7
+ * Features call `useBottomActions` to push actions; the `<BottomActions>`
8
+ * layout component reads this context and renders the bar above BottomNavbar.
9
+ *
10
+ * Supports two modes:
11
+ * - Page mode: primary page actions (Add to Cart, Buy Now, Place Bid, etc.)
12
+ * - Bulk mode: activated when sieveFilter("bulk.selectedCount", SIEVE_OP.GT, "0") — shows selection
13
+ * count + custom bulk action buttons (Delete, Archive, Export, etc.)
14
+ *
15
+ * @example — product detail page
16
+ * ```tsx
17
+ * useBottomActions({
18
+ * actions: [
19
+ * { id: "wishlist", icon: <Heart className="w-4 h-4" />, label: t("wishlist"), variant: "ghost", grow: false, onClick: handleWishlist },
20
+ * { id: "cart", label: t("addToCart"), variant: "outline", onClick: handleAddToCart },
21
+ * { id: "buy", label: t("buyNow"), variant: "primary", onClick: handleBuyNow },
22
+ * ],
23
+ * });
24
+ * ```
25
+ *
26
+ * @example — admin listing with bulk select
27
+ * ```tsx
28
+ * useBottomActions({
29
+ * bulk: {
30
+ * selectedCount: selectedIds.length,
31
+ * onClearSelection: () => setSelectedIds([]),
32
+ * actions: [
33
+ * { id: "delete", label: t("bulkDelete", { count: selectedIds.length }), variant: "danger", onClick: handleBulkDelete },
34
+ * ],
35
+ * },
36
+ * });
37
+ * ```
38
+ */
3
39
  import { createContext, useCallback, useContext, useMemo, useRef, useState, } from "react";
4
40
  const EMPTY = { actions: [] };
5
41
  const BottomActionsContext = createContext(null);
@@ -2,7 +2,7 @@
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { useCallback } from "react";
4
4
  import { Package } from "lucide-react";
5
- import { BaseListingCard, Button, Caption, Row, Span, Stack, StatusBadge, Text, TextLink } from "../../../ui";
5
+ import { BaseListingCard, Button, Caption, Row, Span, Stack, StatusBadge, Text, TextLink, Div } from "../../../ui";
6
6
  import { formatCurrency, formatDate } from "../../../utils";
7
7
  import { OrderStatusValues } from "../schemas";
8
8
  import { useLongPress } from "../../../react/hooks/useLongPress";
@@ -48,7 +48,7 @@ export function MarketplaceOrderCard({ order, links, labels, className = "", var
48
48
  const longPress = useLongPress(() => onSelect?.(orderId, !isSelected));
49
49
  const isListVariant = variant === "list";
50
50
  const itemCount = order.items?.length ?? 0;
51
- return (_jsxs("div", { className: `group relative overflow-hidden rounded-xl border border-zinc-200 bg-[var(--appkit-color-surface)] transition-all duration-200 hover:shadow-md border-[var(--appkit-color-border-subtle)] bg-[var(--appkit-color-surface)] ${isSelected ? "ring-2 ring-primary-500 dark:ring-primary-400" : ""} ${className}`, onMouseDown: onSelect && !isSelected ? longPress.onMouseDown : undefined, onMouseUp: onSelect && !isSelected ? longPress.onMouseUp : undefined, onMouseLeave: onSelect && !isSelected ? longPress.onMouseLeave : undefined, onTouchStart: onSelect && !isSelected ? longPress.onTouchStart : undefined, onTouchEnd: onSelect && !isSelected ? longPress.onTouchEnd : undefined, "data-section": "marketplaceordercard-div-411", children: [onSelect && (_jsx(BaseListingCard.Checkbox, { selected: isSelected, onSelect: handleSelect, label: isSelected ? "Deselect order" : "Select order", position: "top-2 left-2", className: selectable || isSelected ? "opacity-100" : "opacity-0 group-hover:opacity-100 transition-opacity" })), _jsxs("div", { className: `flex gap-4 p-4 ${isListVariant ? "flex-row items-center justify-between" : "flex-col"}`, "data-section": "marketplaceordercard-div-412", children: [_jsxs("div", { className: `flex items-start gap-3 ${selectable ? "pl-8" : ""} ${isListVariant ? "min-w-0 flex-1" : ""}`, "data-section": "marketplaceordercard-div-413", children: [_jsx(Row, { className: "h-10 w-10 flex-shrink-0", surface: "subtle", align: "center", justify: "center", rounded: "lg", children: _jsx(Package, { className: "h-5 w-5 text-[var(--appkit-color-text-muted)] text-[var(--appkit-color-text-muted)]" }) }), _jsxs(Stack, { className: "min-w-0", gap: "xs", children: [_jsx(TextLink, { href: detailHref, className: "leading-tight", children: _jsx(Text, { weight: "semibold", className: "truncate", children: order.productTitle ?? shortId }) }), _jsxs(Caption, { className: "font-mono", children: [mergedLabels.orderNumber, " ", shortId] }), _jsxs(Caption, { children: [mergedLabels.placedOn, " ", formatDate(order.orderDate)] }), itemCount > 1 && (_jsxs(Caption, { children: [mergedLabels.items, ": ", _jsx(Span, { weight: "medium", children: itemCount })] }))] })] }), _jsxs("div", { className: `flex ${isListVariant ? "flex-shrink-0 items-center gap-4" : "flex-col gap-3"}`, "data-section": "marketplaceordercard-div-416", children: [_jsxs("div", { className: `flex ${isListVariant ? "items-center gap-4" : "flex-wrap items-center justify-between gap-3"}`, "data-section": "marketplaceordercard-div-417", children: [_jsx(StatusBadge, { status: status, label: statusLabel }), _jsx(Text, { weight: "semibold", className: "tabular-nums", children: formatCurrency(order.totalPrice, order.currency) })] }), _jsxs(Row, { align: "center", gap: "sm", wrap: true, children: [(isShipped || isDelivered) &&
51
+ return (_jsxs(Div, { className: `group relative overflow-hidden rounded-xl border border-zinc-200 bg-[var(--appkit-color-surface)] transition-all duration-200 hover:shadow-md border-[var(--appkit-color-border-subtle)] bg-[var(--appkit-color-surface)] ${isSelected ? "ring-2 ring-primary-500 dark:ring-primary-400" : ""} ${className}`, onMouseDown: onSelect && !isSelected ? longPress.onMouseDown : undefined, onMouseUp: onSelect && !isSelected ? longPress.onMouseUp : undefined, onMouseLeave: onSelect && !isSelected ? longPress.onMouseLeave : undefined, onTouchStart: onSelect && !isSelected ? longPress.onTouchStart : undefined, onTouchEnd: onSelect && !isSelected ? longPress.onTouchEnd : undefined, "data-section": "marketplaceordercard-div-411", children: [onSelect && (_jsx(BaseListingCard.Checkbox, { selected: isSelected, onSelect: handleSelect, label: isSelected ? "Deselect order" : "Select order", position: "top-2 left-2", className: selectable || isSelected ? "opacity-100" : "opacity-0 group-hover:opacity-100 transition-opacity" })), _jsxs(Div, { className: `flex gap-4 p-4 ${isListVariant ? "flex-row items-center justify-between" : "flex-col"}`, "data-section": "marketplaceordercard-div-412", children: [_jsxs(Div, { className: `flex items-start gap-3 ${selectable ? "pl-8" : ""} ${isListVariant ? "min-w-0 flex-1" : ""}`, "data-section": "marketplaceordercard-div-413", children: [_jsx(Row, { className: "h-10 w-10 flex-shrink-0", surface: "subtle", align: "center", justify: "center", rounded: "lg", children: _jsx(Package, { className: "h-5 w-5 text-[var(--appkit-color-text-muted)] text-[var(--appkit-color-text-muted)]" }) }), _jsxs(Stack, { className: "min-w-0", gap: "xs", children: [_jsx(TextLink, { href: detailHref, className: "leading-tight", children: _jsx(Text, { weight: "semibold", className: "truncate", children: order.productTitle ?? shortId }) }), _jsxs(Caption, { className: "font-mono", children: [mergedLabels.orderNumber, " ", shortId] }), _jsxs(Caption, { children: [mergedLabels.placedOn, " ", formatDate(order.orderDate)] }), itemCount > 1 && (_jsxs(Caption, { children: [mergedLabels.items, ": ", _jsx(Span, { weight: "medium", children: itemCount })] }))] })] }), _jsxs(Div, { className: `flex ${isListVariant ? "flex-shrink-0 items-center gap-4" : "flex-col gap-3"}`, "data-section": "marketplaceordercard-div-416", children: [_jsxs(Div, { className: `flex ${isListVariant ? "items-center gap-4" : "flex-wrap items-center justify-between gap-3"}`, "data-section": "marketplaceordercard-div-417", children: [_jsx(StatusBadge, { status: status, label: statusLabel }), _jsx(Text, { weight: "semibold", className: "tabular-nums", children: formatCurrency(order.totalPrice, order.currency) })] }), _jsxs(Row, { align: "center", gap: "sm", wrap: true, children: [(isShipped || isDelivered) &&
52
52
  trackHref &&
53
53
  order.trackingNumber && (_jsx(Button, { variant: "ghost", size: "sm", className: CLS_ACTION_BUTTON, onClick: () => navigate(trackHref), children: mergedLabels.trackOrder })), isDelivered && reviewHref && (_jsx(Button, { variant: "outline", size: "sm", className: CLS_ACTION_BUTTON, onClick: () => navigate(reviewHref), children: mergedLabels.writeReview })), _jsx(Button, { variant: "secondary", size: "sm", className: CLS_ACTION_BUTTON, onClick: () => navigate(detailHref), children: mergedLabels.viewOrder })] })] })] })] }));
54
54
  }
@@ -521,8 +521,8 @@ export declare const orderFirestoreSchema: z.ZodObject<{
521
521
  bin: string;
522
522
  }>>;
523
523
  }, "strip", z.ZodTypeAny, {
524
- status: "cancelled" | "pending" | "processing" | "refunded" | "confirmed" | "shipped" | "delivered" | "return_requested" | "returned";
525
524
  currency: string;
525
+ status: "cancelled" | "pending" | "processing" | "refunded" | "confirmed" | "shipped" | "delivered" | "return_requested" | "returned";
526
526
  createdAt: string | Date | z.objectOutputType<{
527
527
  toDate: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodDate>;
528
528
  }, z.ZodTypeAny, "passthrough">;
@@ -666,8 +666,8 @@ export declare const orderFirestoreSchema: z.ZodObject<{
666
666
  }, z.ZodTypeAny, "passthrough"> | undefined;
667
667
  shippingProofUploadedBy?: string | undefined;
668
668
  }, {
669
- status: "cancelled" | "pending" | "processing" | "refunded" | "confirmed" | "shipped" | "delivered" | "return_requested" | "returned";
670
669
  currency: string;
670
+ status: "cancelled" | "pending" | "processing" | "refunded" | "confirmed" | "shipped" | "delivered" | "return_requested" | "returned";
671
671
  createdAt: string | Date | z.objectInputType<{
672
672
  toDate: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodDate>;
673
673
  }, z.ZodTypeAny, "passthrough">;
@@ -150,8 +150,8 @@ export declare const payoutFirestoreSchema: z.ZodObject<{
150
150
  toDate: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodDate>;
151
151
  }, z.ZodTypeAny, "passthrough">>]>>;
152
152
  }, "strip", z.ZodTypeAny, {
153
- status: "pending" | "paid" | "failed" | "processing";
154
153
  currency: string;
154
+ status: "pending" | "paid" | "failed" | "processing";
155
155
  storeId: string;
156
156
  createdAt: string | Date | z.objectOutputType<{
157
157
  toDate: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodDate>;
@@ -200,8 +200,8 @@ export declare const payoutFirestoreSchema: z.ZodObject<{
200
200
  toDate: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodDate>;
201
201
  }, z.ZodTypeAny, "passthrough"> | undefined;
202
202
  }, {
203
- status: "pending" | "paid" | "failed" | "processing";
204
203
  currency: string;
204
+ status: "pending" | "paid" | "failed" | "processing";
205
205
  storeId: string;
206
206
  createdAt: string | Date | z.objectInputType<{
207
207
  toDate: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodDate>;
@@ -289,8 +289,8 @@ export declare const paymentRecordSchema: z.ZodObject<{
289
289
  status: z.ZodDefault<z.ZodEnum<["pending", "authorized", "captured", "failed", "refunded", "partially_refunded"]>>;
290
290
  createdAt: z.ZodOptional<z.ZodString>;
291
291
  }, "strip", z.ZodTypeAny, {
292
- status: "pending" | "failed" | "captured" | "authorized" | "refunded" | "partially_refunded";
293
292
  currency: string;
293
+ status: "pending" | "failed" | "captured" | "authorized" | "refunded" | "partially_refunded";
294
294
  id: string;
295
295
  amount: number;
296
296
  orderId: string;
@@ -302,8 +302,8 @@ export declare const paymentRecordSchema: z.ZodObject<{
302
302
  amount: number;
303
303
  orderId: string;
304
304
  gateway: "bank_transfer" | "upi" | "razorpay" | "stripe" | "paypal" | "cod" | "whatsapp";
305
- status?: "pending" | "failed" | "captured" | "authorized" | "refunded" | "partially_refunded" | undefined;
306
305
  currency?: string | undefined;
306
+ status?: "pending" | "failed" | "captured" | "authorized" | "refunded" | "partially_refunded" | undefined;
307
307
  createdAt?: string | undefined;
308
308
  gatewayPaymentId?: string | undefined;
309
309
  }>;
@@ -32,5 +32,5 @@ export function BidHistory({ isLoading = false, isEmpty = false, renderList, ren
32
32
  }
33
33
  if (renderList)
34
34
  return _jsx(Div, { className: className, children: renderList() });
35
- return (_jsxs(Div, { className: className, children: [labels.title && (_jsx(Heading, { level: 3, className: "mb-3 tracking-wide", color: "muted", size: "sm", weight: "semibold", transform: "uppercase", children: labels.title })), _jsx(Stack, { gap: "sm", children: bids.map((bid, i) => renderBid ? (_jsx(React.Fragment, { children: renderBid(bid, i) }, bid.id)) : (_jsxs("div", { className: "flex items-center justify-between rounded-lg border border-[var(--appkit-color-border-subtle)] bg-[var(--appkit-color-surface)] p-3 text-sm", "data-section": "bidhistory-div-422", children: [_jsx(Span, { weight: "bold", className: "text-primary-600 dark:text-primary-400", children: currency ? formatCurrency(bid.amount, currency) : bid.amount.toLocaleString() }), _jsx(Span, { size: "xs", color: "muted", children: formatBidDate(bid.placedAt) })] }, bid.id))) })] }));
35
+ return (_jsxs(Div, { className: className, children: [labels.title && (_jsx(Heading, { level: 3, className: "mb-3 tracking-wide", color: "muted", size: "sm", weight: "semibold", transform: "uppercase", children: labels.title })), _jsx(Stack, { gap: "sm", children: bids.map((bid, i) => renderBid ? (_jsx(React.Fragment, { children: renderBid(bid, i) }, bid.id)) : (_jsxs(Div, { className: "flex items-center justify-between rounded-lg border border-[var(--appkit-color-border-subtle)] bg-[var(--appkit-color-surface)] p-3 text-sm", "data-section": "bidhistory-div-422", children: [_jsx(Span, { weight: "bold", className: "text-primary-600 dark:text-primary-400", children: currency ? formatCurrency(bid.amount, currency) : bid.amount.toLocaleString() }), _jsx(Span, { size: "xs", color: "muted", children: formatBidDate(bid.placedAt) })] }, bid.id))) })] }));
36
36
  }
@@ -51,6 +51,6 @@ export function MarketplaceBundleCard({ bundle, className = "", variant = "grid"
51
51
  ? "opacity-100"
52
52
  : "opacity-0 group-hover:opacity-100 transition-opacity" }))] }), _jsxs(BaseListingCard.Info, { variant: variant, children: [_jsx(TextLink, { href: String(detailHref), children: _jsx(Text, { size: "sm", weight: "medium", color: "primary", truncate: 2, children: bundle.name }) }), _jsxs(Row, { justify: "between", className: "mt-1", gap: "sm", children: [_jsx(Text, { size: "sm", weight: "semibold", color: "primary", children: price
53
53
  ? formatCurrency(price / 100, getDefaultCurrency())
54
- : "—" }), _jsx(Text, { className: "text-[var(--appkit-color-text-muted)]", size: "xs", children: mergedLabels.itemsLabel(memberCount) })] }), _jsx("div", { className: CLS_VIEW_BTN, role: "button", tabIndex: 0, onClick: handleNavigate, onKeyDown: (e) => { if (e.key === "Enter" || e.key === " ")
54
+ : "—" }), _jsx(Text, { className: "text-[var(--appkit-color-text-muted)]", size: "xs", children: mergedLabels.itemsLabel(memberCount) })] }), _jsx(Div, { className: CLS_VIEW_BTN, role: "button", tabIndex: 0, onClick: handleNavigate, onKeyDown: (e) => { if (e.key === "Enter" || e.key === " ")
55
55
  handleNavigate(); }, children: "View Bundle" })] })] }));
56
56
  }
@@ -20,7 +20,7 @@ export function ProductGalleryClient({ images, productName }) {
20
20
  return (_jsx(Div, { className: `${__O.hidden}`, border: "subtle", rounded: "xl", surface: "muted", children: _jsx(Row, { className: "aspect-square text-[var(--appkit-color-border)] dark:text-[var(--appkit-color-border-subtle)]", align: "center", justify: "center", children: _jsx(PlaceholderSvg, {}) }) }));
21
21
  }
22
22
  const mainImage = images[activeIndex] ?? images[0];
23
- return (_jsxs(Stack, { gap: "3", children: [_jsx("div", { className: "overflow-hidden rounded-xl border border-[var(--appkit-color-border-subtle)] cursor-zoom-in aspect-square w-full", onClick: () => setLightboxIndex(activeIndex), role: "button", tabIndex: 0, onKeyDown: (e) => {
23
+ return (_jsxs(Stack, { gap: "3", children: [_jsx(Div, { className: "overflow-hidden rounded-xl border border-[var(--appkit-color-border-subtle)] cursor-zoom-in aspect-square w-full", onClick: () => setLightboxIndex(activeIndex), role: "button", tabIndex: 0, onKeyDown: (e) => {
24
24
  if (e.key === "Enter" || e.key === " ")
25
25
  setLightboxIndex(activeIndex);
26
26
  }, "aria-label": `View ${productName ?? "product"} image in full screen`, children: _jsx(MediaImage, { src: mainImage, alt: productName ? `${productName} — image ${activeIndex + 1}` : `Product image ${activeIndex + 1}`, size: "gallery", className: "transition-transform duration-300 hover:scale-105" }) }), images.length > 1 && (_jsx(Div, { layout: "flex", gap: "2", className: `${__O.xAuto}`, padding: "b-2xs", children: images.map((src, i) => (_jsx("button", { type: "button", onClick: () => setActiveIndex(i), className: `flex-shrink-0 h-16 w-16 overflow-hidden rounded-lg border-2 transition-all${i === activeIndex
@@ -19,7 +19,7 @@ function MemberThumb({ member, isCurrent }) {
19
19
  const image = member.images?.[0] ?? "";
20
20
  const href = memberHref(member);
21
21
  const price = formatCurrency(member.price, member.currency ?? "INR");
22
- return (_jsxs(Link, { href: href, "aria-label": member.title, className: "flex flex-col items-center gap-1.5 flex-shrink-0 w-16 group", children: [_jsxs("div", { className: `relative w-14 h-14 rounded-full overflow-hidden border-2 transition-all ${isCurrent
22
+ return (_jsxs(Link, { href: href, "aria-label": member.title, className: "flex flex-col items-center gap-1.5 flex-shrink-0 w-16 group", children: [_jsxs(Div, { className: `relative w-14 h-14 rounded-full overflow-hidden border-2 transition-all ${isCurrent
23
23
  ? "border-[var(--appkit-color-primary)] ring-2 ring-[var(--appkit-color-primary)]/30"
24
24
  : "border-[var(--appkit-color-border)] group-hover:border-[var(--appkit-color-primary)]"}`, children: [_jsx(MediaImage, { src: image, alt: member.title, size: "card" }), member.isGroupParent && (_jsx(Span, { color: "inverse", rounded: "sm", className: "absolute bottom-0 right-0 bg-[var(--appkit-color-primary)] text-[8px] leading-none px-[0.25rem] py-[0.125rem]", children: "Set" }))] }), _jsx(Text, { className: "text-[10px] leading-tight line-clamp-2 w-full", color: "muted", align: "center", children: member.title }), _jsx(Text, { className: "text-[10px]", color: "primary", weight: "semibold", children: price })] }));
25
25
  }
@@ -19,7 +19,7 @@ function ListingThumb({ listing, isCurrent, }) {
19
19
  const image = listing.images?.[0] ?? listing.mainImage ?? "";
20
20
  const href = getHref(listing);
21
21
  const price = formatCurrency(listing.price, listing.currency ?? "INR");
22
- return (_jsxs(Link, { href: href, "aria-label": listing.title, className: "flex flex-col items-center gap-1.5 flex-shrink-0 w-16 group", children: [_jsx("div", { className: `w-14 h-14 rounded-full overflow-hidden border-2 transition-all ${isCurrent
22
+ return (_jsxs(Link, { href: href, "aria-label": listing.title, className: "flex flex-col items-center gap-1.5 flex-shrink-0 w-16 group", children: [_jsx(Div, { className: `w-14 h-14 rounded-full overflow-hidden border-2 transition-all ${isCurrent
23
23
  ? "border-[var(--appkit-color-primary)] ring-2 ring-[var(--appkit-color-primary)]/30"
24
24
  : "border-[var(--appkit-color-border)] group-hover:border-[var(--appkit-color-primary)]"}`, children: image ? (
25
25
  // eslint-disable-next-line @next/next/no-img-element
@@ -4,7 +4,7 @@ import { DatabaseError } from "../../../errors";
4
4
  import { BaseRepository, prepareForFirestore, } from "../../../providers/db-firebase";
5
5
  import { cacheManager } from "../../../core";
6
6
  import { generateUniqueId, slugify, buildSearchTokens, tokenizeQuery, generateBarcodeId } from "../../../utils";
7
- import { PRODUCT_COLLECTION, ProductStatusValues, } from "../schemas";
7
+ import { PRODUCT_COLLECTION, ProductStatusValues } from "../schemas";
8
8
  import { PRODUCT_FIELDS } from "../../../constants/field-names";
9
9
  /**
10
10
  * Canonical listing-kind tokens used in `listingType`. Note: the public Sieve
@@ -22,7 +22,7 @@ export declare const productFeatureAdminCreateSchema: z.ZodObject<{
22
22
  isActive: z.ZodBoolean;
23
23
  displayOrder: z.ZodNumber;
24
24
  }, "strip", z.ZodTypeAny, {
25
- category: "custom" | "seller" | "auction" | "condition" | "shipping" | "preorder" | "platform";
25
+ category: "seller" | "custom" | "auction" | "condition" | "shipping" | "preorder" | "platform";
26
26
  label: string;
27
27
  scope: "store" | "platform";
28
28
  icon: string;
@@ -33,7 +33,7 @@ export declare const productFeatureAdminCreateSchema: z.ZodObject<{
33
33
  description?: string | undefined;
34
34
  iconColor?: string | undefined;
35
35
  }, {
36
- category: "custom" | "seller" | "auction" | "condition" | "shipping" | "preorder" | "platform";
36
+ category: "seller" | "custom" | "auction" | "condition" | "shipping" | "preorder" | "platform";
37
37
  label: string;
38
38
  scope: "store" | "platform";
39
39
  icon: string;
@@ -55,7 +55,7 @@ export declare const productFeatureStoreCreateSchema: z.ZodObject<{
55
55
  isActive: z.ZodBoolean;
56
56
  displayOrder: z.ZodNumber;
57
57
  }, "strip", z.ZodTypeAny, {
58
- category: "custom" | "seller" | "auction" | "condition" | "shipping" | "preorder" | "platform";
58
+ category: "seller" | "custom" | "auction" | "condition" | "shipping" | "preorder" | "platform";
59
59
  label: string;
60
60
  icon: string;
61
61
  isActive: boolean;
@@ -64,7 +64,7 @@ export declare const productFeatureStoreCreateSchema: z.ZodObject<{
64
64
  description?: string | undefined;
65
65
  iconColor?: string | undefined;
66
66
  }, {
67
- category: "custom" | "seller" | "auction" | "condition" | "shipping" | "preorder" | "platform";
67
+ category: "seller" | "custom" | "auction" | "condition" | "shipping" | "preorder" | "platform";
68
68
  label: string;
69
69
  icon: string;
70
70
  isActive: boolean;
@@ -84,7 +84,7 @@ export declare const productFeatureUpdateSchema: z.ZodObject<{
84
84
  isActive: z.ZodOptional<z.ZodBoolean>;
85
85
  displayOrder: z.ZodOptional<z.ZodNumber>;
86
86
  }, "strip", z.ZodTypeAny, {
87
- category?: "custom" | "seller" | "auction" | "condition" | "shipping" | "preorder" | "platform" | undefined;
87
+ category?: "seller" | "custom" | "auction" | "condition" | "shipping" | "preorder" | "platform" | undefined;
88
88
  description?: string | undefined;
89
89
  label?: string | undefined;
90
90
  icon?: string | undefined;
@@ -93,7 +93,7 @@ export declare const productFeatureUpdateSchema: z.ZodObject<{
93
93
  iconColor?: string | undefined;
94
94
  productTypes?: ("auction" | "prize-draw" | "classified" | "digital-code" | "live" | "all" | "product" | "preorder")[] | undefined;
95
95
  }, {
96
- category?: "custom" | "seller" | "auction" | "condition" | "shipping" | "preorder" | "platform" | undefined;
96
+ category?: "seller" | "custom" | "auction" | "condition" | "shipping" | "preorder" | "platform" | undefined;
97
97
  description?: string | undefined;
98
98
  label?: string | undefined;
99
99
  icon?: string | undefined;
@@ -7,7 +7,7 @@
7
7
  */
8
8
  import { BaseRepository, prepareForFirestore, } from "../../../providers/db-firebase";
9
9
  import { normalizeError } from "../../../errors/normalize";
10
- import { CLAIMED_COUPONS_COLLECTION, createClaimedCouponId, } from "../schemas";
10
+ import { CLAIMED_COUPONS_COLLECTION, createClaimedCouponId } from "../schemas";
11
11
  import { DatabaseError } from "../../../errors";
12
12
  import { COUPON_USAGE_FIELDS } from "../../../constants/field-names";
13
13
  export class ClaimedCouponsRepository extends BaseRepository {
@@ -1,4 +1,4 @@
1
- import { buildColumns, } from "../../../ui/columns";
1
+ import { buildColumns } from "../../../ui/columns";
2
2
  /**
3
3
  * Default admin column definitions for a review table.
4
4
  *
@@ -28,5 +28,5 @@ export function ScamAwarenessModal({ isOpen, onAcknowledged }) {
28
28
  onAcknowledged();
29
29
  },
30
30
  });
31
- return (_jsx(Modal, { isOpen: isOpen, onClose: () => { }, showCloseButton: false, size: "lg", title: _jsxs(Row, { gap: "sm", align: "center", children: [_jsx(Shield, { className: "h-5 w-5 text-[color:var(--appkit-color-warning,theme(colors.amber.500))]" }), _jsx(Span, { children: "Before you start \u2014 Stay Safe on LetItRip" })] }), actions: _jsx(Row, { gap: "sm", justify: "end", className: "w-full", children: _jsx("button", { className: "appkit-button appkit-button--primary appkit-button--md", disabled: !checked || mutation.isPending, onClick: () => mutation.mutate(), children: mutation.isPending ? "Saving…" : "Continue to LetItRip →" }) }), children: _jsxs(Stack, { gap: "md", children: [_jsx(Text, { variant: "secondary", size: "sm", children: "LetItRip connects you with verified sellers, but collectibles markets attract scams. Take 60 seconds to learn the most common patterns \u2014 it could save your money." }), _jsx(Div, { layout: "grid", gap: "3", className: "grid-cols-1 sm:grid-cols-2", children: SCAM_CATEGORIES.map((cat) => (_jsxs("div", { className: "flex gap-3 rounded-lg border border-[color:var(--appkit-color-border,theme(colors.zinc.200))] bg-[color:var(--appkit-color-surface,theme(colors.zinc.50))] p-3", children: [_jsx(Span, { layout: "flex-center", className: "mt-0.5 h-8 w-8 shrink-0 bg-[color:var(--appkit-color-warning,theme(colors.amber.500))]/10 text-[color:var(--appkit-color-warning,theme(colors.amber.600))]", rounded: "md", children: CATEGORY_ICONS[cat.id] ?? _jsx(Shield, { className: "h-4 w-4" }) }), _jsxs(Stack, { gap: "none", children: [_jsx(Text, { weight: "semibold", size: "sm", children: cat.label }), _jsx(Text, { variant: "secondary", className: "leading-relaxed", size: "xs", children: cat.description })] })] }, cat.id))) }), _jsxs(Row, { textSize: "sm", gap: "md", wrap: true, children: [_jsx("a", { href: String(ROUTES.PUBLIC.SCAM_TYPES), target: "_blank", rel: "noopener noreferrer", className: "text-[color:var(--appkit-color-primary,theme(colors.blue.600))] hover:underline", children: "See all 27 scam types \u2192" }), _jsx("a", { href: String(ROUTES.PUBLIC.SCAM_FAQS), target: "_blank", rel: "noopener noreferrer", className: "text-[color:var(--appkit-color-primary,theme(colors.blue.600))] hover:underline", children: "Common scam FAQs \u2192" })] }), mutation.isError && (_jsx(Text, { variant: "error", size: "sm", children: "Something went wrong \u2014 please try again." })), _jsx(Checkbox, { id: "scam-awareness-ack", checked: checked, onChange: (e) => setChecked(e.target.checked), label: "I have read the above and understand the risks of buying and selling collectibles online." })] }) }));
31
+ return (_jsx(Modal, { isOpen: isOpen, onClose: () => { }, showCloseButton: false, size: "lg", title: _jsxs(Row, { gap: "sm", align: "center", children: [_jsx(Shield, { className: "h-5 w-5 text-[color:var(--appkit-color-warning,theme(colors.amber.500))]" }), _jsx(Span, { children: "Before you start \u2014 Stay Safe on LetItRip" })] }), actions: _jsx(Row, { gap: "sm", justify: "end", className: "w-full", children: _jsx("button", { className: "appkit-button appkit-button--primary appkit-button--md", disabled: !checked || mutation.isPending, onClick: () => mutation.mutate(), children: mutation.isPending ? "Saving…" : "Continue to LetItRip →" }) }), children: _jsxs(Stack, { gap: "md", children: [_jsx(Text, { variant: "secondary", size: "sm", children: "LetItRip connects you with verified sellers, but collectibles markets attract scams. Take 60 seconds to learn the most common patterns \u2014 it could save your money." }), _jsx(Div, { layout: "grid", gap: "3", className: "grid-cols-1 sm:grid-cols-2", children: SCAM_CATEGORIES.map((cat) => (_jsxs(Div, { className: "flex gap-3 rounded-lg border border-[color:var(--appkit-color-border,theme(colors.zinc.200))] bg-[color:var(--appkit-color-surface,theme(colors.zinc.50))] p-3", children: [_jsx(Span, { layout: "flex-center", className: "mt-0.5 h-8 w-8 shrink-0 bg-[color:var(--appkit-color-warning,theme(colors.amber.500))]/10 text-[color:var(--appkit-color-warning,theme(colors.amber.600))]", rounded: "md", children: CATEGORY_ICONS[cat.id] ?? _jsx(Shield, { className: "h-4 w-4" }) }), _jsxs(Stack, { gap: "none", children: [_jsx(Text, { weight: "semibold", size: "sm", children: cat.label }), _jsx(Text, { variant: "secondary", className: "leading-relaxed", size: "xs", children: cat.description })] })] }, cat.id))) }), _jsxs(Row, { textSize: "sm", gap: "md", wrap: true, children: [_jsx("a", { href: String(ROUTES.PUBLIC.SCAM_TYPES), target: "_blank", rel: "noopener noreferrer", className: "text-[color:var(--appkit-color-primary,theme(colors.blue.600))] hover:underline", children: "See all 27 scam types \u2192" }), _jsx("a", { href: String(ROUTES.PUBLIC.SCAM_FAQS), target: "_blank", rel: "noopener noreferrer", className: "text-[color:var(--appkit-color-primary,theme(colors.blue.600))] hover:underline", children: "Common scam FAQs \u2192" })] }), mutation.isError && (_jsx(Text, { variant: "error", size: "sm", children: "Something went wrong \u2014 please try again." })), _jsx(Checkbox, { id: "scam-awareness-ack", checked: checked, onChange: (e) => setChecked(e.target.checked), label: "I have read the above and understand the risks of buying and selling collectibles online." })] }) }));
32
32
  }
@@ -216,7 +216,7 @@ export function Search({ isOpen, onClose, onSearch, onOpen, value, onChange, pla
216
216
  if (inlineBlurRef.current)
217
217
  clearTimeout(inlineBlurRef.current);
218
218
  inlineBlurRef.current = setTimeout(() => setIsInlineOpen(false), 120);
219
- }, placeholder: placeholder ?? labels.placeholder, className: "w-full rounded-lg border border-zinc-300 bg-[var(--appkit-color-surface)] pl-9 text-zinc-900 placeholder:text-zinc-400 focus:border-primary focus:ring-2 focus:ring-primary/20 border-[var(--appkit-color-border)] bg-[var(--appkit-color-surface)] dark:text-white dark:placeholder:text-slate-500" }), query && (_jsx(Button, { rounded: "full", textColor: "faint", type: "button", variant: "ghost", onClick: handleClear, className: "absolute right-3 p-[0.125rem] hover:text-[var(--appkit-color-text-muted)] dark:hover:text-[var(--appkit-color-text)] transition-colors", "aria-label": labels.clearAriaLabel, children: _jsx("svg", { className: "w-4 h-4", "aria-hidden": "true", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) }) }))] }), resourceTypes && resourceTypes.length > 0 && (_jsx("select", { value: selectedType, onChange: (e) => handleTypeChange(e.target.value), "aria-label": labels.resourceTypeLabel ?? "Search in", className: "flex-shrink-0 rounded-lg border border-zinc-300 bg-white px-2 py-2 text-sm text-zinc-700 focus:border-primary focus:outline-none focus:ring-2 focus:ring-primary/20 border-[var(--appkit-color-border)] bg-[var(--appkit-color-surface)] text-[var(--appkit-color-text-muted)] cursor-pointer", children: resourceTypes.map((opt) => (_jsx("option", { value: opt.value, children: opt.label }, opt.value))) })), deferred && (_jsx(Button, { rounded: "lg", paddingX: "sm", paddingY: "sm", type: "button", variant: "primary", onClick: handleDeferredSubmit, "aria-label": labels.ariaLabel, className: "flex-shrink-0", children: _jsx("svg", { className: "w-4 h-4", "aria-hidden": "true", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: SVG_PATH_SEARCH }) }) })), isInlineOpen && (filteredQuickLinks.length > 0 || query) && (_jsxs("div", { className: "absolute top-full left-0 right-0 mt-2 rounded-xl overflow-hidden border border-zinc-200 bg-[var(--appkit-color-surface)] shadow-lg border-[var(--appkit-color-border)] bg-[var(--appkit-color-surface)] [z-index:var(--appkit-z-dropdown)]", onMouseDown: (event) => event.preventDefault(), children: [filteredQuickLinks.length > 0 && (_jsx(Ul, { children: filteredQuickLinks.map((link, index) => renderInlineQuickLink(link, index)) })), query && suggestionsLoading && (_jsx(Div, { padding: "inline", children: _jsx(Text, { variant: "secondary", size: "sm", children: labels.searching }) })), query &&
219
+ }, placeholder: placeholder ?? labels.placeholder, className: "w-full rounded-lg border border-zinc-300 bg-[var(--appkit-color-surface)] pl-9 text-zinc-900 placeholder:text-zinc-400 focus:border-primary focus:ring-2 focus:ring-primary/20 border-[var(--appkit-color-border)] bg-[var(--appkit-color-surface)] dark:text-white dark:placeholder:text-slate-500" }), query && (_jsx(Button, { rounded: "full", textColor: "faint", type: "button", variant: "ghost", onClick: handleClear, className: "absolute right-3 p-[0.125rem] hover:text-[var(--appkit-color-text-muted)] dark:hover:text-[var(--appkit-color-text)] transition-colors", "aria-label": labels.clearAriaLabel, children: _jsx("svg", { className: "w-4 h-4", "aria-hidden": "true", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) }) }))] }), resourceTypes && resourceTypes.length > 0 && (_jsx("select", { value: selectedType, onChange: (e) => handleTypeChange(e.target.value), "aria-label": labels.resourceTypeLabel ?? "Search in", className: "flex-shrink-0 rounded-lg border border-zinc-300 bg-white px-2 py-2 text-sm text-zinc-700 focus:border-primary focus:outline-none focus:ring-2 focus:ring-primary/20 border-[var(--appkit-color-border)] bg-[var(--appkit-color-surface)] text-[var(--appkit-color-text-muted)] cursor-pointer", children: resourceTypes.map((opt) => (_jsx("option", { value: opt.value, children: opt.label }, opt.value))) })), deferred && (_jsx(Button, { rounded: "lg", paddingX: "sm", paddingY: "sm", type: "button", variant: "primary", onClick: handleDeferredSubmit, "aria-label": labels.ariaLabel, className: "flex-shrink-0", children: _jsx("svg", { className: "w-4 h-4", "aria-hidden": "true", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: SVG_PATH_SEARCH }) }) })), isInlineOpen && (filteredQuickLinks.length > 0 || query) && (_jsxs(Div, { className: "absolute top-full left-0 right-0 mt-2 rounded-xl overflow-hidden border border-zinc-200 bg-[var(--appkit-color-surface)] shadow-lg border-[var(--appkit-color-border)] bg-[var(--appkit-color-surface)] [z-index:var(--appkit-z-dropdown)]", onMouseDown: (event) => event.preventDefault(), children: [filteredQuickLinks.length > 0 && (_jsx(Ul, { children: filteredQuickLinks.map((link, index) => renderInlineQuickLink(link, index)) })), query && suggestionsLoading && (_jsx(Div, { padding: "inline", children: _jsx(Text, { variant: "secondary", size: "sm", children: labels.searching }) })), query &&
220
220
  suggestions.slice(0, 5).map((suggestion, suggestionIndex) => {
221
221
  const itemIndex = inlineQuickLinkItems.length + suggestionIndex;
222
222
  const isActive = activeIndex === itemIndex;
@@ -24,8 +24,8 @@ export declare const searchProductItemSchema: z.ZodObject<{
24
24
  title: string;
25
25
  slug: string;
26
26
  id: string;
27
- status?: string | undefined;
28
27
  currency?: string | undefined;
28
+ status?: string | undefined;
29
29
  featured?: boolean | undefined;
30
30
  listingType?: "standard" | "auction" | "pre-order" | "prize-draw" | "bundle" | undefined;
31
31
  isPromoted?: boolean | undefined;
@@ -35,8 +35,8 @@ export declare const searchProductItemSchema: z.ZodObject<{
35
35
  title: string;
36
36
  slug: string;
37
37
  id: string;
38
- status?: string | undefined;
39
38
  currency?: string | undefined;
39
+ status?: string | undefined;
40
40
  featured?: boolean | undefined;
41
41
  listingType?: "standard" | "auction" | "pre-order" | "prize-draw" | "bundle" | undefined;
42
42
  isPromoted?: boolean | undefined;
@@ -9,7 +9,7 @@
9
9
  * (src/actions/seller.actions.ts) alongside the other seller server actions.
10
10
  */
11
11
  import type { JsonValue } from "../../../schemas/types";
12
- import type { SellerPayoutDetails, SellerShippingConfig } from "../../auth/schemas/firestore";
12
+ import type { SellerPayoutDetails } from "../../auth/schemas/firestore";
13
13
  import type { StoreDocument } from "../../stores/schemas/firestore";
14
14
  import type { ProductDocument } from "../../products/schemas/firestore";
15
15
  import type { OrderDocument } from "../../orders/schemas/firestore";
@@ -115,7 +115,7 @@ export declare function requestPayout(userId: string, userName: string, userEmai
115
115
  export declare function bulkSellerOrder(userId: string, userRole: string, userDisplayName: string, userEmail: string, orderIds: string[]): Promise<BulkSellerOrderResult>;
116
116
  export declare function createSellerProduct(userId: string, userName: string, userEmail: string, input: Record<string, JsonValue>): Promise<void>;
117
117
  export declare function getSellerStore(userId: string): Promise<StoreDocument | null>;
118
- export declare function getSellerShipping(userId: string): Promise<SellerShippingConfig | null>;
118
+ export declare function getSellerShipping(userId: string): Promise<import("../../auth").SellerShippingConfig | null>;
119
119
  export declare function getSellerPayoutSettings(userId: string): Promise<SellerPayoutDetails | {
120
120
  method: string;
121
121
  isConfigured: boolean;
@@ -71,7 +71,7 @@ export function SellerCouponEditorView({ couponId, initial, onSave, onCancel, })
71
71
  }
72
72
  };
73
73
  const isEdit = Boolean(couponId);
74
- return (_jsx(Form, { onSubmit: handleSubmit, noValidate: true, children: _jsxs(Stack, { gap: "none", className: `max-w-lg mx-auto border border-[var(--appkit-color-border)] bg-[var(--appkit-color-surface)] ${__O.hidden}`, rounded: "xl", shadow: "sm", children: [_jsx("div", { className: "h-[3px] w-full [background:linear-gradient(to_right,var(--appkit-color-primary-700)_0%,var(--appkit-color-cobalt)_55%,var(--appkit-color-secondary-400)_100%)]", "aria-hidden": "true" }), _jsx(Div, { border: "bottom", paddingY: "y-md-lg", padding: "x-lg", children: _jsxs(Row, { justify: "between", gap: "3", children: [_jsx(Heading, { level: 2, className: "text-[var(--appkit-color-text)]", size: "lg", weight: "semibold", children: isEdit ? "Edit Coupon" : "Create Coupon" }), isEdit && (_jsx(Badge, { variant: draft.isActive ? "success" : "default", children: draft.isActive ? "Active" : "Inactive" }))] }) }), _jsxs(Stack, { gap: "5", padding: "lg", children: [error && (_jsx(Div, { textSize: "sm", className: "border border-error/20", color: "error", surface: "danger-surface", padding: "inline", rounded: "lg", children: error })), _jsx(Input, { label: "Coupon Code", value: draft.code, onChange: (e) => set("code", e.target.value.toUpperCase().replace(/\s+/g, "")), placeholder: "e.g. WELCOME10", required: true, disabled: isEdit, helperText: isEdit ? "Code cannot be changed after creation" : "Customers enter this at checkout" }), _jsx(Select, { label: "Discount Type", value: draft.type, options: TYPE_OPTIONS, onChange: (e) => set("type", e.target.value) }), draft.type !== "free_shipping" && (_jsx(Input, { label: draft.type === "percentage" ? "Discount Percentage (%)" : "Discount Amount (₹)", type: "number", min: 1, max: draft.type === "percentage" ? 100 : undefined, value: draft.value, onChange: (e) => set("value", e.target.value), placeholder: draft.type === "percentage" ? "e.g. 10" : "e.g. 50", required: true, helperText: draft.type === "percentage"
74
+ return (_jsx(Form, { onSubmit: handleSubmit, noValidate: true, children: _jsxs(Stack, { gap: "none", className: `max-w-lg mx-auto border border-[var(--appkit-color-border)] bg-[var(--appkit-color-surface)] ${__O.hidden}`, rounded: "xl", shadow: "sm", children: [_jsx(Div, { className: "h-[3px] w-full [background:linear-gradient(to_right,var(--appkit-color-primary-700)_0%,var(--appkit-color-cobalt)_55%,var(--appkit-color-secondary-400)_100%)]", "aria-hidden": "true" }), _jsx(Div, { border: "bottom", paddingY: "y-md-lg", padding: "x-lg", children: _jsxs(Row, { justify: "between", gap: "3", children: [_jsx(Heading, { level: 2, className: "text-[var(--appkit-color-text)]", size: "lg", weight: "semibold", children: isEdit ? "Edit Coupon" : "Create Coupon" }), isEdit && (_jsx(Badge, { variant: draft.isActive ? "success" : "default", children: draft.isActive ? "Active" : "Inactive" }))] }) }), _jsxs(Stack, { gap: "5", padding: "lg", children: [error && (_jsx(Div, { textSize: "sm", className: "border border-error/20", color: "error", surface: "danger-surface", padding: "inline", rounded: "lg", children: error })), _jsx(Input, { label: "Coupon Code", value: draft.code, onChange: (e) => set("code", e.target.value.toUpperCase().replace(/\s+/g, "")), placeholder: "e.g. WELCOME10", required: true, disabled: isEdit, helperText: isEdit ? "Code cannot be changed after creation" : "Customers enter this at checkout" }), _jsx(Select, { label: "Discount Type", value: draft.type, options: TYPE_OPTIONS, onChange: (e) => set("type", e.target.value) }), draft.type !== "free_shipping" && (_jsx(Input, { label: draft.type === "percentage" ? "Discount Percentage (%)" : "Discount Amount (₹)", type: "number", min: 1, max: draft.type === "percentage" ? 100 : undefined, value: draft.value, onChange: (e) => set("value", e.target.value), placeholder: draft.type === "percentage" ? "e.g. 10" : "e.g. 50", required: true, helperText: draft.type === "percentage"
75
75
  ? "Enter a value between 1 and 100"
76
76
  : "Fixed rupee discount applied to the order" })), draft.type === "percentage" && (_jsx(Input, { label: "Max Discount Cap (\u20B9, optional)", type: "number", min: 0, value: draft.maxDiscount, onChange: (e) => set("maxDiscount", e.target.value), placeholder: "Leave blank for no cap", helperText: "Maximum rupee discount regardless of percentage" })), _jsx(Input, { label: "Minimum Order Amount (\u20B9, optional)", type: "number", min: 0, value: draft.minPurchase, onChange: (e) => set("minPurchase", e.target.value), placeholder: "Leave blank for no minimum" }), _jsxs(Div, { children: [_jsx(Text, { size: "sm", className: CLS_SECTION_LABEL, children: "Usage Limits" }), _jsxs(Div, { layout: "grid", gap: "3", className: "grid-cols-2", children: [_jsx(Input, { label: "Total Uses", type: "number", min: 0, value: draft.totalLimit, onChange: (e) => set("totalLimit", e.target.value), placeholder: "0 = unlimited" }), _jsx(Input, { label: "Per Customer", type: "number", min: 0, value: draft.perUserLimit, onChange: (e) => set("perUserLimit", e.target.value), placeholder: "0 = unlimited" })] })] }), _jsxs(Div, { children: [_jsx(Text, { size: "sm", className: CLS_SECTION_LABEL, children: "Validity Period" }), _jsxs(Div, { layout: "grid", gap: "3", className: "grid-cols-2", children: [_jsx(Input, { label: "Start Date", type: "date", value: draft.startDate, onChange: (e) => set("startDate", e.target.value), required: true }), _jsx(Input, { label: "End Date", type: "date", value: draft.endDate, onChange: (e) => set("endDate", e.target.value), required: true })] })] }), _jsxs(Div, { children: [_jsx(Text, { size: "sm", className: CLS_SECTION_LABEL, children: "Applicability (optional)" }), _jsxs(Stack, { gap: "sm", children: [_jsxs(Div, { children: [_jsx(Text, { size: "xs", className: "mb-1 text-[var(--appkit-color-text-secondary)]", children: "Applicable products" }), _jsx(ProductInlineSelect, { scope: "store", multiple: true, value: draft.applicableProducts, onChange: (v) => set("applicableProducts", v), placeholder: "Restrict to specific products\u2026" })] }), _jsxs(Div, { children: [_jsx(Text, { size: "xs", className: "mb-1 text-[var(--appkit-color-text-secondary)]", children: "Applicable categories" }), _jsx(CategoryInlineSelect, { value: "", onChange: (id) => {
77
77
  if (!id || draft.applicableCategories.includes(id))
@@ -92,7 +92,7 @@ export function SellerGoogleReviewsView({ onSave, onSync, }) {
92
92
  }
93
93
  }, [onSync, showToast]);
94
94
  if (loading) {
95
- return (_jsx(Stack, { gap: "md", paddingY: "y-lg", paddingX: "x-md", children: Array.from({ length: 3 }).map((_, i) => (_jsx("div", { className: "h-12 animate-pulse rounded-xl border border-zinc-100 border-[var(--appkit-color-border)] bg-zinc-50 bg-[var(--appkit-color-surface-elevated)]" }, i))) }));
95
+ return (_jsx(Stack, { gap: "md", paddingY: "y-lg", paddingX: "x-md", children: Array.from({ length: 3 }).map((_, i) => (_jsx(Div, { className: "h-12 animate-pulse rounded-xl border border-zinc-100 border-[var(--appkit-color-border)] bg-zinc-50 bg-[var(--appkit-color-surface-elevated)]" }, i))) }));
96
96
  }
97
97
  const formattedLastSync = draft.lastSyncedAt
98
98
  ? new Date(draft.lastSyncedAt).toLocaleString("en-IN", {
@@ -358,9 +358,12 @@ export function SellerOrdersView({ orderDetailApiBase = SELLER_ENDPOINTS.ORDERS,
358
358
  buildBulkAction(ACTIONS.STORE["set-location"], () => setSetLocationOpen(true), { icon: _jsx(MapPin, { className: "w-4 h-4" }) }),
359
359
  buildBulkAction(ACTIONS.STORE["request-payout"], () => void requestPayoutForSelection(), { variant: "primary" }),
360
360
  ];
361
+ // useBottomActions must run unconditionally on every render — it was
362
+ // previously called after the `hasChildren` early return below, which
363
+ // skips the hook call in passthrough mode, violating the Rules of Hooks.
364
+ useBottomActions(selection.selectedCount > 0 ? { bulk: { selectedCount: selection.selectedCount, onClearSelection: selection.clearSelection, actions: bulkActions } } : {});
361
365
  if (hasChildren) {
362
366
  return _jsx(ListingLayout, { portal: "seller", ...props, children: children });
363
367
  }
364
- useBottomActions(selection.selectedCount > 0 ? { bulk: { selectedCount: selection.selectedCount, onClearSelection: selection.clearSelection, actions: bulkActions } } : {});
365
368
  return (_jsxs(Div, { className: "min-h-screen", children: [_jsx(ListingToolbar, { filterCount: activeFilterCount, onFiltersClick: openFilters, searchValue: searchInput, searchPlaceholder: "Search by order ID or buyer name", onSearchChange: setSearchInput, onSearchCommit: commitSearch, sortValue: table.get("sort") || DEFAULT_SORT, sortOptions: SORT_OPTIONS, onSortChange: (v) => { table.set("sort", v); }, showTableView: true, view: view, onViewChange: (v) => setView(v), onResetAll: resetAll, hasActiveState: hasActiveState }), totalPages > 1 && (_jsx(Row, { border: "bottom", className: "sticky top-[calc(var(--header-height,0px)+44px)] z-10 backdrop-blur-sm", surface: "default", padding: "toolbar", justify: "center", children: _jsx(Pagination, { currentPage: currentPage, totalPages: totalPages, onPageChange: (p) => table.setPage(p) }) })), selection.selectedIds.length > 0 && (_jsx(Div, { border: "default", paddingX: "x-sm-md", className: "sticky top-[calc(var(--header-height,0px)+88px)] z-20 backdrop-blur-sm border-b", surface: "default", padding: "y-xs", children: _jsx(BulkActionBar, { selectedCount: selection.selectedIds.length, onClearSelection: selection.clearSelection, actions: bulkActions }) })), _jsxs(Div, { paddingX: "x-sm-md", padding: "y-md", children: [errorMessage && (_jsx(Div, { textSize: "sm", className: "mb-4 border border-error/20", color: "error", surface: "danger-surface", padding: "inline", rounded: "xl", children: errorMessage })), _jsx(DataTable, { rows: rows, columns: columns, isLoading: isLoading, emptyLabel: "No orders yet", selectedIds: selection.selectedIdSet, onToggleSelect: selection.toggle, onToggleSelectAll: () => selection.toggleAll(), renderRowActions: renderRowActions })] }), _jsx(ListingFilterDrawer, { open: filterOpen, onClose: () => setFilterOpen(false), onApply: applyFilters, onClear: clearFilters, activeCount: activeFilterCount, children: _jsx(FilterChipGroup, { label: "Status", tabs: STATUS_OPTIONS, value: pendingFilters.status ?? "", onChange: (id) => setPendingFilters((p) => ({ ...p, status: id })) }) }), selectedOrderId && (_jsx(OrderDetailDrawer, { orderId: selectedOrderId, apiBase: orderDetailApiBase, onClose: () => setSelectedOrderId(null) })), setLocationOpen && (_jsx(PhysicalLocationModal, { count: selection.selectedIds.length, onSave: handleSetLocation, onClose: () => setSetLocationOpen(false) }))] }));
366
369
  }