@logickernel/frame 0.1.0

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 (50) hide show
  1. package/README.md +461 -0
  2. package/dist/adapters/nextjs.js +31 -0
  3. package/dist/adapters/nextjs.js.map +1 -0
  4. package/dist/adapters/nextjs.mjs +25 -0
  5. package/dist/adapters/nextjs.mjs.map +1 -0
  6. package/dist/components/AppSidebar.js +467 -0
  7. package/dist/components/AppSidebar.js.map +1 -0
  8. package/dist/components/AppSidebar.mjs +446 -0
  9. package/dist/components/AppSidebar.mjs.map +1 -0
  10. package/dist/components/NavMain.js +133 -0
  11. package/dist/components/NavMain.js.map +1 -0
  12. package/dist/components/NavMain.mjs +112 -0
  13. package/dist/components/NavMain.mjs.map +1 -0
  14. package/dist/components/NavUser.js +88 -0
  15. package/dist/components/NavUser.js.map +1 -0
  16. package/dist/components/NavUser.mjs +86 -0
  17. package/dist/components/NavUser.mjs.map +1 -0
  18. package/dist/components/TeamSwitcher.js +164 -0
  19. package/dist/components/TeamSwitcher.js.map +1 -0
  20. package/dist/components/TeamSwitcher.mjs +162 -0
  21. package/dist/components/TeamSwitcher.mjs.map +1 -0
  22. package/dist/hooks/useNavigation.d.mts +24 -0
  23. package/dist/hooks/useNavigation.d.ts +24 -0
  24. package/dist/hooks/useNavigation.js +59 -0
  25. package/dist/hooks/useNavigation.js.map +1 -0
  26. package/dist/hooks/useNavigation.mjs +57 -0
  27. package/dist/hooks/useNavigation.mjs.map +1 -0
  28. package/dist/index.d.mts +58 -0
  29. package/dist/index.d.ts +58 -0
  30. package/dist/index.js +495 -0
  31. package/dist/index.js.map +1 -0
  32. package/dist/index.mjs +465 -0
  33. package/dist/index.mjs.map +1 -0
  34. package/dist/types/index.d.mts +85 -0
  35. package/dist/types/index.d.ts +85 -0
  36. package/dist/types/index.js +4 -0
  37. package/dist/types/index.js.map +1 -0
  38. package/dist/types/index.mjs +3 -0
  39. package/dist/types/index.mjs.map +1 -0
  40. package/dist/types/ui-components.d.js +4 -0
  41. package/dist/types/ui-components.d.js.map +1 -0
  42. package/dist/types/ui-components.d.mjs +3 -0
  43. package/dist/types/ui-components.d.mjs.map +1 -0
  44. package/dist/utils/iconMapper.d.mts +16 -0
  45. package/dist/utils/iconMapper.d.ts +16 -0
  46. package/dist/utils/iconMapper.js +52 -0
  47. package/dist/utils/iconMapper.js.map +1 -0
  48. package/dist/utils/iconMapper.mjs +30 -0
  49. package/dist/utils/iconMapper.mjs.map +1 -0
  50. package/package.json +76 -0
