@mohasinac/appkit 3.1.2 → 3.1.4

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.
@@ -82,7 +82,7 @@ function filterGroups(groups, navConfig, permissions) {
82
82
  }))
83
83
  .filter((group) => group.items.length > 0);
84
84
  }
85
- const DEFAULT_CONTENT_PADDING = "px-5 py-8 md:pl-14 md:pr-6 lg:pl-16 lg:pr-10";
85
+ const DEFAULT_CONTENT_PADDING = "px-5 py-8 lg:pl-14 lg:pr-6 xl:pl-16 xl:pr-10";
86
86
  const DEFAULT_CONTENT_MAX_WIDTH = "max-w-screen-2xl";
87
87
  export function DashboardLayoutClient({ variant, groups, permissions, activeHref: explicitActiveHref, responsive: _responsive, className, contentPadding, contentSurface, contentMaxWidth, children, }) {
88
88
  const pathname = usePathname();
@@ -3,8 +3,8 @@
3
3
  * sidebar (admin, store/seller, user). Replaces three identical inline copies
4
4
  * that previously baked hardcoded hex gradients per role — see plan §1.
5
5
  *
6
- * Background uses `--appkit-color-primary-*` / `--appkit-color-secondary-*`
7
- * tokens so the handle re-themes correctly in light and dark modes. Chevron
6
+ * Background uses `--appkit-gradient-sidebar` so the handle re-themes
7
+ * correctly: blue→green in light mode, pink→sky-blue in dark mode. Chevron
8
8
  * foreground is pinned to `--appkit-color-text-on-primary` so it stays
9
9
  * readable against the gradient regardless of theme.
10
10
  */
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import { jsx as _jsx } from "react/jsx-runtime";
3
3
  const HANDLE_STYLE = {
4
- background: "linear-gradient(to bottom, var(--appkit-color-primary-700, var(--appkit-color-primary)), var(--appkit-color-secondary-500, var(--appkit-color-secondary)))",
4
+ background: "var(--appkit-gradient-sidebar)", // audit-inline-style-ok: theme gradient CSS var, not a raw colour
5
5
  };
6
6
  const CHEVRON_STYLE = {
7
7
  color: "var(--appkit-color-text-on-primary)",
@@ -31,5 +31,5 @@ export declare const HEADER_HEIGHT_CSS_VAR = "--header-height";
31
31
  * Exported so DashboardLayoutClient can call `window.matchMedia(DASHBOARD_DESKTOP_MEDIA_QUERY)`
32
32
  * without re-hardcoding the value across every layout consumer.
33
33
  */
34
- export declare const DASHBOARD_DESKTOP_BREAKPOINT_PX = 768;
35
- export declare const DASHBOARD_DESKTOP_MEDIA_QUERY = "(min-width: 768px)";
34
+ export declare const DASHBOARD_DESKTOP_BREAKPOINT_PX = 1024;
35
+ export declare const DASHBOARD_DESKTOP_MEDIA_QUERY = "(min-width: 1024px)";
@@ -54,5 +54,5 @@ export const HEADER_HEIGHT_CSS_VAR = "--header-height";
54
54
  * Exported so DashboardLayoutClient can call `window.matchMedia(DASHBOARD_DESKTOP_MEDIA_QUERY)`
55
55
  * without re-hardcoding the value across every layout consumer.
56
56
  */
57
- export const DASHBOARD_DESKTOP_BREAKPOINT_PX = 768;
57
+ export const DASHBOARD_DESKTOP_BREAKPOINT_PX = 1024;
58
58
  export const DASHBOARD_DESKTOP_MEDIA_QUERY = `(min-width: ${DASHBOARD_DESKTOP_BREAKPOINT_PX}px)`;
@@ -196,6 +196,12 @@ export declare const EVENT_ENDPOINTS: {
196
196
  readonly ENTRIES: (id: string) => string;
197
197
  readonly LEADERBOARD: (id: string, limit?: number) => string;
198
198
  readonly SPIN: (id: string) => string;
199
+ readonly LOTTERY_PULL: (id: string) => string;
200
+ readonly LOTTERY_ENTRIES: (id: string) => string;
201
+ };
202
+ export declare const LOTTERY_ENDPOINTS: {
203
+ readonly FLAG_ENTRY: (entryId: string) => string;
204
+ readonly REOPEN_SLOT: (entryId: string) => string;
199
205
  };
200
206
  export declare const FAQ_ENDPOINTS: {
201
207
  readonly LIST: "/api/faqs";
@@ -235,6 +241,8 @@ export declare const PRODUCT_ENDPOINTS: {
235
241
  readonly LIST: "/api/products";
236
242
  readonly BY_SLUG: (slug: string) => string;
237
243
  readonly BY_ID: (id: string) => string;
244
+ readonly LOTTERY_PULL: (id: string) => string;
245
+ readonly LOTTERY_ENTRIES: (id: string) => string;
238
246
  };
239
247
  export declare const PROMOTION_ENDPOINTS: {
240
248
  readonly LIST: "/api/coupons";
@@ -526,6 +534,12 @@ export declare const API_ENDPOINTS: {
526
534
  readonly ENTRIES: (id: string) => string;
527
535
  readonly LEADERBOARD: (id: string, limit?: number) => string;
528
536
  readonly SPIN: (id: string) => string;
537
+ readonly LOTTERY_PULL: (id: string) => string;
538
+ readonly LOTTERY_ENTRIES: (id: string) => string;
539
+ };
540
+ readonly LOTTERY: {
541
+ readonly FLAG_ENTRY: (entryId: string) => string;
542
+ readonly REOPEN_SLOT: (entryId: string) => string;
529
543
  };
530
544
  readonly FAQS: {
531
545
  readonly LIST: "/api/faqs";
@@ -565,6 +579,8 @@ export declare const API_ENDPOINTS: {
565
579
  readonly LIST: "/api/products";
566
580
  readonly BY_SLUG: (slug: string) => string;
567
581
  readonly BY_ID: (id: string) => string;
582
+ readonly LOTTERY_PULL: (id: string) => string;
583
+ readonly LOTTERY_ENTRIES: (id: string) => string;
568
584
  };
569
585
  readonly PROMOTIONS: {
570
586
  readonly LIST: "/api/coupons";
@@ -855,6 +871,12 @@ export declare const API_ROUTES: {
855
871
  readonly ENTRIES: (id: string) => string;
856
872
  readonly LEADERBOARD: (id: string, limit?: number) => string;
857
873
  readonly SPIN: (id: string) => string;
874
+ readonly LOTTERY_PULL: (id: string) => string;
875
+ readonly LOTTERY_ENTRIES: (id: string) => string;
876
+ };
877
+ readonly LOTTERY: {
878
+ readonly FLAG_ENTRY: (entryId: string) => string;
879
+ readonly REOPEN_SLOT: (entryId: string) => string;
858
880
  };
859
881
  readonly FAQS: {
860
882
  readonly LIST: "/api/faqs";
@@ -894,6 +916,8 @@ export declare const API_ROUTES: {
894
916
  readonly LIST: "/api/products";
895
917
  readonly BY_SLUG: (slug: string) => string;
896
918
  readonly BY_ID: (id: string) => string;
919
+ readonly LOTTERY_PULL: (id: string) => string;
920
+ readonly LOTTERY_ENTRIES: (id: string) => string;
897
921
  };
898
922
  readonly PROMOTIONS: {
899
923
  readonly LIST: "/api/coupons";
@@ -252,6 +252,16 @@ export const EVENT_ENDPOINTS = {
252
252
  LEADERBOARD: (id, limit) => `/api/events/${id}/leaderboard${limit !== undefined ? `?limit=${limit}` : ""}`,
253
253
  // SB9-E user spin assignment
254
254
  SPIN: (id) => `/api/events/${id}/spin`,
255
+ // Lottery: user self-pull (draw happens immediately on submit)
256
+ LOTTERY_PULL: (id) => `/api/events/${id}/lottery-pull`,
257
+ LOTTERY_ENTRIES: (id) => `/api/events/${id}/lottery-entries`,
258
+ };
259
+ // ---------------------------------------------------------------------------
260
+ // Lottery
261
+ // ---------------------------------------------------------------------------
262
+ export const LOTTERY_ENDPOINTS = {
263
+ FLAG_ENTRY: (entryId) => `/api/lottery-entries/${entryId}/flag`,
264
+ REOPEN_SLOT: (entryId) => `/api/lottery-entries/${entryId}/reopen-slot`,
255
265
  };
256
266
  // ---------------------------------------------------------------------------
257
267
  // FAQ
@@ -312,6 +322,9 @@ export const PRODUCT_ENDPOINTS = {
312
322
  LIST: "/api/products",
313
323
  BY_SLUG: (slug) => `/api/products/${slug}`,
314
324
  BY_ID: (id) => `/api/products/${id}`,
325
+ // Lottery: user self-pull for prize-draw products in lottery mode
326
+ LOTTERY_PULL: (id) => `/api/products/${id}/lottery-pull`,
327
+ LOTTERY_ENTRIES: (id) => `/api/products/${id}/lottery-entries`,
315
328
  };
316
329
  // ---------------------------------------------------------------------------
317
330
  // Promotions
@@ -474,6 +487,7 @@ export const API_ENDPOINTS = {
474
487
  COPILOT: COPILOT_ENDPOINTS,
475
488
  CORPORATE: CORPORATE_ENDPOINTS,
476
489
  EVENTS: EVENT_ENDPOINTS,
490
+ LOTTERY: LOTTERY_ENDPOINTS,
477
491
  FAQS: FAQ_ENDPOINTS,
478
492
  HOMEPAGE: HOMEPAGE_ENDPOINTS,
479
493
  LOYALTY: LOYALTY_ENDPOINTS,
@@ -61,7 +61,7 @@ function DrawerContent({ groups, items, activeHref, onItemClick, }) {
61
61
  }) }));
62
62
  }
63
63
  function DrawerPanel({ title, onClose, children, }) {
64
- return (_jsxs(Div, { className: "hidden md:block", children: [_jsx(Div, { surface: "overlay-xs", className: "fixed inset-0 z-40 backdrop-blur-sm", onClick: onClose, "aria-hidden": "true" }), _jsxs(Stack, { border: "default", shadow: "2xl", role: "dialog", "aria-modal": "true", "aria-label": title, className: "fixed top-0 right-0 z-50 h-full w-64 border-l", surface: "default", children: [_jsxs(Row, { border: "bottom-subtle", paddingY: "y-sm-tall", className: "shrink-0", padding: "x-md", align: "center", justify: "between", children: [_jsx(Span, { size: "xs", weight: "semibold", transform: "uppercase", color: "muted", children: title }), _jsx("button", { type: "button", onClick: onClose, "aria-label": "Close", className: "flex items-center justify-center w-7 h-7 rounded-md text-zinc-400 hover:bg-zinc-100 dark:hover:bg-slate-800 hover:text-zinc-700 dark:hover:text-zinc-200 transition-colors", children: _jsx("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", "aria-hidden": "true", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) }) })] }), _jsx(Div, { className: `flex-1 ${__O.yAuto}`, children: children })] })] }));
64
+ return (_jsxs(Div, { className: "hidden lg:block", children: [_jsx(Div, { surface: "overlay-xs", className: "fixed inset-0 z-40 backdrop-blur-sm", onClick: onClose, "aria-hidden": "true" }), _jsxs(Stack, { border: "default", shadow: "2xl", role: "dialog", "aria-modal": "true", "aria-label": title, className: "fixed top-0 right-0 z-50 h-full w-64 border-l", surface: "default", children: [_jsxs(Row, { border: "bottom-subtle", paddingY: "y-sm-tall", className: "shrink-0", padding: "x-md", align: "center", justify: "between", children: [_jsx(Span, { size: "xs", weight: "semibold", transform: "uppercase", color: "muted", children: title }), _jsx("button", { type: "button", onClick: onClose, "aria-label": "Close", className: "flex items-center justify-center w-7 h-7 rounded-md text-zinc-400 hover:bg-zinc-100 dark:hover:bg-slate-800 hover:text-zinc-700 dark:hover:text-zinc-200 transition-colors", children: _jsx("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", "aria-hidden": "true", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) }) })] }), _jsx(Div, { className: `flex-1 ${__O.yAuto}`, children: children })] })] }));
65
65
  }
