@mohasinac/appkit 2.7.34 → 2.7.35

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.
@@ -620,6 +620,54 @@ export const ACTIONS = {
620
620
  description: "Submit the order with the chosen payment method.",
621
621
  kind: "primary",
622
622
  },
623
+ "continue-to-verification": {
624
+ id: "checkout.continue-to-verification",
625
+ label: "Continue to Verification",
626
+ description: "Advance from address selection to identity verification step.",
627
+ kind: "primary",
628
+ },
629
+ "send-otp": {
630
+ id: "checkout.send-otp",
631
+ label: "Send verification code",
632
+ description: "Send a one-time code to the buyer's registered email to verify identity before checkout.",
633
+ kind: "primary",
634
+ },
635
+ "verify-otp": {
636
+ id: "checkout.verify-otp",
637
+ label: "Verify & Continue",
638
+ description: "Submit the one-time code and proceed to payment selection.",
639
+ kind: "primary",
640
+ },
641
+ "resend-otp": {
642
+ id: "checkout.resend-otp",
643
+ label: "Resend code",
644
+ description: "Re-send the verification code to the buyer's registered email.",
645
+ kind: "ghost",
646
+ },
647
+ "pay-online": {
648
+ id: "checkout.pay-online",
649
+ label: "Pay Online (Razorpay)",
650
+ description: "Initiate an online payment via Razorpay UPI/Card/NetBanking.",
651
+ kind: "primary",
652
+ },
653
+ "pay-cod": {
654
+ id: "checkout.pay-cod",
655
+ label: "Cash on Delivery",
656
+ description: "Place the order for cash-on-delivery payment.",
657
+ kind: "secondary",
658
+ },
659
+ "admin-bypass": {
660
+ id: "checkout.admin-bypass",
661
+ label: "Skip Verification — Admin Bypass",
662
+ description: "Admin test mode: skip identity verification and place a test order without payment.",
663
+ kind: "secondary",
664
+ },
665
+ "admin-bypass-payment": {
666
+ id: "checkout.admin-bypass-payment",
667
+ label: "No Payment — Admin Bypass Order",
668
+ description: "Admin test mode: place a real order record without charging any payment.",
669
+ kind: "secondary",
670
+ },
623
671
  },