@@ -0,0 +1,133 @@
1
+ 'use strict';
2
+
3
+ var LucideIcons = require('lucide-react');
4
+ var collapsible = require('@/components/ui/collapsible');
5
+ var sidebar = require('@/components/ui/sidebar');
6
+ var jsxRuntime = require('react/jsx-runtime');
7
+
8
+ function _interopNamespace(e) {
9
+ if (e && e.__esModule) return e;
10
+ var n = Object.create(null);
11
+ if (e) {
12
+ Object.keys(e).forEach(function (k) {
13
+ if (k !== 'default') {
14
+ var d = Object.getOwnPropertyDescriptor(e, k);
15
+ Object.defineProperty(n, k, d.get ? d : {
16
+ enumerable: true,
17
+ get: function () { return e[k]; }
18
+ });
19
+ }
20
+ });
21
+ }
22
+ n.default = e;
23
+ return Object.freeze(n);
24
+ }
25
+
26
+ var LucideIcons__namespace = /*#__PURE__*/_interopNamespace(LucideIcons);
27
+
28
+ var ICON_MAP = {
29
+ Home: LucideIcons__namespace.Home,
30
+ Users: LucideIcons__namespace.Users,
31
+ GalleryVerticalEnd: LucideIcons__namespace.GalleryVerticalEnd,
32
+ Settings: LucideIcons__namespace.Settings,
33
+ CreditCard: LucideIcons__namespace.CreditCard,
34
+ Building2: LucideIcons__namespace.Building2,
35
+ Check: LucideIcons__namespace.Check,
36
+ ChevronsUpDown: LucideIcons__namespace.ChevronsUpDown,
37
+ ChevronRight: LucideIcons__namespace.ChevronRight,
38
+ BadgeCheck: LucideIcons__namespace.BadgeCheck,
39
+ LogOut: LucideIcons__namespace.LogOut
40
+ // Add more icons as needed
41
+ };
42
+ function getIconComponent(icon) {
43
+ if (!icon) {
44
+ return void 0;
45
+ }
46
+ if (typeof icon !== "string") {
47
+ return icon;
48
+ }
49
+ return ICON_MAP[icon];
50
+ }
51
+ function NavMain({ items, adapter }) {
52
+ const pathname = adapter.usePathname();
53
+ const Link = adapter.Link;
54
+ const groups = [];
55
+ let currentGroup = {
56
+ items: []
57
+ };
58
+ items.forEach((item) => {
59
+ const iconComponent = getIconComponent(item.icon);
60
+ if (!item.url) {
61
+ if (currentGroup.items.length > 0 || currentGroup.label) {
62
+ groups.push(currentGroup);
63
+ }
64
+ currentGroup = {
65
+ label: { title: item.title, icon: iconComponent },
66
+ items: []
67
+ };
68
+ } else {
69
+ currentGroup.items.push({
70
+ title: item.title,
71
+ url: item.url,
72
+ icon: iconComponent,
73
+ isActive: item.isActive,
74
+ items: item.items
75
+ });
76
+ }
77
+ });
78
+ if (currentGroup.items.length > 0 || currentGroup.label) {
79
+ groups.push(currentGroup);
80
+ }
81
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: groups.map((group, groupIndex) => /* @__PURE__ */ jsxRuntime.jsxs(sidebar.SidebarGroup, { children: [
82
+ group.label && /* @__PURE__ */ jsxRuntime.jsxs(sidebar.SidebarGroupLabel, { children: [
83
+ group.label.icon && /* @__PURE__ */ jsxRuntime.jsx(group.label.icon, { className: "mr-2" }),
84
+ group.label.title
85
+ ] }),
86
+ group.items.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(sidebar.SidebarMenu, { children: group.items.map((item) => {
87
+ const isActive = pathname === item.url || item.isActive;
88
+ const hasSubItems = item.items && item.items.length > 0;
89
+ if (hasSubItems) {
90
+ return /* @__PURE__ */ jsxRuntime.jsx(
91
+ collapsible.Collapsible,
92
+ {
93
+ asChild: true,
94
+ defaultOpen: isActive,
95
+ className: "group/collapsible",
96
+ children: /* @__PURE__ */ jsxRuntime.jsxs(sidebar.SidebarMenuItem, { children: [
97
+ /* @__PURE__ */ jsxRuntime.jsx(collapsible.CollapsibleTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
98
+ sidebar.SidebarMenuButton,
99
+ {
100
+ tooltip: item.title,
101
+ isActive,
102
+ children: [
103
+ item.icon && /* @__PURE__ */ jsxRuntime.jsx(item.icon, {}),
104
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: item.title }),
105
+ /* @__PURE__ */ jsxRuntime.jsx(LucideIcons.ChevronRight, { className: "ml-auto transition-transform duration-200 group-data-[state=open]/collapsible:rotate-90" })
106
+ ]
107
+ }
108
+ ) }),
109
+ /* @__PURE__ */ jsxRuntime.jsx(collapsible.CollapsibleContent, { children: /* @__PURE__ */ jsxRuntime.jsx(sidebar.SidebarMenuSub, { children: item.items?.map((subItem) => /* @__PURE__ */ jsxRuntime.jsx(sidebar.SidebarMenuSubItem, { children: /* @__PURE__ */ jsxRuntime.jsx(sidebar.SidebarMenuSubButton, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(Link, { href: subItem.url, children: /* @__PURE__ */ jsxRuntime.jsx("span", { children: subItem.title }) }) }) }, subItem.title)) }) })
110
+ ] })
111
+ },
112
+ item.title
113
+ );
114
+ }
115
+ return /* @__PURE__ */ jsxRuntime.jsx(sidebar.SidebarMenuItem, { children: /* @__PURE__ */ jsxRuntime.jsx(
116
+ sidebar.SidebarMenuButton,
117
+ {
118
+ asChild: true,
119
+ tooltip: item.title,
120
+ isActive,
121
+ children: /* @__PURE__ */ jsxRuntime.jsxs(Link, { href: item.url, children: [
122
+ item.icon && /* @__PURE__ */ jsxRuntime.jsx(item.icon, {}),
123
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: item.title })
124
+ ] })
125
+ }
126
+ ) }, item.title);
127
+ }) })
128
+ ] }, groupIndex)) });
129
+ }
130
+
131
+ exports.NavMain = NavMain;
132
+ //# sourceMappingURL=NavMain.js.map
133
+ //# sourceMappingURL=NavMain.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/utils/iconMapper.ts","../../src/components/NavMain.tsx"],"names":["LucideIcons","SidebarGroup","SidebarGroupLabel","jsx","SidebarMenu","Collapsible","SidebarMenuItem","CollapsibleTrigger","jsxs","SidebarMenuButton","ChevronRight","CollapsibleContent","SidebarMenuSub","SidebarMenuSubItem","SidebarMenuSubButton"],"mappings":"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","file":"NavMain.js","sourcesContent":["/**\n * Icon mapper utility\n * Maps icon name strings to Lucide React icon components\n */\n\nimport * as LucideIcons from \"lucide-react\"\nimport type { LucideIcon } from \"lucide-react\"\n\n/**\n * Map of icon names to Lucide icon components\n * Used to convert icon name strings from API to icon components\n */\nconst ICON_MAP: Record<string, LucideIcon> = {\n Home: LucideIcons.Home,\n Users: LucideIcons.Users,\n GalleryVerticalEnd: LucideIcons.GalleryVerticalEnd,\n Settings: LucideIcons.Settings,\n CreditCard: LucideIcons.CreditCard,\n Building2: LucideIcons.Building2,\n Check: LucideIcons.Check,\n ChevronsUpDown: LucideIcons.ChevronsUpDown,\n ChevronRight: LucideIcons.ChevronRight,\n BadgeCheck: LucideIcons.BadgeCheck,\n LogOut: LucideIcons.LogOut,\n // Add more icons as needed\n}\n\n/**\n * Get icon component from icon name or component\n * \n * @param icon - Icon name (string) or icon component\n * @returns Icon component or undefined\n */\nexport function getIconComponent(\n icon?: string | LucideIcon\n): LucideIcon | undefined {\n if (!icon) {\n return undefined\n }\n\n // If it's already a component, return it\n if (typeof icon !== \"string\") {\n return icon\n }\n\n // Look up icon by name\n return ICON_MAP[icon]\n}\n\n","\"use client\"\n\nimport { ChevronRight, type LucideIcon } from \"lucide-react\"\n\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n} from \"@/components/ui/collapsible\"\nimport {\n SidebarGroup,\n SidebarGroupLabel,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarMenuSub,\n SidebarMenuSubButton,\n SidebarMenuSubItem,\n} from \"@/components/ui/sidebar\"\nimport { getIconComponent } from \"../utils/iconMapper\"\nimport type { FrameworkAdapter, NavigationItem } from \"../types\"\n\ninterface NavMainProps {\n items: NavigationItem[]\n adapter: FrameworkAdapter\n}\n\nexport function NavMain({ items, adapter }: NavMainProps) {\n const pathname = adapter.usePathname()\n const Link = adapter.Link\n\n // Split items into groups based on label items\n const groups: Array<{\n label?: { title: string; icon?: LucideIcon }\n items: Array<{\n title: string\n url: string\n icon?: LucideIcon\n isActive?: boolean\n items?: {\n title: string\n url: string\n }[]\n }>\n }> = []\n let currentGroup: {\n label?: { title: string; icon?: LucideIcon }\n items: Array<{\n title: string\n url: string\n icon?: LucideIcon\n isActive?: boolean\n items?: {\n title: string\n url: string\n }[]\n }>\n } = {\n items: [],\n }\n\n items.forEach((item) => {\n // Convert icon (string or component) to component\n const iconComponent = getIconComponent(item.icon)\n\n if (!item.url) {\n // This is a label - start a new group\n if (currentGroup.items.length > 0 || currentGroup.label) {\n groups.push(currentGroup)\n }\n currentGroup = {\n label: { title: item.title, icon: iconComponent },\n items: [],\n }\n } else {\n // This is a menu item - add to current group\n currentGroup.items.push({\n title: item.title,\n url: item.url,\n icon: iconComponent,\n isActive: item.isActive,\n items: item.items,\n })\n }\n })\n\n // Push the last group\n if (currentGroup.items.length > 0 || currentGroup.label) {\n groups.push(currentGroup)\n }\n\n return (\n <>\n {groups.map((group, groupIndex) => (\n <SidebarGroup key={groupIndex}>\n {group.label && (\n <SidebarGroupLabel>\n {group.label.icon && (\n <group.label.icon className=\"mr-2\" />\n )}\n {group.label.title}\n </SidebarGroupLabel>\n )}\n {group.items.length > 0 && (\n <SidebarMenu>\n {group.items.map((item) => {\n const isActive = pathname === item.url || item.isActive\n const hasSubItems = item.items && item.items.length > 0\n\n if (hasSubItems) {\n return (\n <Collapsible\n key={item.title}\n asChild\n defaultOpen={isActive}\n className=\"group/collapsible\"\n >\n <SidebarMenuItem>\n <CollapsibleTrigger asChild>\n <SidebarMenuButton\n tooltip={item.title}\n isActive={isActive}\n >\n {item.icon && <item.icon />}\n <span>{item.title}</span>\n <ChevronRight className=\"ml-auto transition-transform duration-200 group-data-[state=open]/collapsible:rotate-90\" />\n </SidebarMenuButton>\n </CollapsibleTrigger>\n <CollapsibleContent>\n <SidebarMenuSub>\n {item.items?.map((subItem) => (\n <SidebarMenuSubItem key={subItem.title}>\n <SidebarMenuSubButton asChild>\n <Link href={subItem.url}>\n <span>{subItem.title}</span>\n </Link>\n </SidebarMenuSubButton>\n </SidebarMenuSubItem>\n ))}\n </SidebarMenuSub>\n </CollapsibleContent>\n </SidebarMenuItem>\n </Collapsible>\n )\n }\n\n return (\n <SidebarMenuItem key={item.title}>\n <SidebarMenuButton\n asChild\n tooltip={item.title}\n isActive={isActive}\n >\n <Link href={item.url}>\n {item.icon && <item.icon />}\n <span>{item.title}</span>\n </Link>\n </SidebarMenuButton>\n </SidebarMenuItem>\n )\n })}\n </SidebarMenu>\n )}\n </SidebarGroup>\n ))}\n </>\n )\n}\n\n"]}
@@ -0,0 +1,112 @@
1
+ import * as LucideIcons from 'lucide-react';
2
+ import { ChevronRight } from 'lucide-react';
3
+ import { Collapsible, CollapsibleTrigger, CollapsibleContent } from '@/components/ui/collapsible';
4
+ import { SidebarGroup, SidebarGroupLabel, SidebarMenu, SidebarMenuItem, SidebarMenuButton, SidebarMenuSub, SidebarMenuSubItem, SidebarMenuSubButton } from '@/components/ui/sidebar';
5
+ import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
6
+
7
+ var ICON_MAP = {
8
+ Home: LucideIcons.Home,
9
+ Users: LucideIcons.Users,
10
+ GalleryVerticalEnd: LucideIcons.GalleryVerticalEnd,
11
+ Settings: LucideIcons.Settings,
12
+ CreditCard: LucideIcons.CreditCard,
13
+ Building2: LucideIcons.Building2,
14
+ Check: LucideIcons.Check,
15
+ ChevronsUpDown: LucideIcons.ChevronsUpDown,
16
+ ChevronRight: LucideIcons.ChevronRight,
17
+ BadgeCheck: LucideIcons.BadgeCheck,
18
+ LogOut: LucideIcons.LogOut
19
+ // Add more icons as needed
20
+ };
21
+ function getIconComponent(icon) {
22
+ if (!icon) {
23
+ return void 0;
24
+ }
25
+ if (typeof icon !== "string") {
26
+ return icon;
27
+ }
28
+ return ICON_MAP[icon];
29
+ }
30
+ function NavMain({ items, adapter }) {
31
+ const pathname = adapter.usePathname();
32
+ const Link = adapter.Link;
33
+ const groups = [];
34
+ let currentGroup = {
35
+ items: []
36
+ };
37
+ items.forEach((item) => {
38
+ const iconComponent = getIconComponent(item.icon);
39
+ if (!item.url) {
40
+ if (currentGroup.items.length > 0 || currentGroup.label) {
41
+ groups.push(currentGroup);
42
+ }
43
+ currentGroup = {
44
+ label: { title: item.title, icon: iconComponent },
45
+ items: []
46
+ };
47
+ } else {
48
+ currentGroup.items.push({
49
+ title: item.title,
50
+ url: item.url,
51
+ icon: iconComponent,
52
+ isActive: item.isActive,
53
+ items: item.items
54
+ });
55
+ }
56
+ });
57
+ if (currentGroup.items.length > 0 || currentGroup.label) {
58
+ groups.push(currentGroup);
59
+ }
60
+ return /* @__PURE__ */ jsx(Fragment, { children: groups.map((group, groupIndex) => /* @__PURE__ */ jsxs(SidebarGroup, { children: [
61
+ group.label && /* @__PURE__ */ jsxs(SidebarGroupLabel, { children: [
62
+ group.label.icon && /* @__PURE__ */ jsx(group.label.icon, { className: "mr-2" }),
63
+ group.label.title
64
+ ] }),
65
+ group.items.length > 0 && /* @__PURE__ */ jsx(SidebarMenu, { children: group.items.map((item) => {
66
+ const isActive = pathname === item.url || item.isActive;
67
+ const hasSubItems = item.items && item.items.length > 0;
68
+ if (hasSubItems) {
69
+ return /* @__PURE__ */ jsx(
70
+ Collapsible,
71
+ {
72
+ asChild: true,
73
+ defaultOpen: isActive,
74
+ className: "group/collapsible",
75
+ children: /* @__PURE__ */ jsxs(SidebarMenuItem, { children: [
76
+ /* @__PURE__ */ jsx(CollapsibleTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
77
+ SidebarMenuButton,
78
+ {
79
+ tooltip: item.title,
80
+ isActive,
81
+ children: [
82
+ item.icon && /* @__PURE__ */ jsx(item.icon, {}),
83
+ /* @__PURE__ */ jsx("span", { children: item.title }),
84
+ /* @__PURE__ */ jsx(ChevronRight, { className: "ml-auto transition-transform duration-200 group-data-[state=open]/collapsible:rotate-90" })
85
+ ]
86
+ }
87
+ ) }),
88
+ /* @__PURE__ */ jsx(CollapsibleContent, { children: /* @__PURE__ */ jsx(SidebarMenuSub, { children: item.items?.map((subItem) => /* @__PURE__ */ jsx(SidebarMenuSubItem, { children: /* @__PURE__ */ jsx(SidebarMenuSubButton, { asChild: true, children: /* @__PURE__ */ jsx(Link, { href: subItem.url, children: /* @__PURE__ */ jsx("span", { children: subItem.title }) }) }) }, subItem.title)) }) })
89
+ ] })
90
+ },
91
+ item.title
92
+ );
93
+ }
94
+ return /* @__PURE__ */ jsx(SidebarMenuItem, { children: /* @__PURE__ */ jsx(
95
+ SidebarMenuButton,
96
+ {
97
+ asChild: true,
98
+ tooltip: item.title,
99
+ isActive,
100
+ children: /* @__PURE__ */ jsxs(Link, { href: item.url, children: [
101
+ item.icon && /* @__PURE__ */ jsx(item.icon, {}),
102
+ /* @__PURE__ */ jsx("span", { children: item.title })
103
+ ] })
104
+ }
105
+ ) }, item.title);
106
+ }) })
107
+ ] }, groupIndex)) });
108
+ }
109
+
110
+ export { NavMain };
111
+ //# sourceMappingURL=NavMain.mjs.map
112
+ //# sourceMappingURL=NavMain.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/utils/iconMapper.ts","../../src/components/NavMain.tsx"],"names":["ChevronRight"],"mappings":"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","file":"NavMain.mjs","sourcesContent":["/**\n * Icon mapper utility\n * Maps icon name strings to Lucide React icon components\n */\n\nimport * as LucideIcons from \"lucide-react\"\nimport type { LucideIcon } from \"lucide-react\"\n\n/**\n * Map of icon names to Lucide icon components\n * Used to convert icon name strings from API to icon components\n */\nconst ICON_MAP: Record<string, LucideIcon> = {\n Home: LucideIcons.Home,\n Users: LucideIcons.Users,\n GalleryVerticalEnd: LucideIcons.GalleryVerticalEnd,\n Settings: LucideIcons.Settings,\n CreditCard: LucideIcons.CreditCard,\n Building2: LucideIcons.Building2,\n Check: LucideIcons.Check,\n ChevronsUpDown: LucideIcons.ChevronsUpDown,\n ChevronRight: LucideIcons.ChevronRight,\n BadgeCheck: LucideIcons.BadgeCheck,\n LogOut: LucideIcons.LogOut,\n // Add more icons as needed\n}\n\n/**\n * Get icon component from icon name or component\n * \n * @param icon - Icon name (string) or icon component\n * @returns Icon component or undefined\n */\nexport function getIconComponent(\n icon?: string | LucideIcon\n): LucideIcon | undefined {\n if (!icon) {\n return undefined\n }\n\n // If it's already a component, return it\n if (typeof icon !== \"string\") {\n return icon\n }\n\n // Look up icon by name\n return ICON_MAP[icon]\n}\n\n","\"use client\"\n\nimport { ChevronRight, type LucideIcon } from \"lucide-react\"\n\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n} from \"@/components/ui/collapsible\"\nimport {\n SidebarGroup,\n SidebarGroupLabel,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarMenuSub,\n SidebarMenuSubButton,\n SidebarMenuSubItem,\n} from \"@/components/ui/sidebar\"\nimport { getIconComponent } from \"../utils/iconMapper\"\nimport type { FrameworkAdapter, NavigationItem } from \"../types\"\n\ninterface NavMainProps {\n items: NavigationItem[]\n adapter: FrameworkAdapter\n}\n\nexport function NavMain({ items, adapter }: NavMainProps) {\n const pathname = adapter.usePathname()\n const Link = adapter.Link\n\n // Split items into groups based on label items\n const groups: Array<{\n label?: { title: string; icon?: LucideIcon }\n items: Array<{\n title: string\n url: string\n icon?: LucideIcon\n isActive?: boolean\n items?: {\n title: string\n url: string\n }[]\n }>\n }> = []\n let currentGroup: {\n label?: { title: string; icon?: LucideIcon }\n items: Array<{\n title: string\n url: string\n icon?: LucideIcon\n isActive?: boolean\n items?: {\n title: string\n url: string\n }[]\n }>\n } = {\n items: [],\n }\n\n items.forEach((item) => {\n // Convert icon (string or component) to component\n const iconComponent = getIconComponent(item.icon)\n\n if (!item.url) {\n // This is a label - start a new group\n if (currentGroup.items.length > 0 || currentGroup.label) {\n groups.push(currentGroup)\n }\n currentGroup = {\n label: { title: item.title, icon: iconComponent },\n items: [],\n }\n } else {\n // This is a menu item - add to current group\n currentGroup.items.push({\n title: item.title,\n url: item.url,\n icon: iconComponent,\n isActive: item.isActive,\n items: item.items,\n })\n }\n })\n\n // Push the last group\n if (currentGroup.items.length > 0 || currentGroup.label) {\n groups.push(currentGroup)\n }\n\n return (\n <>\n {groups.map((group, groupIndex) => (\n <SidebarGroup key={groupIndex}>\n {group.label && (\n <SidebarGroupLabel>\n {group.label.icon && (\n <group.label.icon className=\"mr-2\" />\n )}\n {group.label.title}\n </SidebarGroupLabel>\n )}\n {group.items.length > 0 && (\n <SidebarMenu>\n {group.items.map((item) => {\n const isActive = pathname === item.url || item.isActive\n const hasSubItems = item.items && item.items.length > 0\n\n if (hasSubItems) {\n return (\n <Collapsible\n key={item.title}\n asChild\n defaultOpen={isActive}\n className=\"group/collapsible\"\n >\n <SidebarMenuItem>\n <CollapsibleTrigger asChild>\n <SidebarMenuButton\n tooltip={item.title}\n isActive={isActive}\n >\n {item.icon && <item.icon />}\n <span>{item.title}</span>\n <ChevronRight className=\"ml-auto transition-transform duration-200 group-data-[state=open]/collapsible:rotate-90\" />\n </SidebarMenuButton>\n </CollapsibleTrigger>\n <CollapsibleContent>\n <SidebarMenuSub>\n {item.items?.map((subItem) => (\n <SidebarMenuSubItem key={subItem.title}>\n <SidebarMenuSubButton asChild>\n <Link href={subItem.url}>\n <span>{subItem.title}</span>\n </Link>\n </SidebarMenuSubButton>\n </SidebarMenuSubItem>\n ))}\n </SidebarMenuSub>\n </CollapsibleContent>\n </SidebarMenuItem>\n </Collapsible>\n )\n }\n\n return (\n <SidebarMenuItem key={item.title}>\n <SidebarMenuButton\n asChild\n tooltip={item.title}\n isActive={isActive}\n >\n <Link href={item.url}>\n {item.icon && <item.icon />}\n <span>{item.title}</span>\n </Link>\n </SidebarMenuButton>\n </SidebarMenuItem>\n )\n })}\n </SidebarMenu>\n )}\n </SidebarGroup>\n ))}\n </>\n )\n}\n\n"]}
@@ -0,0 +1,88 @@
1
+ 'use strict';
2
+
3
+ var lucideReact = require('lucide-react');
4
+ var avatar = require('@/components/ui/avatar');
5
+ var dropdownMenu = require('@/components/ui/dropdown-menu');
6
+ var sidebar = require('@/components/ui/sidebar');
7
+ var jsxRuntime = require('react/jsx-runtime');
8
+
9
+ function getInitials(name, email) {
10
+ if (name) {
11
+ const parts = name.trim().split(/\s+/);
12
+ if (parts.length >= 2) {
13
+ return (parts[0][0] + parts[parts.length - 1][0]).toUpperCase();
14
+ }
15
+ return name[0].toUpperCase();
16
+ }
17
+ return email[0].toUpperCase();
18
+ }
19
+ function NavUser({ user, adapter }) {
20
+ const { isMobile } = sidebar.useSidebar();
21
+ const router = adapter.useRouter();
22
+ const initials = getInitials(user.name, user.email);
23
+ const displayName = user.name || user.email;
24
+ const handleSignOut = async () => {
25
+ if (adapter.signOut) {
26
+ await adapter.signOut({ redirect: false });
27
+ }
28
+ router.push("/auth/signin");
29
+ if (router.refresh) {
30
+ router.refresh();
31
+ }
32
+ };
33
+ return /* @__PURE__ */ jsxRuntime.jsx(sidebar.SidebarMenu, { children: /* @__PURE__ */ jsxRuntime.jsx(sidebar.SidebarMenuItem, { children: /* @__PURE__ */ jsxRuntime.jsxs(dropdownMenu.DropdownMenu, { children: [
34
+ /* @__PURE__ */ jsxRuntime.jsx(dropdownMenu.DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
35
+ sidebar.SidebarMenuButton,
36
+ {
37
+ size: "lg",
38
+ className: "data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground",
39
+ children: [
40
+ /* @__PURE__ */ jsxRuntime.jsxs(avatar.Avatar, { className: "h-8 w-8 rounded-lg", children: [
41
+ /* @__PURE__ */ jsxRuntime.jsx(avatar.AvatarImage, { src: user.image || void 0, alt: displayName }),
42
+ /* @__PURE__ */ jsxRuntime.jsx(avatar.AvatarFallback, { className: "rounded-lg", children: initials })
43
+ ] }),
44
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid flex-1 text-left text-sm leading-tight", children: [
45
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate font-medium", children: displayName }),
46
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate text-xs", children: user.email })
47
+ ] }),
48
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronsUpDown, { className: "ml-auto size-4" })
49
+ ]
50
+ }
51
+ ) }),
52
+ /* @__PURE__ */ jsxRuntime.jsxs(
53
+ dropdownMenu.DropdownMenuContent,
54
+ {
55
+ className: "w-(--radix-dropdown-menu-trigger-width) min-w-56 rounded-lg",
56
+ side: isMobile ? "bottom" : "right",
57
+ align: "end",
58
+ sideOffset: 4,
59
+ children: [
60
+ /* @__PURE__ */ jsxRuntime.jsx(dropdownMenu.DropdownMenuLabel, { className: "p-0 font-normal", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 px-1 py-1.5 text-left text-sm", children: [
61
+ /* @__PURE__ */ jsxRuntime.jsxs(avatar.Avatar, { className: "h-8 w-8 rounded-lg", children: [
62
+ /* @__PURE__ */ jsxRuntime.jsx(avatar.AvatarImage, { src: user.image || void 0, alt: displayName }),
63
+ /* @__PURE__ */ jsxRuntime.jsx(avatar.AvatarFallback, { className: "rounded-lg", children: initials })
64
+ ] }),
65
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid flex-1 text-left text-sm leading-tight", children: [
66
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate font-medium", children: displayName }),
67
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate text-xs", children: user.email })
68
+ ] })
69
+ ] }) }),
70
+ /* @__PURE__ */ jsxRuntime.jsx(dropdownMenu.DropdownMenuSeparator, {}),
71
+ /* @__PURE__ */ jsxRuntime.jsx(dropdownMenu.DropdownMenuGroup, { children: /* @__PURE__ */ jsxRuntime.jsxs(dropdownMenu.DropdownMenuItem, { children: [
72
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.BadgeCheck, {}),
73
+ "Account"
74
+ ] }) }),
75
+ /* @__PURE__ */ jsxRuntime.jsx(dropdownMenu.DropdownMenuSeparator, {}),
76
+ /* @__PURE__ */ jsxRuntime.jsxs(dropdownMenu.DropdownMenuItem, { onClick: handleSignOut, children: [
77
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.LogOut, {}),
78
+ "Log out"
79
+ ] })
80
+ ]
81
+ }
82
+ )
83
+ ] }) }) });
84
+ }
85
+
86
+ exports.NavUser = NavUser;
87
+ //# sourceMappingURL=NavUser.js.map
88
+ //# sourceMappingURL=NavUser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/components/NavUser.tsx"],"names":["useSidebar","jsx","SidebarMenu","SidebarMenuItem","DropdownMenu","DropdownMenuTrigger","jsxs","SidebarMenuButton","Avatar","AvatarImage","AvatarFallback","ChevronsUpDown","DropdownMenuContent","DropdownMenuLabel","DropdownMenuSeparator","DropdownMenuGroup","DropdownMenuItem","BadgeCheck","LogOut"],"mappings":"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","file":"NavUser.js","sourcesContent":["\"use client\"\n\nimport {\n BadgeCheck,\n ChevronsUpDown,\n LogOut,\n} from \"lucide-react\"\n\nimport {\n Avatar,\n AvatarFallback,\n AvatarImage,\n} from \"@/components/ui/avatar\"\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\"\nimport {\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n useSidebar,\n} from \"@/components/ui/sidebar\"\nimport type { FrameworkAdapter, User } from \"../types\"\n\nfunction getInitials(name: string | null, email: string): string {\n if (name) {\n const parts = name.trim().split(/\\s+/)\n if (parts.length >= 2) {\n return (parts[0][0] + parts[parts.length - 1][0]).toUpperCase()\n }\n return name[0].toUpperCase()\n }\n return email[0].toUpperCase()\n}\n\ninterface NavUserProps {\n user: User\n adapter: FrameworkAdapter\n}\n\nexport function NavUser({ user, adapter }: NavUserProps) {\n const { isMobile } = useSidebar()\n const router = adapter.useRouter()\n const initials = getInitials(user.name, user.email)\n const displayName = user.name || user.email\n\n const handleSignOut = async () => {\n if (adapter.signOut) {\n await adapter.signOut({ redirect: false })\n }\n router.push(\"/auth/signin\")\n if (router.refresh) {\n router.refresh()\n }\n }\n\n return (\n <SidebarMenu>\n <SidebarMenuItem>\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <SidebarMenuButton\n size=\"lg\"\n className=\"data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground\"\n >\n <Avatar className=\"h-8 w-8 rounded-lg\">\n <AvatarImage src={user.image || undefined} alt={displayName} />\n <AvatarFallback className=\"rounded-lg\">{initials}</AvatarFallback>\n </Avatar>\n <div className=\"grid flex-1 text-left text-sm leading-tight\">\n <span className=\"truncate font-medium\">{displayName}</span>\n <span className=\"truncate text-xs\">{user.email}</span>\n </div>\n <ChevronsUpDown className=\"ml-auto size-4\" />\n </SidebarMenuButton>\n </DropdownMenuTrigger>\n <DropdownMenuContent\n className=\"w-(--radix-dropdown-menu-trigger-width) min-w-56 rounded-lg\"\n side={isMobile ? \"bottom\" : \"right\"}\n align=\"end\"\n sideOffset={4}\n >\n <DropdownMenuLabel className=\"p-0 font-normal\">\n <div className=\"flex items-center gap-2 px-1 py-1.5 text-left text-sm\">\n <Avatar className=\"h-8 w-8 rounded-lg\">\n <AvatarImage src={user.image || undefined} alt={displayName} />\n <AvatarFallback className=\"rounded-lg\">{initials}</AvatarFallback>\n </Avatar>\n <div className=\"grid flex-1 text-left text-sm leading-tight\">\n <span className=\"truncate font-medium\">{displayName}</span>\n <span className=\"truncate text-xs\">{user.email}</span>\n </div>\n </div>\n </DropdownMenuLabel>\n <DropdownMenuSeparator />\n <DropdownMenuGroup>\n <DropdownMenuItem>\n <BadgeCheck />\n Account\n </DropdownMenuItem>\n </DropdownMenuGroup>\n <DropdownMenuSeparator />\n <DropdownMenuItem onClick={handleSignOut}>\n <LogOut />\n Log out\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </SidebarMenuItem>\n </SidebarMenu>\n )\n}\n\n"]}
@@ -0,0 +1,86 @@
1
+ import { ChevronsUpDown, BadgeCheck, LogOut } from 'lucide-react';
2
+ import { Avatar, AvatarImage, AvatarFallback } from '@/components/ui/avatar';
3
+ import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuGroup, DropdownMenuItem } from '@/components/ui/dropdown-menu';
4
+ import { useSidebar, SidebarMenu, SidebarMenuItem, SidebarMenuButton } from '@/components/ui/sidebar';
5
+ import { jsx, jsxs } from 'react/jsx-runtime';
6
+
7
+ function getInitials(name, email) {
8
+ if (name) {
9
+ const parts = name.trim().split(/\s+/);
10
+ if (parts.length >= 2) {
11
+ return (parts[0][0] + parts[parts.length - 1][0]).toUpperCase();
12
+ }
13
+ return name[0].toUpperCase();
14
+ }
15
+ return email[0].toUpperCase();
16
+ }
17
+ function NavUser({ user, adapter }) {
18
+ const { isMobile } = useSidebar();
19
+ const router = adapter.useRouter();
20
+ const initials = getInitials(user.name, user.email);
21
+ const displayName = user.name || user.email;
22
+ const handleSignOut = async () => {
23
+ if (adapter.signOut) {
24
+ await adapter.signOut({ redirect: false });
25
+ }
26
+ router.push("/auth/signin");
27
+ if (router.refresh) {
28
+ router.refresh();
29
+ }
30
+ };
31
+ return /* @__PURE__ */ jsx(SidebarMenu, { children: /* @__PURE__ */ jsx(SidebarMenuItem, { children: /* @__PURE__ */ jsxs(DropdownMenu, { children: [
32
+ /* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
33
+ SidebarMenuButton,
34
+ {
35
+ size: "lg",
36
+ className: "data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground",
37
+ children: [
38
+ /* @__PURE__ */ jsxs(Avatar, { className: "h-8 w-8 rounded-lg", children: [
39
+ /* @__PURE__ */ jsx(AvatarImage, { src: user.image || void 0, alt: displayName }),
40
+ /* @__PURE__ */ jsx(AvatarFallback, { className: "rounded-lg", children: initials })
41
+ ] }),
42
+ /* @__PURE__ */ jsxs("div", { className: "grid flex-1 text-left text-sm leading-tight", children: [
43
+ /* @__PURE__ */ jsx("span", { className: "truncate font-medium", children: displayName }),
44
+ /* @__PURE__ */ jsx("span", { className: "truncate text-xs", children: user.email })
45
+ ] }),
46
+ /* @__PURE__ */ jsx(ChevronsUpDown, { className: "ml-auto size-4" })
47
+ ]
48
+ }
49
+ ) }),
50
+ /* @__PURE__ */ jsxs(
51
+ DropdownMenuContent,
52
+ {
53
+ className: "w-(--radix-dropdown-menu-trigger-width) min-w-56 rounded-lg",
54
+ side: isMobile ? "bottom" : "right",
55
+ align: "end",
56
+ sideOffset: 4,
57
+ children: [
58
+ /* @__PURE__ */ jsx(DropdownMenuLabel, { className: "p-0 font-normal", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 px-1 py-1.5 text-left text-sm", children: [
59
+ /* @__PURE__ */ jsxs(Avatar, { className: "h-8 w-8 rounded-lg", children: [
60
+ /* @__PURE__ */ jsx(AvatarImage, { src: user.image || void 0, alt: displayName }),
61
+ /* @__PURE__ */ jsx(AvatarFallback, { className: "rounded-lg", children: initials })
62
+ ] }),
63
+ /* @__PURE__ */ jsxs("div", { className: "grid flex-1 text-left text-sm leading-tight", children: [
64
+ /* @__PURE__ */ jsx("span", { className: "truncate font-medium", children: displayName }),
65
+ /* @__PURE__ */ jsx("span", { className: "truncate text-xs", children: user.email })
66
+ ] })
67
+ ] }) }),
68
+ /* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
69
+ /* @__PURE__ */ jsx(DropdownMenuGroup, { children: /* @__PURE__ */ jsxs(DropdownMenuItem, { children: [
70
+ /* @__PURE__ */ jsx(BadgeCheck, {}),
71
+ "Account"
72
+ ] }) }),
73
+ /* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
74
+ /* @__PURE__ */ jsxs(DropdownMenuItem, { onClick: handleSignOut, children: [
75
+ /* @__PURE__ */ jsx(LogOut, {}),
76
+ "Log out"
77
+ ] })
78
+ ]
79
+ }
80
+ )
81
+ ] }) }) });
82
+ }
83
+
84
+ export { NavUser };
85
+ //# sourceMappingURL=NavUser.mjs.map
86
+ //# sourceMappingURL=NavUser.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/components/NavUser.tsx"],"names":[],"mappings":"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","file":"NavUser.mjs","sourcesContent":["\"use client\"\n\nimport {\n BadgeCheck,\n ChevronsUpDown,\n LogOut,\n} from \"lucide-react\"\n\nimport {\n Avatar,\n AvatarFallback,\n AvatarImage,\n} from \"@/components/ui/avatar\"\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\"\nimport {\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n useSidebar,\n} from \"@/components/ui/sidebar\"\nimport type { FrameworkAdapter, User } from \"../types\"\n\nfunction getInitials(name: string | null, email: string): string {\n if (name) {\n const parts = name.trim().split(/\\s+/)\n if (parts.length >= 2) {\n return (parts[0][0] + parts[parts.length - 1][0]).toUpperCase()\n }\n return name[0].toUpperCase()\n }\n return email[0].toUpperCase()\n}\n\ninterface NavUserProps {\n user: User\n adapter: FrameworkAdapter\n}\n\nexport function NavUser({ user, adapter }: NavUserProps) {\n const { isMobile } = useSidebar()\n const router = adapter.useRouter()\n const initials = getInitials(user.name, user.email)\n const displayName = user.name || user.email\n\n const handleSignOut = async () => {\n if (adapter.signOut) {\n await adapter.signOut({ redirect: false })\n }\n router.push(\"/auth/signin\")\n if (router.refresh) {\n router.refresh()\n }\n }\n\n return (\n <SidebarMenu>\n <SidebarMenuItem>\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <SidebarMenuButton\n size=\"lg\"\n className=\"data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground\"\n >\n <Avatar className=\"h-8 w-8 rounded-lg\">\n <AvatarImage src={user.image || undefined} alt={displayName} />\n <AvatarFallback className=\"rounded-lg\">{initials}</AvatarFallback>\n </Avatar>\n <div className=\"grid flex-1 text-left text-sm leading-tight\">\n <span className=\"truncate font-medium\">{displayName}</span>\n <span className=\"truncate text-xs\">{user.email}</span>\n </div>\n <ChevronsUpDown className=\"ml-auto size-4\" />\n </SidebarMenuButton>\n </DropdownMenuTrigger>\n <DropdownMenuContent\n className=\"w-(--radix-dropdown-menu-trigger-width) min-w-56 rounded-lg\"\n side={isMobile ? \"bottom\" : \"right\"}\n align=\"end\"\n sideOffset={4}\n >\n <DropdownMenuLabel className=\"p-0 font-normal\">\n <div className=\"flex items-center gap-2 px-1 py-1.5 text-left text-sm\">\n <Avatar className=\"h-8 w-8 rounded-lg\">\n <AvatarImage src={user.image || undefined} alt={displayName} />\n <AvatarFallback className=\"rounded-lg\">{initials}</AvatarFallback>\n </Avatar>\n <div className=\"grid flex-1 text-left text-sm leading-tight\">\n <span className=\"truncate font-medium\">{displayName}</span>\n <span className=\"truncate text-xs\">{user.email}</span>\n </div>\n </div>\n </DropdownMenuLabel>\n <DropdownMenuSeparator />\n <DropdownMenuGroup>\n <DropdownMenuItem>\n <BadgeCheck />\n Account\n </DropdownMenuItem>\n </DropdownMenuGroup>\n <DropdownMenuSeparator />\n <DropdownMenuItem onClick={handleSignOut}>\n <LogOut />\n Log out\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </SidebarMenuItem>\n </SidebarMenu>\n )\n}\n\n"]}