66
66
  export function UserSidebar({ items, groups, mobileOpen = false, onCloseMobile, desktopOpen = false, onToggle, variant = "overlay" }) {
67
67
  const pathname = usePathname();
@@ -77,10 +77,10 @@ export function UserSidebar({ items, groups, mobileOpen = false, onCloseMobile,
77
77
  // ── Persistent sidebar variant (desktop left slide-over, mobile bottom-sheet) ──────
78
78
  if (variant === "sidebar") {
79
79
  const handleToggle = onToggle ?? close;
80
- return (_jsxs(_Fragment, { children: [desktopOpen && (_jsx(Div, { surface: "overlay-xs", className: "hidden md:block fixed inset-0 backdrop-blur-[2px] z-30", onClick: handleToggle, "aria-hidden": "true" })), _jsxs(Div, { className: `hidden md:flex fixed left-0 z-40 transition-transform duration-300 top-[var(--header-height,3.5rem)] h-[calc(100vh-var(--header-height,3.5rem))] w-[13rem] ${desktopOpen ? "translate-x-0" : "-translate-x-[calc(100%-1.25rem)]"}`, children: [_jsxs(Stack, { border: "default", surface: "default", className: `flex-1 border-r dark:border-[var(--appkit-color-border)] ${__O.hidden}`, shadow: "xl", children: [_jsx(Div, { border: "bottom-subtle", paddingY: "y-sm-tall", className: "shrink-0", padding: "x-md", children: _jsx(Span, { size: "xs", weight: "semibold", transform: "uppercase", color: "muted", children: "My Account" }) }), _jsx(Div, { className: `flex-1 ${__O.yAuto}`, children: _jsx(DrawerContent, { groups: groups, items: items, activeHref: pathname }) })] }), _jsx(SidebarCollapseToggle, { expanded: desktopOpen, onToggle: handleToggle })] }), _jsx(Div, { className: "md:hidden", children: _jsx(BottomSheet, { open: mobileOpen, onClose: close, title: "My Account", children: _jsx(DrawerContent, { groups: groups, items: items, activeHref: pathname, onItemClick: close }) }) })] }));
80
+ return (_jsxs(_Fragment, { children: [desktopOpen && (_jsx(Div, { surface: "overlay-xs", className: "hidden lg:block fixed inset-0 backdrop-blur-[2px] z-30", onClick: handleToggle, "aria-hidden": "true" })), _jsxs(Div, { className: `hidden lg:flex fixed left-0 z-40 transition-transform duration-300 top-[var(--header-height,3.5rem)] h-[calc(100vh-var(--header-height,3.5rem))] w-[13rem] ${desktopOpen ? "translate-x-0" : "-translate-x-[calc(100%-1.25rem)]"}`, children: [_jsxs(Stack, { border: "default", surface: "default", className: `flex-1 border-r dark:border-[var(--appkit-color-border)] ${__O.hidden}`, shadow: "xl", children: [_jsx(Div, { border: "bottom-subtle", paddingY: "y-sm-tall", className: "shrink-0", padding: "x-md", children: _jsx(Span, { size: "xs", weight: "semibold", transform: "uppercase", color: "muted", children: "My Account" }) }), _jsx(Div, { className: `flex-1 ${__O.yAuto}`, children: _jsx(DrawerContent, { groups: groups, items: items, activeHref: pathname }) })] }), _jsx(SidebarCollapseToggle, { expanded: desktopOpen, onToggle: handleToggle })] }), _jsx(Div, { className: "lg:hidden", children: _jsx(BottomSheet, { open: mobileOpen, onClose: close, title: "My Account", children: _jsx(DrawerContent, { groups: groups, items: items, activeHref: pathname, onItemClick: close }) }) })] }));
81
81
  }
82
82
  // ── Overlay variant (default) — portal on desktop, bottom-sheet on mobile ─
83
83
  const content = (_jsx(DrawerContent, { groups: groups, items: items, activeHref: pathname, onItemClick: close }));
84
84
  return (_jsxs(_Fragment, { children: [mounted && mobileOpen &&
85
- createPortal(_jsx(DrawerPanel, { title: "My Account", onClose: close, children: content }), document.body), _jsx(Div, { className: "md:hidden", children: _jsx(BottomSheet, { open: mobileOpen, onClose: close, title: "My Account", children: _jsx(DrawerContent, { groups: groups, items: items, activeHref: pathname, onItemClick: close }) }) })] }));
85
+ createPortal(_jsx(DrawerPanel, { title: "My Account", onClose: close, children: content }), document.body), _jsx(Div, { className: "lg:hidden", children: _jsx(BottomSheet, { open: mobileOpen, onClose: close, title: "My Account", children: _jsx(DrawerContent, { groups: groups, items: items, activeHref: pathname, onItemClick: close }) }) })] }));
86
86
  }
