@cellarnode/ui 0.2.1 → 0.3.1

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 (70) hide show
  1. package/README.md +238 -0
  2. package/dist/chat/chat-toggle-button.d.ts +6 -3
  3. package/dist/chat/chat-toggle-button.d.ts.map +1 -1
  4. package/dist/chat/chat-toggle-button.js +9 -4
  5. package/dist/chat/chat-toggle-button.js.map +1 -1
  6. package/dist/chat/messenger-layout.d.ts.map +1 -1
  7. package/dist/chat/messenger-layout.js +7 -2
  8. package/dist/chat/messenger-layout.js.map +1 -1
  9. package/dist/components/stat-card.d.ts +12 -0
  10. package/dist/components/stat-card.d.ts.map +1 -0
  11. package/dist/components/stat-card.js +10 -0
  12. package/dist/components/stat-card.js.map +1 -0
  13. package/dist/globe/country-coords.d.ts +29 -0
  14. package/dist/globe/country-coords.d.ts.map +1 -0
  15. package/dist/globe/country-coords.js +117 -0
  16. package/dist/globe/country-coords.js.map +1 -0
  17. package/dist/globe/globe-loading-skeleton.d.ts +10 -0
  18. package/dist/globe/globe-loading-skeleton.d.ts.map +1 -0
  19. package/dist/globe/globe-loading-skeleton.js +23 -0
  20. package/dist/globe/globe-loading-skeleton.js.map +1 -0
  21. package/dist/globe/index.d.ts +2 -0
  22. package/dist/globe/index.d.ts.map +1 -1
  23. package/dist/globe/index.js +2 -0
  24. package/dist/globe/index.js.map +1 -1
  25. package/dist/hooks/use-deferred-mount.d.ts +16 -0
  26. package/dist/hooks/use-deferred-mount.d.ts.map +1 -0
  27. package/dist/hooks/use-deferred-mount.js +32 -0
  28. package/dist/hooks/use-deferred-mount.js.map +1 -0
  29. package/dist/index.d.ts +3 -0
  30. package/dist/index.d.ts.map +1 -1
  31. package/dist/index.js +2 -0
  32. package/dist/index.js.map +1 -1
  33. package/dist/nav/app-shell.d.ts +18 -0
  34. package/dist/nav/app-shell.d.ts.map +1 -0
  35. package/dist/nav/app-shell.js +9 -0
  36. package/dist/nav/app-shell.js.map +1 -0
  37. package/dist/nav/app-sidebar.d.ts +33 -0
  38. package/dist/nav/app-sidebar.d.ts.map +1 -0
  39. package/dist/nav/app-sidebar.js +46 -0
  40. package/dist/nav/app-sidebar.js.map +1 -0
  41. package/dist/nav/expandable-nav-item.d.ts +11 -0
  42. package/dist/nav/expandable-nav-item.d.ts.map +1 -0
  43. package/dist/nav/expandable-nav-item.js +27 -0
  44. package/dist/nav/expandable-nav-item.js.map +1 -0
  45. package/dist/nav/index.d.ts +6 -0
  46. package/dist/nav/index.d.ts.map +1 -0
  47. package/dist/nav/index.js +5 -0
  48. package/dist/nav/index.js.map +1 -0
  49. package/dist/nav/types.d.ts +40 -0
  50. package/dist/nav/types.d.ts.map +1 -0
  51. package/dist/nav/types.js +4 -0
  52. package/dist/nav/types.js.map +1 -0
  53. package/dist/opportunities/index.d.ts +3 -0
  54. package/dist/opportunities/index.d.ts.map +1 -0
  55. package/dist/opportunities/index.js +2 -0
  56. package/dist/opportunities/index.js.map +1 -0
  57. package/dist/opportunities/opportunities-table.d.ts +23 -0
  58. package/dist/opportunities/opportunities-table.d.ts.map +1 -0
  59. package/dist/opportunities/opportunities-table.js +115 -0
  60. package/dist/opportunities/opportunities-table.js.map +1 -0
  61. package/dist/profile/index.d.ts +2 -0
  62. package/dist/profile/index.d.ts.map +1 -0
  63. package/dist/profile/index.js +2 -0
  64. package/dist/profile/index.js.map +1 -0
  65. package/dist/profile/profile.d.ts +50 -0
  66. package/dist/profile/profile.d.ts.map +1 -0
  67. package/dist/profile/profile.js +30 -0
  68. package/dist/profile/profile.js.map +1 -0
  69. package/package.json +24 -2
  70. package/src/theme/tokens.css +6 -0
@@ -4,4 +4,6 @@ export { numericToAlpha2, alpha2ToNumeric } from "./map/country-code-map";
4
4
  export { useElectronEmitter } from "./electron-arc";
5
5
  export { GlobeView } from "./globe-view";
6
6
  export { addStarfield, addHalo, getVignetteStyle } from "./scene-extras";
7
+ export { GlobeLoadingSkeleton } from "./globe-loading-skeleton";
8
+ export { countryCoords, resolveCountries, COUNTRY_COORDS } from "./country-coords";
7
9
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/globe/index.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,UAAU,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAGjG,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAC3F,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAG1E,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAEpD,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAGzC,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/globe/index.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,UAAU,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAGjG,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAC3F,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAG1E,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAEpD,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAGzC,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAEzE,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Defers mounting of heavy components (e.g. WebGL globe) until the browser is
3
+ * idle, preventing them from blocking the main thread during initial page paint.
4
+ *
5
+ * Uses `requestIdleCallback` with a `setTimeout` fallback for browsers that
6
+ * don't support it (Safari < 18).
7
+ *
8
+ * @example
9
+ * function GlobeWrapper() {
10
+ * const mounted = useDeferredMount();
11
+ * if (!mounted) return <Skeleton className="h-96 w-full rounded-xl" />;
12
+ * return <Suspense fallback={<Skeleton />}><GlobeView /></Suspense>;
13
+ * }
14
+ */
15
+ export declare function useDeferredMount(delayMs?: number): boolean;
16
+ //# sourceMappingURL=use-deferred-mount.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-deferred-mount.d.ts","sourceRoot":"","sources":["../../src/hooks/use-deferred-mount.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;GAaG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,SAAK,GAAG,OAAO,CAmBtD"}
@@ -0,0 +1,32 @@
1
+ import { useEffect, useState } from "react";
2
+ /**
3
+ * Defers mounting of heavy components (e.g. WebGL globe) until the browser is
4
+ * idle, preventing them from blocking the main thread during initial page paint.
5
+ *
6
+ * Uses `requestIdleCallback` with a `setTimeout` fallback for browsers that
7
+ * don't support it (Safari < 18).
8
+ *
9
+ * @example
10
+ * function GlobeWrapper() {
11
+ * const mounted = useDeferredMount();
12
+ * if (!mounted) return <Skeleton className="h-96 w-full rounded-xl" />;
13
+ * return <Suspense fallback={<Skeleton />}><GlobeView /></Suspense>;
14
+ * }
15
+ */
16
+ export function useDeferredMount(delayMs = 50) {
17
+ const [mounted, setMounted] = useState(false);
18
+ useEffect(() => {
19
+ let handle;
20
+ if (typeof requestIdleCallback !== "undefined") {
21
+ handle = requestIdleCallback(() => setMounted(true), {
22
+ timeout: delayMs,
23
+ });
24
+ return () => cancelIdleCallback(handle);
25
+ }
26
+ // Safari fallback
27
+ const timer = setTimeout(() => setMounted(true), delayMs);
28
+ return () => clearTimeout(timer);
29
+ }, [delayMs]);
30
+ return mounted;
31
+ }
32
+ //# sourceMappingURL=use-deferred-mount.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-deferred-mount.js","sourceRoot":"","sources":["../../src/hooks/use-deferred-mount.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAE5C;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAAO,GAAG,EAAE;IAC3C,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAE9C,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,MAAc,CAAC;QAEnB,IAAI,OAAO,mBAAmB,KAAK,WAAW,EAAE,CAAC;YAC/C,MAAM,GAAG,mBAAmB,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE;gBACnD,OAAO,EAAE,OAAO;aACjB,CAAC,CAAC;YACH,OAAO,GAAG,EAAE,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC;QAC1C,CAAC;QAED,kBAAkB;QAClB,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,CAAC;QAC1D,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;IACnC,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;IAEd,OAAO,OAAO,CAAC;AACjB,CAAC"}
package/dist/index.d.ts CHANGED
@@ -3,6 +3,7 @@ export { toneClass, offerStatusTone, type SemanticTone, } from "./lib/semantic-t
3
3
  export { COMMON_CURRENCIES, type CurrencyCode } from "./lib/currencies";
