@create-flow/common-ui 0.3.7 → 0.3.8

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.
package/dist/index.cjs CHANGED
@@ -3,60 +3,12 @@
3
3
 
4
4
  var jsxRuntime = require('react/jsx-runtime');
5
5
  var react = require('react');
6
+ var authUi = require('@create-flow/auth-ui');
6
7
 
7
8
  // src/components/Hello.tsx
8
9
  function Hello() {
9
10
  return /* @__PURE__ */ jsxRuntime.jsx("div", { children: "Hello world" });
10
11
  }
11
-
12
- // src/utils/authApi.ts
13
- var DEFAULT_AUTH_HOST = (() => {
14
- if (typeof process !== "undefined" && process.env?.NEXT_PUBLIC_AUTH_API_HOST) {
15
- const envHost = process.env.NEXT_PUBLIC_AUTH_API_HOST.trim();
16
- if (envHost.length > 0) return envHost;
17
- }
18
- return "https://auth.create-flow.ai";
19
- })();
20
- var DEFAULT_APP_ID = typeof process !== "undefined" ? process.env?.NEXT_PUBLIC_AUTH_APP_ID?.trim() ?? "" : "";
21
- function normalizeHost(host) {
22
- const value = (host ?? DEFAULT_AUTH_HOST).trim();
23
- if (!value) throw new Error("Auth host is not configured");
24
- if (/^https?:\/\//i.test(value)) return value.replace(/\/+$/g, "");
25
- return `https://${value}`.replace(/\/+$/g, "");
26
- }
27
- function buildAuthUrl(path, host, query) {
28
- const normalizedHost = normalizeHost(host);
29
- const normalizedPath = path.startsWith("/") ? path : `/${path}`;
30
- const url = new URL(normalizedPath, normalizedHost);
31
- if (query) {
32
- for (const [key, value] of Object.entries(query)) {
33
- if (value !== void 0 && value !== null) {
34
- url.searchParams.set(key, value);
35
- }
36
- }
37
- }
38
- return url;
39
- }
40
- async function fetchWithCredentials(url, init = {}) {
41
- const response = await fetch(url.toString(), {
42
- credentials: "include",
43
- cache: "no-store",
44
- ...init
45
- });
46
- let data = null;
47
- try {
48
- data = await response.json();
49
- } catch {
50
- }
51
- return { response, data };
52
- }
53
- async function getAuthJson(path, host, query) {
54
- const url = buildAuthUrl(path, host, query);
55
- return fetchWithCredentials(url, { method: "GET" });
56
- }
57
- function getResolvedAppId(appId) {
58
- return (appId ?? DEFAULT_APP_ID).trim();
59
- }
60
12
  function HomeIcon({ className }) {
61
13
  return /* @__PURE__ */ jsxRuntime.jsxs("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.75", strokeLinecap: "round", strokeLinejoin: "round", children: [
62
14
  /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M3 9l9-7 9 7v11a2 2 0 01-2 2H5a2 2 0 01-2-2z" }),
@@ -66,57 +18,25 @@ function HomeIcon({ className }) {
66
18
  function FolderIcon({ className }) {
67
19
  return /* @__PURE__ */ jsxRuntime.jsx("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.75", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M22 19a2 2 0 01-2 2H4a2 2 0 01-2-2V5a2 2 0 012-2h5l2 3h9a2 2 0 012 2z" }) });
68
20
  }
69
- function UserIcon({ className }) {
70
- return /* @__PURE__ */ jsxRuntime.jsxs("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.75", strokeLinecap: "round", strokeLinejoin: "round", children: [
71
- /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "12", cy: "8", r: "4" }),
72
- /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M4 20c0-4 3.6-7 8-7s8 3 8 7" })
73
- ] });
74
- }
75
21
  function SettingsIcon({ className }) {
76
22
  return /* @__PURE__ */ jsxRuntime.jsxs("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.75", strokeLinecap: "round", strokeLinejoin: "round", children: [
77
23
  /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "12", cy: "12", r: "3" }),
78
24
  /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M19.4 15a1.65 1.65 0 00.33 1.82l.06.06a2 2 0 010 2.83 2 2 0 01-2.83 0l-.06-.06a1.65 1.65 0 00-1.82-.33 1.65 1.65 0 00-1 1.51V21a2 2 0 01-4 0v-.09A1.65 1.65 0 009 19.4a1.65 1.65 0 00-1.82.33l-.06.06a2 2 0 01-2.83-2.83l.06-.06A1.65 1.65 0 004.68 15a1.65 1.65 0 00-1.51-1H3a2 2 0 010-4h.09A1.65 1.65 0 004.6 9a1.65 1.65 0 00-.33-1.82l-.06-.06a2 2 0 012.83-2.83l.06.06A1.65 1.65 0 009 4.68a1.65 1.65 0 001-1.51V3a2 2 0 014 0v.09a1.65 1.65 0 001 1.51 1.65 1.65 0 001.82-.33l.06-.06a2 2 0 012.83 2.83l-.06.06A1.65 1.65 0 0019.4 9a1.65 1.65 0 001.51 1H21a2 2 0 010 4h-.09a1.65 1.65 0 00-1.51 1z" })
79
25
  ] });
80
26
  }
81
- function LogOutIcon({ className }) {
82
- return /* @__PURE__ */ jsxRuntime.jsxs("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.75", strokeLinecap: "round", strokeLinejoin: "round", children: [
83
- /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M9 21H5a2 2 0 01-2-2V5a2 2 0 012-2h4" }),
84
- /* @__PURE__ */ jsxRuntime.jsx("polyline", { points: "16,17 21,12 16,7" }),
85
- /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "21", y1: "12", x2: "9", y2: "12" })
86
- ] });
87
- }
88
27
  function ChevronLeftIcon({ className }) {
89
28
  return /* @__PURE__ */ jsxRuntime.jsx("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M15 18l-6-6 6-6" }) });
90
29
  }
91
30
  function ChevronRightIcon({ className }) {
92
31
  return /* @__PURE__ */ jsxRuntime.jsx("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M9 18l6-6-6-6" }) });
93
32
  }
94
- function ChevronsUpDownIcon({ className }) {
95
- return /* @__PURE__ */ jsxRuntime.jsx("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M7 15l5 5 5-5M7 9l5-5 5 5" }) });
96
- }
97
33
  var defaultNavItems = [
98
34
  { href: "/dashboard", label: "Dashboard", icon: HomeIcon, exact: true },
99
35
  { href: "/dashboard/projects", label: "Projects", icon: FolderIcon, exact: false },
100
36
  { href: "/dashboard/settings", label: "Settings", icon: SettingsIcon, exact: false }
101
37
  ];
102
- var AVATAR_COLORS = [
103
- "bg-violet-600",
104
- "bg-indigo-600",
105
- "bg-sky-600",
106
- "bg-emerald-600",
107
- "bg-amber-600",
108
- "bg-rose-600"
109
- ];
110
- function getAvatarColor(name) {
111
- let hash = 0;
112
- for (let i = 0; i < name.length; i++) hash = name.charCodeAt(i) + ((hash << 5) - hash);
113
- return AVATAR_COLORS[Math.abs(hash) % AVATAR_COLORS.length];
114
- }
115
- function getInitials(name) {
116
- return name.split(" ").filter(Boolean).map((w) => w[0]).join("").toUpperCase().slice(0, 2);
117
- }
118
38
  function Sidebar({
119
- user: userProp,
39
+ user,
120
40
  appId,
121
41
  authHost,
122
42
  navItems = defaultNavItems,
@@ -127,64 +47,13 @@ function Sidebar({
127
47
  onLogout
128
48
  }) {
129
49
  const [isCollapsed, setIsCollapsed] = react.useState(false);
130
- const [isUserMenuOpen, setIsUserMenuOpen] = react.useState(false);
131
- const [fetchedUser, setFetchedUser] = react.useState(null);
132
- const [isLoading, setIsLoading] = react.useState(!userProp);
133
50
  const [pathname, setPathname] = react.useState(typeof window !== "undefined" ? window.location.pathname : "/");
134
- const menuRef = react.useRef(null);
135
51
  react.useEffect(() => {
136
52
  setPathname(window.location.pathname);
137
53
  }, []);
138
- react.useEffect(() => {
139
- if (userProp) return;
140
- let cancelled = false;
141
- async function fetchSession() {
142
- try {
143
- const { response, data } = await getAuthJson("api/auth/session", authHost);
144
- if (!cancelled && response.ok && data?.user) {
145
- setFetchedUser(data.user);
146
- }
147
- } catch (err) {
148
- console.error("Failed to fetch session:", err);
149
- } finally {
150
- if (!cancelled) setIsLoading(false);
151
- }
152
- }
153
- fetchSession();
154
- return () => {
155
- cancelled = true;
156
- };
157
- }, [authHost, userProp]);
158
- react.useEffect(() => {
159
- function handleClickOutside(e) {
160
- if (menuRef.current && !menuRef.current.contains(e.target)) {
161
- setIsUserMenuOpen(false);
162
- }
163
- }
164
- document.addEventListener("mousedown", handleClickOutside);
165
- return () => document.removeEventListener("mousedown", handleClickOutside);
166
- }, []);
167
- const user = userProp || fetchedUser;
168
- if (isLoading || !user) return null;
169
- const displayName = user.name || user.email?.split("@")[0] || "User";
170
- const initials = getInitials(displayName);
171
- const avatarColor = getAvatarColor(displayName);
172
54
  function isActive(href, exact) {
173
55
  return exact ? pathname === href : pathname.startsWith(href);
174
56
  }
175
- async function handleLogout() {
176
- const resolvedAppId = getResolvedAppId(appId);
177
- try {
178
- await getAuthJson("api/auth/logout", authHost, resolvedAppId ? { appId: resolvedAppId } : void 0);
179
- } catch (err) {
180
- console.error("Logout error:", err);
181
- }
182
- if (onLogout) {
183
- onLogout();
184
- } else {
185
- window.location.href = logoutRedirectTo;
186
- }
187
- }
188
57
  return /* @__PURE__ */ jsxRuntime.jsxs(
189
58
  "aside",
190
59
  {
@@ -224,85 +93,18 @@ function Sidebar({
224
93
  href
225
94
  );
226
95
  }) }),
227
- /* @__PURE__ */ jsxRuntime.jsxs(
228
- "div",
96
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-shrink-0 p-2 border-t border-zinc-200", children: /* @__PURE__ */ jsxRuntime.jsx(
97
+ authUi.UserMenu,
229
98
  {
230
- ref: menuRef,
231
- className: "relative flex-shrink-0 p-2 border-t border-zinc-200",
232
- children: [
233
- isUserMenuOpen && /* @__PURE__ */ jsxRuntime.jsxs(
234
- "div",
235
- {
236
- className: "absolute bottom-full mb-1 z-50 bg-white border border-zinc-200 rounded-xl shadow-lg shadow-zinc-200/50 overflow-hidden " + (isCollapsed ? "left-full ml-2 w-52" : "left-2 right-2"),
237
- children: [
238
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-3.5 py-3 border-b border-zinc-100", children: [
239
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-medium text-zinc-900 truncate", children: displayName }),
240
- user.email && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-zinc-500 truncate mt-0.5", children: user.email })
241
- ] }),
242
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-1", children: [
243
- /* @__PURE__ */ jsxRuntime.jsxs(
244
- "a",
245
- {
246
- href: profileHref,
247
- onClick: () => setIsUserMenuOpen(false),
248
- className: "flex items-center gap-2.5 w-full px-3 py-2 text-sm text-zinc-700 hover:bg-zinc-50 rounded-lg transition-colors",
249
- children: [
250
- /* @__PURE__ */ jsxRuntime.jsx(UserIcon, { className: "w-4 h-4 text-zinc-400" }),
251
- "Profile"
252
- ]
253
- }
254
- ),
255
- /* @__PURE__ */ jsxRuntime.jsxs(
256
- "a",
257
- {
258
- href: settingsHref,
259
- onClick: () => setIsUserMenuOpen(false),
260
- className: "flex items-center gap-2.5 w-full px-3 py-2 text-sm text-zinc-700 hover:bg-zinc-50 rounded-lg transition-colors",
261
- children: [
262
- /* @__PURE__ */ jsxRuntime.jsx(SettingsIcon, { className: "w-4 h-4 text-zinc-400" }),
263
- "Settings"
264
- ]
265
- }
266
- ),
267
- /* @__PURE__ */ jsxRuntime.jsxs(
268
- "button",
269
- {
270
- onClick: handleLogout,
271
- className: "flex items-center gap-2.5 w-full px-3 py-2 text-sm text-zinc-700 hover:bg-zinc-50 rounded-lg transition-colors text-left",
272
- children: [
273
- /* @__PURE__ */ jsxRuntime.jsx(LogOutIcon, { className: "w-4 h-4 text-zinc-400" }),
274
- "Log out"
275
- ]
276
- }
277
- )
278
- ] })
279
- ]
280
- }
281
- ),
282
- /* @__PURE__ */ jsxRuntime.jsxs(
283
- "button",
284
- {
285
- onClick: () => setIsUserMenuOpen((o) => !o),
286
- title: isCollapsed ? displayName : void 0,
287
- className: "w-full flex items-center gap-2.5 p-2 rounded-lg hover:bg-zinc-50 transition-colors text-left " + (isCollapsed ? "justify-center" : ""),
288
- children: [
289
- /* @__PURE__ */ jsxRuntime.jsx(
290
- "div",
291
- {
292
- className: "w-7 h-7 rounded-full flex items-center justify-center flex-shrink-0 " + avatarColor,
293
- children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs font-semibold text-white leading-none", children: initials })
294
- }
295
- ),
296
- !isCollapsed && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
297
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-medium text-zinc-900 truncate leading-tight", children: displayName }) }),
298
- /* @__PURE__ */ jsxRuntime.jsx(ChevronsUpDownIcon, { className: "w-3.5 h-3.5 text-zinc-400 flex-shrink-0" })
299
- ] })
300
- ]
301
- }
302
- )
303
- ]
99
+ user,
100
+ appId,
101
+ authHost,
102
+ logoutRedirectTo,
103
+ profileHref,
104
+ settingsHref,
105
+ onLogout
304
106
  }