@@ -33,7 +33,7 @@ function GroupsContent({ groups, activePath, onItemClick, }) {
33
33
  }) }));
34
34
  }
35
35
  function DrawerPanel({ title, onClose, children, }) {
36
- return (_jsxs(Div, { className: "hidden md:block", children: [_jsx(Div, { surface: "overlay-xs", className: "fixed inset-0 z-40 backdrop-blur-sm", onClick: onClose, "aria-hidden": "true" }), _jsxs(Stack, { border: "default", shadow: "2xl", role: "dialog", "aria-modal": "true", "aria-label": title, className: "fixed top-0 right-0 z-50 h-full w-64 border-l", surface: "default", children: [_jsxs(Row, { border: "bottom-subtle", paddingY: "y-sm-tall", className: "shrink-0", padding: "x-md", align: "center", justify: "between", children: [_jsx(Span, { size: "xs", weight: "semibold", transform: "uppercase", color: "muted", children: title }), _jsx("button", { type: "button", onClick: onClose, "aria-label": "Close", className: "flex items-center justify-center w-7 h-7 rounded-md text-zinc-400 hover:bg-zinc-100 dark:hover:bg-slate-800 hover:text-zinc-700 dark:hover:text-zinc-200 transition-colors", children: _jsx("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", "aria-hidden": "true", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) }) })] }), _jsx(Div, { className: `flex-1 ${__O.yAuto}`, children: children })] })] }));
36
+ return (_jsxs(Div, { className: "hidden lg:block", children: [_jsx(Div, { surface: "overlay-xs", className: "fixed inset-0 z-40 backdrop-blur-sm", onClick: onClose, "aria-hidden": "true" }), _jsxs(Stack, { border: "default", shadow: "2xl", role: "dialog", "aria-modal": "true", "aria-label": title, className: "fixed top-0 right-0 z-50 h-full w-64 border-l", surface: "default", children: [_jsxs(Row, { border: "bottom-subtle", paddingY: "y-sm-tall", className: "shrink-0", padding: "x-md", align: "center", justify: "between", children: [_jsx(Span, { size: "xs", weight: "semibold", transform: "uppercase", color: "muted", children: title }), _jsx("button", { type: "button", onClick: onClose, "aria-label": "Close", className: "flex items-center justify-center w-7 h-7 rounded-md text-zinc-400 hover:bg-zinc-100 dark:hover:bg-slate-800 hover:text-zinc-700 dark:hover:text-zinc-200 transition-colors", children: _jsx("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", "aria-hidden": "true", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) }) })] }), _jsx(Div, { className: `flex-1 ${__O.yAuto}`, children: children })] })] }));
37
37
  }