4
4
  export { useIsMobile } from "./hooks/use-mobile";
5
5
  export { useToast, toast as radixToast } from "./hooks/use-toast";
6
+ export { useDeferredMount } from "./hooks/use-deferred-mount";
6
7
  export * from "./components/accordion";
7
8
  export * from "./components/alert";
8
9
  export * from "./components/avatar";
@@ -57,4 +58,6 @@ export { AnimatedList } from "./components/animated-list";
57
58
  export type { AnimatedListItem, AnimatedListProps } from "./components/animated-list";
58
59
  export { ClassificationSelect } from "./components/classification-select";
59
60
  export type { ClassificationSelectProps, CategoryOption } from "./components/classification-select";
61
+ export { StatCard } from "./components/stat-card";
62
+ export type { StatCardProps } from "./components/stat-card";
60
63
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -4,6 +4,7 @@ export { COMMON_CURRENCIES } from "./lib/currencies";
4
4
  // Hooks
5
5
  export { useIsMobile } from "./hooks/use-mobile";
6
6
  export { useToast, toast as radixToast } from "./hooks/use-toast";
7
+ export { useDeferredMount } from "./hooks/use-deferred-mount";
7
8
  // Components (alphabetical)
8
9
  export * from "./components/accordion";
9
10
  export * from "./components/alert";