624
672
  NAV: {
625
673
  "sign-in": {
package/dist/client.d.ts CHANGED
@@ -53,6 +53,10 @@ export { Badge } from "./ui/components/Badge";
53
53
  export { Button } from "./ui/components/Button";
54
54
  export { Checkbox } from "./ui/components/Checkbox";
55
55
  export { Input } from "./ui/components/Input";
56
+ export { OtpInput } from "./ui/components/OtpInput";
57
+ export type { OtpInputProps } from "./ui/components/OtpInput";
58
+ export { DateInput, DateRangeInput } from "./ui/components/DateInput";
59
+ export type { DateInputProps, DateRangeInputProps } from "./ui/components/DateInput";
56
60
  export { Select } from "./ui/components/Select";
57
61
  export type { SelectOption, SelectProps } from "./ui/components/Select";
58
62
  export { Heading } from "./ui/components/Typography";
package/dist/client.js CHANGED
@@ -121,6 +121,8 @@ export { Badge } from "./ui/components/Badge";
121
121
  export { Button } from "./ui/components/Button";
122
122
  export { Checkbox } from "./ui/components/Checkbox";
123
123
  export { Input } from "./ui/components/Input";
124
+ export { OtpInput } from "./ui/components/OtpInput";
125
+ export { DateInput, DateRangeInput } from "./ui/components/DateInput";
124
126
  export { Select } from "./ui/components/Select";
125
127
  export { Heading } from "./ui/components/Typography";
126
128
  export { Label, Text } from "./ui/components/Typography";
@@ -7,5 +7,8 @@ export interface FeaturedAuctionsSectionProps {
7
7
  className?: string;
8
8
  filterByBrand?: string;
9
9
  initialItems?: ProductItem[];
10
+ rows?: number;
11
+ autoScroll?: boolean;
12
+ scrollInterval?: number;
10
13
  }
11
- export declare function FeaturedAuctionsSection({ title, description, viewMoreHref, viewMoreLabel, className, filterByBrand, initialItems, }: FeaturedAuctionsSectionProps): import("react/jsx-runtime").JSX.Element;
14
+ export declare function FeaturedAuctionsSection({ title, description, viewMoreHref, viewMoreLabel, className, filterByBrand, initialItems, rows, autoScroll, scrollInterval, }: FeaturedAuctionsSectionProps): import("react/jsx-runtime").JSX.Element;
@@ -4,7 +4,7 @@ import { THEME_CONSTANTS } from "../../../tokens";
4
4
  import { SectionCarousel } from "./SectionCarousel";
5
5
  import { useFeaturedAuctions } from "../hooks/useFeaturedAuctions";
6
6
  import { MarketplaceAuctionCard } from "../../auctions/components/MarketplaceAuctionCard";
7
- export function FeaturedAuctionsSection({ title = "Live Auctions", description, viewMoreHref, viewMoreLabel = "View all auctions →", className = "", filterByBrand, initialItems, }) {
7
+ export function FeaturedAuctionsSection({ title = "Live Auctions", description, viewMoreHref, viewMoreLabel = "View all auctions →", className = "", filterByBrand, initialItems, rows = 1, autoScroll = false, scrollInterval = 5000, }) {
8
8
  const { data: items = [], isLoading } = useFeaturedAuctions({ filterByBrand, initialData: initialItems });
9
- return (_jsx(SectionCarousel, { title: title, description: description, pillLabel: "Live Auctions", headingVariant: "editorial", viewMoreHref: viewMoreHref, viewMoreLabel: viewMoreLabel, items: items, isLoading: isLoading, skeletonCount: 4, perView: THEME_CONSTANTS.carousel.perView.standard, gap: 16, keyExtractor: (product) => product.id, renderItem: (product) => (_jsx(MarketplaceAuctionCard, { product: product })), className: className }));
9
+ return (_jsx(SectionCarousel, { title: title, description: description, pillLabel: "Live Auctions", headingVariant: "editorial", viewMoreHref: viewMoreHref, viewMoreLabel: viewMoreLabel, items: items, isLoading: isLoading, skeletonCount: 4, perView: THEME_CONSTANTS.carousel.perView.standard, gap: 16, rows: Math.min(Math.max(rows, 1), 4), autoScroll: autoScroll, autoScrollInterval: scrollInterval, keyExtractor: (product) => product.id, renderItem: (product) => (_jsx(MarketplaceAuctionCard, { product: product })), className: className }));
10
10
  }
@@ -7,5 +7,8 @@ export interface FeaturedPreOrdersSectionProps {
7
7
  className?: string;
8
8
  filterByBrand?: string;
9
9
  initialItems?: ProductItem[];
10
+ rows?: number;
11
+ autoScroll?: boolean;
12
+ scrollInterval?: number;
10
13
  }
11
- export declare function FeaturedPreOrdersSection({ title, description, viewMoreHref, viewMoreLabel, className, filterByBrand, initialItems, }: FeaturedPreOrdersSectionProps): import("react/jsx-runtime").JSX.Element;
14
+ export declare function FeaturedPreOrdersSection({ title, description, viewMoreHref, viewMoreLabel, className, filterByBrand, initialItems, rows, autoScroll, scrollInterval, }: FeaturedPreOrdersSectionProps): import("react/jsx-runtime").JSX.Element;
@@ -4,7 +4,7 @@ import { THEME_CONSTANTS } from "../../../tokens";
4
4
  import { SectionCarousel } from "./SectionCarousel";
5
5
  import { useFeaturedPreOrders } from "../hooks/useFeaturedPreOrders";
6
6
  import { MarketplacePreorderCard } from "../../pre-orders/components/MarketplacePreorderCard";
7
- export function FeaturedPreOrdersSection({ title = "Reserve Before It Ships", description, viewMoreHref, viewMoreLabel = "View all pre-orders →", className = "", filterByBrand, initialItems, }) {
7
+ export function FeaturedPreOrdersSection({ title = "Reserve Before It Ships", description, viewMoreHref, viewMoreLabel = "View all pre-orders →", className = "", filterByBrand, initialItems, rows = 1, autoScroll = false, scrollInterval = 5000, }) {
8
8
  const { data: items = [], isLoading } = useFeaturedPreOrders({ filterByBrand, initialData: initialItems });
9
- return (_jsx(SectionCarousel, { title: title, description: description, pillLabel: "Pre-Order Incoming", headingVariant: "editorial", viewMoreHref: viewMoreHref, viewMoreLabel: viewMoreLabel, items: items, isLoading: isLoading, skeletonCount: 4, perView: THEME_CONSTANTS.carousel.perView.standard, gap: 16, keyExtractor: (product) => product.id, renderItem: (product) => (_jsx(MarketplacePreorderCard, { product: product })), className: className }));
9
+ return (_jsx(SectionCarousel, { title: title, description: description, pillLabel: "Pre-Order Incoming", headingVariant: "editorial", viewMoreHref: viewMoreHref, viewMoreLabel: viewMoreLabel, items: items, isLoading: isLoading, skeletonCount: 4, perView: THEME_CONSTANTS.carousel.perView.standard, gap: 16, rows: Math.min(Math.max(rows, 1), 4), autoScroll: autoScroll, autoScrollInterval: scrollInterval, keyExtractor: (product) => product.id, renderItem: (product) => (_jsx(MarketplacePreorderCard, { product: product })), className: className }));
10
10
  }
@@ -1,5 +1,4 @@
1
1
  import type { ProductItem } from "../../products/types";
2
- import type { SectionPagination } from "../schemas/firestore";
3
2
  export interface FeaturedProductsSectionProps {
4
3
  title?: string;
5
4
  description?: string;
@@ -8,11 +7,9 @@ export interface FeaturedProductsSectionProps {
8
7
  className?: string;
9
8
  filterByBrand?: string;
10
9
  initialItems?: ProductItem[];
11
- /** Number of grid rows (1–4). When 1 (default), renders the existing horizontal carousel. */
12
10
  rows?: number;
13
- /** Maximum items to show. Clamped to 5–20. */
14
11
  maxItems?: number;
15
- /** Pagination strategy for rows > 1. */
16
- pagination?: SectionPagination;
12
+ autoScroll?: boolean;
13
+ scrollInterval?: number;
17
14
  }
18
- export declare function FeaturedProductsSection({ title, description, viewMoreHref, viewMoreLabel, className, filterByBrand, initialItems, rows, maxItems, pagination, }: FeaturedProductsSectionProps): import("react/jsx-runtime").JSX.Element | null;
15
+ export declare function FeaturedProductsSection({ title, description, viewMoreHref, viewMoreLabel, className, filterByBrand, initialItems, rows, autoScroll, scrollInterval, }: FeaturedProductsSectionProps): import("react/jsx-runtime").JSX.Element;
@@ -1,48 +1,11 @@
1
1
  "use client";
2
- import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { useState, useEffect, useRef } from "react";
4
- import Link from "next/link";
2
+ import { jsx as _jsx } from "react/jsx-runtime";
5
3
  import { SectionCarousel } from "./SectionCarousel";
6
4
  import { useFeaturedProducts } from "../hooks/useFeaturedProducts";
7
- import { useMediaQuery } from "../../../react";
8
5
  import { InteractiveProductCard } from "../../products/components/InteractiveProductCard";
9
6
  import { ROUTES } from "../../../next";
10
- import { Section, Heading, Text } from "../../../ui";
11
7
  import { THEME_CONSTANTS } from "../../../tokens";
12
- // --- Multi-row grid + pagination -----------------------------------------------
13
- function ProductGrid({ items, rows, maxItems, pagination, viewMoreHref, viewMoreLabel, title, description, }) {
14
- const { themed } = THEME_CONSTANTS;
15
- // On mobile (<sm, 2-col grid) a second row doubles the section height to ~2 screens.
16
- // Collapse to 1 row automatically so the section fits within one viewport.
17
- const isMobile = useMediaQuery("(max-width: 639px)");
18
- const effectiveRows = isMobile ? 1 : rows;
19
- const pageSize = Math.min(effectiveRows * 5, maxItems);
20
- const [offset, setOffset] = useState(0);
21
- const timerRef = useRef(null);
22
- const totalItems = Math.min(items.length, maxItems);
23
- const visible = items.slice(offset, Math.min(offset + pageSize, totalItems));
24
- const canNext = offset + pageSize < totalItems;
25
- const canPrev = offset > 0;
26
- const next = () => setOffset((o) => Math.min(o + pageSize, totalItems - pageSize));
27
- const prev = () => setOffset((o) => Math.max(o - pageSize, 0));
28
- useEffect(() => {
29
- if (pagination !== "auto-scroll")
30
- return;
31
- timerRef.current = setInterval(() => {
32
- setOffset((o) => {
33
- const nextOffset = o + pageSize;
34
- return nextOffset >= totalItems ? 0 : nextOffset;
35
- });
36
- }, 5000);
37
- return () => { if (timerRef.current)
38
- clearInterval(timerRef.current); };
39
- }, [pagination, pageSize, totalItems]);
40
- return (_jsx(Section, { className: `py-12 px-4 ${themed.bgPrimary}`, children: _jsxs("div", { className: "mx-auto max-w-7xl", children: [_jsxs("div", { className: "mb-6 flex items-end justify-between gap-4", children: [_jsxs(_Fragment, { children: [_jsx(Heading, { level: 2, className: `text-2xl font-bold md:text-3xl ${themed.textPrimary}`, children: title }), description && (_jsx(Text, { variant: "muted", className: "mt-1 text-sm", children: description }))] }), pagination === "arrows" && (_jsxs("div", { className: "flex shrink-0 gap-2", children: [_jsx("button", { type: "button", onClick: prev, disabled: !canPrev, "aria-label": "Previous", className: "flex h-9 w-9 items-center justify-center rounded-full border border-zinc-200 bg-white text-zinc-600 hover:border-[var(--appkit-color-primary)] hover:text-[var(--appkit-color-primary)] disabled:opacity-40 dark:border-slate-700 dark:bg-slate-900 dark:text-zinc-300", children: "\u2039" }), _jsx("button", { type: "button", onClick: next, disabled: !canNext, "aria-label": "Next", className: "flex h-9 w-9 items-center justify-center rounded-full border border-zinc-200 bg-white text-zinc-600 hover:border-[var(--appkit-color-primary)] hover:text-[var(--appkit-color-primary)] disabled:opacity-40 dark:border-slate-700 dark:bg-slate-900 dark:text-zinc-300", children: "\u203A" })] }))] }), _jsx("div", { className: "grid grid-cols-2 gap-4 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5", children: visible.map((product) => (_jsx(InteractiveProductCard, { product: product, href: String(ROUTES.PUBLIC.PRODUCT_DETAIL(product.slug ?? product.id ?? "")) }, product.id))) }), pagination === "load-more" && canNext && (_jsx("div", { className: "mt-8 text-center", children: _jsx("button", { type: "button", onClick: next, className: "rounded-lg border border-zinc-300 bg-white px-6 py-2 text-sm font-medium text-zinc-700 hover:border-[var(--appkit-color-primary)] hover:text-[var(--appkit-color-primary)] dark:border-slate-600 dark:bg-slate-900 dark:text-zinc-300", children: "Load more" }) })), viewMoreHref && (_jsx("div", { className: "mt-6 text-center", children: _jsx(Link, { href: viewMoreHref, className: "text-sm font-medium text-[var(--appkit-color-primary)] hover:opacity-80", children: viewMoreLabel }) }))] }) }));
41
- }
42
- // --- Main component -----------------------------------------------------------
43
- export function FeaturedProductsSection({ title = "Featured Products", description, viewMoreHref, viewMoreLabel = "View all products →", className = "", filterByBrand, initialItems, rows = 1, maxItems, pagination = "load-more", }) {
44
- const effectiveRows = Math.min(Math.max(rows, 1), 4);
45
- const effectiveMaxItems = Math.min(Math.max(maxItems ?? effectiveRows * 5, 5), 20);
8
+ export function FeaturedProductsSection({ title = "Featured Products", description, viewMoreHref, viewMoreLabel = "View all products →", className = "", filterByBrand, initialItems, rows = 1, autoScroll = false, scrollInterval = 5000, }) {
46
9
  const { data, isLoading } = useFeaturedProducts({
47
10
  filterByBrand,
48
11
  initialData: initialItems?.length
@@ -50,12 +13,5 @@ export function FeaturedProductsSection({ title = "Featured Products", descripti
50
13
  : undefined,
51
14
  });
52
15
  const items = data?.items ?? [];
53
- // Multi-row mode render grid with pagination
54
- if (effectiveRows > 1) {
55
- if (isLoading)
56
- return null;
57
- return (_jsx(ProductGrid, { items: items, rows: effectiveRows, maxItems: effectiveMaxItems, pagination: pagination, viewMoreHref: viewMoreHref, viewMoreLabel: viewMoreLabel, title: title, description: description }));
58
- }
59
- // Single-row mode — original horizontal carousel (backward-compat)
60
- return (_jsx(SectionCarousel, { title: title, description: description, pillLabel: "Featured Products", headingVariant: "editorial", viewMoreHref: viewMoreHref, viewMoreLabel: viewMoreLabel, items: items, isLoading: isLoading, skeletonCount: 4, gap: 16, keyExtractor: (product) => product.id, renderItem: (product) => (_jsx(InteractiveProductCard, { product: product, href: String(ROUTES.PUBLIC.PRODUCT_DETAIL(product.slug ?? product.id ?? "")) })), className: className }));
16
+ return (_jsx(SectionCarousel, { title: title, description: description, pillLabel: "Featured Products", headingVariant: "editorial", viewMoreHref: viewMoreHref, viewMoreLabel: viewMoreLabel, items: items, isLoading: isLoading, skeletonCount: 4, perView: THEME_CONSTANTS.carousel.perView.standard, gap: 16, rows: Math.min(Math.max(rows, 1), 4), autoScroll: autoScroll, autoScrollInterval: scrollInterval, keyExtractor: (product) => product.id, renderItem: (product) => (_jsx(InteractiveProductCard, { product: product, href: String(ROUTES.PUBLIC.PRODUCT_DETAIL(product.slug ?? product.id ?? "")) })), className: className }));
61
17
  }
@@ -84,15 +84,15 @@ function renderSectionElement(section, newsletterFormSlot, faqItems, slides, liv
84
84
  }
85
85
  case "products": {
86
86
  const cfg = config;
87
- return (_jsx(FeaturedProductsSection, { title: cleanTitle(cfg?.title) || "Featured Products", viewMoreHref: ROUTES.PUBLIC.PRODUCTS, viewMoreLabel: "View all products \u2192", filterByBrand: cfg?.filterByBrand, initialItems: sectionData.products, rows: cfg?.rows, maxItems: cfg?.maxItems, pagination: cfg?.pagination }));
87
+ return (_jsx(FeaturedProductsSection, { title: cleanTitle(cfg?.title) || "Featured Products", viewMoreHref: ROUTES.PUBLIC.PRODUCTS, viewMoreLabel: "View all products \u2192", filterByBrand: cfg?.filterByBrand, initialItems: sectionData.products, rows: cfg?.rows, maxItems: cfg?.maxItems, autoScroll: cfg?.autoScroll, scrollInterval: cfg?.scrollInterval }));
88
88
  }
89
89
  case "auctions": {
90
90
  const cfg = config;
91
- return (_jsx(FeaturedAuctionsSection, { title: cleanTitle(cfg?.title) || "Live Auctions", viewMoreHref: ROUTES.PUBLIC.AUCTIONS, viewMoreLabel: "View all auctions \u2192", filterByBrand: cfg?.filterByBrand, initialItems: sectionData.auctions }));
91
+ return (_jsx(FeaturedAuctionsSection, { title: cleanTitle(cfg?.title) || "Live Auctions", viewMoreHref: ROUTES.PUBLIC.AUCTIONS, viewMoreLabel: "View all auctions \u2192", filterByBrand: cfg?.filterByBrand, initialItems: sectionData.auctions, rows: cfg?.rows, autoScroll: cfg?.autoScroll, scrollInterval: cfg?.scrollInterval }));
92
92
  }
93
93
  case "pre-orders": {
94
94
  const cfg = config;
95
- return (_jsx(FeaturedPreOrdersSection, { title: cleanTitle(cfg?.title) || "Reserve Before It Ships", viewMoreHref: ROUTES.PUBLIC.PRE_ORDERS, viewMoreLabel: "View all pre-orders \u2192", filterByBrand: cfg?.filterByBrand, initialItems: sectionData.preOrders }));
95
+ return (_jsx(FeaturedPreOrdersSection, { title: cleanTitle(cfg?.title) || "Reserve Before It Ships", viewMoreHref: ROUTES.PUBLIC.PRE_ORDERS, viewMoreLabel: "View all pre-orders \u2192", filterByBrand: cfg?.filterByBrand, initialItems: sectionData.preOrders, rows: cfg?.rows, autoScroll: cfg?.autoScroll, scrollInterval: cfg?.scrollInterval }));
96
96
  }
97
97
  case "stores": {
98
98
  const cfg = config;