38
38
  export function AdminSidebar({ renderNavItems, renderHeader, renderFooter, activePath = "", groups, mobileOpen = false, desktopOpen = false, variant = "overlay", onCloseMobile, onToggle, }) {
39
39
  const close = onCloseMobile ?? (() => { });
@@ -47,8 +47,8 @@ export function AdminSidebar({ renderNavItems, renderHeader, renderFooter, activ
47
47
  const mobileNavContent = groups ? (_jsx(GroupsContent, { groups: groups, activePath: activePath, onItemClick: close })) : (_jsxs(Nav, { "aria-label": "Admin sidebar", padding: "y-sm", children: [renderHeader?.(), renderNavItems?.(activePath), renderFooter?.()] }));
48
48
  if (variant === "sidebar") {
49
49
  const handleToggle = onToggle ?? close;
50
- return (_jsxs(_Fragment, { children: [desktopOpen && (_jsx(Div, { surface: "overlay-xs", className: "hidden md:block fixed inset-0 backdrop-blur-[2px] z-30", onClick: handleToggle, "aria-hidden": "true" })), _jsxs(Div, { className: `hidden md:flex fixed left-0 z-40 transition-transform duration-300 top-[var(--header-height,3.5rem)] h-[calc(100vh-var(--header-height,3.5rem))] w-[18rem] ${desktopOpen ? "translate-x-0" : "-translate-x-[calc(100%-1.25rem)]"}`, children: [_jsxs(Stack, { border: "default", surface: "sidePanel", className: `flex-1 border-r dark:border-[var(--appkit-color-border)] ${__O.hidden}`, shadow: "xl", children: [_jsx(Div, { border: "bottom-subtle", paddingY: "y-sm-tall", className: "shrink-0", padding: "x-md", children: renderHeader ? renderHeader() : _jsx(Span, { size: "xs", weight: "semibold", transform: "uppercase", color: "muted", children: "Admin Panel" }) }), _jsx(Div, { className: `flex-1 ${__O.yAuto}`, children: navContent }), renderFooter && _jsx(Div, { border: "top", padding: "inline", children: renderFooter() })] }), _jsx(SidebarCollapseToggle, { expanded: desktopOpen, onToggle: handleToggle })] }), _jsx(Div, { className: "md:hidden", children: _jsx(BottomSheet, { open: mobileOpen, onClose: close, title: "Admin Panel", children: mobileNavContent }) })] }));
50
+ return (_jsxs(_Fragment, { children: [desktopOpen && (_jsx(Div, { surface: "overlay-xs", className: "hidden lg:block fixed inset-0 backdrop-blur-[2px] z-30", onClick: handleToggle, "aria-hidden": "true" })), _jsxs(Div, { className: `hidden lg:flex fixed left-0 z-40 transition-transform duration-300 top-[var(--header-height,3.5rem)] h-[calc(100vh-var(--header-height,3.5rem))] w-[18rem] ${desktopOpen ? "translate-x-0" : "-translate-x-[calc(100%-1.25rem)]"}`, children: [_jsxs(Stack, { border: "default", surface: "sidePanel", className: `flex-1 border-r dark:border-[var(--appkit-color-border)] ${__O.hidden}`, shadow: "xl", children: [_jsx(Div, { border: "bottom-subtle", paddingY: "y-sm-tall", className: "shrink-0", padding: "x-md", children: renderHeader ? renderHeader() : _jsx(Span, { size: "xs", weight: "semibold", transform: "uppercase", color: "muted", children: "Admin Panel" }) }), _jsx(Div, { className: `flex-1 ${__O.yAuto}`, children: navContent }), renderFooter && _jsx(Div, { border: "top", padding: "inline", children: renderFooter() })] }), _jsx(SidebarCollapseToggle, { expanded: desktopOpen, onToggle: handleToggle })] }), _jsx(Div, { className: "lg:hidden", children: _jsx(BottomSheet, { open: mobileOpen, onClose: close, title: "Admin Panel", children: mobileNavContent }) })] }));
51
51
  }
52
52
  return (_jsxs(_Fragment, { children: [mounted && mobileOpen &&
53
- createPortal(_jsx(DrawerPanel, { title: "Admin Panel", onClose: close, children: navContent }), document.body), _jsx(Div, { className: "md:hidden", children: _jsx(BottomSheet, { open: mobileOpen, onClose: close, title: "Admin Panel", children: mobileNavContent }) })] }));
53
+ createPortal(_jsx(DrawerPanel, { title: "Admin Panel", onClose: close, children: navContent }), document.body), _jsx(Div, { className: "lg:hidden", children: _jsx(BottomSheet, { open: mobileOpen, onClose: close, title: "Admin Panel", children: mobileNavContent }) })] }));
54
54
  }
@@ -11,7 +11,7 @@ function DefaultNavItem({ item, isActive, }) {
11
11
  const activeClasses = item.highlighted
12
12
  ? "border border-primary-400/40 dark:border-secondary-400/30 text-primary-700 dark:text-secondary-400 bg-primary-50/80 dark:bg-secondary-900/30 px-3 transition-colors duration-150"
13
13
  : isActive
14
- ? "bg-primary-50 dark:bg-secondary-900/30 text-primary-800 dark:text-secondary-200 font-semibold px-3 border-b-2 border-primary-500 dark:border-secondary-400 rounded-none pb-[6px] transition-colors duration-150"
14
+ ? "bg-primary-50 dark:bg-slate-800 text-primary-800 dark:text-white font-semibold px-3 border-b-2 border-primary-500 dark:border-secondary-400 rounded-none pb-[6px] transition-colors duration-150"
15
15
  : "text-zinc-700 dark:text-zinc-300 hover:bg-zinc-100 dark:hover:bg-slate-800 hover:text-zinc-950 dark:hover:text-white transition-colors duration-150 px-3";
16
16
  return (_jsxs(Link, { href: item.href, "aria-current": isActive ? "page" : undefined, className: `flex items-center gap-1.5 py-2 text-sm rounded-lg font-medium transition-colors duration-150 whitespace-nowrap ${activeClasses}`, children: [item.icon, _jsx(Span, { children: item.label })] }));
17
17
  }