@@ -66,4 +67,5 @@ export { ShadcnDialog, ShadcnDialogClose, ShadcnDialogContent, ShadcnDialogDescr
66
67
  export { ShadcnSelect, ShadcnSelectContent, ShadcnSelectGroup, ShadcnSelectItem, ShadcnSelectScrollDownButton, ShadcnSelectScrollUpButton, ShadcnSelectTrigger, ShadcnSelectValue, } from "./components/shadcn-select";
67
68
  export { AnimatedList } from "./components/animated-list";
68
69
  export { ClassificationSelect } from "./components/classification-select";
70
+ export { StatCard } from "./components/stat-card";
69
71
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import React from "react";
2
+ interface AppShellProps {
3
+ /** The rendered sidebar content (e.g. <AppSidebar ...props />) */
4
+ sidebar: React.ReactNode;
5
+ /** Main page content */
6
+ children: React.ReactNode;
7
+ /** Page title for mobile top bar */
8
+ mobileTitle?: string;
9
+ /** Right-side slot for mobile top bar (notifications, avatar, etc.) */
10
+ mobileTray?: React.ReactNode;
11
+ /** Floating overlay (e.g. Chat FAB) rendered outside the scroll area */
12
+ overlay?: React.ReactNode;
13
+ /** Optional extra class on the main content wrapper */
14
+ contentClassName?: string;
15
+ }
16
+ export declare function AppShell({ sidebar, children, mobileTitle, mobileTray, overlay, contentClassName, }: AppShellProps): import("react/jsx-runtime").JSX.Element;
17
+ export {};
18
+ //# sourceMappingURL=app-shell.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-shell.d.ts","sourceRoot":"","sources":["../../src/nav/app-shell.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAIxC,UAAU,aAAa;IACrB,kEAAkE;IAClE,OAAO,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,wBAAwB;IACxB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,oCAAoC;IACpC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,uEAAuE;IACvE,UAAU,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC7B,wEAAwE;IACxE,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,uDAAuD;IACvD,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,wBAAgB,QAAQ,CAAC,EACvB,OAAO,EACP,QAAQ,EACR,WAAW,EACX,UAAU,EACV,OAAO,EACP,gBAAgB,GACjB,EAAE,aAAa,2CAgFf"}
@@ -0,0 +1,9 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState } from "react";
3
+ import { Sheet, SheetContent, SheetTitle } from "../components/sheet";
4
+ import { cn } from "../lib/utils";
5
+ export function AppShell({ sidebar, children, mobileTitle, mobileTray, overlay, contentClassName, }) {
6
+ const [mobileOpen, setMobileOpen] = useState(false);
7
+ return (_jsxs("div", { className: "min-h-dvh", children: [_jsx(Sheet, { open: mobileOpen, onOpenChange: setMobileOpen, children: _jsxs(SheetContent, { side: "left", className: "w-72 max-w-xs p-0 border-r-0 [&>button]:hidden", "aria-describedby": undefined, children: [_jsx(SheetTitle, { className: "sr-only", children: "Navigation" }), _jsx("div", { className: "flex h-full flex-col", children: sidebar })] }) }), _jsx("div", { className: "hidden lg:fixed lg:inset-y-0 lg:z-50 lg:flex lg:w-72 lg:flex-col", children: sidebar }), _jsxs("div", { className: cn("lg:pl-72 flex flex-col min-h-dvh", contentClassName), children: [_jsxs("div", { className: "sticky top-0 z-40 flex h-16 shrink-0 items-center gap-x-4 border-b border-border bg-card px-4 shadow-xs sm:gap-x-6 sm:px-6 lg:hidden", children: [_jsx("button", { type: "button", onClick: () => setMobileOpen(true), className: "-m-2.5 p-2.5 text-foreground", "aria-label": "Open sidebar", children: _jsx("svg", { className: "size-6", fill: "none", viewBox: "0 0 24 24", strokeWidth: 1.5, stroke: "currentColor", "aria-hidden": "true", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25h16.5" }) }) }), _jsx("div", { "aria-hidden": "true", className: "h-6 w-px bg-border" }), _jsxs("div", { className: "flex items-center gap-2 truncate", children: [_jsx("img", { src: "/android-chrome-192x192.png", alt: "", className: "size-4 shrink-0 rounded-xs" }), mobileTitle && (_jsx("span", { className: "text-sm font-semibold font-display text-foreground truncate", children: mobileTitle }))] }), mobileTray && (_jsx("div", { className: "ml-auto flex items-center gap-x-3", children: mobileTray }))] }), _jsx("main", { className: "flex-1 flex flex-col py-8", children: _jsx("div", { className: "flex-1 flex flex-col px-4 sm:px-6 lg:px-8", children: children }) })] }), overlay] }));
8
+ }
9
+ //# sourceMappingURL=app-shell.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-shell.js","sourceRoot":"","sources":["../../src/nav/app-shell.tsx"],"names":[],"mappings":";AAAA,OAAc,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACxC,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,UAAU,EAAoB,MAAM,qBAAqB,CAAC;AACxF,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAiBlC,MAAM,UAAU,QAAQ,CAAC,EACvB,OAAO,EACP,QAAQ,EACR,WAAW,EACX,UAAU,EACV,OAAO,EACP,gBAAgB,GACF;IACd,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAEpD,OAAO,CACL,eAAK,SAAS,EAAC,WAAW,aAExB,KAAC,KAAK,IAAC,IAAI,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,YAClD,MAAC,YAAY,IACX,IAAI,EAAC,MAAM,EACX,SAAS,EAAC,gDAAgD,sBACxC,SAAS,aAE3B,KAAC,UAAU,IAAC,SAAS,EAAC,SAAS,2BAAwB,EACvD,cAAK,SAAS,EAAC,sBAAsB,YAAE,OAAO,GAAO,IACxC,GACT,EAGR,cAAK,SAAS,EAAC,kEAAkE,YAC9E,OAAO,GACJ,EAGN,eAAK,SAAS,EAAE,EAAE,CAAC,kCAAkC,EAAE,gBAAgB,CAAC,aAEtE,eAAK,SAAS,EAAC,sIAAsI,aACnJ,iBACE,IAAI,EAAC,QAAQ,EACb,OAAO,EAAE,GAAG,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,EAClC,SAAS,EAAC,8BAA8B,gBAC7B,cAAc,YAEzB,cACE,SAAS,EAAC,QAAQ,EAClB,IAAI,EAAC,MAAM,EACX,OAAO,EAAC,WAAW,EACnB,WAAW,EAAE,GAAG,EAChB,MAAM,EAAC,cAAc,iBACT,MAAM,YAElB,eACE,aAAa,EAAC,OAAO,EACrB,cAAc,EAAC,OAAO,EACtB,CAAC,EAAC,8CAA8C,GAChD,GACE,GACC,EAET,6BAAiB,MAAM,EAAC,SAAS,EAAC,oBAAoB,GAAG,EAEzD,eAAK,SAAS,EAAC,kCAAkC,aAC/C,cACE,GAAG,EAAC,6BAA6B,EACjC,GAAG,EAAC,EAAE,EACN,SAAS,EAAC,4BAA4B,GACtC,EACD,WAAW,IAAI,CACd,eAAM,SAAS,EAAC,6DAA6D,YAC1E,WAAW,GACP,CACR,IACG,EAEL,UAAU,IAAI,CACb,cAAK,SAAS,EAAC,mCAAmC,YAAE,UAAU,GAAO,CACtE,IACG,EAGN,eAAM,SAAS,EAAC,2BAA2B,YACzC,cAAK,SAAS,EAAC,2CAA2C,YACvD,QAAQ,GACL,GACD,IACH,EAGL,OAAO,IACJ,CACP,CAAC;AACJ,CAAC"}
@@ -0,0 +1,33 @@
1
+ import React from "react";
2
+ import { type SidebarNavLeafItem, type SidebarNavSection, type SidebarUser, type RenderLinkFn } from "./types";
3
+ interface AppSidebarProps {
4
+ /** "Producer Portal" | "Importer Portal" | any custom label */
5
+ portalLabel: string;
6
+ /** Optional pinned dashboard item shown above nav sections */
7
+ dashboardItem?: SidebarNavLeafItem;
8
+ navSections: SidebarNavSection[];
9
+ /** Current route pathname for active-state determination */
10
+ currentPath: string;
11
+ /** Provide the router-aware Link component */
12
+ renderLink: RenderLinkFn;
13
+ user: SidebarUser | null;
14
+ isDark: boolean;
15
+ onToggleTheme: () => void;
16
+ onSignOut: () => void;
17
+ /** Notification button (e.g. <NotificationPanel />) rendered in footer */
18
+ notificationSlot?: React.ReactNode;
19
+ /** Language switcher rendered in footer */
20
+ languageSwitcherSlot?: React.ReactNode;
21
+ /** Any dashboard-specific controls in the footer (e.g. data-source toggle) */
22
+ extraFooterContent?: React.ReactNode;
23
+ /** i18n overrides */
24
+ labels?: {
25
+ signOut?: string;
26
+ user?: string;
27
+ switchToLight?: string;
28
+ switchToDark?: string;
29
+ };
30
+ }
31
+ export declare function AppSidebar({ portalLabel, dashboardItem, navSections, currentPath, renderLink, user, isDark, onToggleTheme, onSignOut, notificationSlot, languageSwitcherSlot, extraFooterContent, labels, }: AppSidebarProps): import("react/jsx-runtime").JSX.Element;
32
+ export {};
33
+ //# sourceMappingURL=app-sidebar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-sidebar.d.ts","sourceRoot":"","sources":["../../src/nav/app-sidebar.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,OAAO,EAEL,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,KAAK,WAAW,EAChB,KAAK,YAAY,EAClB,MAAM,SAAS,CAAC;AAIjB,UAAU,eAAe;IACvB,+DAA+D;IAC/D,WAAW,EAAE,MAAM,CAAC;IACpB,8DAA8D;IAC9D,aAAa,CAAC,EAAE,kBAAkB,CAAC;IACnC,WAAW,EAAE,iBAAiB,EAAE,CAAC;IACjC,4DAA4D;IAC5D,WAAW,EAAE,MAAM,CAAC;IACpB,8CAA8C;IAC9C,UAAU,EAAE,YAAY,CAAC;IACzB,IAAI,EAAE,WAAW,GAAG,IAAI,CAAC;IACzB,MAAM,EAAE,OAAO,CAAC;IAChB,aAAa,EAAE,MAAM,IAAI,CAAC;IAC1B,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,0EAA0E;IAC1E,gBAAgB,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACnC,2CAA2C;IAC3C,oBAAoB,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACvC,8EAA8E;IAC9E,kBAAkB,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACrC,qBAAqB;IACrB,MAAM,CAAC,EAAE;QACP,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,YAAY,CAAC,EAAE,MAAM,CAAC;KACvB,CAAC;CACH;AAOD,wBAAgB,UAAU,CAAC,EACzB,WAAW,EACX,aAAa,EACb,WAAW,EACX,WAAW,EACX,UAAU,EACV,IAAI,EACJ,MAAM,EACN,aAAa,EACb,SAAS,EACT,gBAAgB,EAChB,oBAAoB,EACpB,kBAAkB,EAClB,MAAW,GACZ,EAAE,eAAe,2CAkKjB"}
@@ -0,0 +1,46 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { Sun, Moon } from "lucide-react";
3
+ import { cn } from "../lib/utils";
4
+ import { ExpandableNavItem } from "./expandable-nav-item";
5
+ import { isSidebarNavExpandable, } from "./types";
6
+ const BRAND_NAME = "CellarNode";
7
+ function isActive(currentPath, href) {
8
+ if (href === "/" || href === "/dashboard")
9
+ return currentPath === href;
10
+ return currentPath.startsWith(href);
11
+ }
12
+ export function AppSidebar({ portalLabel, dashboardItem, navSections, currentPath, renderLink, user, isDark, onToggleTheme, onSignOut, notificationSlot, languageSwitcherSlot, extraFooterContent, labels = {}, }) {
13
+ const ThemeIcon = isDark ? Sun : Moon;
14
+ const initials = user?.initials
15
+ ?? (user?.name
16
+ ? user.name
17
+ .split(" ")
18
+ .map((n) => n[0])
19
+ .join("")
20
+ .toUpperCase()
21
+ .slice(0, 2)
22
+ : "?");
23
+ return (_jsxs("div", { className: "relative flex grow flex-col gap-y-5 overflow-y-auto bg-primary px-6 dark:bg-sidebar dark:before:pointer-events-none dark:before:absolute dark:before:inset-0 dark:before:border-r dark:before:border-white/5 dark:before:bg-white/[0.015]", children: [_jsx("div", { className: "relative flex h-16 shrink-0 items-center gap-3", children: renderLink({
24
+ href: dashboardItem?.href ?? "/",
25
+ className: "flex items-center gap-3",
26
+ children: (_jsxs(_Fragment, { children: [_jsx("img", { src: "/android-chrome-192x192.png", alt: BRAND_NAME, className: "size-10 shrink-0 rounded-[1.15rem]" }), _jsxs("div", { className: "flex flex-col leading-none", children: [_jsx("span", { className: "text-sm font-semibold font-display tracking-tight text-white dark:text-sidebar-foreground", children: BRAND_NAME }), _jsx("span", { className: "text-[11px] uppercase tracking-[0.16em] text-white/65 dark:text-sidebar-foreground/65", children: portalLabel })] })] })),
27
+ }) }), _jsx("nav", { className: "relative flex flex-1 flex-col", children: _jsxs("ul", { role: "list", className: "flex flex-1 flex-col gap-y-7", children: [dashboardItem && (_jsx("li", { children: _jsx("ul", { role: "list", className: "-mx-2 mt-2 space-y-1.5", children: _jsx(NavLeafItem, { item: dashboardItem, current: isActive(currentPath, dashboardItem.href), renderLink: renderLink }) }) })), navSections.map((section) => (_jsxs("li", { children: [_jsx("div", { className: "text-[11px] font-semibold uppercase tracking-[0.16em] text-white/50 dark:text-sidebar-foreground/50 mb-2", children: section.label }), _jsx("ul", { role: "list", className: "-mx-2 space-y-1.5", children: section.items.map((item) => isSidebarNavExpandable(item) ? (_jsx(ExpandableNavItem, { name: item.title, icon: item.icon, children: item.children, currentPath: currentPath, renderLink: renderLink }, item.title)) : (_jsx(NavLeafItem, { item: item, current: isActive(currentPath, item.href), renderLink: renderLink }, item.href))) })] }, section.label))), _jsxs("li", { className: "-mx-6 mt-auto", children: [extraFooterContent && (_jsx("div", { className: "px-6 pb-3", children: extraFooterContent })), _jsxs("div", { className: "flex items-center gap-x-4 px-6 py-3", children: [renderLink({
28
+ href: user?.profileHref ?? "/profile",
29
+ className: "flex flex-1 items-center gap-x-4 text-sm/6 font-semibold text-primary-foreground hover:opacity-80 truncate min-w-0",
30
+ children: (_jsxs(_Fragment, { children: [_jsx("span", { className: "inline-grid size-8 shrink-0 select-none place-items-center rounded-full bg-primary/80 text-xs font-semibold text-white outline -outline-offset-1 outline-white/10 dark:bg-white/5", "aria-hidden": "true", children: user?.avatarUrl ? (_jsx("img", { src: user.avatarUrl, alt: user.name, className: "size-full rounded-full object-cover" })) : (initials) }), _jsx("span", { className: "font-display truncate", children: user?.name ?? labels.user ?? "User" })] })),
31
+ }), _jsxs("div", { className: "flex items-center gap-x-2", children: [_jsx("button", { type: "button", onClick: onToggleTheme, "aria-label": isDark
32
+ ? (labels.switchToLight ?? "Switch to light theme")
33
+ : (labels.switchToDark ?? "Switch to dark theme"), className: "inline-flex size-9 items-center justify-center rounded-full border border-white/15 bg-white/5 text-white/80 transition-colors hover:bg-white/10 hover:text-white focus:outline-none focus-visible:ring-2 focus-visible:ring-white/20 dark:border-white/10 dark:bg-white/5 dark:text-zinc-200 dark:hover:bg-white/10 dark:hover:text-zinc-50", children: _jsx(ThemeIcon, { className: "size-4.5", "aria-hidden": "true" }) }), notificationSlot] })] }), languageSwitcherSlot && (_jsx("div", { className: "flex items-center justify-between px-6 pb-3", children: languageSwitcherSlot })), _jsx("div", { className: "px-6 pb-4", children: _jsx("button", { type: "button", onClick: onSignOut, className: "w-full rounded-md border border-white/20 px-3 py-2 text-sm font-semibold text-white/80 hover:bg-white/5 hover:text-white dark:border-white/10 dark:text-zinc-200 dark:hover:bg-white/5 dark:hover:text-zinc-50", children: labels.signOut ?? "Sign out" }) })] })] }) })] }));
34
+ }
35
+ function NavLeafItem({ item, current, renderLink, }) {
36
+ return (_jsx("li", { children: renderLink({
37
+ href: item.href,
38
+ className: cn("group relative flex min-h-11 items-center gap-x-3 rounded-md px-3 py-2 text-sm/6 transition-colors ring-1 ring-transparent", current
39
+ ? "bg-white/10 text-white font-semibold before:absolute before:left-1.5 before:top-1/2 before:h-5 before:w-0.5 before:-translate-y-1/2 before:rounded-full before:bg-white/85 dark:bg-white/6 dark:text-zinc-50 dark:ring-1 dark:ring-white/10 dark:before:bg-primary/80"
40
+ : "text-white/80 font-medium hover:bg-white/6 hover:text-white dark:text-zinc-300 dark:hover:bg-white/5 dark:hover:text-zinc-100"),
41
+ children: (_jsxs(_Fragment, { children: [_jsx(item.icon, { "aria-hidden": "true", className: cn("size-6 shrink-0 transition-opacity", current ? "opacity-100" : "opacity-80 group-hover:opacity-100") }), _jsx("span", { className: cn("font-display truncate", current ? "tracking-[0.01em]" : ""), children: item.title }), item.badgeCount != null && item.badgeCount > 0 ? (_jsx("span", { "aria-hidden": "true", className: cn("ml-auto w-9 min-w-max rounded-full px-2.5 py-0.5 text-center text-xs/5 font-medium whitespace-nowrap outline-1 -outline-offset-1", current
42
+ ? "bg-white/12 text-white outline-white/15 dark:bg-white/8 dark:text-zinc-100 dark:outline-white/10"
43
+ : "bg-white/8 text-white/80 outline-white/10 dark:bg-white/5 dark:text-zinc-300 dark:outline-white/5"), children: item.badgeCount > 99 ? "99+" : item.badgeCount })) : null] })),
44
+ }) }));
45
+ }
46
+ //# sourceMappingURL=app-sidebar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-sidebar.js","sourceRoot":"","sources":["../../src/nav/app-sidebar.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import type { SidebarNavSubItem, IconType, RenderLinkFn } from "./types";
2
+ interface ExpandableNavItemProps {
3
+ name: string;
4
+ icon: IconType;
5
+ children: SidebarNavSubItem[];
6
+ currentPath: string;
7
+ renderLink: RenderLinkFn;
8
+ }
9
+ export declare function ExpandableNavItem({ name, icon: Icon, children, currentPath, renderLink, }: ExpandableNavItemProps): import("react/jsx-runtime").JSX.Element;
10
+ export {};
11
+ //# sourceMappingURL=expandable-nav-item.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"expandable-nav-item.d.ts","sourceRoot":"","sources":["../../src/nav/expandable-nav-item.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,iBAAiB,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEzE,UAAU,sBAAsB;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,QAAQ,CAAC;IACf,QAAQ,EAAE,iBAAiB,EAAE,CAAC;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,YAAY,CAAC;CAC1B;AAED,wBAAgB,iBAAiB,CAAC,EAChC,IAAI,EACJ,IAAI,EAAE,IAAI,EACV,QAAQ,EACR,WAAW,EACX,UAAU,GACX,EAAE,sBAAsB,2CAuExB"}
@@ -0,0 +1,27 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState, useEffect } from "react";
3
+ import { ChevronDown, ChevronUp } from "lucide-react";
4
+ import { cn } from "../lib/utils";
5
+ export function ExpandableNavItem({ name, icon: Icon, children, currentPath, renderLink, }) {
6
+ const isChildActive = children.some((child) => child.href === "/" ? currentPath === "/" : currentPath.startsWith(child.href));
7
+ const [open, setOpen] = useState(isChildActive);
8
+ useEffect(() => {
9
+ if (isChildActive)
10
+ setOpen(true);
11
+ }, [isChildActive]);
12
+ return (_jsxs("li", { children: [_jsxs("button", { type: "button", onClick: () => setOpen((prev) => !prev), className: cn("group relative flex w-full min-h-11 items-center gap-x-3 rounded-md px-3 py-2 text-sm/6 transition-colors ring-1 ring-transparent", isChildActive
13
+ ? "text-white font-semibold"
14
+ : "text-white/80 font-medium hover:bg-white/6 hover:text-white dark:text-zinc-300 dark:hover:bg-white/5 dark:hover:text-zinc-100"), children: [_jsx(Icon, { "aria-hidden": "true", className: cn("size-6 shrink-0 transition-opacity", isChildActive ? "opacity-100" : "opacity-80 group-hover:opacity-100") }), _jsx("span", { className: cn("font-display truncate", isChildActive ? "tracking-[0.01em]" : ""), children: name }), open ? (_jsx(ChevronUp, { "aria-hidden": "true", className: "ml-auto size-4 shrink-0 opacity-60 group-hover:opacity-80" })) : (_jsx(ChevronDown, { "aria-hidden": "true", className: "ml-auto size-4 shrink-0 opacity-60 group-hover:opacity-80" }))] }), open && (_jsx("ul", { role: "list", className: "mt-1 space-y-1", children: children.map((child, index) => {
15
+ const current = index === 0
16
+ ? currentPath === child.href
17
+ : currentPath === child.href || currentPath.startsWith(child.href + "/");
18
+ return (_jsx("li", { children: renderLink({
19
+ href: child.href,
20
+ className: cn("group relative flex min-h-9 items-center gap-x-3 rounded-md pl-12 pr-3 py-1.5 text-sm/6 transition-colors ring-1 ring-transparent", current
21
+ ? "bg-white/10 text-white font-semibold before:absolute before:left-1.5 before:top-1/2 before:h-5 before:w-0.5 before:-translate-y-1/2 before:rounded-full before:bg-white/85 dark:bg-white/6 dark:text-zinc-50 dark:ring-1 dark:ring-white/10 dark:before:bg-primary/80"
22
+ : "text-white/80 font-medium hover:bg-white/6 hover:text-white dark:text-zinc-300 dark:hover:bg-white/5 dark:hover:text-zinc-100"),
23
+ children: (_jsx("span", { className: cn("font-display truncate", current ? "tracking-[0.01em]" : ""), children: child.title })),
24
+ }) }, child.href));
25
+ }) }))] }));
26
+ }
27
+ //# sourceMappingURL=expandable-nav-item.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"expandable-nav-item.js","sourceRoot":"","sources":["../../src/nav/expandable-nav-item.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACtD,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAWlC,MAAM,UAAU,iBAAiB,CAAC,EAChC,IAAI,EACJ,IAAI,EAAE,IAAI,EACV,QAAQ,EACR,WAAW,EACX,UAAU,GACa;IACvB,MAAM,aAAa,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAC5C,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC,WAAW,KAAK,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,CAC9E,CAAC;IAEF,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAC,aAAa,CAAC,CAAC;IAEhD,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,aAAa;YAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IACnC,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC;IAEpB,OAAO,CACL,yBACE,kBACE,IAAI,EAAC,QAAQ,EACb,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,EACvC,SAAS,EAAE,EAAE,CACX,mIAAmI,EACnI,aAAa;oBACX,CAAC,CAAC,0BAA0B;oBAC5B,CAAC,CAAC,+HAA+H,CACpI,aAED,KAAC,IAAI,mBACS,MAAM,EAClB,SAAS,EAAE,EAAE,CACX,oCAAoC,EACpC,aAAa,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,oCAAoC,CACrE,GACD,EACF,eAAM,SAAS,EAAE,EAAE,CAAC,uBAAuB,EAAE,aAAa,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,EAAE,CAAC,YACnF,IAAI,GACA,EACN,IAAI,CAAC,CAAC,CAAC,CACN,KAAC,SAAS,mBAAa,MAAM,EAAC,SAAS,EAAC,2DAA2D,GAAG,CACvG,CAAC,CAAC,CAAC,CACF,KAAC,WAAW,mBAAa,MAAM,EAAC,SAAS,EAAC,2DAA2D,GAAG,CACzG,IACM,EAER,IAAI,IAAI,CACP,aAAI,IAAI,EAAC,MAAM,EAAC,SAAS,EAAC,gBAAgB,YACvC,QAAQ,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;oBAC7B,MAAM,OAAO,GACX,KAAK,KAAK,CAAC;wBACT,CAAC,CAAC,WAAW,KAAK,KAAK,CAAC,IAAI;wBAC5B,CAAC,CAAC,WAAW,KAAK,KAAK,CAAC,IAAI,IAAI,WAAW,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,GAAG,GAAG,CAAC,CAAC;oBAE7E,OAAO,CACL,uBACG,UAAU,CAAC;4BACV,IAAI,EAAE,KAAK,CAAC,IAAI;4BAChB,SAAS,EAAE,EAAE,CACX,mIAAmI,EACnI,OAAO;gCACL,CAAC,CAAC,uQAAuQ;gCACzQ,CAAC,CAAC,+HAA+H,CACpI;4BACD,QAAQ,EAAE,CACR,eAAM,SAAS,EAAE,EAAE,CAAC,uBAAuB,EAAE,OAAO,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,EAAE,CAAC,YAC7E,KAAK,CAAC,KAAK,GACP,CACR;yBACF,CAAC,IAdK,KAAK,CAAC,IAAI,CAed,CACN,CAAC;gBACJ,CAAC,CAAC,GACC,CACN,IACE,CACN,CAAC;AACJ,CAAC"}
@@ -0,0 +1,6 @@
1
+ export { AppSidebar } from "./app-sidebar";
2
+ export { AppShell } from "./app-shell";
3
+ export { ExpandableNavItem } from "./expandable-nav-item";
4
+ export type { IconType, RenderLinkFn, SidebarNavLeafItem, SidebarNavExpandableItem, SidebarNavSectionItem, SidebarNavSection, SidebarNavSubItem, SidebarUser, } from "./types";
5
+ export { isSidebarNavExpandable } from "./types";
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/nav/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,YAAY,EACV,QAAQ,EACR,YAAY,EACZ,kBAAkB,EAClB,wBAAwB,EACxB,qBAAqB,EACrB,iBAAiB,EACjB,iBAAiB,EACjB,WAAW,GACZ,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAC"}
@@ -0,0 +1,5 @@
1
+ export { AppSidebar } from "./app-sidebar";
2
+ export { AppShell } from "./app-shell";
3
+ export { ExpandableNavItem } from "./expandable-nav-item";
4
+ export { isSidebarNavExpandable } from "./types";
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/nav/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAW1D,OAAO,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAC"}
@@ -0,0 +1,40 @@
1
+ import type React from "react";
2
+ export type IconType = React.ComponentType<{
3
+ className?: string;
4
+ "aria-hidden"?: boolean | "true" | "false";
5
+ }>;
6
+ export type RenderLinkFn = (props: {
7
+ href: string;
8
+ className?: string;
9
+ children: React.ReactNode;
10
+ }) => React.ReactElement;
11
+ export interface SidebarNavSubItem {
12
+ title: string;
13
+ href: string;
14
+ }
15
+ export interface SidebarNavLeafItem {
16
+ title: string;
17
+ href: string;
18
+ icon: IconType;
19
+ badgeCount?: number;
20
+ }
21
+ export interface SidebarNavExpandableItem {
22
+ title: string;
23
+ icon: IconType;
24
+ expandable: true;
25
+ children: SidebarNavSubItem[];
26
+ }
27
+ export type SidebarNavSectionItem = SidebarNavLeafItem | SidebarNavExpandableItem;
28
+ export interface SidebarNavSection {
29
+ label: string;
30
+ items: SidebarNavSectionItem[];
31
+ }
32
+ export interface SidebarUser {
33
+ name: string;
34
+ email?: string;
35
+ initials?: string;
36
+ avatarUrl?: string;
37
+ profileHref: string;
38
+ }
39
+ export declare function isSidebarNavExpandable(item: SidebarNavSectionItem): item is SidebarNavExpandableItem;
40
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/nav/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,MAAM,MAAM,QAAQ,GAAG,KAAK,CAAC,aAAa,CAAC;IACzC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,OAAO,CAAC;CAC5C,CAAC,CAAC;AAEH,MAAM,MAAM,YAAY,GAAG,CAAC,KAAK,EAAE;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B,KAAK,KAAK,CAAC,YAAY,CAAC;AAEzB,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,QAAQ,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,wBAAwB;IACvC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,QAAQ,CAAC;IACf,UAAU,EAAE,IAAI,CAAC;IACjB,QAAQ,EAAE,iBAAiB,EAAE,CAAC;CAC/B;AAED,MAAM,MAAM,qBAAqB,GAAG,kBAAkB,GAAG,wBAAwB,CAAC;AAElF,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,qBAAqB,EAAE,CAAC;CAChC;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,qBAAqB,GAC1B,IAAI,IAAI,wBAAwB,CAElC"}
@@ -0,0 +1,4 @@
1
+ export function isSidebarNavExpandable(item) {
2
+ return "expandable" in item && item.expandable === true;
3
+ }
4
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/nav/types.ts"],"names":[],"mappings":"AA+CA,MAAM,UAAU,sBAAsB,CACpC,IAA2B;IAE3B,OAAO,YAAY,IAAI,IAAI,IAAI,IAAI,CAAC,UAAU,KAAK,IAAI,CAAC;AAC1D,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { OpportunitiesTable } from "./opportunities-table";
2
+ export type { OpportunitiesTableProps, OpportunityRow } from "./opportunities-table";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/opportunities/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,YAAY,EAAE,uBAAuB,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { OpportunitiesTable } from "./opportunities-table";
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/opportunities/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC"}
@@ -0,0 +1,23 @@
1
+ import * as React from "react";
2
+ export interface OpportunityRow {
3
+ id: string;
4
+ name: string;
5
+ marketIdentifier?: string | null;
6
+ beverageType?: string | null;
7
+ countryOfOrigin?: string | null;
8
+ status: string;
9
+ submissionDeadline?: string | null;
10
+ createdAt: string;
11
+ }
12
+ export interface OpportunitiesTableProps {
13
+ data: OpportunityRow[];
14
+ isLoading?: boolean;
15
+ /** Router-agnostic link renderer */
16
+ renderLink?: (href: string, children: React.ReactNode) => React.ReactNode;
17
+ /** Build href for a row. If not provided, rows are not clickable. */
18
+ getRowHref?: (row: OpportunityRow) => string;
19
+ emptyMessage?: string;
20
+ pageSize?: number;
21
+ }
22
+ export declare function OpportunitiesTable({ data, isLoading, renderLink, getRowHref, emptyMessage, pageSize, }: OpportunitiesTableProps): import("react/jsx-runtime").JSX.Element;
23
+ //# sourceMappingURL=opportunities-table.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"opportunities-table.d.ts","sourceRoot":"","sources":["../../src/opportunities/opportunities-table.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AA0B/B,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,cAAc,EAAE,CAAC;IACvB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,oCAAoC;IACpC,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC,SAAS,KAAK,KAAK,CAAC,SAAS,CAAC;IAC1E,qEAAqE;IACrE,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK,MAAM,CAAC;IAC7C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AA+QD,wBAAgB,kBAAkB,CAAC,EACjC,IAAI,EACJ,SAAiB,EACjB,UAAU,EACV,UAAU,EACV,YAAwC,EACxC,QAAa,GACd,EAAE,uBAAuB,2CAuHzB"}
@@ -0,0 +1,115 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import * as React from "react";
3
+ import { useReactTable, getCoreRowModel, getFilteredRowModel, getPaginationRowModel, } from "@tanstack/react-table";
4
+ import { AnimatePresence, motion } from "motion/react";
5
+ import { format, formatDistanceToNow, isPast, parseISO } from "date-fns";
6
+ import { Clock, Search, ChevronDown, ChevronLeft, ChevronRight, Rows3, Rows4, } from "lucide-react";
7
+ import { cn } from "../lib/utils";
8
+ import { ShadcnButton } from "../components/shadcn-button";
9
+ import { ShadcnInput } from "../components/shadcn-input";
10
+ import { Skeleton } from "../components/skeleton";
11
+ // ─── Country flags ────────────────────────────────────────────────────────────
12
+ const COUNTRY_FLAGS = {
13
+ AR: "🇦🇷", AU: "🇦🇺", AT: "🇦🇹", BE: "🇧🇪", BR: "🇧🇷",
14
+ CA: "🇨🇦", CL: "🇨🇱", CN: "🇨🇳", HR: "🇭🇷", CZ: "🇨🇿",
15
+ DK: "🇩🇰", FR: "🇫🇷", DE: "🇩🇪", GR: "🇬🇷", HU: "🇭🇺",
16
+ IE: "🇮🇪", IT: "🇮🇹", JP: "🇯🇵", MX: "🇲🇽", NL: "🇳🇱",
17
+ NO: "🇳🇴", PL: "🇵🇱", PT: "🇵🇹", ES: "🇪🇸", SE: "🇸🇪",
18
+ CH: "🇨🇭", TR: "🇹🇷", GB: "🇬🇧", US: "🇺🇸", ZA: "🇿🇦",
19
+ KR: "🇰🇷", NZ: "🇳🇿", SK: "🇸🇰", SI: "🇸🇮", FI: "🇫🇮",
20
+ EE: "🇪🇪", LV: "🇱🇻", LT: "🇱🇹", LU: "🇱🇺", RO: "🇷🇴",
21
+ };
22
+ const COUNTRY_NAME_TO_ISO = {
23
+ "Argentina": "AR", "Australia": "AU", "Austria": "AT", "Belgium": "BE",
24
+ "Brazil": "BR", "Canada": "CA", "Chile": "CL", "China": "CN",
25
+ "Croatia": "HR", "Czech Republic": "CZ", "Czechia": "CZ",
26
+ "Denmark": "DK", "France": "FR", "Germany": "DE", "Greece": "GR",
27
+ "Hungary": "HU", "Ireland": "IE", "Italy": "IT", "Japan": "JP",
28
+ "Mexico": "MX", "Netherlands": "NL", "Norway": "NO", "Poland": "PL",
29
+ "Portugal": "PT", "Spain": "ES", "Sweden": "SE", "Switzerland": "CH",
30
+ "Turkey": "TR", "Türkiye": "TR", "United Kingdom": "GB", "UK": "GB",
31
+ "United States": "US", "USA": "US", "South Africa": "ZA",
32
+ "South Korea": "KR", "New Zealand": "NZ", "Slovakia": "SK",
33
+ "Slovenia": "SI", "Finland": "FI", "Estonia": "EE", "Latvia": "LV",
34
+ "Lithuania": "LT", "Luxembourg": "LU", "Romania": "RO",
35
+ };
36
+ function getFlag(country) {
37
+ if (!country)
38
+ return "🏳️";
39
+ const upper = country.toUpperCase();
40
+ if (COUNTRY_FLAGS[upper])
41
+ return COUNTRY_FLAGS[upper];
42
+ const iso = COUNTRY_NAME_TO_ISO[country];
43
+ return iso ? (COUNTRY_FLAGS[iso] ?? "🏳️") : "🏳️";
44
+ }
45
+ // ─── Helpers ──────────────────────────────────────────────────────────────────
46
+ function StatusBadge({ status }) {
47
+ const normalised = status.toLowerCase();
48
+ return (_jsx("span", { className: cn("inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-semibold", normalised === "open" &&
49
+ "bg-emerald-100 text-emerald-800 dark:bg-emerald-900/30 dark:text-emerald-400", normalised === "closed" && "bg-muted text-muted-foreground", normalised === "draft" &&
50
+ "bg-amber-100 text-amber-800 dark:bg-amber-900/30 dark:text-amber-400", !["open", "closed", "draft"].includes(normalised) &&
51
+ "bg-muted text-muted-foreground"), children: status }));
52
+ }
53
+ function DeadlineDisplay({ deadline, full = false, }) {
54
+ if (!deadline)
55
+ return _jsx("span", { className: "text-muted-foreground", children: "\u2014" });
56
+ const date = parseISO(deadline);
57
+ const past = isPast(date);
58
+ const daysLeft = Math.ceil((date.getTime() - Date.now()) / (1000 * 60 * 60 * 24));
59
+ return (_jsxs("span", { className: cn("inline-flex items-center gap-1 text-sm", past && "text-destructive", !past && daysLeft <= 7 && "text-amber-600 dark:text-amber-400", !past && daysLeft > 7 && "text-emerald-600 dark:text-emerald-400"), children: [_jsx(Clock, { className: "size-3.5 shrink-0" }), full
60
+ ? format(date, "PPP")
61
+ : formatDistanceToNow(date, { addSuffix: true })] }));
62
+ }
63
+ // ─── Skeleton ─────────────────────────────────────────────────────────────────
64
+ function RowSkeleton({ density }) {
65
+ return (_jsxs("li", { className: cn("flex items-center gap-3 px-4", density === "comfortable" ? "py-3.5" : "py-2"), children: [_jsx(Skeleton, { className: "size-7 shrink-0 rounded-md" }), _jsxs("div", { className: "flex flex-1 flex-col gap-1.5", children: [_jsx(Skeleton, { className: "h-3.5 w-48 rounded" }), _jsx(Skeleton, { className: "h-3 w-28 rounded" })] }), _jsx(Skeleton, { className: "h-5 w-16 rounded-full" }), _jsx(Skeleton, { className: "h-5 w-16 rounded-full" }), _jsx(Skeleton, { className: "h-4 w-24 rounded" }), _jsx(Skeleton, { className: "size-5 shrink-0 rounded" })] }));
66
+ }
67
+ // ─── Detail grid ──────────────────────────────────────────────────────────────
68
+ function DetailField({ label, children, }) {
69
+ return (_jsxs("div", { className: "flex flex-col gap-0.5", children: [_jsx("span", { className: "text-xs font-medium text-muted-foreground", children: label }), _jsx("span", { className: "text-sm text-foreground", children: children })] }));
70
+ }
71
+ // ─── Row item ─────────────────────────────────────────────────────────────────
72
+ function OpportunityRowItem({ row, density, renderLink, getRowHref, }) {
73
+ const [expanded, setExpanded] = React.useState(false);
74
+ const href = getRowHref?.(row);
75
+ const flag = getFlag(row.countryOfOrigin);
76
+ const nameContent = (_jsx("span", { className: "text-sm font-semibold text-foreground hover:underline", children: row.name }));
77
+ return (_jsxs("li", { className: "bg-card", children: [_jsxs("div", { className: cn("flex items-center gap-3 px-4", density === "comfortable" ? "py-3.5" : "py-2"), children: [_jsx("span", { className: "shrink-0 text-xl leading-none", role: "img", "aria-label": row.countryOfOrigin ?? "Unknown country", children: flag }), _jsxs("div", { className: "min-w-0 flex-1", children: [href && renderLink ? (renderLink(href, nameContent)) : (nameContent), row.marketIdentifier && (_jsx("p", { className: "truncate text-xs text-muted-foreground", children: row.marketIdentifier }))] }), row.beverageType && (_jsx("span", { className: "hidden shrink-0 rounded-full bg-muted px-2 py-0.5 text-xs text-muted-foreground sm:inline-block", children: row.beverageType })), _jsx(StatusBadge, { status: row.status }), _jsx("span", { className: "hidden shrink-0 md:inline-flex", children: _jsx(DeadlineDisplay, { deadline: row.submissionDeadline }) }), _jsx("button", { type: "button", onClick: () => setExpanded((v) => !v), "aria-expanded": expanded, "aria-label": expanded ? "Collapse details" : "Expand details", className: "shrink-0 rounded-md p-1 text-muted-foreground transition-colors hover:bg-muted hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", children: _jsx(ChevronDown, { className: cn("size-4 transition-transform duration-200", expanded && "rotate-180") }) })] }), _jsx(AnimatePresence, { initial: false, children: expanded && (_jsx(motion.div, { initial: { height: 0, opacity: 0 }, animate: { height: "auto", opacity: 1 }, exit: { height: 0, opacity: 0 }, transition: { duration: 0.2, ease: "easeInOut" }, className: "overflow-hidden", children: _jsx("div", { className: "border-t border-border/40 bg-muted/20 px-4 pb-4 pt-3", children: _jsxs("div", { className: "grid grid-cols-2 gap-4 md:grid-cols-3", children: [_jsx(DetailField, { label: "Country of Origin", children: row.countryOfOrigin
78
+ ? `${flag} ${row.countryOfOrigin}`
79
+ : "—" }), _jsx(DetailField, { label: "Beverage Type", children: row.beverageType ?? "—" }), _jsx(DetailField, { label: "Submission Deadline", children: _jsx(DeadlineDisplay, { deadline: row.submissionDeadline, full: true }) }), _jsx(DetailField, { label: "Market Identifier", children: row.marketIdentifier ?? "—" }), _jsx(DetailField, { label: "Status", children: _jsx(StatusBadge, { status: row.status }) })] }) }) }, "detail")) })] }));
80
+ }
81
+ // ─── Main component ───────────────────────────────────────────────────────────
82
+ const DUMMY_COLUMNS = [
83
+ { accessorKey: "name" },
84
+ { accessorKey: "marketIdentifier" },
85
+ { accessorKey: "beverageType" },
86
+ { accessorKey: "countryOfOrigin" },
87
+ { accessorKey: "status" },
88
+ { accessorKey: "submissionDeadline" },
89
+ ];
90
+ export function OpportunitiesTable({ data, isLoading = false, renderLink, getRowHref, emptyMessage = "No opportunities found.", pageSize = 10, }) {
91
+ const [globalFilter, setGlobalFilter] = React.useState("");
92
+ const [density, setDensity] = React.useState("comfortable");
93
+ const table = useReactTable({
94
+ data,
95
+ columns: DUMMY_COLUMNS,
96
+ state: { globalFilter },
97
+ onGlobalFilterChange: setGlobalFilter,
98
+ globalFilterFn: (row, _columnId, filterValue) => {
99
+ const q = filterValue.toLowerCase();
100
+ return (row.original.name.toLowerCase().includes(q) ||
101
+ (row.original.marketIdentifier?.toLowerCase().includes(q) ?? false) ||
102
+ (row.original.beverageType?.toLowerCase().includes(q) ?? false) ||
103
+ (row.original.countryOfOrigin?.toLowerCase().includes(q) ?? false));
104
+ },
105
+ getCoreRowModel: getCoreRowModel(),
106
+ getFilteredRowModel: getFilteredRowModel(),
107
+ getPaginationRowModel: getPaginationRowModel(),
108
+ initialState: { pagination: { pageSize } },
109
+ });
110
+ const { pageIndex } = table.getState().pagination;
111
+ const pageCount = table.getPageCount();
112
+ const filteredCount = table.getFilteredRowModel().rows.length;
113
+ return (_jsxs("div", { className: "space-y-4", children: [_jsxs("div", { className: "flex flex-wrap items-center gap-3", children: [_jsxs("div", { className: "relative flex-1", children: [_jsx(Search, { className: "pointer-events-none absolute left-3 top-1/2 size-4 -translate-y-1/2 text-muted-foreground" }), _jsx(ShadcnInput, { value: globalFilter, onChange: (e) => setGlobalFilter(e.target.value), placeholder: "Search name, market, type, country\u2026", className: "pl-9" })] }), _jsxs("div", { className: "flex shrink-0 items-center gap-1", children: [_jsx(ShadcnButton, { variant: density === "comfortable" ? "secondary" : "ghost", size: "icon-sm", onClick: () => setDensity("comfortable"), title: "Comfortable density", children: _jsx(Rows4, { className: "size-4" }) }), _jsx(ShadcnButton, { variant: density === "compact" ? "secondary" : "ghost", size: "icon-sm", onClick: () => setDensity("compact"), title: "Compact density", children: _jsx(Rows3, { className: "size-4" }) })] }), !isLoading && (_jsxs("span", { className: "shrink-0 text-xs text-muted-foreground", children: [filteredCount, " ", filteredCount === 1 ? "opportunity" : "opportunities"] }))] }), _jsx("ul", { className: "divide-y divide-border/50 overflow-hidden rounded-2xl border border-border/60 bg-card", children: isLoading ? (Array.from({ length: 5 }).map((_, i) => (_jsx(RowSkeleton, { density: density }, i)))) : table.getRowModel().rows.length === 0 ? (_jsx("li", { className: "py-16 text-center text-sm text-muted-foreground", children: emptyMessage })) : (table.getRowModel().rows.map((row) => (_jsx(OpportunityRowItem, { row: row.original, density: density, renderLink: renderLink, getRowHref: getRowHref }, row.id)))) }), !isLoading && pageCount > 1 && (_jsxs("div", { className: "flex items-center justify-between gap-4", children: [_jsxs("p", { className: "text-xs text-muted-foreground", children: ["Page ", pageIndex + 1, " of ", pageCount] }), _jsxs("div", { className: "flex items-center gap-1.5", children: [_jsxs(ShadcnButton, { variant: "outline", size: "sm", onClick: () => table.previousPage(), disabled: !table.getCanPreviousPage(), children: [_jsx(ChevronLeft, { className: "size-4" }), "Previous"] }), _jsxs(ShadcnButton, { variant: "outline", size: "sm", onClick: () => table.nextPage(), disabled: !table.getCanNextPage(), children: ["Next", _jsx(ChevronRight, { className: "size-4" })] })] })] }))] }));
114
+ }
115
+ //# sourceMappingURL=opportunities-table.js.map