305
- )
107
+ ) })
306
108
  ]
307
109
  }
308
110
  );
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/Hello.tsx","../src/utils/authApi.ts","../src/components/Sidebar.tsx"],"names":["jsx","jsxs","useState","useRef","useEffect","Fragment"],"mappings":"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","file":"index.cjs","sourcesContent":["export function Hello() {\n return <div>Hello world</div>;\n}\n","const DEFAULT_AUTH_HOST = (() => {\n if (typeof process !== \"undefined\" && process.env?.NEXT_PUBLIC_AUTH_API_HOST) {\n const envHost = process.env.NEXT_PUBLIC_AUTH_API_HOST.trim();\n if (envHost.length > 0) return envHost;\n }\n return \"https://auth.create-flow.ai\";\n})();\n\nconst DEFAULT_APP_ID =\n typeof process !== \"undefined\"\n ? process.env?.NEXT_PUBLIC_AUTH_APP_ID?.trim() ?? \"\"\n : \"\";\n\nfunction normalizeHost(host?: string) {\n const value = (host ?? DEFAULT_AUTH_HOST).trim();\n if (!value) throw new Error(\"Auth host is not configured\");\n if (/^https?:\\/\\//i.test(value)) return value.replace(/\\/+$/g, \"\");\n return `https://${value}`.replace(/\\/+$/g, \"\");\n}\n\nfunction buildAuthUrl(\n path: string,\n host?: string,\n query?: Record<string, string | undefined>\n) {\n const normalizedHost = normalizeHost(host);\n const normalizedPath = path.startsWith(\"/\") ? path : `/${path}`;\n const url = new URL(normalizedPath, normalizedHost);\n\n if (query) {\n for (const [key, value] of Object.entries(query)) {\n if (value !== undefined && value !== null) {\n url.searchParams.set(key, value);\n }\n }\n }\n\n return url;\n}\n\nasync function fetchWithCredentials(url: URL, init: RequestInit = {}) {\n const response = await fetch(url.toString(), {\n credentials: \"include\",\n cache: \"no-store\",\n ...init,\n });\n let data: any = null;\n try {\n data = await response.json();\n } catch {\n // Ignore JSON parse errors\n }\n return { response, data };\n}\n\nexport async function getAuthJson(\n path: string,\n host?: string,\n query?: Record<string, string | undefined>\n) {\n const url = buildAuthUrl(path, host, query);\n return fetchWithCredentials(url, { method: \"GET\" });\n}\n\nexport function getResolvedAppId(appId?: string) {\n return (appId ?? DEFAULT_APP_ID).trim();\n}\n","\"use client\";\n\nimport { useState, useRef, useEffect, useCallback, type ComponentType } from \"react\";\n\nimport { getResolvedAppId, getAuthJson } from \"../utils/authApi\";\n\n// ── Types ─────────────────────────────────────────────────────────────────────\n\nexport type UserType = \"guest\" | \"regular\";\n\nexport interface AuthUser {\n id: string;\n name?: string | null;\n email?: string | null;\n image?: string | null;\n type: UserType;\n appId: string;\n isGuest: boolean;\n}\n\nexport interface NavItem {\n href: string;\n label: string;\n icon: ComponentType<{ className?: string }>;\n exact?: boolean;\n}\n\nexport interface SidebarProps {\n user?: AuthUser;\n appId?: string;\n authHost?: string;\n navItems?: NavItem[];\n title?: string;\n logoutRedirectTo?: string;\n profileHref?: string;\n settingsHref?: string;\n onLogout?: () => void;\n}\n\n// ── Icons ─────────────────────────────────────────────────────────────────────\n\nfunction HomeIcon({ className }: { className?: string }) {\n return (\n <svg className={className} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.75\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M3 9l9-7 9 7v11a2 2 0 01-2 2H5a2 2 0 01-2-2z\" />\n <path d=\"M9 22V12h6v10\" />\n </svg>\n );\n}\n\nfunction FolderIcon({ className }: { className?: string }) {\n return (\n <svg className={className} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.75\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M22 19a2 2 0 01-2 2H4a2 2 0 01-2-2V5a2 2 0 012-2h5l2 3h9a2 2 0 012 2z\" />\n </svg>\n );\n}\n\nfunction UserIcon({ className }: { className?: string }) {\n return (\n <svg className={className} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.75\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <circle cx=\"12\" cy=\"8\" r=\"4\" />\n <path d=\"M4 20c0-4 3.6-7 8-7s8 3 8 7\" />\n </svg>\n );\n}\n\nfunction SettingsIcon({ className }: { className?: string }) {\n return (\n <svg className={className} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.75\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <circle cx=\"12\" cy=\"12\" r=\"3\" />\n <path d=\"M19.4 15a1.65 1.65 0 00.33 1.82l.06.06a2 2 0 010 2.83 2 2 0 01-2.83 0l-.06-.06a1.65 1.65 0 00-1.82-.33 1.65 1.65 0 00-1 1.51V21a2 2 0 01-4 0v-.09A1.65 1.65 0 009 19.4a1.65 1.65 0 00-1.82.33l-.06.06a2 2 0 01-2.83-2.83l.06-.06A1.65 1.65 0 004.68 15a1.65 1.65 0 00-1.51-1H3a2 2 0 010-4h.09A1.65 1.65 0 004.6 9a1.65 1.65 0 00-.33-1.82l-.06-.06a2 2 0 012.83-2.83l.06.06A1.65 1.65 0 009 4.68a1.65 1.65 0 001-1.51V3a2 2 0 014 0v.09a1.65 1.65 0 001 1.51 1.65 1.65 0 001.82-.33l.06-.06a2 2 0 012.83 2.83l-.06.06A1.65 1.65 0 0019.4 9a1.65 1.65 0 001.51 1H21a2 2 0 010 4h-.09a1.65 1.65 0 00-1.51 1z\" />\n </svg>\n );\n}\n\nfunction LogOutIcon({ className }: { className?: string }) {\n return (\n <svg className={className} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.75\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M9 21H5a2 2 0 01-2-2V5a2 2 0 012-2h4\" />\n <polyline points=\"16,17 21,12 16,7\" />\n <line x1=\"21\" y1=\"12\" x2=\"9\" y2=\"12\" />\n </svg>\n );\n}\n\nfunction ChevronLeftIcon({ className }: { className?: string }) {\n return (\n <svg className={className} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M15 18l-6-6 6-6\" />\n </svg>\n );\n}\n\nfunction ChevronRightIcon({ className }: { className?: string }) {\n return (\n <svg className={className} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M9 18l6-6-6-6\" />\n </svg>\n );\n}\n\nfunction ChevronsUpDownIcon({ className }: { className?: string }) {\n return (\n <svg className={className} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M7 15l5 5 5-5M7 9l5-5 5 5\" />\n </svg>\n );\n}\n\n// ── Default nav items ─────────────────────────────────────────────────────────\n\nconst defaultNavItems: NavItem[] = [\n { href: \"/dashboard\", label: \"Dashboard\", icon: HomeIcon, exact: true },\n { href: \"/dashboard/projects\", label: \"Projects\", icon: FolderIcon, exact: false },\n { href: \"/dashboard/settings\", label: \"Settings\", icon: SettingsIcon, exact: false },\n];\n\n// ── Avatar ────────────────────────────────────────────────────────────────────\n\nconst AVATAR_COLORS = [\n \"bg-violet-600\",\n \"bg-indigo-600\",\n \"bg-sky-600\",\n \"bg-emerald-600\",\n \"bg-amber-600\",\n \"bg-rose-600\",\n];\n\nfunction getAvatarColor(name: string): string {\n let hash = 0;\n for (let i = 0; i < name.length; i++) hash = name.charCodeAt(i) + ((hash << 5) - hash);\n return AVATAR_COLORS[Math.abs(hash) % AVATAR_COLORS.length];\n}\n\nfunction getInitials(name: string): string {\n return name\n .split(\" \")\n .filter(Boolean)\n .map((w) => w[0])\n .join(\"\")\n .toUpperCase()\n .slice(0, 2);\n}\n\n// ── Sidebar ───────────────────────────────────────────────────────────────────\n\nexport function Sidebar({\n user: userProp,\n appId,\n authHost,\n navItems = defaultNavItems,\n title = \"Workspace\",\n logoutRedirectTo = \"/\",\n profileHref = \"/profile\",\n settingsHref = \"/settings\",\n onLogout,\n}: SidebarProps) {\n const [isCollapsed, setIsCollapsed] = useState(false);\n const [isUserMenuOpen, setIsUserMenuOpen] = useState(false);\n const [fetchedUser, setFetchedUser] = useState<AuthUser | null>(null);\n const [isLoading, setIsLoading] = useState(!userProp);\n const [pathname, setPathname] = useState(typeof window !== \"undefined\" ? window.location.pathname : \"/\");\n const menuRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n setPathname(window.location.pathname);\n }, []);\n\n useEffect(() => {\n if (userProp) return;\n\n let cancelled = false;\n\n async function fetchSession() {\n try {\n const { response, data } = await getAuthJson(\"api/auth/session\", authHost);\n if (!cancelled && response.ok && data?.user) {\n setFetchedUser(data.user);\n }\n } catch (err) {\n console.error(\"Failed to fetch session:\", err);\n } finally {\n if (!cancelled) setIsLoading(false);\n }\n }\n\n fetchSession();\n return () => { cancelled = true; };\n }, [authHost, userProp]);\n\n useEffect(() => {\n function handleClickOutside(e: MouseEvent) {\n if (menuRef.current && !menuRef.current.contains(e.target as Node)) {\n setIsUserMenuOpen(false);\n }\n }\n document.addEventListener(\"mousedown\", handleClickOutside);\n return () => document.removeEventListener(\"mousedown\", handleClickOutside);\n }, []);\n\n const user = userProp || fetchedUser;\n\n if (isLoading || !user) return null;\n\n const displayName = user.name || user.email?.split(\"@\")[0] || \"User\";\n const initials = getInitials(displayName);\n const avatarColor = getAvatarColor(displayName);\n\n function isActive(href: string, exact: boolean) {\n return exact ? pathname === href : pathname.startsWith(href);\n }\n\n async function handleLogout() {\n const resolvedAppId = getResolvedAppId(appId);\n\n try {\n await getAuthJson(\"api/auth/logout\", authHost, resolvedAppId ? { appId: resolvedAppId } : undefined);\n } catch (err) {\n console.error(\"Logout error:\", err);\n }\n\n if (onLogout) {\n onLogout();\n } else {\n window.location.href = logoutRedirectTo;\n }\n }\n\n return (\n <aside\n className={\n \"relative flex flex-col h-screen bg-white border-r border-zinc-200 transition-all duration-200 ease-in-out flex-shrink-0 \" +\n (isCollapsed ? \"w-[60px]\" : \"w-[220px]\")\n }\n >\n {/* ── Header ─────────────────────────────────────────────────────────── */}\n <div\n className={\n \"flex items-center h-14 px-3 flex-shrink-0 border-b border-zinc-200 \" +\n (isCollapsed ? \"justify-center\" : \"justify-between\")\n }\n >\n {!isCollapsed && (\n <span className=\"text-sm font-semibold text-zinc-900 tracking-tight truncate select-none\">\n {title}\n </span>\n )}\n <button\n onClick={() => setIsCollapsed((c) => !c)}\n title={isCollapsed ? \"Expand sidebar\" : \"Collapse sidebar\"}\n className=\"p-1.5 rounded-md text-zinc-400 hover:text-zinc-700 hover:bg-zinc-100 transition-colors flex-shrink-0\"\n >\n {isCollapsed ? (\n <ChevronRightIcon className=\"w-4 h-4\" />\n ) : (\n <ChevronLeftIcon className=\"w-4 h-4\" />\n )}\n </button>\n </div>\n\n {/* ── Nav ────────────────────────────────────────────────────────────── */}\n <nav className=\"flex-1 overflow-y-auto py-2 px-2 space-y-0.5\">\n {navItems.map(({ href, label, icon: Icon, exact }) => {\n const active = isActive(href, exact ?? false);\n return (\n <a\n key={href}\n href={href}\n title={isCollapsed ? label : undefined}\n className={\n \"flex items-center gap-2.5 px-2.5 py-2 rounded-lg text-sm transition-colors \" +\n (isCollapsed ? \"justify-center \" : \"\") +\n (active\n ? \"bg-zinc-100 text-zinc-900 font-medium\"\n : \"text-zinc-500 hover:bg-zinc-50 hover:text-zinc-900\")\n }\n >\n <Icon className=\"w-4 h-4 flex-shrink-0\" />\n {!isCollapsed && <span className=\"truncate\">{label}</span>}\n </a>\n );\n })}\n </nav>\n\n {/* ── User area ──────────────────────────────────────────────────────── */}\n <div\n ref={menuRef}\n className=\"relative flex-shrink-0 p-2 border-t border-zinc-200\"\n >\n {/* Dropdown menu */}\n {isUserMenuOpen && (\n <div\n className={\n \"absolute bottom-full mb-1 z-50 bg-white border border-zinc-200 rounded-xl shadow-lg shadow-zinc-200/50 overflow-hidden \" +\n (isCollapsed ? \"left-full ml-2 w-52\" : \"left-2 right-2\")\n }\n >\n {/* User info */}\n <div className=\"px-3.5 py-3 border-b border-zinc-100\">\n <p className=\"text-sm font-medium text-zinc-900 truncate\">\n {displayName}\n </p>\n {user.email && (\n <p className=\"text-xs text-zinc-500 truncate mt-0.5\">\n {user.email}\n </p>\n )}\n </div>\n {/* Menu items */}\n <div className=\"p-1\">\n <a\n href={profileHref}\n onClick={() => setIsUserMenuOpen(false)}\n className=\"flex items-center gap-2.5 w-full px-3 py-2 text-sm text-zinc-700 hover:bg-zinc-50 rounded-lg transition-colors\"\n >\n <UserIcon className=\"w-4 h-4 text-zinc-400\" />\n Profile\n </a>\n <a\n href={settingsHref}\n onClick={() => setIsUserMenuOpen(false)}\n className=\"flex items-center gap-2.5 w-full px-3 py-2 text-sm text-zinc-700 hover:bg-zinc-50 rounded-lg transition-colors\"\n >\n <SettingsIcon className=\"w-4 h-4 text-zinc-400\" />\n Settings\n </a>\n <button\n onClick={handleLogout}\n className=\"flex items-center gap-2.5 w-full px-3 py-2 text-sm text-zinc-700 hover:bg-zinc-50 rounded-lg transition-colors text-left\"\n >\n <LogOutIcon className=\"w-4 h-4 text-zinc-400\" />\n Log out\n </button>\n </div>\n </div>\n )}\n\n {/* User trigger button */}\n <button\n onClick={() => setIsUserMenuOpen((o) => !o)}\n title={isCollapsed ? displayName : undefined}\n className={\n \"w-full flex items-center gap-2.5 p-2 rounded-lg hover:bg-zinc-50 transition-colors text-left \" +\n (isCollapsed ? \"justify-center\" : \"\")\n }\n >\n <div\n className={\"w-7 h-7 rounded-full flex items-center justify-center flex-shrink-0 \" + avatarColor}\n >\n <span className=\"text-xs font-semibold text-white leading-none\">\n {initials}\n </span>\n </div>\n {!isCollapsed && (\n <>\n <div className=\"flex-1 min-w-0\">\n <p className=\"text-sm font-medium text-zinc-900 truncate leading-tight\">\n {displayName}\n </p>\n </div>\n <ChevronsUpDownIcon className=\"w-3.5 h-3.5 text-zinc-400 flex-shrink-0\" />\n </>\n )}\n </button>\n </div>\n </aside>\n );\n}\n"]}
1
+ {"version":3,"sources":["../src/components/Hello.tsx","../src/components/Sidebar.tsx"],"names":["jsx","jsxs","useState","useEffect","UserMenu"],"mappings":"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","file":"index.cjs","sourcesContent":["export function Hello() {\n return <div>Hello world</div>;\n}\n","\"use client\";\n\nimport { useState, useEffect, type ComponentType } from \"react\";\nimport { UserMenu } from \"@create-flow/auth-ui\";\nimport type { AuthUser } from \"@create-flow/auth-ui\";\n\n// ── Types ─────────────────────────────────────────────────────────────────────\n\nexport type { AuthUser, UserType } from \"@create-flow/auth-ui\";\n\nexport interface NavItem {\n href: string;\n label: string;\n icon: ComponentType<{ className?: string }>;\n exact?: boolean;\n}\n\nexport interface SidebarProps {\n user?: AuthUser;\n appId?: string;\n authHost?: string;\n navItems?: NavItem[];\n title?: string;\n logoutRedirectTo?: string;\n profileHref?: string;\n settingsHref?: string;\n onLogout?: () => void;\n}\n\n// ── Icons ─────────────────────────────────────────────────────────────────────\n\nfunction HomeIcon({ className }: { className?: string }) {\n return (\n <svg className={className} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.75\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M3 9l9-7 9 7v11a2 2 0 01-2 2H5a2 2 0 01-2-2z\" />\n <path d=\"M9 22V12h6v10\" />\n </svg>\n );\n}\n\nfunction FolderIcon({ className }: { className?: string }) {\n return (\n <svg className={className} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.75\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M22 19a2 2 0 01-2 2H4a2 2 0 01-2-2V5a2 2 0 012-2h5l2 3h9a2 2 0 012 2z\" />\n </svg>\n );\n}\n\nfunction SettingsIcon({ className }: { className?: string }) {\n return (\n <svg className={className} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.75\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <circle cx=\"12\" cy=\"12\" r=\"3\" />\n <path d=\"M19.4 15a1.65 1.65 0 00.33 1.82l.06.06a2 2 0 010 2.83 2 2 0 01-2.83 0l-.06-.06a1.65 1.65 0 00-1.82-.33 1.65 1.65 0 00-1 1.51V21a2 2 0 01-4 0v-.09A1.65 1.65 0 009 19.4a1.65 1.65 0 00-1.82.33l-.06.06a2 2 0 01-2.83-2.83l.06-.06A1.65 1.65 0 004.68 15a1.65 1.65 0 00-1.51-1H3a2 2 0 010-4h.09A1.65 1.65 0 004.6 9a1.65 1.65 0 00-.33-1.82l-.06-.06a2 2 0 012.83-2.83l.06.06A1.65 1.65 0 009 4.68a1.65 1.65 0 001-1.51V3a2 2 0 014 0v.09a1.65 1.65 0 001 1.51 1.65 1.65 0 001.82-.33l.06-.06a2 2 0 012.83 2.83l-.06.06A1.65 1.65 0 0019.4 9a1.65 1.65 0 001.51 1H21a2 2 0 010 4h-.09a1.65 1.65 0 00-1.51 1z\" />\n </svg>\n );\n}\n\nfunction ChevronLeftIcon({ className }: { className?: string }) {\n return (\n <svg className={className} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M15 18l-6-6 6-6\" />\n </svg>\n );\n}\n\nfunction ChevronRightIcon({ className }: { className?: string }) {\n return (\n <svg className={className} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M9 18l6-6-6-6\" />\n </svg>\n );\n}\n\n// ── Default nav items ─────────────────────────────────────────────────────────\n\nconst defaultNavItems: NavItem[] = [\n { href: \"/dashboard\", label: \"Dashboard\", icon: HomeIcon, exact: true },\n { href: \"/dashboard/projects\", label: \"Projects\", icon: FolderIcon, exact: false },\n { href: \"/dashboard/settings\", label: \"Settings\", icon: SettingsIcon, exact: false },\n];\n\n// ── Sidebar ───────────────────────────────────────────────────────────────────\n\nexport function Sidebar({\n user,\n appId,\n authHost,\n navItems = defaultNavItems,\n title = \"Workspace\",\n logoutRedirectTo = \"/\",\n profileHref = \"/profile\",\n settingsHref = \"/settings\",\n onLogout,\n}: SidebarProps) {\n const [isCollapsed, setIsCollapsed] = useState(false);\n const [pathname, setPathname] = useState(typeof window !== \"undefined\" ? window.location.pathname : \"/\");\n\n useEffect(() => {\n setPathname(window.location.pathname);\n }, []);\n\n function isActive(href: string, exact: boolean) {\n return exact ? pathname === href : pathname.startsWith(href);\n }\n\n return (\n <aside\n className={\n \"relative flex flex-col h-screen bg-white border-r border-zinc-200 transition-all duration-200 ease-in-out flex-shrink-0 \" +\n (isCollapsed ? \"w-[60px]\" : \"w-[220px]\")\n }\n >\n {/* ── Header ─────────────────────────────────────────────────────────── */}\n <div\n className={\n \"flex items-center h-14 px-3 flex-shrink-0 border-b border-zinc-200 \" +\n (isCollapsed ? \"justify-center\" : \"justify-between\")\n }\n >\n {!isCollapsed && (\n <span className=\"text-sm font-semibold text-zinc-900 tracking-tight truncate select-none\">\n {title}\n </span>\n )}\n <button\n onClick={() => setIsCollapsed((c) => !c)}\n title={isCollapsed ? \"Expand sidebar\" : \"Collapse sidebar\"}\n className=\"p-1.5 rounded-md text-zinc-400 hover:text-zinc-700 hover:bg-zinc-100 transition-colors flex-shrink-0\"\n >\n {isCollapsed ? (\n <ChevronRightIcon className=\"w-4 h-4\" />\n ) : (\n <ChevronLeftIcon className=\"w-4 h-4\" />\n )}\n </button>\n </div>\n\n {/* ── Nav ────────────────────────────────────────────────────────────── */}\n <nav className=\"flex-1 overflow-y-auto py-2 px-2 space-y-0.5\">\n {navItems.map(({ href, label, icon: Icon, exact }) => {\n const active = isActive(href, exact ?? false);\n return (\n <a\n key={href}\n href={href}\n title={isCollapsed ? label : undefined}\n className={\n \"flex items-center gap-2.5 px-2.5 py-2 rounded-lg text-sm transition-colors \" +\n (isCollapsed ? \"justify-center \" : \"\") +\n (active\n ? \"bg-zinc-100 text-zinc-900 font-medium\"\n : \"text-zinc-500 hover:bg-zinc-50 hover:text-zinc-900\")\n }\n >\n <Icon className=\"w-4 h-4 flex-shrink-0\" />\n {!isCollapsed && <span className=\"truncate\">{label}</span>}\n </a>\n );\n })}\n </nav>\n\n {/* ── User area ──────────────────────────────────────────────────────── */}\n <div className=\"flex-shrink-0 p-2 border-t border-zinc-200\">\n <UserMenu\n user={user}\n appId={appId}\n authHost={authHost}\n logoutRedirectTo={logoutRedirectTo}\n profileHref={profileHref}\n settingsHref={settingsHref}\n onLogout={onLogout}\n />\n </div>\n </aside>\n );\n}\n"]}
package/dist/index.css CHANGED
@@ -1 +1 @@
1
- *,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,0.5);--tw-ring-offset-shadow:0 0 transparent;--tw-ring-shadow:0 0 transparent;--tw-shadow:0 0 transparent;--tw-shadow-colored:0 0 transparent;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,0.5);--tw-ring-offset-shadow:0 0 transparent;--tw-ring-shadow:0 0 transparent;--tw-shadow:0 0 transparent;--tw-shadow-colored:0 0 transparent;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }/*! tailwindcss v3.4.19 | MIT License | https://tailwindcss.com*/*,:after,:before{box-sizing:border-box;border:0 solid #e5e7eb}:after,:before{--tw-content:""}:host,html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder, textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}.absolute{position:absolute}.relative{position:relative}.bottom-full{bottom:100%}.left-2{left:.5rem}.left-full{left:100%}.right-2{right:.5rem}.z-50{z-index:50}.mb-1{margin-bottom:.25rem}.ml-2{margin-left:.5rem}.mt-0\.5{margin-top:.125rem}.flex{display:flex}.h-14{height:3.5rem}.h-3\.5{height:.875rem}.h-4{height:1rem}.h-7{height:1.75rem}.h-screen{height:100vh}.w-3\.5{width:.875rem}.w-4{width:1rem}.w-52{width:13rem}.w-7{width:1.75rem}.w-\[220px\]{width:220px}.w-\[60px\]{width:60px}.w-full{width:100%}.min-w-0{min-width:0}.flex-1{flex:1 1 0%}.flex-shrink-0{flex-shrink:0}.select-none{-webkit-user-select:none;-moz-user-select:none;user-select:none}.flex-col{flex-direction:column}.items-center{align-items:center}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-2\.5{gap:.625rem}.space-y-0\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(0.125rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(0.125rem*var(--tw-space-y-reverse))}.overflow-hidden{overflow:hidden}.overflow-y-auto{overflow-y:auto}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.rounded-md{border-radius:.375rem}.rounded-xl{border-radius:.75rem}.border{border-width:1px}.border-b{border-bottom-width:1px}.border-r{border-right-width:1px}.border-t{border-top-width:1px}.border-zinc-100{--tw-border-opacity:1;border-color:rgb(244 244 245/var(--tw-border-opacity,1))}.border-zinc-200{--tw-border-opacity:1;border-color:rgb(228 228 231/var(--tw-border-opacity,1))}.bg-amber-600{--tw-bg-opacity:1;background-color:rgb(217 119 6/var(--tw-bg-opacity,1))}.bg-emerald-600{--tw-bg-opacity:1;background-color:rgb(5 150 105/var(--tw-bg-opacity,1))}.bg-indigo-600{--tw-bg-opacity:1;background-color:rgb(79 70 229/var(--tw-bg-opacity,1))}.bg-rose-600{--tw-bg-opacity:1;background-color:rgb(225 29 72/var(--tw-bg-opacity,1))}.bg-sky-600{--tw-bg-opacity:1;background-color:rgb(2 132 199/var(--tw-bg-opacity,1))}.bg-violet-600{--tw-bg-opacity:1;background-color:rgb(124 58 237/var(--tw-bg-opacity,1))}.bg-white{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity,1))}.bg-zinc-100{--tw-bg-opacity:1;background-color:rgb(244 244 245/var(--tw-bg-opacity,1))}.p-1{padding:.25rem}.p-1\.5{padding:.375rem}.p-2{padding:.5rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-2\.5{padding-left:.625rem;padding-right:.625rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-3\.5{padding-left:.875rem;padding-right:.875rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.text-left{text-align:left}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xs{font-size:.75rem;line-height:1rem}.font-medium{font-weight:500}.font-semibold{font-weight:600}.leading-none{line-height:1}.leading-tight{line-height:1.25}.tracking-tight{letter-spacing:-.025em}.text-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1))}.text-zinc-400{--tw-text-opacity:1;color:rgb(161 161 170/var(--tw-text-opacity,1))}.text-zinc-500{--tw-text-opacity:1;color:rgb(113 113 122/var(--tw-text-opacity,1))}.text-zinc-700{--tw-text-opacity:1;color:rgb(63 63 70/var(--tw-text-opacity,1))}.text-zinc-900{--tw-text-opacity:1;color:rgb(24 24 27/var(--tw-text-opacity,1))}.shadow-lg{--tw-shadow:0 10px 15px -3px rgba(0,0,0,0.1),0 4px 6px -4px rgba(0,0,0,0.1);--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color),0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 transparent),var(--tw-ring-shadow,0 0 transparent),var(--tw-shadow)}.shadow-zinc-200\/50{--tw-shadow-color:rgba(228,228,231,0.5);--tw-shadow:var(--tw-shadow-colored)}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.transition-all{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.duration-200{transition-duration:.2s}.ease-in-out{transition-timing-function:cubic-bezier(.4,0,.2,1)}.hover\:bg-zinc-100:hover{--tw-bg-opacity:1;background-color:rgb(244 244 245/var(--tw-bg-opacity,1))}.hover\:bg-zinc-50:hover{--tw-bg-opacity:1;background-color:rgb(250 250 250/var(--tw-bg-opacity,1))}.hover\:text-zinc-700:hover{--tw-text-opacity:1;color:rgb(63 63 70/var(--tw-text-opacity,1))}.hover\:text-zinc-900:hover{--tw-text-opacity:1;color:rgb(24 24 27/var(--tw-text-opacity,1))}
1
+ *,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,0.5);--tw-ring-offset-shadow:0 0 transparent;--tw-ring-shadow:0 0 transparent;--tw-shadow:0 0 transparent;--tw-shadow-colored:0 0 transparent;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,0.5);--tw-ring-offset-shadow:0 0 transparent;--tw-ring-shadow:0 0 transparent;--tw-shadow:0 0 transparent;--tw-shadow-colored:0 0 transparent;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }/*! tailwindcss v3.4.19 | MIT License | https://tailwindcss.com*/*,:after,:before{box-sizing:border-box;border:0 solid #e5e7eb}:after,:before{--tw-content:""}:host,html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder, textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}.relative{position:relative}.flex{display:flex}.h-14{height:3.5rem}.h-4{height:1rem}.h-screen{height:100vh}.w-4{width:1rem}.w-\[220px\]{width:220px}.w-\[60px\]{width:60px}.flex-1{flex:1 1 0%}.flex-shrink-0{flex-shrink:0}.select-none{-webkit-user-select:none;-moz-user-select:none;user-select:none}.flex-col{flex-direction:column}.items-center{align-items:center}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-2\.5{gap:.625rem}.space-y-0\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(0.125rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(0.125rem*var(--tw-space-y-reverse))}.overflow-y-auto{overflow-y:auto}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.rounded-lg{border-radius:.5rem}.rounded-md{border-radius:.375rem}.border-b{border-bottom-width:1px}.border-r{border-right-width:1px}.border-t{border-top-width:1px}.border-zinc-200{--tw-border-opacity:1;border-color:rgb(228 228 231/var(--tw-border-opacity,1))}.bg-white{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity,1))}.bg-zinc-100{--tw-bg-opacity:1;background-color:rgb(244 244 245/var(--tw-bg-opacity,1))}.p-1\.5{padding:.375rem}.p-2{padding:.5rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-2\.5{padding-left:.625rem;padding-right:.625rem}.px-3{padding-left:.75rem;padding-right:.75rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.text-sm{font-size:.875rem;line-height:1.25rem}.font-medium{font-weight:500}.font-semibold{font-weight:600}.tracking-tight{letter-spacing:-.025em}.text-zinc-400{--tw-text-opacity:1;color:rgb(161 161 170/var(--tw-text-opacity,1))}.text-zinc-500{--tw-text-opacity:1;color:rgb(113 113 122/var(--tw-text-opacity,1))}.text-zinc-900{--tw-text-opacity:1;color:rgb(24 24 27/var(--tw-text-opacity,1))}.transition-all{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.duration-200{transition-duration:.2s}.ease-in-out{transition-timing-function:cubic-bezier(.4,0,.2,1)}.hover\:bg-zinc-100:hover{--tw-bg-opacity:1;background-color:rgb(244 244 245/var(--tw-bg-opacity,1))}.hover\:bg-zinc-50:hover{--tw-bg-opacity:1;background-color:rgb(250 250 250/var(--tw-bg-opacity,1))}.hover\:text-zinc-700:hover{--tw-text-opacity:1;color:rgb(63 63 70/var(--tw-text-opacity,1))}.hover\:text-zinc-900:hover{--tw-text-opacity:1;color:rgb(24 24 27/var(--tw-text-opacity,1))}
package/dist/index.d.cts CHANGED
@@ -1,18 +1,10 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { ComponentType } from 'react';
3
+ import { AuthUser } from '@create-flow/auth-ui';
4
+ export { AuthUser, UserType } from '@create-flow/auth-ui';
3
5
 
4
6
  declare function Hello(): react_jsx_runtime.JSX.Element;
5
7
 
6
- type UserType = "guest" | "regular";
7
- interface AuthUser {
8
- id: string;
9
- name?: string | null;
10
- email?: string | null;
11
- image?: string | null;
12
- type: UserType;
13
- appId: string;
14
- isGuest: boolean;
15
- }
16
8
  interface NavItem {
17
9
  href: string;
18
10
  label: string;
@@ -32,6 +24,6 @@ interface SidebarProps {
32
24
  settingsHref?: string;
33
25
  onLogout?: () => void;
34
26
  }
35
- declare function Sidebar({ user: userProp, appId, authHost, navItems, title, logoutRedirectTo, profileHref, settingsHref, onLogout, }: SidebarProps): react_jsx_runtime.JSX.Element | null;
27
+ declare function Sidebar({ user, appId, authHost, navItems, title, logoutRedirectTo, profileHref, settingsHref, onLogout, }: SidebarProps): react_jsx_runtime.JSX.Element;
36
28
 
37
- export { type AuthUser, Hello, type NavItem, Sidebar, type SidebarProps, type UserType };
29
+ export { Hello, type NavItem, Sidebar, type SidebarProps };
package/dist/index.d.ts CHANGED
@@ -1,18 +1,10 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { ComponentType } from 'react';
3
+ import { AuthUser } from '@create-flow/auth-ui';
4
+ export { AuthUser, UserType } from '@create-flow/auth-ui';
3
5
 
4
6
  declare function Hello(): react_jsx_runtime.JSX.Element;
5
7
 
6
- type UserType = "guest" | "regular";
7
- interface AuthUser {
8
- id: string;
9
- name?: string | null;
10
- email?: string | null;
11
- image?: string | null;
12
- type: UserType;
13
- appId: string;
14
- isGuest: boolean;
15
- }
16
8
  interface NavItem {
17
9
  href: string;
18
10
  label: string;
@@ -32,6 +24,6 @@ interface SidebarProps {
32
24
  settingsHref?: string;
33
25
  onLogout?: () => void;
34
26
  }
35
- declare function Sidebar({ user: userProp, appId, authHost, navItems, title, logoutRedirectTo, profileHref, settingsHref, onLogout, }: SidebarProps): react_jsx_runtime.JSX.Element | null;
27
+ declare function Sidebar({ user, appId, authHost, navItems, title, logoutRedirectTo, profileHref, settingsHref, onLogout, }: SidebarProps): react_jsx_runtime.JSX.Element;
36
28
 
37
- export { type AuthUser, Hello, type NavItem, Sidebar, type SidebarProps, type UserType };
29
+ export { Hello, type NavItem, Sidebar, type SidebarProps };
package/dist/index.js CHANGED
@@ -1,60 +1,12 @@
1
1
  "use client";
2
- import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
3
- import { useState, useRef, useEffect } from 'react';
2
+ import { jsx, jsxs } from 'react/jsx-runtime';
3
+ import { useState, useEffect } from 'react';
4
+ import { UserMenu } from '@create-flow/auth-ui';
4
5
 
5
6
  // src/components/Hello.tsx
6
7
  function Hello() {
7
8
  return /* @__PURE__ */ jsx("div", { children: "Hello world" });
8
9
  }
9
-
10
- // src/utils/authApi.ts
11
- var DEFAULT_AUTH_HOST = (() => {
12
- if (typeof process !== "undefined" && process.env?.NEXT_PUBLIC_AUTH_API_HOST) {
13
- const envHost = process.env.NEXT_PUBLIC_AUTH_API_HOST.trim();
14
- if (envHost.length > 0) return envHost;
15
- }
16
- return "https://auth.create-flow.ai";
17
- })();
18
- var DEFAULT_APP_ID = typeof process !== "undefined" ? process.env?.NEXT_PUBLIC_AUTH_APP_ID?.trim() ?? "" : "";
19
- function normalizeHost(host) {
20
- const value = (host ?? DEFAULT_AUTH_HOST).trim();
21
- if (!value) throw new Error("Auth host is not configured");
22
- if (/^https?:\/\//i.test(value)) return value.replace(/\/+$/g, "");
23
- return `https://${value}`.replace(/\/+$/g, "");
24
- }
25
- function buildAuthUrl(path, host, query) {
26
- const normalizedHost = normalizeHost(host);
27
- const normalizedPath = path.startsWith("/") ? path : `/${path}`;
28
- const url = new URL(normalizedPath, normalizedHost);
29
- if (query) {
30
- for (const [key, value] of Object.entries(query)) {
31
- if (value !== void 0 && value !== null) {
32
- url.searchParams.set(key, value);
33
- }
34
- }
35
- }
36
- return url;
37
- }
38
- async function fetchWithCredentials(url, init = {}) {
39
- const response = await fetch(url.toString(), {
40
- credentials: "include",
41
- cache: "no-store",
42
- ...init
43
- });
44
- let data = null;
45
- try {
46
- data = await response.json();
47
- } catch {
48
- }
49
- return { response, data };
50
- }
51
- async function getAuthJson(path, host, query) {
52
- const url = buildAuthUrl(path, host, query);
53
- return fetchWithCredentials(url, { method: "GET" });
54
- }
55
- function getResolvedAppId(appId) {
56
- return (appId ?? DEFAULT_APP_ID).trim();
57
- }
58
10
  function HomeIcon({ className }) {
59
11
  return /* @__PURE__ */ jsxs("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.75", strokeLinecap: "round", strokeLinejoin: "round", children: [
60
12
  /* @__PURE__ */ jsx("path", { d: "M3 9l9-7 9 7v11a2 2 0 01-2 2H5a2 2 0 01-2-2z" }),
@@ -64,57 +16,25 @@ function HomeIcon({ className }) {
64
16
  function FolderIcon({ className }) {
65
17
  return /* @__PURE__ */ jsx("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.75", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx("path", { d: "M22 19a2 2 0 01-2 2H4a2 2 0 01-2-2V5a2 2 0 012-2h5l2 3h9a2 2 0 012 2z" }) });
66
18
  }
67
- function UserIcon({ className }) {
68
- return /* @__PURE__ */ jsxs("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.75", strokeLinecap: "round", strokeLinejoin: "round", children: [
69
- /* @__PURE__ */ jsx("circle", { cx: "12", cy: "8", r: "4" }),
70
- /* @__PURE__ */ jsx("path", { d: "M4 20c0-4 3.6-7 8-7s8 3 8 7" })
71
- ] });
72
- }
73
19
  function SettingsIcon({ className }) {
74
20
  return /* @__PURE__ */ jsxs("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.75", strokeLinecap: "round", strokeLinejoin: "round", children: [
75
21
  /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "3" }),
76
22
  /* @__PURE__ */ jsx("path", { d: "M19.4 15a1.65 1.65 0 00.33 1.82l.06.06a2 2 0 010 2.83 2 2 0 01-2.83 0l-.06-.06a1.65 1.65 0 00-1.82-.33 1.65 1.65 0 00-1 1.51V21a2 2 0 01-4 0v-.09A1.65 1.65 0 009 19.4a1.65 1.65 0 00-1.82.33l-.06.06a2 2 0 01-2.83-2.83l.06-.06A1.65 1.65 0 004.68 15a1.65 1.65 0 00-1.51-1H3a2 2 0 010-4h.09A1.65 1.65 0 004.6 9a1.65 1.65 0 00-.33-1.82l-.06-.06a2 2 0 012.83-2.83l.06.06A1.65 1.65 0 009 4.68a1.65 1.65 0 001-1.51V3a2 2 0 014 0v.09a1.65 1.65 0 001 1.51 1.65 1.65 0 001.82-.33l.06-.06a2 2 0 012.83 2.83l-.06.06A1.65 1.65 0 0019.4 9a1.65 1.65 0 001.51 1H21a2 2 0 010 4h-.09a1.65 1.65 0 00-1.51 1z" })
77
23
  ] });
78
24
  }
79
- function LogOutIcon({ className }) {
80
- return /* @__PURE__ */ jsxs("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.75", strokeLinecap: "round", strokeLinejoin: "round", children: [
81
- /* @__PURE__ */ jsx("path", { d: "M9 21H5a2 2 0 01-2-2V5a2 2 0 012-2h4" }),
82
- /* @__PURE__ */ jsx("polyline", { points: "16,17 21,12 16,7" }),
83
- /* @__PURE__ */ jsx("line", { x1: "21", y1: "12", x2: "9", y2: "12" })
84
- ] });
85
- }
86
25
  function ChevronLeftIcon({ className }) {
87
26
  return /* @__PURE__ */ jsx("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx("path", { d: "M15 18l-6-6 6-6" }) });
88
27
  }
89
28
  function ChevronRightIcon({ className }) {
90
29
  return /* @__PURE__ */ jsx("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx("path", { d: "M9 18l6-6-6-6" }) });
91
30
  }
92
- function ChevronsUpDownIcon({ className }) {
93
- return /* @__PURE__ */ jsx("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx("path", { d: "M7 15l5 5 5-5M7 9l5-5 5 5" }) });
94
- }
95
31
  var defaultNavItems = [
96
32
  { href: "/dashboard", label: "Dashboard", icon: HomeIcon, exact: true },
97
33
  { href: "/dashboard/projects", label: "Projects", icon: FolderIcon, exact: false },
98
34
  { href: "/dashboard/settings", label: "Settings", icon: SettingsIcon, exact: false }
99
35
  ];
100
- var AVATAR_COLORS = [
101
- "bg-violet-600",
102
- "bg-indigo-600",
103
- "bg-sky-600",
104
- "bg-emerald-600",
105
- "bg-amber-600",
106
- "bg-rose-600"
107
- ];
108
- function getAvatarColor(name) {
109
- let hash = 0;
110
- for (let i = 0; i < name.length; i++) hash = name.charCodeAt(i) + ((hash << 5) - hash);
111
- return AVATAR_COLORS[Math.abs(hash) % AVATAR_COLORS.length];
112
- }
113
- function getInitials(name) {
114
- return name.split(" ").filter(Boolean).map((w) => w[0]).join("").toUpperCase().slice(0, 2);
115
- }
116
36
  function Sidebar({
117
- user: userProp,
37
+ user,
118
38
  appId,
119
39
  authHost,
120
40
  navItems = defaultNavItems,
@@ -125,64 +45,13 @@ function Sidebar({
125
45
  onLogout
126
46
  }) {
127
47
  const [isCollapsed, setIsCollapsed] = useState(false);
128
- const [isUserMenuOpen, setIsUserMenuOpen] = useState(false);
129
- const [fetchedUser, setFetchedUser] = useState(null);
130
- const [isLoading, setIsLoading] = useState(!userProp);
131
48
  const [pathname, setPathname] = useState(typeof window !== "undefined" ? window.location.pathname : "/");
132
- const menuRef = useRef(null);
133
49
  useEffect(() => {
134
50
  setPathname(window.location.pathname);
135
51
  }, []);
136
- useEffect(() => {
137
- if (userProp) return;
138
- let cancelled = false;
139
- async function fetchSession() {
140
- try {
141
- const { response, data } = await getAuthJson("api/auth/session", authHost);
142
- if (!cancelled && response.ok && data?.user) {
143
- setFetchedUser(data.user);
144
- }
145
- } catch (err) {
146
- console.error("Failed to fetch session:", err);
147
- } finally {
148
- if (!cancelled) setIsLoading(false);
149
- }
150
- }
151
- fetchSession();
152
- return () => {
153
- cancelled = true;
154
- };
155
- }, [authHost, userProp]);
156
- useEffect(() => {
157
- function handleClickOutside(e) {
158
- if (menuRef.current && !menuRef.current.contains(e.target)) {
159
- setIsUserMenuOpen(false);
160
- }
161
- }
162
- document.addEventListener("mousedown", handleClickOutside);
163
- return () => document.removeEventListener("mousedown", handleClickOutside);
164
- }, []);
165
- const user = userProp || fetchedUser;
166
- if (isLoading || !user) return null;
167
- const displayName = user.name || user.email?.split("@")[0] || "User";
168
- const initials = getInitials(displayName);
169
- const avatarColor = getAvatarColor(displayName);
170
52
  function isActive(href, exact) {
171
53
  return exact ? pathname === href : pathname.startsWith(href);
172
54
  }
173
- async function handleLogout() {
174
- const resolvedAppId = getResolvedAppId(appId);
175
- try {
176
- await getAuthJson("api/auth/logout", authHost, resolvedAppId ? { appId: resolvedAppId } : void 0);
177
- } catch (err) {
178
- console.error("Logout error:", err);
179
- }
180
- if (onLogout) {
181
- onLogout();
182
- } else {
183
- window.location.href = logoutRedirectTo;
184
- }
185
- }
186
55
  return /* @__PURE__ */ jsxs(
187
56
  "aside",
188
57
  {
@@ -222,85 +91,18 @@ function Sidebar({
222
91
  href
223
92
  );
224
93
  }) }),
225
- /* @__PURE__ */ jsxs(
226
- "div",
94
+ /* @__PURE__ */ jsx("div", { className: "flex-shrink-0 p-2 border-t border-zinc-200", children: /* @__PURE__ */ jsx(
95
+ UserMenu,
227
96
  {
228
- ref: menuRef,
229
- className: "relative flex-shrink-0 p-2 border-t border-zinc-200",
230
- children: [
231
- isUserMenuOpen && /* @__PURE__ */ jsxs(
232
- "div",
233
- {
234
- className: "absolute bottom-full mb-1 z-50 bg-white border border-zinc-200 rounded-xl shadow-lg shadow-zinc-200/50 overflow-hidden " + (isCollapsed ? "left-full ml-2 w-52" : "left-2 right-2"),
235
- children: [
236
- /* @__PURE__ */ jsxs("div", { className: "px-3.5 py-3 border-b border-zinc-100", children: [
237
- /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-zinc-900 truncate", children: displayName }),
238
- user.email && /* @__PURE__ */ jsx("p", { className: "text-xs text-zinc-500 truncate mt-0.5", children: user.email })
239
- ] }),
240
- /* @__PURE__ */ jsxs("div", { className: "p-1", children: [
241
- /* @__PURE__ */ jsxs(
242
- "a",
243
- {
244
- href: profileHref,
245
- onClick: () => setIsUserMenuOpen(false),
246
- className: "flex items-center gap-2.5 w-full px-3 py-2 text-sm text-zinc-700 hover:bg-zinc-50 rounded-lg transition-colors",
247
- children: [
248
- /* @__PURE__ */ jsx(UserIcon, { className: "w-4 h-4 text-zinc-400" }),
249
- "Profile"
250
- ]
251
- }
252
- ),
253
- /* @__PURE__ */ jsxs(
254
- "a",
255
- {
256
- href: settingsHref,
257
- onClick: () => setIsUserMenuOpen(false),
258
- className: "flex items-center gap-2.5 w-full px-3 py-2 text-sm text-zinc-700 hover:bg-zinc-50 rounded-lg transition-colors",
259
- children: [
260
- /* @__PURE__ */ jsx(SettingsIcon, { className: "w-4 h-4 text-zinc-400" }),
261
- "Settings"
262
- ]
263
- }
264
- ),
265
- /* @__PURE__ */ jsxs(
266
- "button",
267
- {
268
- onClick: handleLogout,
269
- className: "flex items-center gap-2.5 w-full px-3 py-2 text-sm text-zinc-700 hover:bg-zinc-50 rounded-lg transition-colors text-left",
270
- children: [
271
- /* @__PURE__ */ jsx(LogOutIcon, { className: "w-4 h-4 text-zinc-400" }),
272
- "Log out"
273
- ]
274
- }
275
- )
276
- ] })
277
- ]
278
- }
279
- ),
280
- /* @__PURE__ */ jsxs(
281
- "button",
282
- {
283
- onClick: () => setIsUserMenuOpen((o) => !o),
284
- title: isCollapsed ? displayName : void 0,
285
- className: "w-full flex items-center gap-2.5 p-2 rounded-lg hover:bg-zinc-50 transition-colors text-left " + (isCollapsed ? "justify-center" : ""),
286
- children: [
287
- /* @__PURE__ */ jsx(
288
- "div",
289
- {
290
- className: "w-7 h-7 rounded-full flex items-center justify-center flex-shrink-0 " + avatarColor,
291
- children: /* @__PURE__ */ jsx("span", { className: "text-xs font-semibold text-white leading-none", children: initials })
292
- }
293
- ),
294
- !isCollapsed && /* @__PURE__ */ jsxs(Fragment, { children: [
295
- /* @__PURE__ */ jsx("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-zinc-900 truncate leading-tight", children: displayName }) }),
296
- /* @__PURE__ */ jsx(ChevronsUpDownIcon, { className: "w-3.5 h-3.5 text-zinc-400 flex-shrink-0" })
297
- ] })
298
- ]
299
- }
300
- )
301
- ]
97
+ user,
98
+ appId,
99
+ authHost,
100
+ logoutRedirectTo,
101
+ profileHref,
102
+ settingsHref,
103
+ onLogout
302
104
  }
303
- )
105
+ ) })
304
106
  ]
305
107
  }
306
108
  );
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/Hello.tsx","../src/utils/authApi.ts","../src/components/Sidebar.tsx"],"names":["jsx"],"mappings":";;;;AAAO,SAAS,KAAA,GAAQ;AACtB,EAAA,uBAAO,GAAA,CAAC,SAAI,QAAA,EAAA,aAAA,EAAW,CAAA;AACzB;;;ACFA,IAAM,qBAAqB,MAAM;AAC/B,EAAA,IAAI,OAAO,OAAA,KAAY,WAAA,IAAe,OAAA,CAAQ,KAAK,yBAAA,EAA2B;AAC5E,IAAA,MAAM,OAAA,GAAU,OAAA,CAAQ,GAAA,CAAI,yBAAA,CAA0B,IAAA,EAAK;AAC3D,IAAA,IAAI,OAAA,CAAQ,MAAA,GAAS,CAAA,EAAG,OAAO,OAAA;AAAA,EACjC;AACA,EAAA,OAAO,6BAAA;AACT,CAAA,GAAG;AAEH,IAAM,cAAA,GACJ,OAAO,OAAA,KAAY,WAAA,GACf,QAAQ,GAAA,EAAK,uBAAA,EAAyB,IAAA,EAAK,IAAK,EAAA,GAChD,EAAA;AAEN,SAAS,cAAc,IAAA,EAAe;AACpC,EAAA,MAAM,KAAA,GAAA,CAAS,IAAA,IAAQ,iBAAA,EAAmB,IAAA,EAAK;AAC/C,EAAA,IAAI,CAAC,KAAA,EAAO,MAAM,IAAI,MAAM,6BAA6B,CAAA;AACzD,EAAA,IAAI,eAAA,CAAgB,KAAK,KAAK,CAAA,SAAU,KAAA,CAAM,OAAA,CAAQ,SAAS,EAAE,CAAA;AACjE,EAAA,OAAO,CAAA,QAAA,EAAW,KAAK,CAAA,CAAA,CAAG,OAAA,CAAQ,SAAS,EAAE,CAAA;AAC/C;AAEA,SAAS,YAAA,CACP,IAAA,EACA,IAAA,EACA,KAAA,EACA;AACA,EAAA,MAAM,cAAA,GAAiB,cAAc,IAAI,CAAA;AACzC,EAAA,MAAM,iBAAiB,IAAA,CAAK,UAAA,CAAW,GAAG,CAAA,GAAI,IAAA,GAAO,IAAI,IAAI,CAAA,CAAA;AAC7D,EAAA,MAAM,GAAA,GAAM,IAAI,GAAA,CAAI,cAAA,EAAgB,cAAc,CAAA;AAElD,EAAA,IAAI,KAAA,EAAO;AACT,IAAA,KAAA,MAAW,CAAC,GAAA,EAAK,KAAK,KAAK,MAAA,CAAO,OAAA,CAAQ,KAAK,CAAA,EAAG;AAChD,MAAA,IAAI,KAAA,KAAU,MAAA,IAAa,KAAA,KAAU,IAAA,EAAM;AACzC,QAAA,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,GAAA,EAAK,KAAK,CAAA;AAAA,MACjC;AAAA,IACF;AAAA,EACF;AAEA,EAAA,OAAO,GAAA;AACT;AAEA,eAAe,oBAAA,CAAqB,GAAA,EAAU,IAAA,GAAoB,EAAC,EAAG;AACpE,EAAA,MAAM,QAAA,GAAW,MAAM,KAAA,CAAM,GAAA,CAAI,UAAS,EAAG;AAAA,IAC3C,WAAA,EAAa,SAAA;AAAA,IACb,KAAA,EAAO,UAAA;AAAA,IACP,GAAG;AAAA,GACJ,CAAA;AACD,EAAA,IAAI,IAAA,GAAY,IAAA;AAChB,EAAA,IAAI;AACF,IAAA,IAAA,GAAO,MAAM,SAAS,IAAA,EAAK;AAAA,EAC7B,CAAA,CAAA,MAAQ;AAAA,EAER;AACA,EAAA,OAAO,EAAE,UAAU,IAAA,EAAK;AAC1B;AAEA,eAAsB,WAAA,CACpB,IAAA,EACA,IAAA,EACA,KAAA,EACA;AACA,EAAA,MAAM,GAAA,GAAM,YAAA,CAAa,IAAA,EAAM,IAAA,EAAM,KAAK,CAAA;AAC1C,EAAA,OAAO,oBAAA,CAAqB,GAAA,EAAK,EAAE,MAAA,EAAQ,OAAO,CAAA;AACpD;AAEO,SAAS,iBAAiB,KAAA,EAAgB;AAC/C,EAAA,OAAA,CAAQ,KAAA,IAAS,gBAAgB,IAAA,EAAK;AACxC;ACzBA,SAAS,QAAA,CAAS,EAAE,SAAA,EAAU,EAA2B;AACvD,EAAA,uBACE,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAsB,OAAA,EAAQ,aAAY,IAAA,EAAK,MAAA,EAAO,MAAA,EAAO,cAAA,EAAe,WAAA,EAAY,MAAA,EAAO,aAAA,EAAc,OAAA,EAAQ,gBAAe,OAAA,EACvI,QAAA,EAAA;AAAA,oBAAAA,GAAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EAAE,8CAAA,EAA+C,CAAA;AAAA,oBACvDA,GAAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EAAE,eAAA,EAAgB;AAAA,GAAA,EAC1B,CAAA;AAEJ;AAEA,SAAS,UAAA,CAAW,EAAE,SAAA,EAAU,EAA2B;AACzD,EAAA,uBACEA,IAAC,KAAA,EAAA,EAAI,SAAA,EAAsB,SAAQ,WAAA,EAAY,IAAA,EAAK,QAAO,MAAA,EAAO,cAAA,EAAe,aAAY,MAAA,EAAO,aAAA,EAAc,SAAQ,cAAA,EAAe,OAAA,EACvI,0BAAAA,GAAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EAAE,uEAAA,EAAwE,CAAA,EAClF,CAAA;AAEJ;AAEA,SAAS,QAAA,CAAS,EAAE,SAAA,EAAU,EAA2B;AACvD,EAAA,uBACE,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAsB,OAAA,EAAQ,aAAY,IAAA,EAAK,MAAA,EAAO,MAAA,EAAO,cAAA,EAAe,WAAA,EAAY,MAAA,EAAO,aAAA,EAAc,OAAA,EAAQ,gBAAe,OAAA,EACvI,QAAA,EAAA;AAAA,oBAAAA,IAAC,QAAA,EAAA,EAAO,EAAA,EAAG,MAAK,EAAA,EAAG,GAAA,EAAI,GAAE,GAAA,EAAI,CAAA;AAAA,oBAC7BA,GAAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EAAE,6BAAA,EAA8B;AAAA,GAAA,EACxC,CAAA;AAEJ;AAEA,SAAS,YAAA,CAAa,EAAE,SAAA,EAAU,EAA2B;AAC3D,EAAA,uBACE,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAsB,OAAA,EAAQ,aAAY,IAAA,EAAK,MAAA,EAAO,MAAA,EAAO,cAAA,EAAe,WAAA,EAAY,MAAA,EAAO,aAAA,EAAc,OAAA,EAAQ,gBAAe,OAAA,EACvI,QAAA,EAAA;AAAA,oBAAAA,IAAC,QAAA,EAAA,EAAO,EAAA,EAAG,MAAK,EAAA,EAAG,IAAA,EAAK,GAAE,GAAA,EAAI,CAAA;AAAA,oBAC9BA,GAAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EAAE,6kBAAA,EAA8kB;AAAA,GAAA,EACxlB,CAAA;AAEJ;AAEA,SAAS,UAAA,CAAW,EAAE,SAAA,EAAU,EAA2B;AACzD,EAAA,uBACE,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAsB,OAAA,EAAQ,aAAY,IAAA,EAAK,MAAA,EAAO,MAAA,EAAO,cAAA,EAAe,WAAA,EAAY,MAAA,EAAO,aAAA,EAAc,OAAA,EAAQ,gBAAe,OAAA,EACvI,QAAA,EAAA;AAAA,oBAAAA,GAAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EAAE,sCAAA,EAAuC,CAAA;AAAA,oBAC/CA,GAAAA,CAAC,UAAA,EAAA,EAAS,MAAA,EAAO,kBAAA,EAAmB,CAAA;AAAA,oBACpCA,GAAAA,CAAC,MAAA,EAAA,EAAK,EAAA,EAAG,IAAA,EAAK,IAAG,IAAA,EAAK,EAAA,EAAG,GAAA,EAAI,EAAA,EAAG,IAAA,EAAK;AAAA,GAAA,EACvC,CAAA;AAEJ;AAEA,SAAS,eAAA,CAAgB,EAAE,SAAA,EAAU,EAA2B;AAC9D,EAAA,uBACEA,IAAC,KAAA,EAAA,EAAI,SAAA,EAAsB,SAAQ,WAAA,EAAY,IAAA,EAAK,QAAO,MAAA,EAAO,cAAA,EAAe,aAAY,GAAA,EAAI,aAAA,EAAc,SAAQ,cAAA,EAAe,OAAA,EACpI,0BAAAA,GAAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EAAE,iBAAA,EAAkB,CAAA,EAC5B,CAAA;AAEJ;AAEA,SAAS,gBAAA,CAAiB,EAAE,SAAA,EAAU,EAA2B;AAC/D,EAAA,uBACEA,IAAC,KAAA,EAAA,EAAI,SAAA,EAAsB,SAAQ,WAAA,EAAY,IAAA,EAAK,QAAO,MAAA,EAAO,cAAA,EAAe,aAAY,GAAA,EAAI,aAAA,EAAc,SAAQ,cAAA,EAAe,OAAA,EACpI,0BAAAA,GAAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EAAE,eAAA,EAAgB,CAAA,EAC1B,CAAA;AAEJ;AAEA,SAAS,kBAAA,CAAmB,EAAE,SAAA,EAAU,EAA2B;AACjE,EAAA,uBACEA,IAAC,KAAA,EAAA,EAAI,SAAA,EAAsB,SAAQ,WAAA,EAAY,IAAA,EAAK,QAAO,MAAA,EAAO,cAAA,EAAe,aAAY,GAAA,EAAI,aAAA,EAAc,SAAQ,cAAA,EAAe,OAAA,EACpI,0BAAAA,GAAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EAAE,2BAAA,EAA4B,CAAA,EACtC,CAAA;AAEJ;AAIA,IAAM,eAAA,GAA6B;AAAA,EACjC,EAAE,MAAM,YAAA,EAAc,KAAA,EAAO,aAAa,IAAA,EAAM,QAAA,EAAU,OAAO,IAAA,EAAK;AAAA,EACtE,EAAE,MAAM,qBAAA,EAAuB,KAAA,EAAO,YAAY,IAAA,EAAM,UAAA,EAAY,OAAO,KAAA,EAAM;AAAA,EACjF,EAAE,MAAM,qBAAA,EAAuB,KAAA,EAAO,YAAY,IAAA,EAAM,YAAA,EAAc,OAAO,KAAA;AAC/E,CAAA;AAIA,IAAM,aAAA,GAAgB;AAAA,EACpB,eAAA;AAAA,EACA,eAAA;AAAA,EACA,YAAA;AAAA,EACA,gBAAA;AAAA,EACA,cAAA;AAAA,EACA;AACF,CAAA;AAEA,SAAS,eAAe,IAAA,EAAsB;AAC5C,EAAA,IAAI,IAAA,GAAO,CAAA;AACX,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,IAAA,CAAK,MAAA,EAAQ,CAAA,EAAA,EAAK,IAAA,GAAO,IAAA,CAAK,UAAA,CAAW,CAAC,CAAA,IAAA,CAAM,IAAA,IAAQ,CAAA,IAAK,IAAA,CAAA;AACjF,EAAA,OAAO,cAAc,IAAA,CAAK,GAAA,CAAI,IAAI,CAAA,GAAI,cAAc,MAAM,CAAA;AAC5D;AAEA,SAAS,YAAY,IAAA,EAAsB;AACzC,EAAA,OAAO,IAAA,CACJ,MAAM,GAAG,CAAA,CACT,OAAO,OAAO,CAAA,CACd,IAAI,CAAC,CAAA,KAAM,EAAE,CAAC,CAAC,EACf,IAAA,CAAK,EAAE,EACP,WAAA,EAAY,CACZ,KAAA,CAAM,CAAA,EAAG,CAAC,CAAA;AACf;AAIO,SAAS,OAAA,CAAQ;AAAA,EACtB,IAAA,EAAM,QAAA;AAAA,EACN,KAAA;AAAA,EACA,QAAA;AAAA,EACA,QAAA,GAAW,eAAA;AAAA,EACX,KAAA,GAAQ,WAAA;AAAA,EACR,gBAAA,GAAmB,GAAA;AAAA,EACnB,WAAA,GAAc,UAAA;AAAA,EACd,YAAA,GAAe,WAAA;AAAA,EACf;AACF,CAAA,EAAiB;AACf,EAAA,MAAM,CAAC,WAAA,EAAa,cAAc,CAAA,GAAI,SAAS,KAAK,CAAA;AACpD,EAAA,MAAM,CAAC,cAAA,EAAgB,iBAAiB,CAAA,GAAI,SAAS,KAAK,CAAA;AAC1D,EAAA,MAAM,CAAC,WAAA,EAAa,cAAc,CAAA,GAAI,SAA0B,IAAI,CAAA;AACpE,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAI,QAAA,CAAS,CAAC,QAAQ,CAAA;AACpD,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAI,QAAA,CAAS,OAAO,MAAA,KAAW,WAAA,GAAc,MAAA,CAAO,QAAA,CAAS,QAAA,GAAW,GAAG,CAAA;AACvG,EAAA,MAAM,OAAA,GAAU,OAAuB,IAAI,CAAA;AAE3C,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,WAAA,CAAY,MAAA,CAAO,SAAS,QAAQ,CAAA;AAAA,EACtC,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,QAAA,EAAU;AAEd,IAAA,IAAI,SAAA,GAAY,KAAA;AAEhB,IAAA,eAAe,YAAA,GAAe;AAC5B,MAAA,IAAI;AACF,QAAA,MAAM,EAAE,QAAA,EAAU,IAAA,KAAS,MAAM,WAAA,CAAY,oBAAoB,QAAQ,CAAA;AACzE,QAAA,IAAI,CAAC,SAAA,IAAa,QAAA,CAAS,EAAA,IAAM,MAAM,IAAA,EAAM;AAC3C,UAAA,cAAA,CAAe,KAAK,IAAI,CAAA;AAAA,QAC1B;AAAA,MACF,SAAS,GAAA,EAAK;AACZ,QAAA,OAAA,CAAQ,KAAA,CAAM,4BAA4B,GAAG,CAAA;AAAA,MAC/C,CAAA,SAAE;AACA,QAAA,IAAI,CAAC,SAAA,EAAW,YAAA,CAAa,KAAK,CAAA;AAAA,MACpC;AAAA,IACF;AAEA,IAAA,YAAA,EAAa;AACb,IAAA,OAAO,MAAM;AAAE,MAAA,SAAA,GAAY,IAAA;AAAA,IAAM,CAAA;AAAA,EACnC,CAAA,EAAG,CAAC,QAAA,EAAU,QAAQ,CAAC,CAAA;AAEvB,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,SAAS,mBAAmB,CAAA,EAAe;AACzC,MAAA,IAAI,OAAA,CAAQ,WAAW,CAAC,OAAA,CAAQ,QAAQ,QAAA,CAAS,CAAA,CAAE,MAAc,CAAA,EAAG;AAClE,QAAA,iBAAA,CAAkB,KAAK,CAAA;AAAA,MACzB;AAAA,IACF;AACA,IAAA,QAAA,CAAS,gBAAA,CAAiB,aAAa,kBAAkB,CAAA;AACzD,IAAA,OAAO,MAAM,QAAA,CAAS,mBAAA,CAAoB,WAAA,EAAa,kBAAkB,CAAA;AAAA,EAC3E,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,MAAM,OAAO,QAAA,IAAY,WAAA;AAEzB,EAAA,IAAI,SAAA,IAAa,CAAC,IAAA,EAAM,OAAO,IAAA;AAE/B,EAAA,MAAM,WAAA,GAAc,KAAK,IAAA,IAAQ,IAAA,CAAK,OAAO,KAAA,CAAM,GAAG,CAAA,CAAE,CAAC,CAAA,IAAK,MAAA;AAC9D,EAAA,MAAM,QAAA,GAAW,YAAY,WAAW,CAAA;AACxC,EAAA,MAAM,WAAA,GAAc,eAAe,WAAW,CAAA;AAE9C,EAAA,SAAS,QAAA,CAAS,MAAc,KAAA,EAAgB;AAC9C,IAAA,OAAO,KAAA,GAAQ,QAAA,KAAa,IAAA,GAAO,QAAA,CAAS,WAAW,IAAI,CAAA;AAAA,EAC7D;AAEA,EAAA,eAAe,YAAA,GAAe;AAC5B,IAAA,MAAM,aAAA,GAAgB,iBAAiB,KAAK,CAAA;AAE5C,IAAA,IAAI;AACF,MAAA,MAAM,WAAA,CAAY,mBAAmB,QAAA,EAAU,aAAA,GAAgB,EAAE,KAAA,EAAO,aAAA,KAAkB,KAAA,CAAS,CAAA;AAAA,IACrG,SAAS,GAAA,EAAK;AACZ,MAAA,OAAA,CAAQ,KAAA,CAAM,iBAAiB,GAAG,CAAA;AAAA,IACpC;AAEA,IAAA,IAAI,QAAA,EAAU;AACZ,MAAA,QAAA,EAAS;AAAA,IACX,CAAA,MAAO;AACL,MAAA,MAAA,CAAO,SAAS,IAAA,GAAO,gBAAA;AAAA,IACzB;AAAA,EACF;AAEA,EAAA,uBACE,IAAA;AAAA,IAAC,OAAA;AAAA,IAAA;AAAA,MACC,SAAA,EACE,0HAAA,IACC,WAAA,GAAc,UAAA,GAAa,WAAA,CAAA;AAAA,MAI9B,QAAA,EAAA;AAAA,wBAAA,IAAA;AAAA,UAAC,KAAA;AAAA,UAAA;AAAA,YACC,SAAA,EACE,qEAAA,IACC,WAAA,GAAc,gBAAA,GAAmB,iBAAA,CAAA;AAAA,YAGnC,QAAA,EAAA;AAAA,cAAA,CAAC,+BACAA,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,2EACb,QAAA,EAAA,KAAA,EACH,CAAA;AAAA,8BAEFA,GAAAA;AAAA,gBAAC,QAAA;AAAA,gBAAA;AAAA,kBACC,SAAS,MAAM,cAAA,CAAe,CAAC,CAAA,KAAM,CAAC,CAAC,CAAA;AAAA,kBACvC,KAAA,EAAO,cAAc,gBAAA,GAAmB,kBAAA;AAAA,kBACxC,SAAA,EAAU,sGAAA;AAAA,kBAET,QAAA,EAAA,WAAA,mBACCA,GAAAA,CAAC,gBAAA,EAAA,EAAiB,SAAA,EAAU,SAAA,EAAU,CAAA,mBAEtCA,GAAAA,CAAC,eAAA,EAAA,EAAgB,SAAA,EAAU,SAAA,EAAU;AAAA;AAAA;AAEzC;AAAA;AAAA,SACF;AAAA,wBAGAA,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,gDACZ,QAAA,EAAA,QAAA,CAAS,GAAA,CAAI,CAAC,EAAE,IAAA,EAAM,KAAA,EAAO,IAAA,EAAM,IAAA,EAAM,OAAM,KAAM;AACpD,UAAA,MAAM,MAAA,GAAS,QAAA,CAAS,IAAA,EAAM,KAAA,IAAS,KAAK,CAAA;AAC5C,UAAA,uBACE,IAAA;AAAA,YAAC,GAAA;AAAA,YAAA;AAAA,cAEC,IAAA;AAAA,cACA,KAAA,EAAO,cAAc,KAAA,GAAQ,MAAA;AAAA,cAC7B,WACE,6EAAA,IACC,WAAA,GAAc,iBAAA,GAAoB,EAAA,CAAA,IAClC,SACG,uCAAA,GACA,oDAAA,CAAA;AAAA,cAGN,QAAA,EAAA;AAAA,gCAAAA,GAAAA,CAAC,IAAA,EAAA,EAAK,SAAA,EAAU,uBAAA,EAAwB,CAAA;AAAA,gBACvC,CAAC,WAAA,oBAAeA,IAAC,MAAA,EAAA,EAAK,SAAA,EAAU,YAAY,QAAA,EAAA,KAAA,EAAM;AAAA;AAAA,aAAA;AAAA,YAZ9C;AAAA,WAaP;AAAA,QAEJ,CAAC,CAAA,EACH,CAAA;AAAA,wBAGA,IAAA;AAAA,UAAC,KAAA;AAAA,UAAA;AAAA,YACC,GAAA,EAAK,OAAA;AAAA,YACL,SAAA,EAAU,qDAAA;AAAA,YAGT,QAAA,EAAA;AAAA,cAAA,cAAA,oBACC,IAAA;AAAA,gBAAC,KAAA;AAAA,gBAAA;AAAA,kBACC,SAAA,EACE,yHAAA,IACC,WAAA,GAAc,qBAAA,GAAwB,gBAAA,CAAA;AAAA,kBAIzC,QAAA,EAAA;AAAA,oCAAA,IAAA,CAAC,KAAA,EAAA,EAAI,WAAU,sCAAA,EACb,QAAA,EAAA;AAAA,sCAAAA,GAAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,4CAAA,EACV,QAAA,EAAA,WAAA,EACH,CAAA;AAAA,sBACC,IAAA,CAAK,yBACJA,GAAAA,CAAC,OAAE,SAAA,EAAU,uCAAA,EACV,eAAK,KAAA,EACR;AAAA,qBAAA,EAEJ,CAAA;AAAA,oCAEA,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,KAAA,EACb,QAAA,EAAA;AAAA,sCAAA,IAAA;AAAA,wBAAC,GAAA;AAAA,wBAAA;AAAA,0BACC,IAAA,EAAM,WAAA;AAAA,0BACN,OAAA,EAAS,MAAM,iBAAA,CAAkB,KAAK,CAAA;AAAA,0BACtC,SAAA,EAAU,gHAAA;AAAA,0BAEV,QAAA,EAAA;AAAA,4CAAAA,GAAAA,CAAC,QAAA,EAAA,EAAS,SAAA,EAAU,uBAAA,EAAwB,CAAA;AAAA,4BAAE;AAAA;AAAA;AAAA,uBAEhD;AAAA,sCACA,IAAA;AAAA,wBAAC,GAAA;AAAA,wBAAA;AAAA,0BACC,IAAA,EAAM,YAAA;AAAA,0BACN,OAAA,EAAS,MAAM,iBAAA,CAAkB,KAAK,CAAA;AAAA,0BACtC,SAAA,EAAU,gHAAA;AAAA,0BAEV,QAAA,EAAA;AAAA,4CAAAA,GAAAA,CAAC,YAAA,EAAA,EAAa,SAAA,EAAU,uBAAA,EAAwB,CAAA;AAAA,4BAAE;AAAA;AAAA;AAAA,uBAEpD;AAAA,sCACA,IAAA;AAAA,wBAAC,QAAA;AAAA,wBAAA;AAAA,0BACC,OAAA,EAAS,YAAA;AAAA,0BACT,SAAA,EAAU,0HAAA;AAAA,0BAEV,QAAA,EAAA;AAAA,4CAAAA,GAAAA,CAAC,UAAA,EAAA,EAAW,SAAA,EAAU,uBAAA,EAAwB,CAAA;AAAA,4BAAE;AAAA;AAAA;AAAA;AAElD,qBAAA,EACF;AAAA;AAAA;AAAA,eACF;AAAA,8BAIF,IAAA;AAAA,gBAAC,QAAA;AAAA,gBAAA;AAAA,kBACC,SAAS,MAAM,iBAAA,CAAkB,CAAC,CAAA,KAAM,CAAC,CAAC,CAAA;AAAA,kBAC1C,KAAA,EAAO,cAAc,WAAA,GAAc,MAAA;AAAA,kBACnC,SAAA,EACE,+FAAA,IACC,WAAA,GAAc,gBAAA,GAAmB,EAAA,CAAA;AAAA,kBAGpC,QAAA,EAAA;AAAA,oCAAAA,GAAAA;AAAA,sBAAC,KAAA;AAAA,sBAAA;AAAA,wBACC,WAAW,sEAAA,GAAyE,WAAA;AAAA,wBAEpF,QAAA,kBAAAA,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,iDACb,QAAA,EAAA,QAAA,EACH;AAAA;AAAA,qBACF;AAAA,oBACC,CAAC,+BACA,IAAA,CAAA,QAAA,EAAA,EACE,QAAA,EAAA;AAAA,sCAAAA,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,gBAAA,EACb,QAAA,kBAAAA,IAAC,GAAA,EAAA,EAAE,SAAA,EAAU,0DAAA,EACV,QAAA,EAAA,WAAA,EACH,CAAA,EACF,CAAA;AAAA,sCACAA,GAAAA,CAAC,kBAAA,EAAA,EAAmB,SAAA,EAAU,yCAAA,EAA0C;AAAA,qBAAA,EAC1E;AAAA;AAAA;AAAA;AAEJ;AAAA;AAAA;AACF;AAAA;AAAA,GACF;AAEJ","file":"index.js","sourcesContent":["export function Hello() {\n return <div>Hello world</div>;\n}\n","const DEFAULT_AUTH_HOST = (() => {\n if (typeof process !== \"undefined\" && process.env?.NEXT_PUBLIC_AUTH_API_HOST) {\n const envHost = process.env.NEXT_PUBLIC_AUTH_API_HOST.trim();\n if (envHost.length > 0) return envHost;\n }\n return \"https://auth.create-flow.ai\";\n})();\n\nconst DEFAULT_APP_ID =\n typeof process !== \"undefined\"\n ? process.env?.NEXT_PUBLIC_AUTH_APP_ID?.trim() ?? \"\"\n : \"\";\n\nfunction normalizeHost(host?: string) {\n const value = (host ?? DEFAULT_AUTH_HOST).trim();\n if (!value) throw new Error(\"Auth host is not configured\");\n if (/^https?:\\/\\//i.test(value)) return value.replace(/\\/+$/g, \"\");\n return `https://${value}`.replace(/\\/+$/g, \"\");\n}\n\nfunction buildAuthUrl(\n path: string,\n host?: string,\n query?: Record<string, string | undefined>\n) {\n const normalizedHost = normalizeHost(host);\n const normalizedPath = path.startsWith(\"/\") ? path : `/${path}`;\n const url = new URL(normalizedPath, normalizedHost);\n\n if (query) {\n for (const [key, value] of Object.entries(query)) {\n if (value !== undefined && value !== null) {\n url.searchParams.set(key, value);\n }\n }\n }\n\n return url;\n}\n\nasync function fetchWithCredentials(url: URL, init: RequestInit = {}) {\n const response = await fetch(url.toString(), {\n credentials: \"include\",\n cache: \"no-store\",\n ...init,\n });\n let data: any = null;\n try {\n data = await response.json();\n } catch {\n // Ignore JSON parse errors\n }\n return { response, data };\n}\n\nexport async function getAuthJson(\n path: string,\n host?: string,\n query?: Record<string, string | undefined>\n) {\n const url = buildAuthUrl(path, host, query);\n return fetchWithCredentials(url, { method: \"GET\" });\n}\n\nexport function getResolvedAppId(appId?: string) {\n return (appId ?? DEFAULT_APP_ID).trim();\n}\n","\"use client\";\n\nimport { useState, useRef, useEffect, useCallback, type ComponentType } from \"react\";\n\nimport { getResolvedAppId, getAuthJson } from \"../utils/authApi\";\n\n// ── Types ─────────────────────────────────────────────────────────────────────\n\nexport type UserType = \"guest\" | \"regular\";\n\nexport interface AuthUser {\n id: string;\n name?: string | null;\n email?: string | null;\n image?: string | null;\n type: UserType;\n appId: string;\n isGuest: boolean;\n}\n\nexport interface NavItem {\n href: string;\n label: string;\n icon: ComponentType<{ className?: string }>;\n exact?: boolean;\n}\n\nexport interface SidebarProps {\n user?: AuthUser;\n appId?: string;\n authHost?: string;\n navItems?: NavItem[];\n title?: string;\n logoutRedirectTo?: string;\n profileHref?: string;\n settingsHref?: string;\n onLogout?: () => void;\n}\n\n// ── Icons ─────────────────────────────────────────────────────────────────────\n\nfunction HomeIcon({ className }: { className?: string }) {\n return (\n <svg className={className} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.75\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M3 9l9-7 9 7v11a2 2 0 01-2 2H5a2 2 0 01-2-2z\" />\n <path d=\"M9 22V12h6v10\" />\n </svg>\n );\n}\n\nfunction FolderIcon({ className }: { className?: string }) {\n return (\n <svg className={className} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.75\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M22 19a2 2 0 01-2 2H4a2 2 0 01-2-2V5a2 2 0 012-2h5l2 3h9a2 2 0 012 2z\" />\n </svg>\n );\n}\n\nfunction UserIcon({ className }: { className?: string }) {\n return (\n <svg className={className} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.75\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <circle cx=\"12\" cy=\"8\" r=\"4\" />\n <path d=\"M4 20c0-4 3.6-7 8-7s8 3 8 7\" />\n </svg>\n );\n}\n\nfunction SettingsIcon({ className }: { className?: string }) {\n return (\n <svg className={className} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.75\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <circle cx=\"12\" cy=\"12\" r=\"3\" />\n <path d=\"M19.4 15a1.65 1.65 0 00.33 1.82l.06.06a2 2 0 010 2.83 2 2 0 01-2.83 0l-.06-.06a1.65 1.65 0 00-1.82-.33 1.65 1.65 0 00-1 1.51V21a2 2 0 01-4 0v-.09A1.65 1.65 0 009 19.4a1.65 1.65 0 00-1.82.33l-.06.06a2 2 0 01-2.83-2.83l.06-.06A1.65 1.65 0 004.68 15a1.65 1.65 0 00-1.51-1H3a2 2 0 010-4h.09A1.65 1.65 0 004.6 9a1.65 1.65 0 00-.33-1.82l-.06-.06a2 2 0 012.83-2.83l.06.06A1.65 1.65 0 009 4.68a1.65 1.65 0 001-1.51V3a2 2 0 014 0v.09a1.65 1.65 0 001 1.51 1.65 1.65 0 001.82-.33l.06-.06a2 2 0 012.83 2.83l-.06.06A1.65 1.65 0 0019.4 9a1.65 1.65 0 001.51 1H21a2 2 0 010 4h-.09a1.65 1.65 0 00-1.51 1z\" />\n </svg>\n );\n}\n\nfunction LogOutIcon({ className }: { className?: string }) {\n return (\n <svg className={className} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.75\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M9 21H5a2 2 0 01-2-2V5a2 2 0 012-2h4\" />\n <polyline points=\"16,17 21,12 16,7\" />\n <line x1=\"21\" y1=\"12\" x2=\"9\" y2=\"12\" />\n </svg>\n );\n}\n\nfunction ChevronLeftIcon({ className }: { className?: string }) {\n return (\n <svg className={className} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M15 18l-6-6 6-6\" />\n </svg>\n );\n}\n\nfunction ChevronRightIcon({ className }: { className?: string }) {\n return (\n <svg className={className} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M9 18l6-6-6-6\" />\n </svg>\n );\n}\n\nfunction ChevronsUpDownIcon({ className }: { className?: string }) {\n return (\n <svg className={className} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M7 15l5 5 5-5M7 9l5-5 5 5\" />\n </svg>\n );\n}\n\n// ── Default nav items ─────────────────────────────────────────────────────────\n\nconst defaultNavItems: NavItem[] = [\n { href: \"/dashboard\", label: \"Dashboard\", icon: HomeIcon, exact: true },\n { href: \"/dashboard/projects\", label: \"Projects\", icon: FolderIcon, exact: false },\n { href: \"/dashboard/settings\", label: \"Settings\", icon: SettingsIcon, exact: false },\n];\n\n// ── Avatar ────────────────────────────────────────────────────────────────────\n\nconst AVATAR_COLORS = [\n \"bg-violet-600\",\n \"bg-indigo-600\",\n \"bg-sky-600\",\n \"bg-emerald-600\",\n \"bg-amber-600\",\n \"bg-rose-600\",\n];\n\nfunction getAvatarColor(name: string): string {\n let hash = 0;\n for (let i = 0; i < name.length; i++) hash = name.charCodeAt(i) + ((hash << 5) - hash);\n return AVATAR_COLORS[Math.abs(hash) % AVATAR_COLORS.length];\n}\n\nfunction getInitials(name: string): string {\n return name\n .split(\" \")\n .filter(Boolean)\n .map((w) => w[0])\n .join(\"\")\n .toUpperCase()\n .slice(0, 2);\n}\n\n// ── Sidebar ───────────────────────────────────────────────────────────────────\n\nexport function Sidebar({\n user: userProp,\n appId,\n authHost,\n navItems = defaultNavItems,\n title = \"Workspace\",\n logoutRedirectTo = \"/\",\n profileHref = \"/profile\",\n settingsHref = \"/settings\",\n onLogout,\n}: SidebarProps) {\n const [isCollapsed, setIsCollapsed] = useState(false);\n const [isUserMenuOpen, setIsUserMenuOpen] = useState(false);\n const [fetchedUser, setFetchedUser] = useState<AuthUser | null>(null);\n const [isLoading, setIsLoading] = useState(!userProp);\n const [pathname, setPathname] = useState(typeof window !== \"undefined\" ? window.location.pathname : \"/\");\n const menuRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n setPathname(window.location.pathname);\n }, []);\n\n useEffect(() => {\n if (userProp) return;\n\n let cancelled = false;\n\n async function fetchSession() {\n try {\n const { response, data } = await getAuthJson(\"api/auth/session\", authHost);\n if (!cancelled && response.ok && data?.user) {\n setFetchedUser(data.user);\n }\n } catch (err) {\n console.error(\"Failed to fetch session:\", err);\n } finally {\n if (!cancelled) setIsLoading(false);\n }\n }\n\n fetchSession();\n return () => { cancelled = true; };\n }, [authHost, userProp]);\n\n useEffect(() => {\n function handleClickOutside(e: MouseEvent) {\n if (menuRef.current && !menuRef.current.contains(e.target as Node)) {\n setIsUserMenuOpen(false);\n }\n }\n document.addEventListener(\"mousedown\", handleClickOutside);\n return () => document.removeEventListener(\"mousedown\", handleClickOutside);\n }, []);\n\n const user = userProp || fetchedUser;\n\n if (isLoading || !user) return null;\n\n const displayName = user.name || user.email?.split(\"@\")[0] || \"User\";\n const initials = getInitials(displayName);\n const avatarColor = getAvatarColor(displayName);\n\n function isActive(href: string, exact: boolean) {\n return exact ? pathname === href : pathname.startsWith(href);\n }\n\n async function handleLogout() {\n const resolvedAppId = getResolvedAppId(appId);\n\n try {\n await getAuthJson(\"api/auth/logout\", authHost, resolvedAppId ? { appId: resolvedAppId } : undefined);\n } catch (err) {\n console.error(\"Logout error:\", err);\n }\n\n if (onLogout) {\n onLogout();\n } else {\n window.location.href = logoutRedirectTo;\n }\n }\n\n return (\n <aside\n className={\n \"relative flex flex-col h-screen bg-white border-r border-zinc-200 transition-all duration-200 ease-in-out flex-shrink-0 \" +\n (isCollapsed ? \"w-[60px]\" : \"w-[220px]\")\n }\n >\n {/* ── Header ─────────────────────────────────────────────────────────── */}\n <div\n className={\n \"flex items-center h-14 px-3 flex-shrink-0 border-b border-zinc-200 \" +\n (isCollapsed ? \"justify-center\" : \"justify-between\")\n }\n >\n {!isCollapsed && (\n <span className=\"text-sm font-semibold text-zinc-900 tracking-tight truncate select-none\">\n {title}\n </span>\n )}\n <button\n onClick={() => setIsCollapsed((c) => !c)}\n title={isCollapsed ? \"Expand sidebar\" : \"Collapse sidebar\"}\n className=\"p-1.5 rounded-md text-zinc-400 hover:text-zinc-700 hover:bg-zinc-100 transition-colors flex-shrink-0\"\n >\n {isCollapsed ? (\n <ChevronRightIcon className=\"w-4 h-4\" />\n ) : (\n <ChevronLeftIcon className=\"w-4 h-4\" />\n )}\n </button>\n </div>\n\n {/* ── Nav ────────────────────────────────────────────────────────────── */}\n <nav className=\"flex-1 overflow-y-auto py-2 px-2 space-y-0.5\">\n {navItems.map(({ href, label, icon: Icon, exact }) => {\n const active = isActive(href, exact ?? false);\n return (\n <a\n key={href}\n href={href}\n title={isCollapsed ? label : undefined}\n className={\n \"flex items-center gap-2.5 px-2.5 py-2 rounded-lg text-sm transition-colors \" +\n (isCollapsed ? \"justify-center \" : \"\") +\n (active\n ? \"bg-zinc-100 text-zinc-900 font-medium\"\n : \"text-zinc-500 hover:bg-zinc-50 hover:text-zinc-900\")\n }\n >\n <Icon className=\"w-4 h-4 flex-shrink-0\" />\n {!isCollapsed && <span className=\"truncate\">{label}</span>}\n </a>\n );\n })}\n </nav>\n\n {/* ── User area ──────────────────────────────────────────────────────── */}\n <div\n ref={menuRef}\n className=\"relative flex-shrink-0 p-2 border-t border-zinc-200\"\n >\n {/* Dropdown menu */}\n {isUserMenuOpen && (\n <div\n className={\n \"absolute bottom-full mb-1 z-50 bg-white border border-zinc-200 rounded-xl shadow-lg shadow-zinc-200/50 overflow-hidden \" +\n (isCollapsed ? \"left-full ml-2 w-52\" : \"left-2 right-2\")\n }\n >\n {/* User info */}\n <div className=\"px-3.5 py-3 border-b border-zinc-100\">\n <p className=\"text-sm font-medium text-zinc-900 truncate\">\n {displayName}\n </p>\n {user.email && (\n <p className=\"text-xs text-zinc-500 truncate mt-0.5\">\n {user.email}\n </p>\n )}\n </div>\n {/* Menu items */}\n <div className=\"p-1\">\n <a\n href={profileHref}\n onClick={() => setIsUserMenuOpen(false)}\n className=\"flex items-center gap-2.5 w-full px-3 py-2 text-sm text-zinc-700 hover:bg-zinc-50 rounded-lg transition-colors\"\n >\n <UserIcon className=\"w-4 h-4 text-zinc-400\" />\n Profile\n </a>\n <a\n href={settingsHref}\n onClick={() => setIsUserMenuOpen(false)}\n className=\"flex items-center gap-2.5 w-full px-3 py-2 text-sm text-zinc-700 hover:bg-zinc-50 rounded-lg transition-colors\"\n >\n <SettingsIcon className=\"w-4 h-4 text-zinc-400\" />\n Settings\n </a>\n <button\n onClick={handleLogout}\n className=\"flex items-center gap-2.5 w-full px-3 py-2 text-sm text-zinc-700 hover:bg-zinc-50 rounded-lg transition-colors text-left\"\n >\n <LogOutIcon className=\"w-4 h-4 text-zinc-400\" />\n Log out\n </button>\n </div>\n </div>\n )}\n\n {/* User trigger button */}\n <button\n onClick={() => setIsUserMenuOpen((o) => !o)}\n title={isCollapsed ? displayName : undefined}\n className={\n \"w-full flex items-center gap-2.5 p-2 rounded-lg hover:bg-zinc-50 transition-colors text-left \" +\n (isCollapsed ? \"justify-center\" : \"\")\n }\n >\n <div\n className={\"w-7 h-7 rounded-full flex items-center justify-center flex-shrink-0 \" + avatarColor}\n >\n <span className=\"text-xs font-semibold text-white leading-none\">\n {initials}\n </span>\n </div>\n {!isCollapsed && (\n <>\n <div className=\"flex-1 min-w-0\">\n <p className=\"text-sm font-medium text-zinc-900 truncate leading-tight\">\n {displayName}\n </p>\n </div>\n <ChevronsUpDownIcon className=\"w-3.5 h-3.5 text-zinc-400 flex-shrink-0\" />\n </>\n )}\n </button>\n </div>\n </aside>\n );\n}\n"]}
1
+ {"version":3,"sources":["../src/components/Hello.tsx","../src/components/Sidebar.tsx"],"names":["jsx"],"mappings":"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","file":"index.js","sourcesContent":["export function Hello() {\n return <div>Hello world</div>;\n}\n","\"use client\";\n\nimport { useState, useEffect, type ComponentType } from \"react\";\nimport { UserMenu } from \"@create-flow/auth-ui\";\nimport type { AuthUser } from \"@create-flow/auth-ui\";\n\n// ── Types ─────────────────────────────────────────────────────────────────────\n\nexport type { AuthUser, UserType } from \"@create-flow/auth-ui\";\n\nexport interface NavItem {\n href: string;\n label: string;\n icon: ComponentType<{ className?: string }>;\n exact?: boolean;\n}\n\nexport interface SidebarProps {\n user?: AuthUser;\n appId?: string;\n authHost?: string;\n navItems?: NavItem[];\n title?: string;\n logoutRedirectTo?: string;\n profileHref?: string;\n settingsHref?: string;\n onLogout?: () => void;\n}\n\n// ── Icons ─────────────────────────────────────────────────────────────────────\n\nfunction HomeIcon({ className }: { className?: string }) {\n return (\n <svg className={className} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.75\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M3 9l9-7 9 7v11a2 2 0 01-2 2H5a2 2 0 01-2-2z\" />\n <path d=\"M9 22V12h6v10\" />\n </svg>\n );\n}\n\nfunction FolderIcon({ className }: { className?: string }) {\n return (\n <svg className={className} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.75\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M22 19a2 2 0 01-2 2H4a2 2 0 01-2-2V5a2 2 0 012-2h5l2 3h9a2 2 0 012 2z\" />\n </svg>\n );\n}\n\nfunction SettingsIcon({ className }: { className?: string }) {\n return (\n <svg className={className} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.75\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <circle cx=\"12\" cy=\"12\" r=\"3\" />\n <path d=\"M19.4 15a1.65 1.65 0 00.33 1.82l.06.06a2 2 0 010 2.83 2 2 0 01-2.83 0l-.06-.06a1.65 1.65 0 00-1.82-.33 1.65 1.65 0 00-1 1.51V21a2 2 0 01-4 0v-.09A1.65 1.65 0 009 19.4a1.65 1.65 0 00-1.82.33l-.06.06a2 2 0 01-2.83-2.83l.06-.06A1.65 1.65 0 004.68 15a1.65 1.65 0 00-1.51-1H3a2 2 0 010-4h.09A1.65 1.65 0 004.6 9a1.65 1.65 0 00-.33-1.82l-.06-.06a2 2 0 012.83-2.83l.06.06A1.65 1.65 0 009 4.68a1.65 1.65 0 001-1.51V3a2 2 0 014 0v.09a1.65 1.65 0 001 1.51 1.65 1.65 0 001.82-.33l.06-.06a2 2 0 012.83 2.83l-.06.06A1.65 1.65 0 0019.4 9a1.65 1.65 0 001.51 1H21a2 2 0 010 4h-.09a1.65 1.65 0 00-1.51 1z\" />\n </svg>\n );\n}\n\nfunction ChevronLeftIcon({ className }: { className?: string }) {\n return (\n <svg className={className} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M15 18l-6-6 6-6\" />\n </svg>\n );\n}\n\nfunction ChevronRightIcon({ className }: { className?: string }) {\n return (\n <svg className={className} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M9 18l6-6-6-6\" />\n </svg>\n );\n}\n\n// ── Default nav items ─────────────────────────────────────────────────────────\n\nconst defaultNavItems: NavItem[] = [\n { href: \"/dashboard\", label: \"Dashboard\", icon: HomeIcon, exact: true },\n { href: \"/dashboard/projects\", label: \"Projects\", icon: FolderIcon, exact: false },\n { href: \"/dashboard/settings\", label: \"Settings\", icon: SettingsIcon, exact: false },\n];\n\n// ── Sidebar ───────────────────────────────────────────────────────────────────\n\nexport function Sidebar({\n user,\n appId,\n authHost,\n navItems = defaultNavItems,\n title = \"Workspace\",\n logoutRedirectTo = \"/\",\n profileHref = \"/profile\",\n settingsHref = \"/settings\",\n onLogout,\n}: SidebarProps) {\n const [isCollapsed, setIsCollapsed] = useState(false);\n const [pathname, setPathname] = useState(typeof window !== \"undefined\" ? window.location.pathname : \"/\");\n\n useEffect(() => {\n setPathname(window.location.pathname);\n }, []);\n\n function isActive(href: string, exact: boolean) {\n return exact ? pathname === href : pathname.startsWith(href);\n }\n\n return (\n <aside\n className={\n \"relative flex flex-col h-screen bg-white border-r border-zinc-200 transition-all duration-200 ease-in-out flex-shrink-0 \" +\n (isCollapsed ? \"w-[60px]\" : \"w-[220px]\")\n }\n >\n {/* ── Header ─────────────────────────────────────────────────────────── */}\n <div\n className={\n \"flex items-center h-14 px-3 flex-shrink-0 border-b border-zinc-200 \" +\n (isCollapsed ? \"justify-center\" : \"justify-between\")\n }\n >\n {!isCollapsed && (\n <span className=\"text-sm font-semibold text-zinc-900 tracking-tight truncate select-none\">\n {title}\n </span>\n )}\n <button\n onClick={() => setIsCollapsed((c) => !c)}\n title={isCollapsed ? \"Expand sidebar\" : \"Collapse sidebar\"}\n className=\"p-1.5 rounded-md text-zinc-400 hover:text-zinc-700 hover:bg-zinc-100 transition-colors flex-shrink-0\"\n >\n {isCollapsed ? (\n <ChevronRightIcon className=\"w-4 h-4\" />\n ) : (\n <ChevronLeftIcon className=\"w-4 h-4\" />\n )}\n </button>\n </div>\n\n {/* ── Nav ────────────────────────────────────────────────────────────── */}\n <nav className=\"flex-1 overflow-y-auto py-2 px-2 space-y-0.5\">\n {navItems.map(({ href, label, icon: Icon, exact }) => {\n const active = isActive(href, exact ?? false);\n return (\n <a\n key={href}\n href={href}\n title={isCollapsed ? label : undefined}\n className={\n \"flex items-center gap-2.5 px-2.5 py-2 rounded-lg text-sm transition-colors \" +\n (isCollapsed ? \"justify-center \" : \"\") +\n (active\n ? \"bg-zinc-100 text-zinc-900 font-medium\"\n : \"text-zinc-500 hover:bg-zinc-50 hover:text-zinc-900\")\n }\n >\n <Icon className=\"w-4 h-4 flex-shrink-0\" />\n {!isCollapsed && <span className=\"truncate\">{label}</span>}\n </a>\n );\n })}\n </nav>\n\n {/* ── User area ──────────────────────────────────────────────────────── */}\n <div className=\"flex-shrink-0 p-2 border-t border-zinc-200\">\n <UserMenu\n user={user}\n appId={appId}\n authHost={authHost}\n logoutRedirectTo={logoutRedirectTo}\n profileHref={profileHref}\n settingsHref={settingsHref}\n onLogout={onLogout}\n />\n </div>\n </aside>\n );\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@create-flow/common-ui",
3
- "version": "0.3.7",
3
+ "version": "0.3.8",
4
4
  "description": "Shared UI components for Flow apps",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -35,10 +35,12 @@
35
35
  "publish:major": "bun run version:major && bun publish"
36
36
  },
37
37
  "peerDependencies": {
38
+ "@create-flow/auth-ui": ">=0.0.2",
38
39
  "react": ">=18",
39
40
  "react-dom": ">=18"
40
41
  },
41
42
  "devDependencies": {
43
+ "@create-flow/auth-ui": "0.0.2",
42
44
  "@eslint/js": "^9",
43
45
  "@types/react": "^19",
44
46
  "@types/react-dom": "^19",