@@ -64,4 +64,4 @@ export interface TitleBarLayoutProps {
64
64
  *
65
65
  * Receives all domain data as props — zero domain imports.
66
66
  */
67
- export declare function TitleBarLayout({ onToggleSidebar, sidebarOpen, onSearchToggle, searchOpen: _searchOpen, brandName, brandShortName: _brandShortName, siteLogoUrl, logoHref, promotionsHref, compareHref, wishlistHref, wishlistCount, cartHref, cartCount, profileHref, unreadNotificationCount, notificationsHref, loginHref, registerHref, user, notificationSlot, devSlot, navSlot, promoStripText, isDark, onToggleTheme, hasDashboardNav: _hasDashboardNav, onToggleDashboardNav: _onToggleDashboardNav, hideSidebarToggle, id, className, }: TitleBarLayoutProps): import("react/jsx-runtime").JSX.Element;
67
+ export declare function TitleBarLayout({ onToggleSidebar, sidebarOpen, onSearchToggle, searchOpen: _searchOpen, brandName, brandShortName: _brandShortName, siteLogoUrl, logoHref, promotionsHref, compareHref, wishlistHref, wishlistCount, cartHref, cartCount, profileHref, unreadNotificationCount, notificationsHref, loginHref, registerHref, user, notificationSlot, devSlot, navSlot, promoStripText, isDark, onToggleTheme, hasDashboardNav, onToggleDashboardNav, hideSidebarToggle, id, className, }: TitleBarLayoutProps): import("react/jsx-runtime").JSX.Element;
@@ -14,11 +14,11 @@ const countBadge = "absolute -top-0.5 -right-0.5 flex items-center justify-cente
14
14
  *
15
15
  * Receives all domain data as props — zero domain imports.
16
16
  */
17
- export function TitleBarLayout({ onToggleSidebar, sidebarOpen, onSearchToggle, searchOpen: _searchOpen, brandName, brandShortName: _brandShortName, siteLogoUrl, logoHref, promotionsHref, compareHref, wishlistHref, wishlistCount = 0, cartHref, cartCount = 0, profileHref, unreadNotificationCount = 0, notificationsHref, loginHref, registerHref, user, notificationSlot, devSlot, navSlot, promoStripText, isDark = false, onToggleTheme, hasDashboardNav: _hasDashboardNav, onToggleDashboardNav: _onToggleDashboardNav, hideSidebarToggle = false, id = "titlebar", className = "", }) {
17
+ export function TitleBarLayout({ onToggleSidebar, sidebarOpen, onSearchToggle, searchOpen: _searchOpen, brandName, brandShortName: _brandShortName, siteLogoUrl, logoHref, promotionsHref, compareHref, wishlistHref, wishlistCount = 0, cartHref, cartCount = 0, profileHref, unreadNotificationCount = 0, notificationsHref, loginHref, registerHref, user, notificationSlot, devSlot, navSlot, promoStripText, isDark = false, onToggleTheme, hasDashboardNav, onToggleDashboardNav, hideSidebarToggle = false, id = "titlebar", className = "", }) {
18
18
  // ── Element builders ────────────────────────────────────────────────────────
19
19
  const promotionsEl = promotionsHref ? (_jsxs(Link, { href: promotionsHref, "aria-label": "Today's deals", className: "flex items-center gap-1 px-3 py-1 rounded-full text-xs font-bold bg-primary-100 text-primary-700 dark:bg-secondary-900/40 dark:text-secondary-400 hover:bg-primary-200 dark:hover:bg-secondary-900/60 transition-colors border border-primary-200/60 dark:border-secondary-700/40", children: [_jsx("svg", { className: "w-3 h-3", viewBox: "0 0 24 24", fill: "currentColor", "aria-hidden": "true", children: _jsx("path", { d: "M21.41 11.58l-9-9C12.05 2.22 11.55 2 11 2H4c-1.1 0-2 .9-2 2v7c0 .55.22 1.05.59 1.42l9 9c.36.37.86.58 1.41.58.55 0 1.05-.21 1.41-.59l7-7c.37-.36.59-.86.59-1.41 0-.55-.23-1.06-.59-1.42zM5.5 7C4.67 7 4 6.33 4 5.5S4.67 4 5.5 4 7 4.67 7 5.5 6.33 7 5.5 7z" }) }), _jsx(Span, { className: "hidden sm:inline", children: "Today's Deals" })] })) : null;
20
20
  const themeBtn = onToggleTheme ? (_jsx(Button, { type: "button", variant: "ghost", size: "sm", "aria-label": isDark ? "Switch to light mode" : "Switch to dark mode", onClick: onToggleTheme, className: iconBtn, children: isDark ? (_jsx("svg", { className: "w-5 h-5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", "aria-hidden": "true", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 3v1m0 16v1m8.66-9h-1M4.34 12h-1m15.07-6.07-.71.71M6.34 17.66l-.71.71m12.73 0-.71-.71M6.34 6.34l-.71-.71M12 5a7 7 0 1 0 0 14A7 7 0 0 0 12 5z" }) })) : (_jsx("svg", { className: "w-5 h-5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", "aria-hidden": "true", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M21 12.79A9 9 0 1 1 11.21 3a7 7 0 1 0 9.79 9.79z" }) })) })) : null;
21
- const hamburgerBtn = !hideSidebarToggle ? (_jsx(Button, { type: "button", variant: "ghost", size: "sm", "aria-label": sidebarOpen ? "Close menu" : "Open menu", "aria-expanded": sidebarOpen, "aria-controls": "secondary-sidebar", onClick: onToggleSidebar, className: iconBtn, children: _jsx("svg", { className: "w-5 h-5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", "aria-hidden": "true", children: sidebarOpen ? (_jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" })) : (_jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 6h16M4 12h16M4 18h16" })) }) })) : null;
21
+ const hamburgerBtn = !hideSidebarToggle ? (_jsx(Button, { type: "button", variant: "ghost", size: "sm", "aria-label": sidebarOpen ? "Close menu" : hasDashboardNav ? "Open dashboard navigation" : "Open menu", "aria-expanded": sidebarOpen, "aria-controls": "secondary-sidebar", onClick: hasDashboardNav && onToggleDashboardNav ? onToggleDashboardNav : onToggleSidebar, className: iconBtn, children: _jsx("svg", { className: "w-5 h-5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", "aria-hidden": "true", children: sidebarOpen ? (_jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" })) : (_jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 6h16M4 12h16M4 18h16" })) }) })) : null;
22
22
  // Compare is always lg+ (desktop-only feature, less critical on mobile)
