@create-flow/common-ui 0.3.5
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/README.md +45 -0
- package/dist/index.cjs +318 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +37 -0
- package/dist/index.d.ts +37 -0
- package/dist/index.js +311 -0
- package/dist/index.js.map +1 -0
- package/package.json +51 -0
package/README.md
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# common-auth-ui
|
|
2
|
+
|
|
3
|
+
Shared auth UI components for Next.js and React applications.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install common-auth-ui
|
|
9
|
+
# or
|
|
10
|
+
bun add common-auth-ui
|
|
11
|
+
# or
|
|
12
|
+
pnpm add common-auth-ui
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Usage
|
|
16
|
+
|
|
17
|
+
```tsx
|
|
18
|
+
import { Hello } from "common-auth-ui";
|
|
19
|
+
|
|
20
|
+
export default function Page() {
|
|
21
|
+
return <Hello />;
|
|
22
|
+
}
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Development
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
bun install
|
|
29
|
+
bun run build
|
|
30
|
+
bun run lint
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Publishing
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
# Dry run (see what would be published)
|
|
37
|
+
bun run publish:dry
|
|
38
|
+
|
|
39
|
+
# Publish with version bump
|
|
40
|
+
bun run publish:patch # 0.1.0 → 0.1.1
|
|
41
|
+
bun run publish:minor # 0.1.0 → 0.2.0
|
|
42
|
+
bun run publish:major # 0.1.0 → 1.0.0
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Requires `npm login` before first publish. For scoped packages (e.g. `@your-org/common-auth-ui`), add `"publishConfig": { "access": "public" }` to `package.json` if publishing to the public registry.
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
4
|
+
var react = require('react');
|
|
5
|
+
var Link = require('next/link');
|
|
6
|
+
var navigation = require('next/navigation');
|
|
7
|
+
|
|
8
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
9
|
+
|
|
10
|
+
var Link__default = /*#__PURE__*/_interopDefault(Link);
|
|
11
|
+
|
|
12
|
+
// src/components/Hello.tsx
|
|
13
|
+
function Hello() {
|
|
14
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { children: "Hello world" });
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// src/utils/authApi.ts
|
|
18
|
+
var DEFAULT_AUTH_HOST = (() => {
|
|
19
|
+
if (typeof process !== "undefined" && process.env?.NEXT_PUBLIC_AUTH_API_HOST) {
|
|
20
|
+
const envHost = process.env.NEXT_PUBLIC_AUTH_API_HOST.trim();
|
|
21
|
+
if (envHost.length > 0) return envHost;
|
|
22
|
+
}
|
|
23
|
+
return "https://auth.create-flow.ai";
|
|
24
|
+
})();
|
|
25
|
+
var DEFAULT_APP_ID = typeof process !== "undefined" ? process.env?.NEXT_PUBLIC_AUTH_APP_ID?.trim() ?? "" : "";
|
|
26
|
+
function normalizeHost(host) {
|
|
27
|
+
const value = (host ?? DEFAULT_AUTH_HOST).trim();
|
|
28
|
+
if (!value) throw new Error("Auth host is not configured");
|
|
29
|
+
if (/^https?:\/\//i.test(value)) return value.replace(/\/+$/g, "");
|
|
30
|
+
return `https://${value}`.replace(/\/+$/g, "");
|
|
31
|
+
}
|
|
32
|
+
function buildAuthUrl(path, host, query) {
|
|
33
|
+
const normalizedHost = normalizeHost(host);
|
|
34
|
+
const normalizedPath = path.startsWith("/") ? path : `/${path}`;
|
|
35
|
+
const url = new URL(normalizedPath, normalizedHost);
|
|
36
|
+
if (query) {
|
|
37
|
+
for (const [key, value] of Object.entries(query)) {
|
|
38
|
+
if (value !== void 0 && value !== null) {
|
|
39
|
+
url.searchParams.set(key, value);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return url;
|
|
44
|
+
}
|
|
45
|
+
async function fetchWithCredentials(url, init = {}) {
|
|
46
|
+
const response = await fetch(url.toString(), {
|
|
47
|
+
credentials: "include",
|
|
48
|
+
cache: "no-store",
|
|
49
|
+
...init
|
|
50
|
+
});
|
|
51
|
+
let data = null;
|
|
52
|
+
try {
|
|
53
|
+
data = await response.json();
|
|
54
|
+
} catch {
|
|
55
|
+
}
|
|
56
|
+
return { response, data };
|
|
57
|
+
}
|
|
58
|
+
async function getAuthJson(path, host, query) {
|
|
59
|
+
const url = buildAuthUrl(path, host, query);
|
|
60
|
+
return fetchWithCredentials(url, { method: "GET" });
|
|
61
|
+
}
|
|
62
|
+
function getResolvedAppId(appId) {
|
|
63
|
+
return (appId ?? DEFAULT_APP_ID).trim();
|
|
64
|
+
}
|
|
65
|
+
function HomeIcon({ className }) {
|
|
66
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.75", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
67
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M3 9l9-7 9 7v11a2 2 0 01-2 2H5a2 2 0 01-2-2z" }),
|
|
68
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M9 22V12h6v10" })
|
|
69
|
+
] });
|
|
70
|
+
}
|
|
71
|
+
function FolderIcon({ className }) {
|
|
72
|
+
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" }) });
|
|
73
|
+
}
|
|
74
|
+
function UserIcon({ className }) {
|
|
75
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.75", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
76
|
+
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "12", cy: "8", r: "4" }),
|
|
77
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M4 20c0-4 3.6-7 8-7s8 3 8 7" })
|
|
78
|
+
] });
|
|
79
|
+
}
|
|
80
|
+
function SettingsIcon({ className }) {
|
|
81
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.75", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
82
|
+
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "12", cy: "12", r: "3" }),
|
|
83
|
+
/* @__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" })
|
|
84
|
+
] });
|
|
85
|
+
}
|
|
86
|
+
function LogOutIcon({ className }) {
|
|
87
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.75", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
88
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M9 21H5a2 2 0 01-2-2V5a2 2 0 012-2h4" }),
|
|
89
|
+
/* @__PURE__ */ jsxRuntime.jsx("polyline", { points: "16,17 21,12 16,7" }),
|
|
90
|
+
/* @__PURE__ */ jsxRuntime.jsx("line", { x1: "21", y1: "12", x2: "9", y2: "12" })
|
|
91
|
+
] });
|
|
92
|
+
}
|
|
93
|
+
function ChevronLeftIcon({ className }) {
|
|
94
|
+
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" }) });
|
|
95
|
+
}
|
|
96
|
+
function ChevronRightIcon({ className }) {
|
|
97
|
+
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" }) });
|
|
98
|
+
}
|
|
99
|
+
function ChevronsUpDownIcon({ className }) {
|
|
100
|
+
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" }) });
|
|
101
|
+
}
|
|
102
|
+
var defaultNavItems = [
|
|
103
|
+
{ href: "/dashboard", label: "Dashboard", icon: HomeIcon, exact: true },
|
|
104
|
+
{ href: "/dashboard/projects", label: "Projects", icon: FolderIcon, exact: false },
|
|
105
|
+
{ href: "/dashboard/settings", label: "Settings", icon: SettingsIcon, exact: false }
|
|
106
|
+
];
|
|
107
|
+
var AVATAR_COLORS = [
|
|
108
|
+
"bg-violet-600",
|
|
109
|
+
"bg-indigo-600",
|
|
110
|
+
"bg-sky-600",
|
|
111
|
+
"bg-emerald-600",
|
|
112
|
+
"bg-amber-600",
|
|
113
|
+
"bg-rose-600"
|
|
114
|
+
];
|
|
115
|
+
function getAvatarColor(name) {
|
|
116
|
+
let hash = 0;
|
|
117
|
+
for (let i = 0; i < name.length; i++) hash = name.charCodeAt(i) + ((hash << 5) - hash);
|
|
118
|
+
return AVATAR_COLORS[Math.abs(hash) % AVATAR_COLORS.length];
|
|
119
|
+
}
|
|
120
|
+
function getInitials(name) {
|
|
121
|
+
return name.split(" ").filter(Boolean).map((w) => w[0]).join("").toUpperCase().slice(0, 2);
|
|
122
|
+
}
|
|
123
|
+
function Sidebar({
|
|
124
|
+
user: userProp,
|
|
125
|
+
appId,
|
|
126
|
+
authHost,
|
|
127
|
+
navItems = defaultNavItems,
|
|
128
|
+
title = "Workspace",
|
|
129
|
+
logoutRedirectTo = "/",
|
|
130
|
+
profileHref = "/profile",
|
|
131
|
+
settingsHref = "/settings",
|
|
132
|
+
onLogout
|
|
133
|
+
}) {
|
|
134
|
+
const [isCollapsed, setIsCollapsed] = react.useState(false);
|
|
135
|
+
const [isUserMenuOpen, setIsUserMenuOpen] = react.useState(false);
|
|
136
|
+
const [fetchedUser, setFetchedUser] = react.useState(null);
|
|
137
|
+
const [isLoading, setIsLoading] = react.useState(!userProp);
|
|
138
|
+
const pathname = navigation.usePathname();
|
|
139
|
+
const router = navigation.useRouter();
|
|
140
|
+
const menuRef = react.useRef(null);
|
|
141
|
+
react.useEffect(() => {
|
|
142
|
+
if (userProp) return;
|
|
143
|
+
let cancelled = false;
|
|
144
|
+
async function fetchSession() {
|
|
145
|
+
try {
|
|
146
|
+
const { response, data } = await getAuthJson("api/auth/session", authHost);
|
|
147
|
+
if (!cancelled && response.ok && data?.user) {
|
|
148
|
+
setFetchedUser(data.user);
|
|
149
|
+
}
|
|
150
|
+
} catch (err) {
|
|
151
|
+
console.error("Failed to fetch session:", err);
|
|
152
|
+
} finally {
|
|
153
|
+
if (!cancelled) setIsLoading(false);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
fetchSession();
|
|
157
|
+
return () => {
|
|
158
|
+
cancelled = true;
|
|
159
|
+
};
|
|
160
|
+
}, [authHost, userProp]);
|
|
161
|
+
react.useEffect(() => {
|
|
162
|
+
function handleClickOutside(e) {
|
|
163
|
+
if (menuRef.current && !menuRef.current.contains(e.target)) {
|
|
164
|
+
setIsUserMenuOpen(false);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
168
|
+
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
169
|
+
}, []);
|
|
170
|
+
const user = userProp || fetchedUser;
|
|
171
|
+
if (isLoading || !user) return null;
|
|
172
|
+
const displayName = user.name || user.email?.split("@")[0] || "User";
|
|
173
|
+
const initials = getInitials(displayName);
|
|
174
|
+
const avatarColor = getAvatarColor(displayName);
|
|
175
|
+
function isActive(href, exact) {
|
|
176
|
+
return exact ? pathname === href : pathname.startsWith(href);
|
|
177
|
+
}
|
|
178
|
+
async function handleLogout() {
|
|
179
|
+
const resolvedAppId = getResolvedAppId(appId);
|
|
180
|
+
try {
|
|
181
|
+
await getAuthJson("api/auth/logout", authHost, resolvedAppId ? { appId: resolvedAppId } : void 0);
|
|
182
|
+
} catch (err) {
|
|
183
|
+
console.error("Logout error:", err);
|
|
184
|
+
}
|
|
185
|
+
if (onLogout) {
|
|
186
|
+
onLogout();
|
|
187
|
+
} else {
|
|
188
|
+
router.push(logoutRedirectTo);
|
|
189
|
+
router.refresh();
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
193
|
+
"aside",
|
|
194
|
+
{
|
|
195
|
+
className: "relative flex flex-col h-screen bg-white border-r border-zinc-200 transition-all duration-200 ease-in-out flex-shrink-0 " + (isCollapsed ? "w-[60px]" : "w-[220px]"),
|
|
196
|
+
children: [
|
|
197
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
198
|
+
"div",
|
|
199
|
+
{
|
|
200
|
+
className: "flex items-center h-14 px-3 flex-shrink-0 border-b border-zinc-200 " + (isCollapsed ? "justify-center" : "justify-between"),
|
|
201
|
+
children: [
|
|
202
|
+
!isCollapsed && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-semibold text-zinc-900 tracking-tight truncate select-none", children: title }),
|
|
203
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
204
|
+
"button",
|
|
205
|
+
{
|
|
206
|
+
onClick: () => setIsCollapsed((c) => !c),
|
|
207
|
+
title: isCollapsed ? "Expand sidebar" : "Collapse sidebar",
|
|
208
|
+
className: "p-1.5 rounded-md text-zinc-400 hover:text-zinc-700 hover:bg-zinc-100 transition-colors flex-shrink-0",
|
|
209
|
+
children: isCollapsed ? /* @__PURE__ */ jsxRuntime.jsx(ChevronRightIcon, { className: "w-4 h-4" }) : /* @__PURE__ */ jsxRuntime.jsx(ChevronLeftIcon, { className: "w-4 h-4" })
|
|
210
|
+
}
|
|
211
|
+
)
|
|
212
|
+
]
|
|
213
|
+
}
|
|
214
|
+
),
|
|
215
|
+
/* @__PURE__ */ jsxRuntime.jsx("nav", { className: "flex-1 overflow-y-auto py-2 px-2 space-y-0.5", children: navItems.map(({ href, label, icon: Icon, exact }) => {
|
|
216
|
+
const active = isActive(href, exact ?? false);
|
|
217
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
218
|
+
Link__default.default,
|
|
219
|
+
{
|
|
220
|
+
href,
|
|
221
|
+
title: isCollapsed ? label : void 0,
|
|
222
|
+
className: "flex items-center gap-2.5 px-2.5 py-2 rounded-lg text-sm transition-colors " + (isCollapsed ? "justify-center " : "") + (active ? "bg-zinc-100 text-zinc-900 font-medium" : "text-zinc-500 hover:bg-zinc-50 hover:text-zinc-900"),
|
|
223
|
+
children: [
|
|
224
|
+
/* @__PURE__ */ jsxRuntime.jsx(Icon, { className: "w-4 h-4 flex-shrink-0" }),
|
|
225
|
+
!isCollapsed && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: label })
|
|
226
|
+
]
|
|
227
|
+
},
|
|
228
|
+
href
|
|
229
|
+
);
|
|
230
|
+
}) }),
|
|
231
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
232
|
+
"div",
|
|
233
|
+
{
|
|
234
|
+
ref: menuRef,
|
|
235
|
+
className: "relative flex-shrink-0 p-2 border-t border-zinc-200",
|
|
236
|
+
children: [
|
|
237
|
+
isUserMenuOpen && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
238
|
+
"div",
|
|
239
|
+
{
|
|
240
|
+
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"),
|
|
241
|
+
children: [
|
|
242
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-3.5 py-3 border-b border-zinc-100", children: [
|
|
243
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-medium text-zinc-900 truncate", children: displayName }),
|
|
244
|
+
user.email && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-zinc-500 truncate mt-0.5", children: user.email })
|
|
245
|
+
] }),
|
|
246
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-1", children: [
|
|
247
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
248
|
+
Link__default.default,
|
|
249
|
+
{
|
|
250
|
+
href: profileHref,
|
|
251
|
+
onClick: () => setIsUserMenuOpen(false),
|
|
252
|
+
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",
|
|
253
|
+
children: [
|
|
254
|
+
/* @__PURE__ */ jsxRuntime.jsx(UserIcon, { className: "w-4 h-4 text-zinc-400" }),
|
|
255
|
+
"Profile"
|
|
256
|
+
]
|
|
257
|
+
}
|
|
258
|
+
),
|
|
259
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
260
|
+
Link__default.default,
|
|
261
|
+
{
|
|
262
|
+
href: settingsHref,
|
|
263
|
+
onClick: () => setIsUserMenuOpen(false),
|
|
264
|
+
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",
|
|
265
|
+
children: [
|
|
266
|
+
/* @__PURE__ */ jsxRuntime.jsx(SettingsIcon, { className: "w-4 h-4 text-zinc-400" }),
|
|
267
|
+
"Settings"
|
|
268
|
+
]
|
|
269
|
+
}
|
|
270
|
+
),
|
|
271
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
272
|
+
"button",
|
|
273
|
+
{
|
|
274
|
+
onClick: handleLogout,
|
|
275
|
+
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",
|
|
276
|
+
children: [
|
|
277
|
+
/* @__PURE__ */ jsxRuntime.jsx(LogOutIcon, { className: "w-4 h-4 text-zinc-400" }),
|
|
278
|
+
"Log out"
|
|
279
|
+
]
|
|
280
|
+
}
|
|
281
|
+
)
|
|
282
|
+
] })
|
|
283
|
+
]
|
|
284
|
+
}
|
|
285
|
+
),
|
|
286
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
287
|
+
"button",
|
|
288
|
+
{
|
|
289
|
+
onClick: () => setIsUserMenuOpen((o) => !o),
|
|
290
|
+
title: isCollapsed ? displayName : void 0,
|
|
291
|
+
className: "w-full flex items-center gap-2.5 p-2 rounded-lg hover:bg-zinc-50 transition-colors text-left " + (isCollapsed ? "justify-center" : ""),
|
|
292
|
+
children: [
|
|
293
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
294
|
+
"div",
|
|
295
|
+
{
|
|
296
|
+
className: "w-7 h-7 rounded-full flex items-center justify-center flex-shrink-0 " + avatarColor,
|
|
297
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs font-semibold text-white leading-none", children: initials })
|
|
298
|
+
}
|
|
299
|
+
),
|
|
300
|
+
!isCollapsed && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
301
|
+
/* @__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 }) }),
|
|
302
|
+
/* @__PURE__ */ jsxRuntime.jsx(ChevronsUpDownIcon, { className: "w-3.5 h-3.5 text-zinc-400 flex-shrink-0" })
|
|
303
|
+
] })
|
|
304
|
+
]
|
|
305
|
+
}
|
|
306
|
+
)
|
|
307
|
+
]
|
|
308
|
+
}
|
|
309
|
+
)
|
|
310
|
+
]
|
|
311
|
+
}
|
|
312
|
+
);
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
exports.Hello = Hello;
|
|
316
|
+
exports.Sidebar = Sidebar;
|
|
317
|
+
//# sourceMappingURL=index.cjs.map
|
|
318
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/Hello.tsx","../src/utils/authApi.ts","../src/components/Sidebar.tsx"],"names":["jsx","jsxs","useState","usePathname","useRouter","useRef","useEffect","Link","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, type ComponentType } from \"react\";\nimport Link from \"next/link\";\nimport { usePathname, useRouter } from \"next/navigation\";\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 = usePathname();\n const router = useRouter();\n const menuRef = useRef<HTMLDivElement>(null);\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 router.push(logoutRedirectTo);\n router.refresh();\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 <Link\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 </Link>\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 <Link\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 </Link>\n <Link\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 </Link>\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"]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { ComponentType } from 'react';
|
|
3
|
+
|
|
4
|
+
declare function Hello(): react_jsx_runtime.JSX.Element;
|
|
5
|
+
|
|
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
|
+
interface NavItem {
|
|
17
|
+
href: string;
|
|
18
|
+
label: string;
|
|
19
|
+
icon: ComponentType<{
|
|
20
|
+
className?: string;
|
|
21
|
+
}>;
|
|
22
|
+
exact?: boolean;
|
|
23
|
+
}
|
|
24
|
+
interface SidebarProps {
|
|
25
|
+
user?: AuthUser;
|
|
26
|
+
appId?: string;
|
|
27
|
+
authHost?: string;
|
|
28
|
+
navItems?: NavItem[];
|
|
29
|
+
title?: string;
|
|
30
|
+
logoutRedirectTo?: string;
|
|
31
|
+
profileHref?: string;
|
|
32
|
+
settingsHref?: string;
|
|
33
|
+
onLogout?: () => void;
|
|
34
|
+
}
|
|
35
|
+
declare function Sidebar({ user: userProp, appId, authHost, navItems, title, logoutRedirectTo, profileHref, settingsHref, onLogout, }: SidebarProps): react_jsx_runtime.JSX.Element | null;
|
|
36
|
+
|
|
37
|
+
export { type AuthUser, Hello, type NavItem, Sidebar, type SidebarProps, type UserType };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { ComponentType } from 'react';
|
|
3
|
+
|
|
4
|
+
declare function Hello(): react_jsx_runtime.JSX.Element;
|
|
5
|
+
|
|
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
|
+
interface NavItem {
|
|
17
|
+
href: string;
|
|
18
|
+
label: string;
|
|
19
|
+
icon: ComponentType<{
|
|
20
|
+
className?: string;
|
|
21
|
+
}>;
|
|
22
|
+
exact?: boolean;
|
|
23
|
+
}
|
|
24
|
+
interface SidebarProps {
|
|
25
|
+
user?: AuthUser;
|
|
26
|
+
appId?: string;
|
|
27
|
+
authHost?: string;
|
|
28
|
+
navItems?: NavItem[];
|
|
29
|
+
title?: string;
|
|
30
|
+
logoutRedirectTo?: string;
|
|
31
|
+
profileHref?: string;
|
|
32
|
+
settingsHref?: string;
|
|
33
|
+
onLogout?: () => void;
|
|
34
|
+
}
|
|
35
|
+
declare function Sidebar({ user: userProp, appId, authHost, navItems, title, logoutRedirectTo, profileHref, settingsHref, onLogout, }: SidebarProps): react_jsx_runtime.JSX.Element | null;
|
|
36
|
+
|
|
37
|
+
export { type AuthUser, Hello, type NavItem, Sidebar, type SidebarProps, type UserType };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
2
|
+
import { useState, useRef, useEffect } from 'react';
|
|
3
|
+
import Link from 'next/link';
|
|
4
|
+
import { usePathname, useRouter } from 'next/navigation';
|
|
5
|
+
|
|
6
|
+
// src/components/Hello.tsx
|
|
7
|
+
function Hello() {
|
|
8
|
+
return /* @__PURE__ */ jsx("div", { children: "Hello world" });
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
// src/utils/authApi.ts
|
|
12
|
+
var DEFAULT_AUTH_HOST = (() => {
|
|
13
|
+
if (typeof process !== "undefined" && process.env?.NEXT_PUBLIC_AUTH_API_HOST) {
|
|
14
|
+
const envHost = process.env.NEXT_PUBLIC_AUTH_API_HOST.trim();
|
|
15
|
+
if (envHost.length > 0) return envHost;
|
|
16
|
+
}
|
|
17
|
+
return "https://auth.create-flow.ai";
|
|
18
|
+
})();
|
|
19
|
+
var DEFAULT_APP_ID = typeof process !== "undefined" ? process.env?.NEXT_PUBLIC_AUTH_APP_ID?.trim() ?? "" : "";
|
|
20
|
+
function normalizeHost(host) {
|
|
21
|
+
const value = (host ?? DEFAULT_AUTH_HOST).trim();
|
|
22
|
+
if (!value) throw new Error("Auth host is not configured");
|
|
23
|
+
if (/^https?:\/\//i.test(value)) return value.replace(/\/+$/g, "");
|
|
24
|
+
return `https://${value}`.replace(/\/+$/g, "");
|
|
25
|
+
}
|
|
26
|
+
function buildAuthUrl(path, host, query) {
|
|
27
|
+
const normalizedHost = normalizeHost(host);
|
|
28
|
+
const normalizedPath = path.startsWith("/") ? path : `/${path}`;
|
|
29
|
+
const url = new URL(normalizedPath, normalizedHost);
|
|
30
|
+
if (query) {
|
|
31
|
+
for (const [key, value] of Object.entries(query)) {
|
|
32
|
+
if (value !== void 0 && value !== null) {
|
|
33
|
+
url.searchParams.set(key, value);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return url;
|
|
38
|
+
}
|
|
39
|
+
async function fetchWithCredentials(url, init = {}) {
|
|
40
|
+
const response = await fetch(url.toString(), {
|
|
41
|
+
credentials: "include",
|
|
42
|
+
cache: "no-store",
|
|
43
|
+
...init
|
|
44
|
+
});
|
|
45
|
+
let data = null;
|
|
46
|
+
try {
|
|
47
|
+
data = await response.json();
|
|
48
|
+
} catch {
|
|
49
|
+
}
|
|
50
|
+
return { response, data };
|
|
51
|
+
}
|
|
52
|
+
async function getAuthJson(path, host, query) {
|
|
53
|
+
const url = buildAuthUrl(path, host, query);
|
|
54
|
+
return fetchWithCredentials(url, { method: "GET" });
|
|
55
|
+
}
|
|
56
|
+
function getResolvedAppId(appId) {
|
|
57
|
+
return (appId ?? DEFAULT_APP_ID).trim();
|
|
58
|
+
}
|
|
59
|
+
function HomeIcon({ className }) {
|
|
60
|
+
return /* @__PURE__ */ jsxs("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.75", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
61
|
+
/* @__PURE__ */ jsx("path", { d: "M3 9l9-7 9 7v11a2 2 0 01-2 2H5a2 2 0 01-2-2z" }),
|
|
62
|
+
/* @__PURE__ */ jsx("path", { d: "M9 22V12h6v10" })
|
|
63
|
+
] });
|
|
64
|
+
}
|
|
65
|
+
function FolderIcon({ className }) {
|
|
66
|
+
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" }) });
|
|
67
|
+
}
|
|
68
|
+
function UserIcon({ className }) {
|
|
69
|
+
return /* @__PURE__ */ jsxs("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.75", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
70
|
+
/* @__PURE__ */ jsx("circle", { cx: "12", cy: "8", r: "4" }),
|
|
71
|
+
/* @__PURE__ */ jsx("path", { d: "M4 20c0-4 3.6-7 8-7s8 3 8 7" })
|
|
72
|
+
] });
|
|
73
|
+
}
|
|
74
|
+
function SettingsIcon({ className }) {
|
|
75
|
+
return /* @__PURE__ */ jsxs("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.75", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
76
|
+
/* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "3" }),
|
|
77
|
+
/* @__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" })
|
|
78
|
+
] });
|
|
79
|
+
}
|
|
80
|
+
function LogOutIcon({ className }) {
|
|
81
|
+
return /* @__PURE__ */ jsxs("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.75", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
82
|
+
/* @__PURE__ */ jsx("path", { d: "M9 21H5a2 2 0 01-2-2V5a2 2 0 012-2h4" }),
|
|
83
|
+
/* @__PURE__ */ jsx("polyline", { points: "16,17 21,12 16,7" }),
|
|
84
|
+
/* @__PURE__ */ jsx("line", { x1: "21", y1: "12", x2: "9", y2: "12" })
|
|
85
|
+
] });
|
|
86
|
+
}
|
|
87
|
+
function ChevronLeftIcon({ className }) {
|
|
88
|
+
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" }) });
|
|
89
|
+
}
|
|
90
|
+
function ChevronRightIcon({ className }) {
|
|
91
|
+
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" }) });
|
|
92
|
+
}
|
|
93
|
+
function ChevronsUpDownIcon({ className }) {
|
|
94
|
+
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" }) });
|
|
95
|
+
}
|
|
96
|
+
var defaultNavItems = [
|
|
97
|
+
{ href: "/dashboard", label: "Dashboard", icon: HomeIcon, exact: true },
|
|
98
|
+
{ href: "/dashboard/projects", label: "Projects", icon: FolderIcon, exact: false },
|
|
99
|
+
{ href: "/dashboard/settings", label: "Settings", icon: SettingsIcon, exact: false }
|
|
100
|
+
];
|
|
101
|
+
var AVATAR_COLORS = [
|
|
102
|
+
"bg-violet-600",
|
|
103
|
+
"bg-indigo-600",
|
|
104
|
+
"bg-sky-600",
|
|
105
|
+
"bg-emerald-600",
|
|
106
|
+
"bg-amber-600",
|
|
107
|
+
"bg-rose-600"
|
|
108
|
+
];
|
|
109
|
+
function getAvatarColor(name) {
|
|
110
|
+
let hash = 0;
|
|
111
|
+
for (let i = 0; i < name.length; i++) hash = name.charCodeAt(i) + ((hash << 5) - hash);
|
|
112
|
+
return AVATAR_COLORS[Math.abs(hash) % AVATAR_COLORS.length];
|
|
113
|
+
}
|
|
114
|
+
function getInitials(name) {
|
|
115
|
+
return name.split(" ").filter(Boolean).map((w) => w[0]).join("").toUpperCase().slice(0, 2);
|
|
116
|
+
}
|
|
117
|
+
function Sidebar({
|
|
118
|
+
user: userProp,
|
|
119
|
+
appId,
|
|
120
|
+
authHost,
|
|
121
|
+
navItems = defaultNavItems,
|
|
122
|
+
title = "Workspace",
|
|
123
|
+
logoutRedirectTo = "/",
|
|
124
|
+
profileHref = "/profile",
|
|
125
|
+
settingsHref = "/settings",
|
|
126
|
+
onLogout
|
|
127
|
+
}) {
|
|
128
|
+
const [isCollapsed, setIsCollapsed] = useState(false);
|
|
129
|
+
const [isUserMenuOpen, setIsUserMenuOpen] = useState(false);
|
|
130
|
+
const [fetchedUser, setFetchedUser] = useState(null);
|
|
131
|
+
const [isLoading, setIsLoading] = useState(!userProp);
|
|
132
|
+
const pathname = usePathname();
|
|
133
|
+
const router = useRouter();
|
|
134
|
+
const menuRef = useRef(null);
|
|
135
|
+
useEffect(() => {
|
|
136
|
+
if (userProp) return;
|
|
137
|
+
let cancelled = false;
|
|
138
|
+
async function fetchSession() {
|
|
139
|
+
try {
|
|
140
|
+
const { response, data } = await getAuthJson("api/auth/session", authHost);
|
|
141
|
+
if (!cancelled && response.ok && data?.user) {
|
|
142
|
+
setFetchedUser(data.user);
|
|
143
|
+
}
|
|
144
|
+
} catch (err) {
|
|
145
|
+
console.error("Failed to fetch session:", err);
|
|
146
|
+
} finally {
|
|
147
|
+
if (!cancelled) setIsLoading(false);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
fetchSession();
|
|
151
|
+
return () => {
|
|
152
|
+
cancelled = true;
|
|
153
|
+
};
|
|
154
|
+
}, [authHost, userProp]);
|
|
155
|
+
useEffect(() => {
|
|
156
|
+
function handleClickOutside(e) {
|
|
157
|
+
if (menuRef.current && !menuRef.current.contains(e.target)) {
|
|
158
|
+
setIsUserMenuOpen(false);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
162
|
+
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
163
|
+
}, []);
|
|
164
|
+
const user = userProp || fetchedUser;
|
|
165
|
+
if (isLoading || !user) return null;
|
|
166
|
+
const displayName = user.name || user.email?.split("@")[0] || "User";
|
|
167
|
+
const initials = getInitials(displayName);
|
|
168
|
+
const avatarColor = getAvatarColor(displayName);
|
|
169
|
+
function isActive(href, exact) {
|
|
170
|
+
return exact ? pathname === href : pathname.startsWith(href);
|
|
171
|
+
}
|
|
172
|
+
async function handleLogout() {
|
|
173
|
+
const resolvedAppId = getResolvedAppId(appId);
|
|
174
|
+
try {
|
|
175
|
+
await getAuthJson("api/auth/logout", authHost, resolvedAppId ? { appId: resolvedAppId } : void 0);
|
|
176
|
+
} catch (err) {
|
|
177
|
+
console.error("Logout error:", err);
|
|
178
|
+
}
|
|
179
|
+
if (onLogout) {
|
|
180
|
+
onLogout();
|
|
181
|
+
} else {
|
|
182
|
+
router.push(logoutRedirectTo);
|
|
183
|
+
router.refresh();
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
return /* @__PURE__ */ jsxs(
|
|
187
|
+
"aside",
|
|
188
|
+
{
|
|
189
|
+
className: "relative flex flex-col h-screen bg-white border-r border-zinc-200 transition-all duration-200 ease-in-out flex-shrink-0 " + (isCollapsed ? "w-[60px]" : "w-[220px]"),
|
|
190
|
+
children: [
|
|
191
|
+
/* @__PURE__ */ jsxs(
|
|
192
|
+
"div",
|
|
193
|
+
{
|
|
194
|
+
className: "flex items-center h-14 px-3 flex-shrink-0 border-b border-zinc-200 " + (isCollapsed ? "justify-center" : "justify-between"),
|
|
195
|
+
children: [
|
|
196
|
+
!isCollapsed && /* @__PURE__ */ jsx("span", { className: "text-sm font-semibold text-zinc-900 tracking-tight truncate select-none", children: title }),
|
|
197
|
+
/* @__PURE__ */ jsx(
|
|
198
|
+
"button",
|
|
199
|
+
{
|
|
200
|
+
onClick: () => setIsCollapsed((c) => !c),
|
|
201
|
+
title: isCollapsed ? "Expand sidebar" : "Collapse sidebar",
|
|
202
|
+
className: "p-1.5 rounded-md text-zinc-400 hover:text-zinc-700 hover:bg-zinc-100 transition-colors flex-shrink-0",
|
|
203
|
+
children: isCollapsed ? /* @__PURE__ */ jsx(ChevronRightIcon, { className: "w-4 h-4" }) : /* @__PURE__ */ jsx(ChevronLeftIcon, { className: "w-4 h-4" })
|
|
204
|
+
}
|
|
205
|
+
)
|
|
206
|
+
]
|
|
207
|
+
}
|
|
208
|
+
),
|
|
209
|
+
/* @__PURE__ */ jsx("nav", { className: "flex-1 overflow-y-auto py-2 px-2 space-y-0.5", children: navItems.map(({ href, label, icon: Icon, exact }) => {
|
|
210
|
+
const active = isActive(href, exact ?? false);
|
|
211
|
+
return /* @__PURE__ */ jsxs(
|
|
212
|
+
Link,
|
|
213
|
+
{
|
|
214
|
+
href,
|
|
215
|
+
title: isCollapsed ? label : void 0,
|
|
216
|
+
className: "flex items-center gap-2.5 px-2.5 py-2 rounded-lg text-sm transition-colors " + (isCollapsed ? "justify-center " : "") + (active ? "bg-zinc-100 text-zinc-900 font-medium" : "text-zinc-500 hover:bg-zinc-50 hover:text-zinc-900"),
|
|
217
|
+
children: [
|
|
218
|
+
/* @__PURE__ */ jsx(Icon, { className: "w-4 h-4 flex-shrink-0" }),
|
|
219
|
+
!isCollapsed && /* @__PURE__ */ jsx("span", { className: "truncate", children: label })
|
|
220
|
+
]
|
|
221
|
+
},
|
|
222
|
+
href
|
|
223
|
+
);
|
|
224
|
+
}) }),
|
|
225
|
+
/* @__PURE__ */ jsxs(
|
|
226
|
+
"div",
|
|
227
|
+
{
|
|
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
|
+
Link,
|
|
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
|
+
Link,
|
|
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
|
+
]
|
|
302
|
+
}
|
|
303
|
+
)
|
|
304
|
+
]
|
|
305
|
+
}
|
|
306
|
+
);
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
export { Hello, Sidebar };
|
|
310
|
+
//# sourceMappingURL=index.js.map
|
|
311
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/Hello.tsx","../src/utils/authApi.ts","../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","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, type ComponentType } from \"react\";\nimport Link from \"next/link\";\nimport { usePathname, useRouter } from \"next/navigation\";\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 = usePathname();\n const router = useRouter();\n const menuRef = useRef<HTMLDivElement>(null);\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 router.push(logoutRedirectTo);\n router.refresh();\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 <Link\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 </Link>\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 <Link\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 </Link>\n <Link\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 </Link>\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"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@create-flow/common-ui",
|
|
3
|
+
"version": "0.3.5",
|
|
4
|
+
"description": "Shared UI components for Flow apps",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.cjs",
|
|
7
|
+
"module": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.js",
|
|
13
|
+
"require": "./dist/index.cjs"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"dist"
|
|
18
|
+
],
|
|
19
|
+
"publishConfig": {
|
|
20
|
+
"access": "public"
|
|
21
|
+
},
|
|
22
|
+
"sideEffects": false,
|
|
23
|
+
"scripts": {
|
|
24
|
+
"build": "tsup",
|
|
25
|
+
"lint": "eslint src",
|
|
26
|
+
"prepublishOnly": "bun run build",
|
|
27
|
+
"publish:dry": "npm pack --dry-run",
|
|
28
|
+
"version:patch": "node -e \"const p=require('./package.json');const v=p.version.split('.');v[2]++;p.version=v.join('.');require('fs').writeFileSync('package.json',JSON.stringify(p,null,2)+'\\n')\"",
|
|
29
|
+
"version:minor": "node -e \"const p=require('./package.json');const v=p.version.split('.');v[1]++;v[2]=0;p.version=v.join('.');require('fs').writeFileSync('package.json',JSON.stringify(p,null,2)+'\\n')\"",
|
|
30
|
+
"version:major": "node -e \"const p=require('./package.json');const v=p.version.split('.');v[0]++;v[1]=0;v[2]=0;p.version=v.join('.');require('fs').writeFileSync('package.json',JSON.stringify(p,null,2)+'\\n')\"",
|
|
31
|
+
"publish:patch": "bun run version:patch && bun publish",
|
|
32
|
+
"publish:minor": "bun run version:minor && bun publish",
|
|
33
|
+
"publish:major": "bun run version:major && bun publish"
|
|
34
|
+
},
|
|
35
|
+
"peerDependencies": {
|
|
36
|
+
"next": ">=14",
|
|
37
|
+
"react": ">=18",
|
|
38
|
+
"react-dom": ">=18"
|
|
39
|
+
},
|
|
40
|
+
"devDependencies": {
|
|
41
|
+
"@eslint/js": "^9",
|
|
42
|
+
"@types/react": "^19",
|
|
43
|
+
"@types/react-dom": "^19",
|
|
44
|
+
"eslint": "^9",
|
|
45
|
+
"typescript-eslint": "^8",
|
|
46
|
+
"react": "19.2.3",
|
|
47
|
+
"react-dom": "19.2.3",
|
|
48
|
+
"tsup": "^8",
|
|
49
|
+
"typescript": "^5"
|
|
50
|
+
}
|
|
51
|
+
}
|