23
23
  const compareEl = compareHref ? (_jsx(Link, { href: compareHref, "aria-label": "Compare items", className: `${iconBtn} hidden lg:flex`, children: _jsx("svg", { className: "w-5 h-5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", "aria-hidden": "true", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z" }) }) })) : null;
24
24
  const searchBtn = (_jsx(Button, { type: "button", variant: "ghost", size: "sm", "aria-label": "Search", onClick: onSearchToggle, className: iconBtn, children: _jsx("svg", { className: "w-5 h-5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", "aria-hidden": "true", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M21 21l-4.35-4.35M17 11A6 6 0 1 1 5 11a6 6 0 0 1 12 0z" }) }) }));
@@ -45,7 +45,7 @@ function GroupsContent({ groups, activeHref, storeName, storeLogoURL, onItemClic
45
45
  }) })] }));
46
46
  }
47
47
  function DrawerPanel({ title, onClose, children }) {
48
- return (_jsxs(Div, { className: "hidden md:block", children: [_jsx(Div, { surface: "overlay-xs", className: "fixed inset-0 z-40 backdrop-blur-sm", onClick: onClose, "aria-hidden": "true" }), _jsxs(Stack, { border: "default", shadow: "2xl", role: "dialog", "aria-modal": "true", "aria-label": title, className: "fixed top-0 right-0 z-50 h-full w-64 border-l", surface: "default", children: [_jsxs(Row, { border: "bottom-subtle", paddingY: "y-sm-tall", className: "shrink-0", padding: "x-md", align: "center", justify: "between", children: [_jsx(Span, { size: "xs", weight: "semibold", transform: "uppercase", color: "muted", children: title }), _jsx("button", { type: "button", onClick: onClose, "aria-label": "Close", className: "flex items-center justify-center w-7 h-7 rounded-md text-zinc-400 hover:bg-zinc-100 dark:hover:bg-slate-800 hover:text-zinc-700 dark:hover:text-zinc-200 transition-colors", children: _jsx("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", "aria-hidden": "true", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) }) })] }), _jsx(Div, { className: `flex-1 ${__O.yAuto}`, children: children })] })] }));
48
+ return (_jsxs(Div, { className: "hidden lg:block", children: [_jsx(Div, { surface: "overlay-xs", className: "fixed inset-0 z-40 backdrop-blur-sm", onClick: onClose, "aria-hidden": "true" }), _jsxs(Stack, { border: "default", shadow: "2xl", role: "dialog", "aria-modal": "true", "aria-label": title, className: "fixed top-0 right-0 z-50 h-full w-64 border-l", surface: "default", children: [_jsxs(Row, { border: "bottom-subtle", paddingY: "y-sm-tall", className: "shrink-0", padding: "x-md", align: "center", justify: "between", children: [_jsx(Span, { size: "xs", weight: "semibold", transform: "uppercase", color: "muted", children: title }), _jsx("button", { type: "button", onClick: onClose, "aria-label": "Close", className: "flex items-center justify-center w-7 h-7 rounded-md text-zinc-400 hover:bg-zinc-100 dark:hover:bg-slate-800 hover:text-zinc-700 dark:hover:text-zinc-200 transition-colors", children: _jsx("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", "aria-hidden": "true", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) }) })] }), _jsx(Div, { className: `flex-1 ${__O.yAuto}`, children: children })] })] }));
49
49
  }
50
50
  export function StoreSidebar({ items, groups, activeHref, storeName, storeLogoURL, mobileOpen = false, desktopOpen = false, variant = "overlay", onCloseMobile, onToggle, }) {
51
51
  const close = onCloseMobile ?? (() => { });
@@ -59,8 +59,8 @@ export function StoreSidebar({ items, groups, activeHref, storeName, storeLogoUR
59
59
  const navContent = groups ? (_jsx(GroupsContent, { groups: groups, activeHref: activeHref, storeName: storeName, storeLogoURL: storeLogoURL, onItemClick: close })) : (_jsx(FlatContent, { items: items, activeHref: activeHref, storeName: storeName, storeLogoURL: storeLogoURL, onItemClick: close }));
60
60
  if (variant === "sidebar") {
61
61
  const handleToggle = onToggle ?? close;
62
- return (_jsxs(_Fragment, { children: [desktopOpen && (_jsx(Div, { surface: "overlay-xs", className: "hidden md:block fixed inset-0 backdrop-blur-[2px] z-30", onClick: handleToggle, "aria-hidden": "true" })), _jsxs(Div, { className: `hidden md:flex fixed left-0 z-40 transition-transform duration-300 top-[var(--header-height,3.5rem)] h-[calc(100vh-var(--header-height,3.5rem))] w-[18rem] ${desktopOpen ? "translate-x-0" : "-translate-x-[calc(100%-1.25rem)]"}`, children: [_jsxs(Stack, { border: "default", surface: "sidePanel", className: `flex-1 border-r ${__O.hidden}`, shadow: "xl", children: [_jsx(Div, { border: "bottom-subtle", paddingY: "y-sm-tall", className: "shrink-0", padding: "x-md", children: _jsxs(Row, { className: "min-w-0", align: "center", gap: "3", children: [storeLogoURL ? (_jsx("img", { src: storeLogoURL, alt: storeName, className: `${CLS_STORE_AVATAR} object-cover` })) : (_jsx(Div, { className: CLS_STORE_FALLBACK, children: storeName?.[0]?.toUpperCase() })), _jsx(Text, { className: CLS_STORE_NAME, children: storeName || panelTitle })] }) }), _jsx(Div, { className: `flex-1 ${__O.yAuto}`, children: navContent })] }), _jsx(SidebarCollapseToggle, { expanded: desktopOpen, onToggle: handleToggle })] }), _jsx(Div, { className: "md:hidden", children: _jsx(BottomSheet, { open: mobileOpen, onClose: close, title: panelTitle, children: groups ? (_jsx(GroupsContent, { groups: groups, activeHref: activeHref, storeName: storeName, storeLogoURL: storeLogoURL, onItemClick: close })) : (_jsx(FlatContent, { items: items, activeHref: activeHref, storeName: storeName, storeLogoURL: storeLogoURL, onItemClick: close })) }) })] }));
62
+ return (_jsxs(_Fragment, { children: [desktopOpen && (_jsx(Div, { surface: "overlay-xs", className: "hidden lg:block fixed inset-0 backdrop-blur-[2px] z-30", onClick: handleToggle, "aria-hidden": "true" })), _jsxs(Div, { className: `hidden lg:flex fixed left-0 z-40 transition-transform duration-300 top-[var(--header-height,3.5rem)] h-[calc(100vh-var(--header-height,3.5rem))] w-[18rem] ${desktopOpen ? "translate-x-0" : "-translate-x-[calc(100%-1.25rem)]"}`, children: [_jsxs(Stack, { border: "default", surface: "sidePanel", className: `flex-1 border-r ${__O.hidden}`, shadow: "xl", children: [_jsx(Div, { border: "bottom-subtle", paddingY: "y-sm-tall", className: "shrink-0", padding: "x-md", children: _jsxs(Row, { className: "min-w-0", align: "center", gap: "3", children: [storeLogoURL ? (_jsx("img", { src: storeLogoURL, alt: storeName, className: `${CLS_STORE_AVATAR} object-cover` })) : (_jsx(Div, { className: CLS_STORE_FALLBACK, children: storeName?.[0]?.toUpperCase() })), _jsx(Text, { className: CLS_STORE_NAME, children: storeName || panelTitle })] }) }), _jsx(Div, { className: `flex-1 ${__O.yAuto}`, children: navContent })] }), _jsx(SidebarCollapseToggle, { expanded: desktopOpen, onToggle: handleToggle })] }), _jsx(Div, { className: "lg:hidden", children: _jsx(BottomSheet, { open: mobileOpen, onClose: close, title: panelTitle, children: groups ? (_jsx(GroupsContent, { groups: groups, activeHref: activeHref, storeName: storeName, storeLogoURL: storeLogoURL, onItemClick: close })) : (_jsx(FlatContent, { items: items, activeHref: activeHref, storeName: storeName, storeLogoURL: storeLogoURL, onItemClick: close })) }) })] }));
63
63
  }
64
64
  return (_jsxs(_Fragment, { children: [mounted && mobileOpen &&
65
- createPortal(_jsx(DrawerPanel, { title: panelTitle, onClose: close, children: navContent }), document.body), _jsx(Div, { className: "md:hidden", children: _jsx(BottomSheet, { open: mobileOpen, onClose: close, title: panelTitle, children: groups ? (_jsx(GroupsContent, { groups: groups, activeHref: activeHref, storeName: storeName, storeLogoURL: storeLogoURL, onItemClick: close })) : (_jsx(FlatContent, { items: items, activeHref: activeHref, storeName: storeName, storeLogoURL: storeLogoURL, onItemClick: close })) }) })] }));
65
+ createPortal(_jsx(DrawerPanel, { title: panelTitle, onClose: close, children: navContent }), document.body), _jsx(Div, { className: "lg:hidden", children: _jsx(BottomSheet, { open: mobileOpen, onClose: close, title: panelTitle, children: groups ? (_jsx(GroupsContent, { groups: groups, activeHref: activeHref, storeName: storeName, storeLogoURL: storeLogoURL, onItemClick: close })) : (_jsx(FlatContent, { items: items, activeHref: activeHref, storeName: storeName, storeLogoURL: storeLogoURL, onItemClick: close })) }) })] }));
66
66
  }
package/dist/index.d.ts CHANGED
@@ -1778,6 +1778,7 @@ export { EVENT_ADMIN_SORT_OPTIONS } from "./features/events/index";
1778
1778
  export { EVENT_ENTRIES_COLLECTION } from "./features/events/index";
1779
1779
  export { LOTTERY_ENTRIES_COLLECTION } from "./features/lottery/schemas/firestore";
1780
1780
  export { lotteryEntriesSeedData } from "./seed/index";
1781
+ export { LOTTERY_ENTRY_FIELDS } from "./features/lottery/schemas/firestore";
1781
1782
  export { EVENT_ENTRY_FIELDS } from "./features/events/index";
1782
1783
  export { EVENT_ENTRY_INDEXED_FIELDS } from "./features/events/index";
1783
1784
  export { EVENT_FIELDS } from "./features/events/index";
package/dist/index.js CHANGED
@@ -3390,6 +3390,9 @@ export { LOTTERY_ENTRIES_COLLECTION } from "./features/lottery/schemas/firestore
3390
3390
  // lotteryEntriesSeedData - Seed data for the lotteryEntries collection.
3391
3391
  export { lotteryEntriesSeedData } from "./seed/index";
3392
3392
  // [SCHEMA]-Schema / data-shape constant â€" Zod validator, default-value object, or Firestore collection/field name constant.
3393
+ // LOTTERY_ENTRY_FIELDS - Canonical field name constants for lotteryEntries collection.
3394
+ export { LOTTERY_ENTRY_FIELDS } from "./features/lottery/schemas/firestore";
3395
+ // [SCHEMA]-Schema / data-shape constant â€" Zod validator, default-value object, or Firestore collection/field name constant.
3393
3396
  // EVENT_ENTRY_FIELDS - Constant used across modules.
3394
3397
  export { EVENT_ENTRY_FIELDS } from "./features/events/index";
3395
3398
  // [SCHEMA]-Schema / data-shape constant â€" Zod validator, default-value object, or Firestore collection/field name constant.
@@ -113,7 +113,76 @@ const _rawProductsPrizeDrawsSeedData = [
113
113
  createdAt: daysAgo(8),
114
114
  updatedAt: daysAgo(1),
115
115
  },
116
+ // 3. Hot Wheels Rare Numbered Slot Lottery (lottery mode — user self-pull)
117
+ {
118
+ id: "prize-hotwheels-slot-lottery",
119
+ slug: "prize-hotwheels-slot-lottery",
120
+ title: "Hot Wheels Rare — Numbered Slot Lottery",
121
+ description: "<p>10 rare Hot Wheels Redline and Treasure Hunt castings. Submit your UPI transaction ID and claim a slot — prize assigned instantly by weighted random draw. Lower-priced slots have a higher chance!</p>",
122
+ categorySlugs: ["category-diecast-vehicles"],
123
+ categoryNames: ["Diecast Vehicles"],
124
+ brand: "Hot Wheels",
125
+ brandSlug: "brand-hot-wheels",
126
+ price: 99900,
127
+ currency: SCHEMA_DEFAULTS.CURRENCY,
128
+ stockQuantity: 10,
129
+ availableQuantity: 10,
130
+ mainImage: seedExtMedia("https://images.unsplash.com/photo-1594736797933-d0401ba2fe65?w=800&h=800&fit=crop"),
131
+ images: [
132
+ seedExtMedia("https://images.unsplash.com/photo-1594736797933-d0401ba2fe65?w=800&h=800&fit=crop"),
133
+ ],
134
+ status: PRODUCT_FIELDS.STATUS_VALUES.PUBLISHED,
135
+ storeName: "Diecast Depot",
136
+ storeId: "store-diecast-depot",
137
+ featured: false,
138
+ isPromoted: false,
139
+ tags: ["hot-wheels", "lottery", "diecast", "redline", "rare"],
140
+ condition: PRODUCT_FIELDS.CONDITION_VALUES.NEW,
141
+ listingType: "prize-draw",
142
+ prizeDrawMode: "lottery",
143
+ lotteryConfig: _hotWheelsLotteryConfig(),
144
+ prizeDrawItems: _hotWheelsPrizeItems(),
145
+ allowOffers: false,
146
+ createdAt: daysAgo(3),
147
+ updatedAt: daysAgo(1),
148
+ },
116
149
  ];
150
+ function _hotWheelsLotteryConfig() {
151
+ const slots = [
152
+ { slotNumber: 1, name: "Red Line Hot Wheels Custom Camaro (1969)", priceInPaise: 49900, weight: 68, isBooked: true, bookedByUserLotteryNumber: 1, bookedByDisplayName: "Ravi K." },
153
+ { slotNumber: 2, name: "Treasure Hunt Dodge Challenger (2023)", priceInPaise: 79900, weight: 42, isBooked: true, bookedByUserLotteryNumber: 2, bookedByDisplayName: "Aisha M." },
154
+ { slotNumber: 3, name: "Hot Wheels Super Treasure Hunt (sealed)", priceInPaise: 99900, weight: 22, isBooked: true, bookedByUserLotteryNumber: 3, bookedByDisplayName: "Dev S." },
155
+ { slotNumber: 4, name: "Redline Ferrari 246 Dino (1969 original)", priceInPaise: 149900, weight: 1, isBooked: true, bookedByUserLotteryNumber: 4, bookedByDisplayName: "Priya L." },
156
+ { slotNumber: 5, name: "Hot Wheels Mystery Car (sealed, unknown model)", priceInPaise: 29900, weight: 100, isBooked: true, bookedByUserLotteryNumber: 5, bookedByDisplayName: "Mohsin C." },
157
+ { slotNumber: 6, name: "Hot Wheels RLC Exclusive Bone Shaker", priceInPaise: 59900, weight: 55, isBooked: false },
158
+ { slotNumber: 7, name: "Hot Wheels Pop Culture DeLorean (BTTF)", priceInPaise: 39900, weight: 79, isBooked: false },
159
+ { slotNumber: 8, name: "Hot Wheels Premium Car Culture (set of 5)", priceInPaise: 89900, weight: 31, isBooked: false },
160
+ { slotNumber: 9, name: "Hot Wheels ID Car (NFC-chip, sealed)", priceInPaise: 69900, weight: 46, isBooked: false },
161
+ { slotNumber: 10, name: "Redline Hot Wheels Beach Bomb (1969 – prototype type)", priceInPaise: 199900, weight: 1, isBooked: false },
162
+ ];
163
+ return {
164
+ slots,
165
+ totalSlots: 10,
166
+ pricingMode: "variable",
167
+ drawWindowDurationMinutes: 60,
168
+ maxPullsPerTransaction: 1,
169
+ maxPullsPerUser: 1,
170
+ };
171
+ }
172
+ function _hotWheelsPrizeItems() {
173
+ return [
174
+ { itemNumber: 1, title: "Red Line Custom Camaro (1969)", images: [seedExtMedia("https://images.unsplash.com/photo-1594736797933-d0401ba2fe65?w=600&h=600&fit=crop")], condition: PRODUCT_FIELDS.CONDITION_VALUES.USED, estimatedValue: 49900, prizeSlotPrice: 49900, isWon: true },
175
+ { itemNumber: 2, title: "Treasure Hunt Dodge Challenger", images: [seedExtMedia("https://images.unsplash.com/photo-1594736797933-d0401ba2fe65?w=600&h=600&fit=crop")], condition: PRODUCT_FIELDS.CONDITION_VALUES.NEW, estimatedValue: 79900, prizeSlotPrice: 79900, isWon: true },
176
+ { itemNumber: 3, title: "Super Treasure Hunt (sealed)", images: [seedExtMedia("https://images.unsplash.com/photo-1594736797933-d0401ba2fe65?w=600&h=600&fit=crop")], condition: PRODUCT_FIELDS.CONDITION_VALUES.NEW, estimatedValue: 99900, prizeSlotPrice: 99900, isWon: true },
177
+ { itemNumber: 4, title: "Redline Ferrari 246 Dino (1969)", images: [seedExtMedia("https://images.unsplash.com/photo-1594736797933-d0401ba2fe65?w=600&h=600&fit=crop")], condition: PRODUCT_FIELDS.CONDITION_VALUES.USED, estimatedValue: 149900, prizeSlotPrice: 149900, isWon: true },
178
+ { itemNumber: 5, title: "Mystery Car (sealed)", images: [seedExtMedia("https://images.unsplash.com/photo-1594736797933-d0401ba2fe65?w=600&h=600&fit=crop")], condition: PRODUCT_FIELDS.CONDITION_VALUES.NEW, estimatedValue: 29900, prizeSlotPrice: 29900, isWon: true },
179
+ { itemNumber: 6, title: "RLC Exclusive Bone Shaker", images: [seedExtMedia("https://images.unsplash.com/photo-1594736797933-d0401ba2fe65?w=600&h=600&fit=crop")], condition: PRODUCT_FIELDS.CONDITION_VALUES.NEW, estimatedValue: 59900, prizeSlotPrice: 59900, isWon: false },
180
+ { itemNumber: 7, title: "Pop Culture DeLorean (BTTF)", images: [seedExtMedia("https://images.unsplash.com/photo-1594736797933-d0401ba2fe65?w=600&h=600&fit=crop")], condition: PRODUCT_FIELDS.CONDITION_VALUES.NEW, estimatedValue: 39900, prizeSlotPrice: 39900, isWon: false },
181
+ { itemNumber: 8, title: "Premium Car Culture set of 5", images: [seedExtMedia("https://images.unsplash.com/photo-1594736797933-d0401ba2fe65?w=600&h=600&fit=crop")], condition: PRODUCT_FIELDS.CONDITION_VALUES.NEW, estimatedValue: 89900, prizeSlotPrice: 89900, isWon: false },
182
+ { itemNumber: 9, title: "ID Car (NFC-chip, sealed)", images: [seedExtMedia("https://images.unsplash.com/photo-1594736797933-d0401ba2fe65?w=600&h=600&fit=crop")], condition: PRODUCT_FIELDS.CONDITION_VALUES.NEW, estimatedValue: 69900, prizeSlotPrice: 69900, isWon: false },
183
+ { itemNumber: 10, title: "Redline Beach Bomb (1969 prototype type)", images: [seedExtMedia("https://images.unsplash.com/photo-1594736797933-d0401ba2fe65?w=600&h=600&fit=crop")], condition: PRODUCT_FIELDS.CONDITION_VALUES.USED, estimatedValue: 199900, prizeSlotPrice: 199900, isWon: false },
184
+ ];
185
+ }
117
186
  function _pokemonPrizeItems() {
118
187
  return [
119
188
  {