@pelatform/starter.shared 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +138 -6
- package/dist/index.js +1305 -666
- package/package.json +6 -4
package/dist/index.js
CHANGED
|
@@ -1,10 +1,1133 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
+
// src/components/layouts/auth.tsx
|
|
4
|
+
import Link3 from "next/link";
|
|
5
|
+
import { usePathname } from "next/navigation";
|
|
6
|
+
import { useTranslations as useTranslations4 } from "next-intl";
|
|
7
|
+
import { useConfig as useConfig3 } from "@pelatform/starter.hook";
|
|
8
|
+
import { LayoutBlank } from "pelatform-ui/components";
|
|
9
|
+
|
|
10
|
+
// src/components/logo.tsx
|
|
11
|
+
import Link from "next/link";
|
|
12
|
+
import { useConfig } from "@pelatform/starter.hook";
|
|
13
|
+
import { cn } from "pelatform-ui";
|
|
14
|
+
import { Logo } from "pelatform-ui/components";
|
|
15
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
16
|
+
function LogoWithName({ className }) {
|
|
17
|
+
const { app } = useConfig();
|
|
18
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("flex items-center gap-2", className), children: [
|
|
19
|
+
/* @__PURE__ */ jsx(Logo, { className: "size-7" }),
|
|
20
|
+
/* @__PURE__ */ jsx("span", { className: "font-semibold text-lg text-mono", children: app.name })
|
|
21
|
+
] });
|
|
22
|
+
}
|
|
23
|
+
function LogoWithHref({ className, href = "/" }) {
|
|
24
|
+
const { app } = useConfig();
|
|
25
|
+
return /* @__PURE__ */ jsxs(Link, { href, className: cn("flex items-center gap-2", className), children: [
|
|
26
|
+
/* @__PURE__ */ jsx(Logo, { className: "size-7" }),
|
|
27
|
+
/* @__PURE__ */ jsx("span", { className: "font-semibold text-lg text-mono", children: app.name })
|
|
28
|
+
] });
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// src/components/signed-in-hint.tsx
|
|
32
|
+
import Link2 from "next/link";
|
|
33
|
+
import { useTranslations } from "next-intl";
|
|
34
|
+
import { useSession } from "@pelatform/starter.hook";
|
|
35
|
+
import { Button } from "pelatform-ui/default";
|
|
36
|
+
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
37
|
+
function SignedInHint({ linkHref = "/signin" }) {
|
|
38
|
+
const t = useTranslations();
|
|
39
|
+
const { isPending, user } = useSession();
|
|
40
|
+
return /* @__PURE__ */ jsxs2("div", { className: "fixed start-0 bottom-0 z-40 m-5 flex flex-col gap-2", children: [
|
|
41
|
+
/* @__PURE__ */ jsxs2("div", { className: "flex items-center gap-1 text-muted-foreground text-xs", children: [
|
|
42
|
+
t("ui.common.signed.text"),
|
|
43
|
+
" ",
|
|
44
|
+
isPending || !user ? /* @__PURE__ */ jsx2("span", { className: "h-3 w-32 animate-pulse rounded-md border bg-muted-foreground" }) : /* @__PURE__ */ jsx2("b", { className: "text-foreground", children: user.email })
|
|
45
|
+
] }),
|
|
46
|
+
/* @__PURE__ */ jsx2(Button, { variant: "mono", className: "h-8 w-fit rounded-lg px-3 text-xs shadow-sm", children: /* @__PURE__ */ jsx2(Link2, { href: linkHref, children: t("ui.common.signed.button") }) })
|
|
47
|
+
] });
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// src/components/layouts/loader.tsx
|
|
51
|
+
import { useTranslations as useTranslations2 } from "next-intl";
|
|
52
|
+
import { useSession as useSession2 } from "@pelatform/starter.hook";
|
|
53
|
+
import { ScreenLoader } from "pelatform-ui/components";
|
|
54
|
+
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
55
|
+
function LayoutLoader({ children }) {
|
|
56
|
+
const t = useTranslations2();
|
|
57
|
+
const { isPending } = useSession2();
|
|
58
|
+
if (isPending) {
|
|
59
|
+
return /* @__PURE__ */ jsx3(ScreenLoader, { loadingText: t("common.status.loading") });
|
|
60
|
+
}
|
|
61
|
+
return children;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// src/components/layouts/toolbar.tsx
|
|
65
|
+
import { Suspense } from "react";
|
|
66
|
+
import { cn as cn2 } from "pelatform-ui";
|
|
67
|
+
import { ModeSwitcher } from "pelatform-ui/components";
|
|
68
|
+
|
|
69
|
+
// src/components/language-switcher.tsx
|
|
70
|
+
import Image from "next/image";
|
|
71
|
+
import { useRouter } from "next/navigation";
|
|
72
|
+
import { useLocale, useTranslations as useTranslations3 } from "next-intl";
|
|
73
|
+
import { useConfig as useConfig2 } from "@pelatform/starter.hook";
|
|
74
|
+
import {
|
|
75
|
+
LanguageSwitcher as LanguageSwitcherBase
|
|
76
|
+
} from "pelatform-ui/components";
|
|
77
|
+
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
78
|
+
function LanguageSwitcher({
|
|
79
|
+
className,
|
|
80
|
+
type,
|
|
81
|
+
variant,
|
|
82
|
+
size,
|
|
83
|
+
showNames,
|
|
84
|
+
showFlags
|
|
85
|
+
}) {
|
|
86
|
+
const { i18n } = useConfig2();
|
|
87
|
+
const router = useRouter();
|
|
88
|
+
const t = useTranslations3();
|
|
89
|
+
const currentLocale = useLocale();
|
|
90
|
+
const availableLocales = (() => {
|
|
91
|
+
if (!i18n.enabled) {
|
|
92
|
+
return [i18n.defaultLocale];
|
|
93
|
+
}
|
|
94
|
+
const availableLocales2 = Object.keys(i18n.locales);
|
|
95
|
+
return availableLocales2;
|
|
96
|
+
})();
|
|
97
|
+
const languages = availableLocales.map((locale) => {
|
|
98
|
+
const localeConfig = i18n.locales[locale] || null;
|
|
99
|
+
return {
|
|
100
|
+
code: locale,
|
|
101
|
+
name: localeConfig?.name || locale.toUpperCase(),
|
|
102
|
+
flag: `/flags/${localeConfig?.flag}.svg` || ""
|
|
103
|
+
};
|
|
104
|
+
});
|
|
105
|
+
function handleLanguageChange(newLocale) {
|
|
106
|
+
if (newLocale === currentLocale) {
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
document.cookie = `${i18n.localeCookieName}=${newLocale}; max-age=${60 * 60 * 24 * 365}; path=/`;
|
|
110
|
+
router.refresh();
|
|
111
|
+
}
|
|
112
|
+
return /* @__PURE__ */ jsx4(
|
|
113
|
+
LanguageSwitcherBase,
|
|
114
|
+
{
|
|
115
|
+
className,
|
|
116
|
+
type,
|
|
117
|
+
variant,
|
|
118
|
+
size,
|
|
119
|
+
showNames,
|
|
120
|
+
showFlags,
|
|
121
|
+
label: t("ui.common.language"),
|
|
122
|
+
i18nEnabled: i18n.enabled,
|
|
123
|
+
currentLocale,
|
|
124
|
+
locales: languages,
|
|
125
|
+
onLocaleChange: handleLanguageChange,
|
|
126
|
+
customFlagUrl: true,
|
|
127
|
+
Image
|
|
128
|
+
}
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// src/components/layouts/toolbar.tsx
|
|
133
|
+
import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
134
|
+
var DEFAULT_SHOW = ["darkmode"];
|
|
135
|
+
function Toolbar(props) {
|
|
136
|
+
return /* @__PURE__ */ jsx5(Suspense, { fallback: null, children: /* @__PURE__ */ jsx5("div", { className: cn2("fixed end-0 bottom-0 z-40 m-5", props.className), children: /* @__PURE__ */ jsx5(ToolbarRSC, { ...props }) }) });
|
|
137
|
+
}
|
|
138
|
+
function ToolbarRSC({ show = DEFAULT_SHOW }) {
|
|
139
|
+
return /* @__PURE__ */ jsx5("div", { className: "flex flex-col items-center gap-2.5", children: /* @__PURE__ */ jsxs3("div", { className: "shrink-0", children: [
|
|
140
|
+
show.includes("darkmode") && /* @__PURE__ */ jsx5(ModeSwitcher, { variant: "outline", size: "lg", className: "size-10 rounded-full border" }),
|
|
141
|
+
show.includes("help") && /* @__PURE__ */ jsx5("div", { className: "hidden" }),
|
|
142
|
+
show.includes("language") && /* @__PURE__ */ jsx5(LanguageSwitcher, { variant: "outline", size: "lg", className: "size-10 rounded-full border" }),
|
|
143
|
+
show.includes("onboarding") && /* @__PURE__ */ jsx5("div", { className: "hidden" })
|
|
144
|
+
] }) });
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// src/components/layouts/auth.tsx
|
|
148
|
+
import { jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
149
|
+
function AuthLayout({
|
|
150
|
+
children,
|
|
151
|
+
logo = /* @__PURE__ */ jsx6(LogoWithName, {}),
|
|
152
|
+
disableFooter = false,
|
|
153
|
+
signInHint = false,
|
|
154
|
+
signInHref
|
|
155
|
+
}) {
|
|
156
|
+
const { app, path } = useConfig3();
|
|
157
|
+
const pathname = usePathname();
|
|
158
|
+
const t = useTranslations4();
|
|
159
|
+
const footer = /* @__PURE__ */ jsxs4("p", { className: "px-20 py-4 text-center font-medium text-muted-foreground text-xs md:px-0", children: [
|
|
160
|
+
t("ui.common.agree"),
|
|
161
|
+
" ",
|
|
162
|
+
/* @__PURE__ */ jsx6(
|
|
163
|
+
Link3,
|
|
164
|
+
{
|
|
165
|
+
href: path.main.TERMS,
|
|
166
|
+
target: "_blank",
|
|
167
|
+
className: "font-semibold text-foreground hover:text-primary",
|
|
168
|
+
children: t("ui.common.terms")
|
|
169
|
+
}
|
|
170
|
+
),
|
|
171
|
+
" ",
|
|
172
|
+
/* @__PURE__ */ jsx6(
|
|
173
|
+
Link3,
|
|
174
|
+
{
|
|
175
|
+
href: path.main.PRIVACY,
|
|
176
|
+
target: "_blank",
|
|
177
|
+
className: "font-semibold text-foreground hover:text-primary",
|
|
178
|
+
children: t("ui.common.privacy")
|
|
179
|
+
}
|
|
180
|
+
)
|
|
181
|
+
] });
|
|
182
|
+
return /* @__PURE__ */ jsxs4(LayoutLoader, { children: [
|
|
183
|
+
/* @__PURE__ */ jsx6(Toolbar, { show: ["language"], className: "top-0!" }),
|
|
184
|
+
/* @__PURE__ */ jsx6(
|
|
185
|
+
LayoutBlank,
|
|
186
|
+
{
|
|
187
|
+
className: "[&_.max-w-4xl]:max-w-sm [&_.max-w-4xl]:px-0",
|
|
188
|
+
logo,
|
|
189
|
+
logoHref: app.baseUrl,
|
|
190
|
+
footer: disableFooter || pathname === path.auth.SIGN_OUT || pathname === path.auth.CALLBACK ? null : footer,
|
|
191
|
+
children
|
|
192
|
+
}
|
|
193
|
+
),
|
|
194
|
+
/* @__PURE__ */ jsx6(Toolbar, { show: ["darkmode"] }),
|
|
195
|
+
signInHint && /* @__PURE__ */ jsx6(SignedInHint, { linkHref: signInHref || path.auth.SIGN_OUT })
|
|
196
|
+
] });
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// src/components/layouts/header.tsx
|
|
200
|
+
import { useEffect as useEffect2, useState as useState2 } from "react";
|
|
201
|
+
import { usePathname as usePathname2 } from "next/navigation";
|
|
202
|
+
import { Menu, PanelRight } from "lucide-react";
|
|
203
|
+
import { useLayout } from "@pelatform/starter.hook";
|
|
204
|
+
import {
|
|
205
|
+
Button as Button2,
|
|
206
|
+
Sheet,
|
|
207
|
+
SheetBody,
|
|
208
|
+
SheetContent,
|
|
209
|
+
SheetDescription,
|
|
210
|
+
SheetHeader,
|
|
211
|
+
SheetTitle,
|
|
212
|
+
SheetTrigger
|
|
213
|
+
} from "pelatform-ui/default";
|
|
214
|
+
|
|
215
|
+
// src/components/user-menu.tsx
|
|
216
|
+
import { Fragment as Fragment2, useCallback, useEffect, useState } from "react";
|
|
217
|
+
import Link4 from "next/link";
|
|
218
|
+
import { useRouter as useRouter2 } from "next/navigation";
|
|
219
|
+
import { LogOut, PlusCircleIcon, Settings, Shield, UserStar } from "lucide-react";
|
|
220
|
+
import { useTranslations as useTranslations7 } from "next-intl";
|
|
221
|
+
import {
|
|
222
|
+
useConfig as useConfig4,
|
|
223
|
+
useListDeviceSessions,
|
|
224
|
+
useSession as useSession3,
|
|
225
|
+
useSetActiveSession
|
|
226
|
+
} from "@pelatform/starter.hook";
|
|
227
|
+
import { getUserName as getUserName3 } from "@pelatform/starter.utils";
|
|
228
|
+
import { ModeSwitcher as ModeSwitcher2, UserAvatar as UserAvatar2 } from "pelatform-ui/components";
|
|
229
|
+
import {
|
|
230
|
+
Badge,
|
|
231
|
+
DropdownMenu,
|
|
232
|
+
DropdownMenuContent,
|
|
233
|
+
DropdownMenuItem,
|
|
234
|
+
DropdownMenuSeparator,
|
|
235
|
+
DropdownMenuTrigger,
|
|
236
|
+
Skeleton as Skeleton3
|
|
237
|
+
} from "pelatform-ui/default";
|
|
238
|
+
|
|
239
|
+
// src/components/view.tsx
|
|
240
|
+
import { KeyRoundIcon } from "lucide-react";
|
|
241
|
+
import { useLocale as useLocale2, useTranslations as useTranslations6 } from "next-intl";
|
|
242
|
+
import { getUserName as getUserName2 } from "@pelatform/starter.utils";
|
|
243
|
+
import { cn as cn4 } from "pelatform-ui";
|
|
244
|
+
import { Skeleton as Skeleton2 } from "pelatform-ui/default";
|
|
245
|
+
|
|
246
|
+
// src/components/avatar.tsx
|
|
247
|
+
import { BuildingIcon, UserRoundIcon } from "lucide-react";
|
|
248
|
+
import { useTranslations as useTranslations5 } from "next-intl";
|
|
249
|
+
import { getSizeAvatar, getUserName } from "@pelatform/starter.utils";
|
|
250
|
+
import { cn as cn3 } from "pelatform-ui";
|
|
251
|
+
import { getInitials } from "pelatform-ui/components";
|
|
252
|
+
import { Avatar, AvatarFallback, AvatarImage, Skeleton } from "pelatform-ui/default";
|
|
253
|
+
import { jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
254
|
+
function UserAvatar({
|
|
255
|
+
className,
|
|
256
|
+
classNames,
|
|
257
|
+
image,
|
|
258
|
+
isPending,
|
|
259
|
+
size,
|
|
260
|
+
user,
|
|
261
|
+
...props
|
|
262
|
+
}) {
|
|
263
|
+
const t = useTranslations5();
|
|
264
|
+
const name = getUserName(user);
|
|
265
|
+
const src = user?.image;
|
|
266
|
+
if (isPending) {
|
|
267
|
+
return /* @__PURE__ */ jsx7(
|
|
268
|
+
Skeleton,
|
|
269
|
+
{
|
|
270
|
+
className: cn3(
|
|
271
|
+
"shrink-0 rounded-full",
|
|
272
|
+
getSizeAvatar(size),
|
|
273
|
+
className,
|
|
274
|
+
classNames?.base,
|
|
275
|
+
classNames?.skeleton
|
|
276
|
+
)
|
|
277
|
+
}
|
|
278
|
+
);
|
|
279
|
+
}
|
|
280
|
+
return /* @__PURE__ */ jsxs5(
|
|
281
|
+
Avatar,
|
|
282
|
+
{
|
|
283
|
+
className: cn3("rounded-full bg-accent", getSizeAvatar(size), className, classNames?.base),
|
|
284
|
+
...props,
|
|
285
|
+
children: [
|
|
286
|
+
/* @__PURE__ */ jsx7(
|
|
287
|
+
AvatarImage,
|
|
288
|
+
{
|
|
289
|
+
src: image || src || void 0,
|
|
290
|
+
alt: name || t("ui.navigation.user"),
|
|
291
|
+
className: classNames?.image
|
|
292
|
+
}
|
|
293
|
+
),
|
|
294
|
+
/* @__PURE__ */ jsx7(
|
|
295
|
+
AvatarFallback,
|
|
296
|
+
{
|
|
297
|
+
className: cn3("text-foreground uppercase", classNames?.fallback),
|
|
298
|
+
delayMs: src ? 600 : void 0,
|
|
299
|
+
children: getInitials(name, 2) || /* @__PURE__ */ jsx7(UserRoundIcon, { className: cn3("size-[50%]", classNames?.fallbackIcon) })
|
|
300
|
+
}
|
|
301
|
+
)
|
|
302
|
+
]
|
|
303
|
+
}
|
|
304
|
+
);
|
|
305
|
+
}
|
|
306
|
+
function WorkspaceLogo({
|
|
307
|
+
className,
|
|
308
|
+
classNames,
|
|
309
|
+
image,
|
|
310
|
+
isPending,
|
|
311
|
+
size,
|
|
312
|
+
workspace,
|
|
313
|
+
...props
|
|
314
|
+
}) {
|
|
315
|
+
const t = useTranslations5();
|
|
316
|
+
const name = workspace?.name;
|
|
317
|
+
const src = workspace?.logo;
|
|
318
|
+
if (isPending) {
|
|
319
|
+
return /* @__PURE__ */ jsx7(
|
|
320
|
+
Skeleton,
|
|
321
|
+
{
|
|
322
|
+
className: cn3(
|
|
323
|
+
"shrink-0 rounded-full",
|
|
324
|
+
getSizeAvatar(size),
|
|
325
|
+
className,
|
|
326
|
+
classNames?.base,
|
|
327
|
+
classNames?.skeleton
|
|
328
|
+
)
|
|
329
|
+
}
|
|
330
|
+
);
|
|
331
|
+
}
|
|
332
|
+
return /* @__PURE__ */ jsxs5(
|
|
333
|
+
Avatar,
|
|
334
|
+
{
|
|
335
|
+
className: cn3("rounded-full bg-accent", getSizeAvatar(size), className, classNames?.base),
|
|
336
|
+
...props,
|
|
337
|
+
children: [
|
|
338
|
+
/* @__PURE__ */ jsx7(
|
|
339
|
+
AvatarImage,
|
|
340
|
+
{
|
|
341
|
+
src: image || src || void 0,
|
|
342
|
+
alt: name || t("ui.navigation.workspace"),
|
|
343
|
+
className: classNames?.image
|
|
344
|
+
}
|
|
345
|
+
),
|
|
346
|
+
/* @__PURE__ */ jsx7(
|
|
347
|
+
AvatarFallback,
|
|
348
|
+
{
|
|
349
|
+
className: cn3("text-foreground", classNames?.fallback),
|
|
350
|
+
delayMs: src ? 600 : void 0,
|
|
351
|
+
children: /* @__PURE__ */ jsx7(BuildingIcon, { className: cn3("size-[50%]", classNames?.fallbackIcon) })
|
|
352
|
+
}
|
|
353
|
+
)
|
|
354
|
+
]
|
|
355
|
+
}
|
|
356
|
+
);
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
// src/components/view.tsx
|
|
360
|
+
import { Fragment, jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
361
|
+
function UserView({ className, classNames, isPending, size, user }) {
|
|
362
|
+
const t = useTranslations6();
|
|
363
|
+
return /* @__PURE__ */ jsxs6("div", { className: cn4("flex items-center gap-2", className, classNames?.base), children: [
|
|
364
|
+
/* @__PURE__ */ jsx8(
|
|
365
|
+
UserAvatar,
|
|
366
|
+
{
|
|
367
|
+
className: cn4(size !== "sm" && "my-0.5"),
|
|
368
|
+
classNames: classNames?.avatar,
|
|
369
|
+
isPending,
|
|
370
|
+
size,
|
|
371
|
+
user
|
|
372
|
+
}
|
|
373
|
+
),
|
|
374
|
+
/* @__PURE__ */ jsx8("div", { className: cn4("grid flex-1 text-start leading-tight", classNames?.content), children: isPending ? /* @__PURE__ */ jsxs6(Fragment, { children: [
|
|
375
|
+
/* @__PURE__ */ jsx8(
|
|
376
|
+
Skeleton2,
|
|
377
|
+
{
|
|
378
|
+
className: cn4(
|
|
379
|
+
"max-w-full",
|
|
380
|
+
size === "lg" ? "h-4.5 w-32" : "h-3.5 w-24",
|
|
381
|
+
classNames?.title,
|
|
382
|
+
classNames?.skeleton
|
|
383
|
+
)
|
|
384
|
+
}
|
|
385
|
+
),
|
|
386
|
+
size !== "sm" && /* @__PURE__ */ jsx8(
|
|
387
|
+
Skeleton2,
|
|
388
|
+
{
|
|
389
|
+
className: cn4(
|
|
390
|
+
"mt-1.5 max-w-full",
|
|
391
|
+
size === "lg" ? "h-3.5 w-40" : "h-3 w-32",
|
|
392
|
+
classNames?.subtitle,
|
|
393
|
+
classNames?.skeleton
|
|
394
|
+
)
|
|
395
|
+
}
|
|
396
|
+
)
|
|
397
|
+
] }) : /* @__PURE__ */ jsxs6(Fragment, { children: [
|
|
398
|
+
/* @__PURE__ */ jsx8(
|
|
399
|
+
"span",
|
|
400
|
+
{
|
|
401
|
+
className: cn4(
|
|
402
|
+
"truncate font-semibold",
|
|
403
|
+
size === "lg" ? "text-base" : "text-sm",
|
|
404
|
+
classNames?.title
|
|
405
|
+
),
|
|
406
|
+
children: getUserName2(user) || t("ui.navigation.user")
|
|
407
|
+
}
|
|
408
|
+
),
|
|
409
|
+
!user?.isAnonymous && size !== "sm" && (user?.name || user?.username) && /* @__PURE__ */ jsx8(
|
|
410
|
+
"span",
|
|
411
|
+
{
|
|
412
|
+
className: cn4(
|
|
413
|
+
"truncate opacity-70",
|
|
414
|
+
size === "lg" ? "text-sm" : "text-xs",
|
|
415
|
+
classNames?.subtitle
|
|
416
|
+
),
|
|
417
|
+
children: user?.email
|
|
418
|
+
}
|
|
419
|
+
)
|
|
420
|
+
] }) })
|
|
421
|
+
] });
|
|
422
|
+
}
|
|
423
|
+
function ApiKeyView({ className, classNames, apiKey }) {
|
|
424
|
+
const t = useTranslations6();
|
|
425
|
+
const locale = useLocale2();
|
|
426
|
+
const formatExpiration = () => {
|
|
427
|
+
if (!apiKey.expiresAt) return t("common.time.neverExpires");
|
|
428
|
+
const expiresDate = new Date(apiKey.expiresAt);
|
|
429
|
+
return `${t("common.time.expires")} ${expiresDate.toLocaleDateString(locale ?? "en", {
|
|
430
|
+
month: "short",
|
|
431
|
+
day: "numeric",
|
|
432
|
+
year: "numeric"
|
|
433
|
+
})}`;
|
|
434
|
+
};
|
|
435
|
+
return /* @__PURE__ */ jsxs6("div", { className: cn4("flex items-center gap-3 truncate", className, classNames?.base), children: [
|
|
436
|
+
/* @__PURE__ */ jsx8(KeyRoundIcon, { className: cn4("size-4 shrink-0", classNames?.icon) }),
|
|
437
|
+
/* @__PURE__ */ jsxs6("div", { className: "flex flex-col truncate text-start", children: [
|
|
438
|
+
/* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-2", children: [
|
|
439
|
+
/* @__PURE__ */ jsx8("span", { className: "truncate font-semibold text-sm", children: apiKey.name }),
|
|
440
|
+
/* @__PURE__ */ jsxs6("span", { className: "flex-1 truncate text-muted-foreground text-sm", children: [
|
|
441
|
+
apiKey.start,
|
|
442
|
+
"******"
|
|
443
|
+
] })
|
|
444
|
+
] }),
|
|
445
|
+
/* @__PURE__ */ jsx8("div", { className: "truncate text-muted-foreground text-xs", children: formatExpiration() })
|
|
446
|
+
] })
|
|
447
|
+
] });
|
|
448
|
+
}
|
|
449
|
+
function WorkspaceView({ className, classNames, isPending, size, workspace }) {
|
|
450
|
+
const t = useTranslations6();
|
|
451
|
+
return /* @__PURE__ */ jsxs6("div", { className: cn4("flex items-center gap-2 truncate", className, classNames?.base), children: [
|
|
452
|
+
/* @__PURE__ */ jsx8(
|
|
453
|
+
WorkspaceLogo,
|
|
454
|
+
{
|
|
455
|
+
className: cn4(size !== "sm" && "my-0.5"),
|
|
456
|
+
classNames: classNames?.avatar,
|
|
457
|
+
isPending,
|
|
458
|
+
workspace,
|
|
459
|
+
size
|
|
460
|
+
}
|
|
461
|
+
),
|
|
462
|
+
/* @__PURE__ */ jsx8("div", { className: cn4("flex flex-col truncate text-start leading-tight", classNames?.content), children: isPending ? /* @__PURE__ */ jsxs6(Fragment, { children: [
|
|
463
|
+
/* @__PURE__ */ jsx8(
|
|
464
|
+
Skeleton2,
|
|
465
|
+
{
|
|
466
|
+
className: cn4(
|
|
467
|
+
"max-w-full",
|
|
468
|
+
size === "lg" ? "h-4.5 w-32" : "h-3.5 w-24",
|
|
469
|
+
classNames?.title,
|
|
470
|
+
classNames?.skeleton
|
|
471
|
+
)
|
|
472
|
+
}
|
|
473
|
+
),
|
|
474
|
+
size !== "sm" && /* @__PURE__ */ jsx8(
|
|
475
|
+
Skeleton2,
|
|
476
|
+
{
|
|
477
|
+
className: cn4(
|
|
478
|
+
"mt-1.5 max-w-full",
|
|
479
|
+
size === "lg" ? "h-3.5 w-24" : "h-3 w-16",
|
|
480
|
+
classNames?.subtitle,
|
|
481
|
+
classNames?.skeleton
|
|
482
|
+
)
|
|
483
|
+
}
|
|
484
|
+
)
|
|
485
|
+
] }) : /* @__PURE__ */ jsxs6(Fragment, { children: [
|
|
486
|
+
/* @__PURE__ */ jsx8(
|
|
487
|
+
"span",
|
|
488
|
+
{
|
|
489
|
+
className: cn4(
|
|
490
|
+
"truncate font-semibold",
|
|
491
|
+
size === "lg" ? "text-base" : "text-sm",
|
|
492
|
+
classNames?.title
|
|
493
|
+
),
|
|
494
|
+
children: workspace?.name || t("ui.navigation.workspace")
|
|
495
|
+
}
|
|
496
|
+
),
|
|
497
|
+
size !== "sm" && workspace?.slug && /* @__PURE__ */ jsx8(
|
|
498
|
+
"span",
|
|
499
|
+
{
|
|
500
|
+
className: cn4(
|
|
501
|
+
"truncate opacity-70",
|
|
502
|
+
size === "lg" ? "text-sm" : "text-xs",
|
|
503
|
+
classNames?.subtitle
|
|
504
|
+
),
|
|
505
|
+
children: workspace.slug
|
|
506
|
+
}
|
|
507
|
+
)
|
|
508
|
+
] }) })
|
|
509
|
+
] });
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
// src/components/user-menu.tsx
|
|
513
|
+
import { Fragment as Fragment3, jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
514
|
+
function UserMenu({ hiddenSwitcher = false }) {
|
|
515
|
+
const { features, path } = useConfig4();
|
|
516
|
+
const router = useRouter2();
|
|
517
|
+
const t = useTranslations7();
|
|
518
|
+
const { isPending: sessionPending, user } = useSession3();
|
|
519
|
+
const { setActiveSessionAsync } = useSetActiveSession();
|
|
520
|
+
const { data: deviceSessions, isPending: deviceSessionsPending } = useListDeviceSessions({
|
|
521
|
+
enabled: features.multiSession
|
|
522
|
+
});
|
|
523
|
+
const [activeSessionPending, setActiveSessionPending] = useState(false);
|
|
524
|
+
const isPending = sessionPending || activeSessionPending;
|
|
525
|
+
const switchAccount = useCallback(
|
|
526
|
+
async (sessionToken) => {
|
|
527
|
+
setActiveSessionPending(true);
|
|
528
|
+
try {
|
|
529
|
+
await setActiveSessionAsync({ sessionToken });
|
|
530
|
+
router.refresh();
|
|
531
|
+
setActiveSessionPending(false);
|
|
532
|
+
} catch (error) {
|
|
533
|
+
console.error("Error switching account:", error);
|
|
534
|
+
setActiveSessionPending(false);
|
|
535
|
+
}
|
|
536
|
+
},
|
|
537
|
+
[router, setActiveSessionAsync]
|
|
538
|
+
);
|
|
539
|
+
useEffect(() => {
|
|
540
|
+
if (!features.multiSession) return;
|
|
541
|
+
setActiveSessionPending(false);
|
|
542
|
+
}, [features.multiSession, user?.id]);
|
|
543
|
+
const userEmail = user?.email || "user@example.com";
|
|
544
|
+
const userName = getUserName3(user);
|
|
545
|
+
const userAvatar = user?.image || void 0;
|
|
546
|
+
const userRole = user?.role || "user";
|
|
547
|
+
return /* @__PURE__ */ jsxs7(DropdownMenu, { children: [
|
|
548
|
+
/* @__PURE__ */ jsx9(DropdownMenuTrigger, { className: "focus:outline-none focus:ring-0", children: isPending ? /* @__PURE__ */ jsx9(Skeleton3, { className: "size-8 shrink-0 rounded-full" }) : /* @__PURE__ */ jsx9(UserAvatar2, { className: "size-8", indicator: true, src: userAvatar, alt: userName }) }),
|
|
549
|
+
/* @__PURE__ */ jsxs7(DropdownMenuContent, { className: "w-56", side: "bottom", align: "end", sideOffset: 11, children: [
|
|
550
|
+
/* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-3 px-3 py-2", children: [
|
|
551
|
+
/* @__PURE__ */ jsx9(UserAvatar2, { src: userAvatar, alt: userName }),
|
|
552
|
+
/* @__PURE__ */ jsxs7("div", { className: "flex min-w-0 flex-1 flex-col items-start", children: [
|
|
553
|
+
/* @__PURE__ */ jsx9("span", { className: "truncate font-semibold text-foreground text-sm", children: userName }),
|
|
554
|
+
/* @__PURE__ */ jsx9("span", { className: "block w-full truncate text-muted-foreground text-xs", children: userEmail }),
|
|
555
|
+
/* @__PURE__ */ jsx9(Badge, { variant: "success", appearance: "outline", size: "sm", className: "mt-1", children: userRole.toUpperCase() })
|
|
556
|
+
] })
|
|
557
|
+
] }),
|
|
558
|
+
/* @__PURE__ */ jsx9(DropdownMenuSeparator, {}),
|
|
559
|
+
/* @__PURE__ */ jsx9(DropdownMenuItem, { asChild: true, children: /* @__PURE__ */ jsxs7(Link4, { href: path.account.SETTINGS, children: [
|
|
560
|
+
/* @__PURE__ */ jsx9(Settings, {}),
|
|
561
|
+
/* @__PURE__ */ jsx9("span", { children: t("ui.navigation.preferences") })
|
|
562
|
+
] }) }),
|
|
563
|
+
/* @__PURE__ */ jsx9(DropdownMenuItem, { asChild: true, children: /* @__PURE__ */ jsxs7(Link4, { href: path.account.SECURITY, children: [
|
|
564
|
+
/* @__PURE__ */ jsx9(Shield, {}),
|
|
565
|
+
/* @__PURE__ */ jsx9("span", { children: t("ui.navigation.security") })
|
|
566
|
+
] }) }),
|
|
567
|
+
"admin" === userRole && /* @__PURE__ */ jsx9(DropdownMenuItem, { asChild: true, children: /* @__PURE__ */ jsxs7(Link4, { href: path.admin.OVERVIEW, children: [
|
|
568
|
+
/* @__PURE__ */ jsx9(UserStar, {}),
|
|
569
|
+
/* @__PURE__ */ jsx9("span", { children: "Admin Dashboard" })
|
|
570
|
+
] }) }),
|
|
571
|
+
!hiddenSwitcher && /* @__PURE__ */ jsxs7(Fragment3, { children: [
|
|
572
|
+
/* @__PURE__ */ jsx9(DropdownMenuSeparator, {}),
|
|
573
|
+
/* @__PURE__ */ jsx9(
|
|
574
|
+
ModeSwitcher2,
|
|
575
|
+
{
|
|
576
|
+
type: "sub-dropdown",
|
|
577
|
+
label: {
|
|
578
|
+
system: t("ui.common.system"),
|
|
579
|
+
dark: t("ui.common.dark"),
|
|
580
|
+
light: t("ui.common.light")
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
),
|
|
584
|
+
/* @__PURE__ */ jsx9(LanguageSwitcher, { type: "sub-dropdown" })
|
|
585
|
+
] }),
|
|
586
|
+
/* @__PURE__ */ jsx9(DropdownMenuSeparator, {}),
|
|
587
|
+
/* @__PURE__ */ jsx9(DropdownMenuItem, { asChild: true, children: /* @__PURE__ */ jsxs7(Link4, { href: path.auth.SIGN_OUT, children: [
|
|
588
|
+
/* @__PURE__ */ jsx9(LogOut, {}),
|
|
589
|
+
/* @__PURE__ */ jsx9("span", { children: t("ui.navigation.signOut") })
|
|
590
|
+
] }) }),
|
|
591
|
+
user && features.multiSession && /* @__PURE__ */ jsxs7(Fragment3, { children: [
|
|
592
|
+
/* @__PURE__ */ jsx9(DropdownMenuSeparator, {}),
|
|
593
|
+
!deviceSessions && deviceSessionsPending && /* @__PURE__ */ jsxs7(Fragment3, { children: [
|
|
594
|
+
/* @__PURE__ */ jsx9(DropdownMenuItem, { disabled: true, children: /* @__PURE__ */ jsx9(UserView, { isPending: true }) }),
|
|
595
|
+
/* @__PURE__ */ jsx9(DropdownMenuSeparator, {})
|
|
596
|
+
] }),
|
|
597
|
+
deviceSessions?.filter((sessionData) => sessionData.user.id !== user?.id).map(({ session, user: multiUser }) => /* @__PURE__ */ jsxs7(Fragment2, { children: [
|
|
598
|
+
/* @__PURE__ */ jsxs7(DropdownMenuItem, { onClick: () => switchAccount(session.token), children: [
|
|
599
|
+
/* @__PURE__ */ jsx9(UserAvatar2, { src: multiUser?.image || void 0, alt: getUserName3(multiUser) }),
|
|
600
|
+
/* @__PURE__ */ jsxs7("div", { className: "flex min-w-0 flex-1 flex-col items-start", children: [
|
|
601
|
+
/* @__PURE__ */ jsx9("span", { className: "truncate font-semibold text-foreground text-xs", children: getUserName3(multiUser) }),
|
|
602
|
+
/* @__PURE__ */ jsx9("span", { className: "block w-full truncate text-muted-foreground text-xs", children: multiUser?.email })
|
|
603
|
+
] })
|
|
604
|
+
] }),
|
|
605
|
+
/* @__PURE__ */ jsx9(DropdownMenuSeparator, {})
|
|
606
|
+
] }, session.id)),
|
|
607
|
+
/* @__PURE__ */ jsx9(DropdownMenuItem, { asChild: true, children: /* @__PURE__ */ jsxs7(Link4, { href: path.auth.SIGN_IN, children: [
|
|
608
|
+
/* @__PURE__ */ jsx9(PlusCircleIcon, {}),
|
|
609
|
+
t("common.actions.addAccount")
|
|
610
|
+
] }) })
|
|
611
|
+
] })
|
|
612
|
+
] })
|
|
613
|
+
] });
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
// src/components/layouts/header.tsx
|
|
617
|
+
import { jsx as jsx10, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
618
|
+
function Header({ children }) {
|
|
619
|
+
return /* @__PURE__ */ jsx10("header", { className: "fixed start-0 end-0 top-0 z-10 flex h-(--header-height-mobile) shrink-0 items-stretch border-border border-b bg-background/95 pe-(--removed-body-scroll-bar-size,0px) backdrop-blur-sm supports-backdrop-filter:bg-background/60 lg:h-(--header-height)", children: /* @__PURE__ */ jsx10("div", { className: "@container flex grow items-stretch justify-between gap-2.5 pe-5", children }) });
|
|
620
|
+
}
|
|
621
|
+
function HeaderLeft() {
|
|
622
|
+
const { logoHeader, sidebarToggle } = useLayout();
|
|
623
|
+
return /* @__PURE__ */ jsx10("div", { className: "flex items-center gap-2 px-5 lg:w-(--sidebar-width)", children: /* @__PURE__ */ jsxs8("div", { className: "flex w-full items-center justify-between", children: [
|
|
624
|
+
logoHeader,
|
|
625
|
+
/* @__PURE__ */ jsx10(
|
|
626
|
+
Button2,
|
|
627
|
+
{
|
|
628
|
+
mode: "icon",
|
|
629
|
+
variant: "ghost",
|
|
630
|
+
onClick: sidebarToggle,
|
|
631
|
+
className: "hidden text-muted-foreground hover:text-foreground lg:inline-flex",
|
|
632
|
+
children: /* @__PURE__ */ jsx10(PanelRight, { className: "-rotate-180 in-data-[sidebar-open=false]:rotate-0 opacity-100" })
|
|
633
|
+
}
|
|
634
|
+
)
|
|
635
|
+
] }) });
|
|
636
|
+
}
|
|
637
|
+
function HeaderRight({ sidebar, button }) {
|
|
638
|
+
const { isMobile } = useLayout();
|
|
639
|
+
return /* @__PURE__ */ jsxs8("nav", { className: "flex items-center gap-1.5 lg:gap-2.5", children: [
|
|
640
|
+
button,
|
|
641
|
+
isMobile && sidebar,
|
|
642
|
+
/* @__PURE__ */ jsx10(UserMenu, {})
|
|
643
|
+
] });
|
|
644
|
+
}
|
|
645
|
+
function HeaderSidebarMobile({ children }) {
|
|
646
|
+
const pathname = usePathname2();
|
|
647
|
+
const [isSheetOpen, setIsSheetOpen] = useState2(false);
|
|
648
|
+
useEffect2(() => {
|
|
649
|
+
setIsSheetOpen(false);
|
|
650
|
+
}, [pathname]);
|
|
651
|
+
return /* @__PURE__ */ jsxs8(Sheet, { open: isSheetOpen, onOpenChange: setIsSheetOpen, children: [
|
|
652
|
+
/* @__PURE__ */ jsx10(SheetTrigger, { asChild: true, children: /* @__PURE__ */ jsx10(Button2, { variant: "ghost", mode: "icon", size: "icon", children: /* @__PURE__ */ jsx10(Menu, { className: "size-4" }) }) }),
|
|
653
|
+
/* @__PURE__ */ jsxs8(SheetContent, { className: "w-(--sidebar-width) gap-0 p-0", side: "left", close: false, children: [
|
|
654
|
+
/* @__PURE__ */ jsxs8(SheetHeader, { className: "hidden space-y-0 p-0", children: [
|
|
655
|
+
/* @__PURE__ */ jsx10(SheetTitle, { className: "sr-only", children: "Navigation menu" }),
|
|
656
|
+
/* @__PURE__ */ jsx10(SheetDescription, { className: "sr-only", children: "NavigatSheet Description" })
|
|
657
|
+
] }),
|
|
658
|
+
/* @__PURE__ */ jsx10(SheetBody, { className: "flex grow flex-col p-0", children })
|
|
659
|
+
] })
|
|
660
|
+
] });
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
// src/components/layouts/sidebar.tsx
|
|
664
|
+
import { useCallback as useCallback2, useMemo } from "react";
|
|
665
|
+
import Link5 from "next/link";
|
|
666
|
+
import { usePathname as usePathname3 } from "next/navigation";
|
|
667
|
+
import { useTranslations as useTranslations8 } from "next-intl";
|
|
668
|
+
import { useLayout as useLayout2 } from "@pelatform/starter.hook";
|
|
669
|
+
import { BackLink } from "pelatform-ui/components";
|
|
670
|
+
import {
|
|
671
|
+
AccordionMenu,
|
|
672
|
+
AccordionMenuGroup,
|
|
673
|
+
AccordionMenuIndicator,
|
|
674
|
+
AccordionMenuItem,
|
|
675
|
+
AccordionMenuLabel,
|
|
676
|
+
AccordionMenuSub,
|
|
677
|
+
AccordionMenuSubContent,
|
|
678
|
+
AccordionMenuSubTrigger,
|
|
679
|
+
Badge as Badge2,
|
|
680
|
+
ScrollArea
|
|
681
|
+
} from "pelatform-ui/default";
|
|
682
|
+
import { Fragment as Fragment4, jsx as jsx11, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
683
|
+
function Sidebar({ children }) {
|
|
684
|
+
const { isMobile } = useLayout2();
|
|
685
|
+
if (isMobile) {
|
|
686
|
+
return null;
|
|
687
|
+
}
|
|
688
|
+
return /* @__PURE__ */ jsxs9("aside", { className: "in-data-[sidebar-open=false]:-start-full fixed start-0 top-(--header-height) bottom-0 flex w-(--sidebar-width) shrink-0 flex-col items-stretch border-border border-e transition-all duration-300", children: [
|
|
689
|
+
children,
|
|
690
|
+
/* @__PURE__ */ jsx11("div", {})
|
|
691
|
+
] });
|
|
692
|
+
}
|
|
693
|
+
function SidebarHeaderBack({
|
|
694
|
+
linkHref = "/",
|
|
695
|
+
admin = false
|
|
696
|
+
}) {
|
|
697
|
+
const t = useTranslations8();
|
|
698
|
+
return /* @__PURE__ */ jsx11("div", { className: "flex h-14 shrink-0 items-center gap-2 border-border border-b px-2.5 lg:h-15", children: /* @__PURE__ */ jsx11(BackLink, { Link: Link5, href: linkHref, children: admin ? t("common.actions.back") : t("ui.navigation.settings") }) });
|
|
699
|
+
}
|
|
700
|
+
function SidebarContent({ children }) {
|
|
701
|
+
return /* @__PURE__ */ jsx11(ScrollArea, { className: "mt-2 mb-2.5 h-[calc(100vh-5.5rem)] grow lg:mt-4 lg:mb-7.5 lg:h-[calc(100vh-4rem)]", children });
|
|
702
|
+
}
|
|
703
|
+
function SidebarContentMenu({
|
|
704
|
+
menu,
|
|
705
|
+
type = "default"
|
|
706
|
+
}) {
|
|
707
|
+
const pathname = usePathname3();
|
|
708
|
+
const normalize = useCallback2((p) => {
|
|
709
|
+
if (!p) return "/";
|
|
710
|
+
if (p !== "/" && p.endsWith("/")) return p.replace(/\/+$/, "");
|
|
711
|
+
return p;
|
|
712
|
+
}, []);
|
|
713
|
+
const current = useMemo(() => normalize(pathname), [pathname, normalize]);
|
|
714
|
+
const allPaths = useMemo(
|
|
715
|
+
() => menu.flatMap(
|
|
716
|
+
(g) => (g.children ?? []).map((c) => c.path).filter((p) => !!p && p !== "#")
|
|
717
|
+
),
|
|
718
|
+
[menu]
|
|
719
|
+
);
|
|
720
|
+
const activePath = useMemo(() => {
|
|
721
|
+
const candidates = allPaths.map(normalize);
|
|
722
|
+
let best = "";
|
|
723
|
+
for (const p of candidates) {
|
|
724
|
+
if (p === "/") {
|
|
725
|
+
if (current === "/") {
|
|
726
|
+
best = "/";
|
|
727
|
+
}
|
|
728
|
+
continue;
|
|
729
|
+
}
|
|
730
|
+
if (current === p || current.startsWith(`${p}/`)) {
|
|
731
|
+
if (p.length > best.length) {
|
|
732
|
+
best = p;
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
}
|
|
736
|
+
return best;
|
|
737
|
+
}, [allPaths, current, normalize]);
|
|
738
|
+
const matchPath = useCallback2(
|
|
739
|
+
(path) => normalize(path) === activePath,
|
|
740
|
+
[activePath, normalize]
|
|
741
|
+
);
|
|
742
|
+
if (type === "toggle") {
|
|
743
|
+
return /* @__PURE__ */ jsx11(
|
|
744
|
+
AccordionMenu,
|
|
745
|
+
{
|
|
746
|
+
type: "single",
|
|
747
|
+
selectedValue: "menu-trigger",
|
|
748
|
+
defaultValue: "menu-trigger",
|
|
749
|
+
matchPath,
|
|
750
|
+
collapsible: true,
|
|
751
|
+
className: "space-y-7.5 px-2.5",
|
|
752
|
+
classNames: {
|
|
753
|
+
item: "h-8.5 px-2.5 text-sm font-normal text-foreground hover:text-primary data-[selected=true]:bg-muted data-[selected=true]:text-foreground [&[data-selected=true]_svg]:opacity-100",
|
|
754
|
+
subTrigger: "text-xs font-normal text-muted-foreground hover:bg-transparent",
|
|
755
|
+
subContent: "ps-0"
|
|
756
|
+
},
|
|
757
|
+
children: menu.map((item, index) => /* @__PURE__ */ jsxs9(AccordionMenuSub, { value: item.title || "menu", children: [
|
|
758
|
+
/* @__PURE__ */ jsxs9(AccordionMenuSubTrigger, { value: "menu-trigger", children: [
|
|
759
|
+
/* @__PURE__ */ jsx11("span", { children: item.title }),
|
|
760
|
+
/* @__PURE__ */ jsx11(AccordionMenuIndicator, {})
|
|
761
|
+
] }),
|
|
762
|
+
/* @__PURE__ */ jsx11(AccordionMenuSubContent, { type: "single", collapsible: true, parentValue: "menu-trigger", children: item.children?.map((child, idx) => {
|
|
763
|
+
const content = /* @__PURE__ */ jsxs9(Fragment4, { children: [
|
|
764
|
+
child.icon && /* @__PURE__ */ jsx11(child.icon, {}),
|
|
765
|
+
/* @__PURE__ */ jsx11("span", { children: child.title }),
|
|
766
|
+
child.badge && /* @__PURE__ */ jsx11(
|
|
767
|
+
Badge2,
|
|
768
|
+
{
|
|
769
|
+
size: "sm",
|
|
770
|
+
variant: child.badgeVariant ?? "destructive",
|
|
771
|
+
appearance: "light",
|
|
772
|
+
children: child.badge
|
|
773
|
+
}
|
|
774
|
+
)
|
|
775
|
+
] });
|
|
776
|
+
if (child.external && child.path) {
|
|
777
|
+
return /* @__PURE__ */ jsx11(
|
|
778
|
+
Link5,
|
|
779
|
+
{
|
|
780
|
+
href: child.path,
|
|
781
|
+
target: "_blank",
|
|
782
|
+
rel: "noopener noreferrer",
|
|
783
|
+
className: "relative flex h-8.5 w-full cursor-pointer select-none items-center gap-2 rounded-lg px-2.5 py-1.5 text-start font-normal text-foreground text-sm outline-hidden transition-colors hover:bg-accent hover:text-primary focus-visible:bg-accent focus-visible:text-accent-foreground disabled:bg-transparent disabled:opacity-50 data-[selected=true]:bg-muted data-[selected=true]:text-foreground [&[data-selected=true]_svg]:opacity-100 [&>a]:w-full [&>a]:items-center [&>a]:gap-2 [&_a]:flex [&_svg:not([class*=size-])]:size-4 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg]:opacity-60",
|
|
784
|
+
children: content
|
|
785
|
+
},
|
|
786
|
+
child.path || `ext-${idx}`
|
|
787
|
+
);
|
|
788
|
+
}
|
|
789
|
+
return /* @__PURE__ */ jsx11(AccordionMenuItem, { value: child.path || "#", children: /* @__PURE__ */ jsx11(Link5, { href: child.path || "#", children: content }) }, idx);
|
|
790
|
+
}) })
|
|
791
|
+
] }, index))
|
|
792
|
+
}
|
|
793
|
+
);
|
|
794
|
+
}
|
|
795
|
+
return /* @__PURE__ */ jsx11(
|
|
796
|
+
AccordionMenu,
|
|
797
|
+
{
|
|
798
|
+
type: "multiple",
|
|
799
|
+
selectedValue: pathname,
|
|
800
|
+
matchPath,
|
|
801
|
+
className: "space-y-7.5 px-2.5",
|
|
802
|
+
classNames: {
|
|
803
|
+
label: "text-xs font-normal text-muted-foreground mb-2",
|
|
804
|
+
item: "h-8.5 px-2.5 text-sm font-normal text-foreground hover:text-primary data-[selected=true]:bg-muted data-[selected=true]:font-medium data-[selected=true]:text-foreground [&[data-selected=true]_svg]:opacity-100",
|
|
805
|
+
group: ""
|
|
806
|
+
},
|
|
807
|
+
children: menu.map((item, index) => {
|
|
808
|
+
return /* @__PURE__ */ jsxs9(AccordionMenuGroup, { children: [
|
|
809
|
+
/* @__PURE__ */ jsx11(AccordionMenuLabel, { children: item.title }),
|
|
810
|
+
item.children?.map((child, idx) => {
|
|
811
|
+
const content = /* @__PURE__ */ jsxs9(Fragment4, { children: [
|
|
812
|
+
child.icon && /* @__PURE__ */ jsx11(child.icon, {}),
|
|
813
|
+
/* @__PURE__ */ jsx11("span", { children: child.title }),
|
|
814
|
+
child.badge && /* @__PURE__ */ jsx11(
|
|
815
|
+
Badge2,
|
|
816
|
+
{
|
|
817
|
+
size: "sm",
|
|
818
|
+
variant: child.badgeVariant ?? "destructive",
|
|
819
|
+
appearance: "light",
|
|
820
|
+
children: child.badge
|
|
821
|
+
}
|
|
822
|
+
)
|
|
823
|
+
] });
|
|
824
|
+
if (child.external && child.path) {
|
|
825
|
+
return /* @__PURE__ */ jsx11(
|
|
826
|
+
Link5,
|
|
827
|
+
{
|
|
828
|
+
href: child.path,
|
|
829
|
+
target: "_blank",
|
|
830
|
+
rel: "noopener noreferrer",
|
|
831
|
+
className: "relative flex h-8.5 w-full cursor-pointer select-none items-center gap-2 rounded-lg px-2.5 py-1.5 text-start font-normal text-foreground text-sm outline-hidden transition-colors hover:bg-accent hover:text-primary focus-visible:bg-accent focus-visible:text-accent-foreground disabled:bg-transparent disabled:opacity-50 data-[selected=true]:bg-muted data-[selected=true]:font-medium data-[selected=true]:text-foreground [&[data-selected=true]_svg]:opacity-100 [&>a]:w-full [&>a]:items-center [&>a]:gap-2 [&_a]:flex [&_svg:not([class*=size-])]:size-4 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg]:opacity-60",
|
|
832
|
+
children: content
|
|
833
|
+
},
|
|
834
|
+
child.path || `ext-${idx}`
|
|
835
|
+
);
|
|
836
|
+
}
|
|
837
|
+
return /* @__PURE__ */ jsx11(AccordionMenuItem, { value: child.path || "#", children: /* @__PURE__ */ jsx11(Link5, { href: child.path || "#", children: content }) }, idx);
|
|
838
|
+
})
|
|
839
|
+
] }, index);
|
|
840
|
+
})
|
|
841
|
+
}
|
|
842
|
+
);
|
|
843
|
+
}
|
|
844
|
+
|
|
845
|
+
// src/components/layouts/site-footer.tsx
|
|
846
|
+
import Link6 from "next/link";
|
|
847
|
+
import { useTranslations as useTranslations9 } from "next-intl";
|
|
848
|
+
import { useConfig as useConfig5 } from "@pelatform/starter.hook";
|
|
849
|
+
import { cn as cn5 } from "pelatform-ui";
|
|
850
|
+
import { SiteFooter as UISiteFooter } from "pelatform-ui/components";
|
|
851
|
+
import { Button as Button3 } from "pelatform-ui/default";
|
|
852
|
+
import { jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
853
|
+
function SiteFooter({ disableProjectBy = false }) {
|
|
854
|
+
const { app } = useConfig5();
|
|
855
|
+
const t = useTranslations9();
|
|
856
|
+
return /* @__PURE__ */ jsxs10(UISiteFooter, { className: cn5("*:gap-2! *:py-0!", disableProjectBy ? "*:justify-center!" : ""), children: [
|
|
857
|
+
/* @__PURE__ */ jsxs10("div", { className: "text-balance text-center text-muted-foreground text-sm leading-loose md:text-left", children: [
|
|
858
|
+
"\xA9 ",
|
|
859
|
+
(/* @__PURE__ */ new Date()).getFullYear(),
|
|
860
|
+
" ",
|
|
861
|
+
app.name,
|
|
862
|
+
". ",
|
|
863
|
+
t("ui.common.copyright")
|
|
864
|
+
] }),
|
|
865
|
+
!disableProjectBy && /* @__PURE__ */ jsx12("div", { className: "flex items-center gap-2.5 text-balance text-sm leading-loose", children: /* @__PURE__ */ jsxs10("div", { className: "inline-flex items-center gap-1", children: [
|
|
866
|
+
/* @__PURE__ */ jsx12("span", { className: "text-muted-foreground", children: t("ui.common.projectBy") }),
|
|
867
|
+
" ",
|
|
868
|
+
/* @__PURE__ */ jsx12(Button3, { mode: "link", underline: "dashed", children: /* @__PURE__ */ jsx12(
|
|
869
|
+
Link6,
|
|
870
|
+
{
|
|
871
|
+
href: "https://pelatform.com",
|
|
872
|
+
target: "_blank",
|
|
873
|
+
className: "font-medium text-foreground",
|
|
874
|
+
children: "Pelatform"
|
|
875
|
+
}
|
|
876
|
+
) })
|
|
877
|
+
] }) })
|
|
878
|
+
] });
|
|
879
|
+
}
|
|
880
|
+
|
|
881
|
+
// src/components/layouts/site-header.tsx
|
|
882
|
+
import { useState as useState3 } from "react";
|
|
883
|
+
import Link7 from "next/link";
|
|
884
|
+
import { usePathname as usePathname4, useRouter as useRouter3 } from "next/navigation";
|
|
885
|
+
import { useTranslations as useTranslations10 } from "next-intl";
|
|
886
|
+
import { useConfig as useConfig6, useSession as useSession4 } from "@pelatform/starter.hook";
|
|
887
|
+
import {
|
|
888
|
+
MainNav,
|
|
889
|
+
MobileNav,
|
|
890
|
+
MobileNavItemRenderer,
|
|
891
|
+
ModeSwitcher as ModeSwitcher3,
|
|
892
|
+
SiteHeader as UISiteHeader
|
|
893
|
+
} from "pelatform-ui/components";
|
|
894
|
+
import { Button as Button4, Separator } from "pelatform-ui/default";
|
|
895
|
+
import { jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
896
|
+
function SiteHeader({
|
|
897
|
+
menu,
|
|
898
|
+
logo = /* @__PURE__ */ jsx13(LogoWithHref, { href: "/home" })
|
|
899
|
+
}) {
|
|
900
|
+
const { path } = useConfig6();
|
|
901
|
+
const pathname = usePathname4();
|
|
902
|
+
const router = useRouter3();
|
|
903
|
+
const t = useTranslations10();
|
|
904
|
+
const { isPending, session, user } = useSession4();
|
|
905
|
+
const [, setMobileNavOpen] = useState3(false);
|
|
906
|
+
const isAuthenticated = !isPending && session && user;
|
|
907
|
+
return /* @__PURE__ */ jsxs11(UISiteHeader, { className: "backdrop-blur-none supports-backdrop-filter:bg-background", children: [
|
|
908
|
+
/* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-4.5", children: [
|
|
909
|
+
logo,
|
|
910
|
+
/* @__PURE__ */ jsx13(MainNav, { Link: Link7, pathname, items: menu })
|
|
911
|
+
] }),
|
|
912
|
+
/* @__PURE__ */ jsx13("div", { className: "flex items-center justify-end gap-3", children: /* @__PURE__ */ jsxs11("nav", { className: "flex items-center gap-0 md:gap-1", children: [
|
|
913
|
+
/* @__PURE__ */ jsx13(ModeSwitcher3, {}),
|
|
914
|
+
/* @__PURE__ */ jsx13(LanguageSwitcher, {}),
|
|
915
|
+
/* @__PURE__ */ jsx13(Separator, { orientation: "vertical", className: "mx-3 h-5 max-lg:hidden" }),
|
|
916
|
+
/* @__PURE__ */ jsx13(MobileNav, { children: /* @__PURE__ */ jsxs11("div", { className: "flex flex-col space-y-3", children: [
|
|
917
|
+
menu?.map(
|
|
918
|
+
(item, navIndex) => item.href || item.children ? /* @__PURE__ */ jsx13(
|
|
919
|
+
MobileNavItemRenderer,
|
|
920
|
+
{
|
|
921
|
+
item,
|
|
922
|
+
Link: Link7,
|
|
923
|
+
pathname,
|
|
924
|
+
level: 1,
|
|
925
|
+
onOpenChange: setMobileNavOpen
|
|
926
|
+
},
|
|
927
|
+
`nav-${navIndex}-${item.href}`
|
|
928
|
+
) : null
|
|
929
|
+
),
|
|
930
|
+
/* @__PURE__ */ jsx13("div", { className: "border-t pt-3", children: isAuthenticated ? /* @__PURE__ */ jsx13(
|
|
931
|
+
Button4,
|
|
932
|
+
{
|
|
933
|
+
variant: "outline",
|
|
934
|
+
size: "sm",
|
|
935
|
+
className: "w-full",
|
|
936
|
+
onClick: () => router.push(path.auth.SIGN_OUT),
|
|
937
|
+
children: t("ui.navigation.signOut")
|
|
938
|
+
}
|
|
939
|
+
) : /* @__PURE__ */ jsx13(Button4, { variant: "secondary", size: "sm", className: "w-full", children: /* @__PURE__ */ jsx13(Link7, { href: path.auth.SIGN_IN, children: t("ui.navigation.signIn") }) }) })
|
|
940
|
+
] }) }),
|
|
941
|
+
isAuthenticated ? /* @__PURE__ */ jsx13(UserMenu, { hiddenSwitcher: true }) : /* @__PURE__ */ jsx13(Button4, { variant: "secondary", size: "sm", className: "hidden md:flex", children: /* @__PURE__ */ jsx13(Link7, { href: path.auth.SIGN_IN, children: t("ui.navigation.signIn") }) })
|
|
942
|
+
] }) })
|
|
943
|
+
] });
|
|
944
|
+
}
|
|
945
|
+
function SiteHeaderSecondary({
|
|
946
|
+
menu,
|
|
947
|
+
logo = /* @__PURE__ */ jsx13(LogoWithHref, { href: "/home" }),
|
|
948
|
+
loginLink
|
|
949
|
+
}) {
|
|
950
|
+
const pathname = usePathname4();
|
|
951
|
+
const t = useTranslations10();
|
|
952
|
+
const [, setMobileNavOpen] = useState3(false);
|
|
953
|
+
return /* @__PURE__ */ jsxs11(UISiteHeader, { className: "backdrop-blur-none supports-backdrop-filter:bg-background", children: [
|
|
954
|
+
/* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-4.5", children: [
|
|
955
|
+
logo,
|
|
956
|
+
/* @__PURE__ */ jsx13(MainNav, { Link: Link7, pathname, items: menu })
|
|
957
|
+
] }),
|
|
958
|
+
/* @__PURE__ */ jsx13("div", { className: "flex items-center justify-end gap-3", children: /* @__PURE__ */ jsxs11("nav", { className: "flex items-center gap-0 md:gap-1", children: [
|
|
959
|
+
/* @__PURE__ */ jsx13(ModeSwitcher3, {}),
|
|
960
|
+
/* @__PURE__ */ jsx13(LanguageSwitcher, {}),
|
|
961
|
+
/* @__PURE__ */ jsx13(Separator, { orientation: "vertical", className: "mx-3 h-5 max-lg:hidden" }),
|
|
962
|
+
/* @__PURE__ */ jsx13(MobileNav, { children: /* @__PURE__ */ jsxs11("div", { className: "flex flex-col space-y-3", children: [
|
|
963
|
+
menu?.map(
|
|
964
|
+
(item, navIndex) => item.href || item.children ? /* @__PURE__ */ jsx13(
|
|
965
|
+
MobileNavItemRenderer,
|
|
966
|
+
{
|
|
967
|
+
item,
|
|
968
|
+
Link: Link7,
|
|
969
|
+
pathname,
|
|
970
|
+
level: 1,
|
|
971
|
+
onOpenChange: setMobileNavOpen
|
|
972
|
+
},
|
|
973
|
+
`nav-${navIndex}-${item.href}`
|
|
974
|
+
) : null
|
|
975
|
+
),
|
|
976
|
+
loginLink && /* @__PURE__ */ jsx13("div", { className: "border-t pt-3", children: /* @__PURE__ */ jsx13(Button4, { variant: "secondary", size: "sm", className: "w-full", children: /* @__PURE__ */ jsx13(Link7, { href: loginLink, children: t("ui.navigation.signIn") }) }) })
|
|
977
|
+
] }) }),
|
|
978
|
+
loginLink && /* @__PURE__ */ jsx13(Button4, { variant: "secondary", size: "sm", className: "hidden md:flex", children: /* @__PURE__ */ jsx13(Link7, { href: loginLink, children: t("ui.navigation.signIn") }) })
|
|
979
|
+
] }) })
|
|
980
|
+
] });
|
|
981
|
+
}
|
|
982
|
+
|
|
983
|
+
// src/components/providers/layout.tsx
|
|
984
|
+
import { useEffect as useEffect3, useState as useState4 } from "react";
|
|
985
|
+
import { LayoutContext } from "@pelatform/starter.hook";
|
|
986
|
+
import { cn as cn6 } from "pelatform-ui";
|
|
987
|
+
import { useIsMobile } from "pelatform-ui/hooks";
|
|
988
|
+
import { jsx as jsx14 } from "react/jsx-runtime";
|
|
989
|
+
var SIDEBAR_WIDTH = "240px";
|
|
990
|
+
var HEADER_HEIGHT = "54px";
|
|
991
|
+
var SIDEBAR_WIDTH_MOBILE = "240px";
|
|
992
|
+
var HEADER_HEIGHT_MOBILE = "54px";
|
|
993
|
+
function LayoutProvider({
|
|
994
|
+
children,
|
|
995
|
+
style: customStyle,
|
|
996
|
+
bodyClassName = "",
|
|
997
|
+
className = "",
|
|
998
|
+
logoHeader = /* @__PURE__ */ jsx14(LogoWithHref, {})
|
|
999
|
+
}) {
|
|
1000
|
+
const isMobile = useIsMobile();
|
|
1001
|
+
const [isSidebarOpen, setIsSidebarOpen] = useState4(true);
|
|
1002
|
+
const defaultStyle = {
|
|
1003
|
+
"--sidebar-width": SIDEBAR_WIDTH,
|
|
1004
|
+
"--header-height": HEADER_HEIGHT,
|
|
1005
|
+
"--sidebar-width-mobile": SIDEBAR_WIDTH_MOBILE,
|
|
1006
|
+
"--header-height-mobile": HEADER_HEIGHT_MOBILE
|
|
1007
|
+
};
|
|
1008
|
+
const style = {
|
|
1009
|
+
...defaultStyle,
|
|
1010
|
+
...customStyle
|
|
1011
|
+
};
|
|
1012
|
+
const sidebarToggle = () => setIsSidebarOpen((open) => !open);
|
|
1013
|
+
useEffect3(() => {
|
|
1014
|
+
if (bodyClassName) {
|
|
1015
|
+
const body = document.body;
|
|
1016
|
+
const existingClasses = body.className;
|
|
1017
|
+
body.className = `${existingClasses} ${bodyClassName}`.trim();
|
|
1018
|
+
return () => {
|
|
1019
|
+
body.className = existingClasses;
|
|
1020
|
+
};
|
|
1021
|
+
}
|
|
1022
|
+
}, [bodyClassName]);
|
|
1023
|
+
return /* @__PURE__ */ jsx14(
|
|
1024
|
+
LayoutContext.Provider,
|
|
1025
|
+
{
|
|
1026
|
+
value: {
|
|
1027
|
+
bodyClassName,
|
|
1028
|
+
style,
|
|
1029
|
+
isMobile,
|
|
1030
|
+
isSidebarOpen,
|
|
1031
|
+
sidebarToggle,
|
|
1032
|
+
logoHeader
|
|
1033
|
+
},
|
|
1034
|
+
children: /* @__PURE__ */ jsx14(
|
|
1035
|
+
"div",
|
|
1036
|
+
{
|
|
1037
|
+
"data-slot": "layout-wrapper",
|
|
1038
|
+
className: cn6("flex grow", className),
|
|
1039
|
+
"data-sidebar-open": isSidebarOpen,
|
|
1040
|
+
style,
|
|
1041
|
+
children
|
|
1042
|
+
}
|
|
1043
|
+
)
|
|
1044
|
+
}
|
|
1045
|
+
);
|
|
1046
|
+
}
|
|
1047
|
+
|
|
1048
|
+
// src/components/layouts/wrapper.tsx
|
|
1049
|
+
import { Fragment as Fragment5, jsx as jsx15, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
1050
|
+
function LayoutWrapper({
|
|
1051
|
+
children,
|
|
1052
|
+
sidebarHeader,
|
|
1053
|
+
sidebarMenu,
|
|
1054
|
+
logoHeader
|
|
1055
|
+
}) {
|
|
1056
|
+
const sidebarContent = /* @__PURE__ */ jsxs12(Fragment5, { children: [
|
|
1057
|
+
sidebarHeader,
|
|
1058
|
+
/* @__PURE__ */ jsx15(SidebarContent, { children: sidebarMenu })
|
|
1059
|
+
] });
|
|
1060
|
+
return /* @__PURE__ */ jsxs12(LayoutProvider, { logoHeader, children: [
|
|
1061
|
+
/* @__PURE__ */ jsxs12(Header, { children: [
|
|
1062
|
+
/* @__PURE__ */ jsx15(HeaderLeft, {}),
|
|
1063
|
+
/* @__PURE__ */ jsx15(HeaderRight, { sidebar: /* @__PURE__ */ jsx15(HeaderSidebarMobile, { children: sidebarContent }) })
|
|
1064
|
+
] }),
|
|
1065
|
+
/* @__PURE__ */ jsxs12("div", { className: "flex grow pt-(--header-height-mobile) lg:pt-(--header-height)", children: [
|
|
1066
|
+
/* @__PURE__ */ jsx15(Sidebar, { children: sidebarContent }),
|
|
1067
|
+
/* @__PURE__ */ jsx15("main", { className: "grow transition-all duration-300 lg:in-data-[sidebar-open=false]:ps-0 lg:ps-(--sidebar-width)", children })
|
|
1068
|
+
] })
|
|
1069
|
+
] });
|
|
1070
|
+
}
|
|
1071
|
+
|
|
1072
|
+
// src/components/providers/config.tsx
|
|
1073
|
+
import { useMemo as useMemo2 } from "react";
|
|
1074
|
+
import { defaultConfig, mergeConfig } from "@pelatform/starter.config";
|
|
1075
|
+
import {
|
|
1076
|
+
ConfigContext,
|
|
1077
|
+
defaultAuthQueryOptions,
|
|
1078
|
+
QueryContext
|
|
1079
|
+
} from "@pelatform/starter.hook";
|
|
1080
|
+
import { jsx as jsx16 } from "react/jsx-runtime";
|
|
1081
|
+
function ConfigProvider({ config, authClient, children, ...props }) {
|
|
1082
|
+
const mergedConfig = useMemo2(() => {
|
|
1083
|
+
return mergeConfig(defaultConfig, config);
|
|
1084
|
+
}, [config]);
|
|
1085
|
+
const configWithAuth = {
|
|
1086
|
+
...mergedConfig,
|
|
1087
|
+
authClient
|
|
1088
|
+
};
|
|
1089
|
+
return /* @__PURE__ */ jsx16(
|
|
1090
|
+
QueryContext.Provider,
|
|
1091
|
+
{
|
|
1092
|
+
value: {
|
|
1093
|
+
...defaultAuthQueryOptions,
|
|
1094
|
+
...props
|
|
1095
|
+
},
|
|
1096
|
+
children: /* @__PURE__ */ jsx16(ConfigContext.Provider, { value: configWithAuth, children })
|
|
1097
|
+
}
|
|
1098
|
+
);
|
|
1099
|
+
}
|
|
1100
|
+
|
|
1101
|
+
// src/components/providers/shared.tsx
|
|
1102
|
+
import { Suspense as Suspense2 } from "react";
|
|
1103
|
+
import { ReactQueryDevtools } from "@tanstack/react-query-devtools";
|
|
1104
|
+
import { NextIntlClientProvider } from "next-intl";
|
|
1105
|
+
import { useConfig as useConfig7 } from "@pelatform/starter.hook";
|
|
1106
|
+
import { QueryProvider, ThemeProvider } from "pelatform-ui/components";
|
|
1107
|
+
import { Toaster as Sonner } from "pelatform-ui/default";
|
|
1108
|
+
import { jsx as jsx17, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
1109
|
+
function SharedProviders({
|
|
1110
|
+
children,
|
|
1111
|
+
locale,
|
|
1112
|
+
messages,
|
|
1113
|
+
timeZone = "Asia/Jakarta",
|
|
1114
|
+
sonnerPosition = "top-center"
|
|
1115
|
+
}) {
|
|
1116
|
+
const config = useConfig7();
|
|
1117
|
+
return /* @__PURE__ */ jsxs13(QueryProvider, { children: [
|
|
1118
|
+
/* @__PURE__ */ jsx17(ThemeProvider, { defaultTheme: config.ui.defaultTheme, children: /* @__PURE__ */ jsx17(NextIntlClientProvider, { locale, messages, timeZone, children: /* @__PURE__ */ jsxs13(Suspense2, { children: [
|
|
1119
|
+
children,
|
|
1120
|
+
/* @__PURE__ */ jsx17(Sonner, { position: sonnerPosition })
|
|
1121
|
+
] }) }) }),
|
|
1122
|
+
/* @__PURE__ */ jsx17(ReactQueryDevtools, { initialIsOpen: false })
|
|
1123
|
+
] });
|
|
1124
|
+
}
|
|
1125
|
+
|
|
3
1126
|
// src/components/utils/card.tsx
|
|
4
1127
|
import { useFormState } from "react-hook-form";
|
|
5
|
-
import { cn } from "pelatform-ui";
|
|
6
|
-
import { Button, Card, CardContent, CardFooter, Skeleton, Spinner } from "pelatform-ui/default";
|
|
7
|
-
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
1128
|
+
import { cn as cn7 } from "pelatform-ui";
|
|
1129
|
+
import { Button as Button5, Card, CardContent, CardFooter, Skeleton as Skeleton4, Spinner } from "pelatform-ui/default";
|
|
1130
|
+
import { Fragment as Fragment6, jsx as jsx18, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
8
1131
|
function CardComponent({
|
|
9
1132
|
children,
|
|
10
1133
|
className,
|
|
@@ -20,10 +1143,10 @@ function CardComponent({
|
|
|
20
1143
|
isSubmitting,
|
|
21
1144
|
...props
|
|
22
1145
|
}) {
|
|
23
|
-
return /* @__PURE__ */
|
|
1146
|
+
return /* @__PURE__ */ jsxs14(
|
|
24
1147
|
Card,
|
|
25
1148
|
{
|
|
26
|
-
className:
|
|
1149
|
+
className: cn7(
|
|
27
1150
|
"w-full overflow-hidden",
|
|
28
1151
|
isDestructive && "border-destructive/70",
|
|
29
1152
|
className,
|
|
@@ -31,8 +1154,8 @@ function CardComponent({
|
|
|
31
1154
|
),
|
|
32
1155
|
...props,
|
|
33
1156
|
children: [
|
|
34
|
-
/* @__PURE__ */
|
|
35
|
-
/* @__PURE__ */
|
|
1157
|
+
/* @__PURE__ */ jsxs14(CardContent, { className: cn7("space-y-6 p-5 sm:p-10", classNames?.content), children: [
|
|
1158
|
+
/* @__PURE__ */ jsx18(
|
|
36
1159
|
CardHeaderComponent,
|
|
37
1160
|
{
|
|
38
1161
|
classNames,
|
|
@@ -43,7 +1166,7 @@ function CardComponent({
|
|
|
43
1166
|
),
|
|
44
1167
|
children
|
|
45
1168
|
] }),
|
|
46
|
-
/* @__PURE__ */
|
|
1169
|
+
/* @__PURE__ */ jsx18(
|
|
47
1170
|
CardFooterComponent,
|
|
48
1171
|
{
|
|
49
1172
|
classNames,
|
|
@@ -67,12 +1190,12 @@ function CardHeaderComponent({
|
|
|
67
1190
|
description,
|
|
68
1191
|
isPending
|
|
69
1192
|
}) {
|
|
70
|
-
return /* @__PURE__ */
|
|
71
|
-
/* @__PURE__ */
|
|
72
|
-
description && /* @__PURE__ */
|
|
73
|
-
] }) : /* @__PURE__ */
|
|
74
|
-
/* @__PURE__ */
|
|
75
|
-
description && /* @__PURE__ */
|
|
1193
|
+
return /* @__PURE__ */ jsx18("div", { className: cn7("flex flex-col space-y-2", className, classNames?.header), children: isPending ? /* @__PURE__ */ jsxs14(Fragment6, { children: [
|
|
1194
|
+
/* @__PURE__ */ jsx18(Skeleton4, { className: cn7("h-7 w-1/3", classNames?.skeleton) }),
|
|
1195
|
+
description && /* @__PURE__ */ jsx18(Skeleton4, { className: cn7("h-5 w-2/3", classNames?.skeleton) })
|
|
1196
|
+
] }) : /* @__PURE__ */ jsxs14(Fragment6, { children: [
|
|
1197
|
+
/* @__PURE__ */ jsx18("h2", { className: cn7("font-medium text-xl", classNames?.title), children: title }),
|
|
1198
|
+
description && /* @__PURE__ */ jsx18("p", { className: cn7("text-muted-foreground text-sm", classNames?.description), children: description })
|
|
76
1199
|
] }) });
|
|
77
1200
|
}
|
|
78
1201
|
function CardFooterComponent({
|
|
@@ -86,40 +1209,40 @@ function CardFooterComponent({
|
|
|
86
1209
|
isPending,
|
|
87
1210
|
isSubmitting
|
|
88
1211
|
}) {
|
|
89
|
-
return /* @__PURE__ */
|
|
1212
|
+
return /* @__PURE__ */ jsx18(
|
|
90
1213
|
CardFooter,
|
|
91
1214
|
{
|
|
92
|
-
className:
|
|
1215
|
+
className: cn7(
|
|
93
1216
|
"flex items-center justify-between space-x-4 bg-muted p-3 sm:px-10",
|
|
94
1217
|
isDestructive && "border-destructive/70",
|
|
95
1218
|
className,
|
|
96
1219
|
classNames?.footer
|
|
97
1220
|
),
|
|
98
|
-
children: isPending ? /* @__PURE__ */
|
|
99
|
-
instructions && /* @__PURE__ */
|
|
100
|
-
|
|
1221
|
+
children: isPending ? /* @__PURE__ */ jsxs14(Fragment6, { children: [
|
|
1222
|
+
instructions && /* @__PURE__ */ jsx18(
|
|
1223
|
+
Skeleton4,
|
|
101
1224
|
{
|
|
102
|
-
className:
|
|
1225
|
+
className: cn7(
|
|
103
1226
|
"h-4 w-48 max-w-full bg-muted-foreground/10 md:h-5 md:w-60",
|
|
104
1227
|
classNames?.skeleton
|
|
105
1228
|
)
|
|
106
1229
|
}
|
|
107
1230
|
),
|
|
108
|
-
actionLabel && /* @__PURE__ */
|
|
109
|
-
|
|
1231
|
+
actionLabel && /* @__PURE__ */ jsx18(
|
|
1232
|
+
Skeleton4,
|
|
110
1233
|
{
|
|
111
|
-
className:
|
|
1234
|
+
className: cn7("h-8 w-20 bg-muted-foreground/10 md:ms-auto", classNames?.skeleton)
|
|
112
1235
|
}
|
|
113
1236
|
)
|
|
114
|
-
] }) : /* @__PURE__ */
|
|
115
|
-
instructions && /* @__PURE__ */
|
|
1237
|
+
] }) : /* @__PURE__ */ jsxs14(Fragment6, { children: [
|
|
1238
|
+
instructions && /* @__PURE__ */ jsx18(
|
|
116
1239
|
"div",
|
|
117
1240
|
{
|
|
118
|
-
className:
|
|
1241
|
+
className: cn7("text-muted-foreground text-xs md:text-sm", classNames?.instructions),
|
|
119
1242
|
children: instructions
|
|
120
1243
|
}
|
|
121
1244
|
),
|
|
122
|
-
actionLabel && /* @__PURE__ */
|
|
1245
|
+
actionLabel && /* @__PURE__ */ jsx18(
|
|
123
1246
|
CardActionComponent,
|
|
124
1247
|
{
|
|
125
1248
|
classNames,
|
|
@@ -147,13 +1270,13 @@ function CardActionComponent({
|
|
|
147
1270
|
const formState = useFormState();
|
|
148
1271
|
isSubmitting = formState.isSubmitting;
|
|
149
1272
|
}
|
|
150
|
-
return /* @__PURE__ */
|
|
151
|
-
|
|
1273
|
+
return /* @__PURE__ */ jsxs14(
|
|
1274
|
+
Button5,
|
|
152
1275
|
{
|
|
153
1276
|
type: onClick ? "button" : "submit",
|
|
154
1277
|
variant: isDestructive ? "destructive" : "primary",
|
|
155
1278
|
size: "sm",
|
|
156
|
-
className:
|
|
1279
|
+
className: cn7(
|
|
157
1280
|
"ms-auto",
|
|
158
1281
|
isSubmitting || disabled ? "pointer-events-auto! cursor-not-allowed" : "",
|
|
159
1282
|
classNames?.button,
|
|
@@ -163,7 +1286,7 @@ function CardActionComponent({
|
|
|
163
1286
|
disabled: isSubmitting || disabled,
|
|
164
1287
|
...props,
|
|
165
1288
|
children: [
|
|
166
|
-
isSubmitting && /* @__PURE__ */
|
|
1289
|
+
isSubmitting && /* @__PURE__ */ jsx18(Spinner, {}),
|
|
167
1290
|
actionLabel
|
|
168
1291
|
]
|
|
169
1292
|
}
|
|
@@ -171,10 +1294,10 @@ function CardActionComponent({
|
|
|
171
1294
|
}
|
|
172
1295
|
|
|
173
1296
|
// src/components/utils/dialog.tsx
|
|
174
|
-
import { useTranslations } from "next-intl";
|
|
175
|
-
import { cn as
|
|
1297
|
+
import { useTranslations as useTranslations11 } from "next-intl";
|
|
1298
|
+
import { cn as cn8 } from "pelatform-ui";
|
|
176
1299
|
import {
|
|
177
|
-
Button as
|
|
1300
|
+
Button as Button6,
|
|
178
1301
|
Dialog,
|
|
179
1302
|
DialogContent,
|
|
180
1303
|
DialogDescription,
|
|
@@ -182,7 +1305,7 @@ import {
|
|
|
182
1305
|
DialogHeader,
|
|
183
1306
|
DialogTitle
|
|
184
1307
|
} from "pelatform-ui/default";
|
|
185
|
-
import { jsx as
|
|
1308
|
+
import { jsx as jsx19, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
186
1309
|
function DialogComponent({
|
|
187
1310
|
children,
|
|
188
1311
|
classNames,
|
|
@@ -195,18 +1318,18 @@ function DialogComponent({
|
|
|
195
1318
|
button,
|
|
196
1319
|
...props
|
|
197
1320
|
}) {
|
|
198
|
-
return /* @__PURE__ */
|
|
1321
|
+
return /* @__PURE__ */ jsx19(Dialog, { onOpenChange, ...props, children: /* @__PURE__ */ jsxs15(
|
|
199
1322
|
DialogContent,
|
|
200
1323
|
{
|
|
201
1324
|
onOpenAutoFocus: (e) => e.preventDefault(),
|
|
202
1325
|
className: classNames?.dialog?.content,
|
|
203
1326
|
children: [
|
|
204
|
-
/* @__PURE__ */
|
|
205
|
-
/* @__PURE__ */
|
|
206
|
-
description && /* @__PURE__ */
|
|
1327
|
+
/* @__PURE__ */ jsxs15(DialogHeader, { className: cn8("space-y-2", classNames?.header), children: [
|
|
1328
|
+
/* @__PURE__ */ jsx19(DialogTitle, { className: classNames?.title, children: title }),
|
|
1329
|
+
description && /* @__PURE__ */ jsx19(DialogDescription, { className: classNames?.description, children: description })
|
|
207
1330
|
] }),
|
|
208
1331
|
children,
|
|
209
|
-
!disableFooter && /* @__PURE__ */
|
|
1332
|
+
!disableFooter && /* @__PURE__ */ jsx19(
|
|
210
1333
|
DialogFooterComponent,
|
|
211
1334
|
{
|
|
212
1335
|
classNames,
|
|
@@ -228,14 +1351,14 @@ function DialogFooterComponent({
|
|
|
228
1351
|
cancelButtonDisabled,
|
|
229
1352
|
button
|
|
230
1353
|
}) {
|
|
231
|
-
const t =
|
|
232
|
-
return /* @__PURE__ */
|
|
233
|
-
cancelButton && /* @__PURE__ */
|
|
234
|
-
|
|
1354
|
+
const t = useTranslations11();
|
|
1355
|
+
return /* @__PURE__ */ jsxs15(DialogFooter, { className: cn8(className, classNames?.dialog?.footer), children: [
|
|
1356
|
+
cancelButton && /* @__PURE__ */ jsx19(
|
|
1357
|
+
Button6,
|
|
235
1358
|
{
|
|
236
1359
|
type: "button",
|
|
237
1360
|
variant: "secondary",
|
|
238
|
-
className:
|
|
1361
|
+
className: cn8(classNames?.button, classNames?.secondaryButton),
|
|
239
1362
|
onClick: () => onOpenChange?.(false),
|
|
240
1363
|
disabled: cancelButtonDisabled,
|
|
241
1364
|
children: t("common.actions.cancel")
|
|
@@ -246,154 +1369,41 @@ function DialogFooterComponent({
|
|
|
246
1369
|
}
|
|
247
1370
|
|
|
248
1371
|
// src/components/utils/skeleton.tsx
|
|
249
|
-
import { cn as
|
|
250
|
-
import { Card as Card2, Skeleton as
|
|
251
|
-
import { jsx as
|
|
1372
|
+
import { cn as cn9 } from "pelatform-ui";
|
|
1373
|
+
import { Card as Card2, Skeleton as Skeleton5 } from "pelatform-ui/default";
|
|
1374
|
+
import { jsx as jsx20, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
252
1375
|
function SkeletonViewComponent({ classNames }) {
|
|
253
|
-
return /* @__PURE__ */
|
|
254
|
-
/* @__PURE__ */
|
|
255
|
-
/* @__PURE__ */
|
|
256
|
-
/* @__PURE__ */
|
|
1376
|
+
return /* @__PURE__ */ jsxs16(Card2, { className: cn9("flex-row items-center gap-3 px-4 py-3", classNames?.cell), children: [
|
|
1377
|
+
/* @__PURE__ */ jsxs16("div", { className: "flex items-center gap-2", children: [
|
|
1378
|
+
/* @__PURE__ */ jsx20(Skeleton5, { className: cn9("size-5 rounded-full", classNames?.skeleton) }),
|
|
1379
|
+
/* @__PURE__ */ jsx20("div", { children: /* @__PURE__ */ jsx20(Skeleton5, { className: cn9("h-4 w-32", classNames?.skeleton) }) })
|
|
257
1380
|
] }),
|
|
258
|
-
/* @__PURE__ */
|
|
1381
|
+
/* @__PURE__ */ jsx20(Skeleton5, { className: cn9("ms-auto size-8 w-16", classNames?.skeleton) })
|
|
259
1382
|
] });
|
|
260
1383
|
}
|
|
261
1384
|
function SkeletonInputComponent({ classNames }) {
|
|
262
|
-
return /* @__PURE__ */
|
|
263
|
-
/* @__PURE__ */
|
|
264
|
-
/* @__PURE__ */
|
|
1385
|
+
return /* @__PURE__ */ jsxs16("div", { className: "flex flex-col gap-1.5", children: [
|
|
1386
|
+
/* @__PURE__ */ jsx20(Skeleton5, { className: cn9("h-4 w-32", classNames?.skeleton) }),
|
|
1387
|
+
/* @__PURE__ */ jsx20(Skeleton5, { className: cn9("h-9 w-full", classNames?.skeleton) })
|
|
265
1388
|
] });
|
|
266
1389
|
}
|
|
267
1390
|
|
|
268
|
-
// src/components/avatar.tsx
|
|
269
|
-
import { BuildingIcon, UserRoundIcon } from "lucide-react";
|
|
270
|
-
import { useTranslations as useTranslations2 } from "next-intl";
|
|
271
|
-
import { getSizeAvatar, getUserName } from "@pelatform/starter.utils";
|
|
272
|
-
import { cn as cn4 } from "pelatform-ui";
|
|
273
|
-
import { getInitials } from "pelatform-ui/components";
|
|
274
|
-
import { Avatar, AvatarFallback, AvatarImage, Skeleton as Skeleton3 } from "pelatform-ui/default";
|
|
275
|
-
import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
276
|
-
function UserAvatar({
|
|
277
|
-
className,
|
|
278
|
-
classNames,
|
|
279
|
-
image,
|
|
280
|
-
isPending,
|
|
281
|
-
size,
|
|
282
|
-
user,
|
|
283
|
-
...props
|
|
284
|
-
}) {
|
|
285
|
-
const t = useTranslations2();
|
|
286
|
-
const name = getUserName(user);
|
|
287
|
-
const src = user?.image;
|
|
288
|
-
if (isPending) {
|
|
289
|
-
return /* @__PURE__ */ jsx4(
|
|
290
|
-
Skeleton3,
|
|
291
|
-
{
|
|
292
|
-
className: cn4(
|
|
293
|
-
"shrink-0 rounded-full",
|
|
294
|
-
getSizeAvatar(size),
|
|
295
|
-
className,
|
|
296
|
-
classNames?.base,
|
|
297
|
-
classNames?.skeleton
|
|
298
|
-
)
|
|
299
|
-
}
|
|
300
|
-
);
|
|
301
|
-
}
|
|
302
|
-
return /* @__PURE__ */ jsxs4(
|
|
303
|
-
Avatar,
|
|
304
|
-
{
|
|
305
|
-
className: cn4("rounded-full bg-accent", getSizeAvatar(size), className, classNames?.base),
|
|
306
|
-
...props,
|
|
307
|
-
children: [
|
|
308
|
-
/* @__PURE__ */ jsx4(
|
|
309
|
-
AvatarImage,
|
|
310
|
-
{
|
|
311
|
-
src: image || src || void 0,
|
|
312
|
-
alt: name || t("ui.navigation.user"),
|
|
313
|
-
className: classNames?.image
|
|
314
|
-
}
|
|
315
|
-
),
|
|
316
|
-
/* @__PURE__ */ jsx4(
|
|
317
|
-
AvatarFallback,
|
|
318
|
-
{
|
|
319
|
-
className: cn4("text-foreground uppercase", classNames?.fallback),
|
|
320
|
-
delayMs: src ? 600 : void 0,
|
|
321
|
-
children: getInitials(name, 2) || /* @__PURE__ */ jsx4(UserRoundIcon, { className: cn4("size-[50%]", classNames?.fallbackIcon) })
|
|
322
|
-
}
|
|
323
|
-
)
|
|
324
|
-
]
|
|
325
|
-
}
|
|
326
|
-
);
|
|
327
|
-
}
|
|
328
|
-
function WorkspaceLogo({
|
|
329
|
-
className,
|
|
330
|
-
classNames,
|
|
331
|
-
image,
|
|
332
|
-
isPending,
|
|
333
|
-
size,
|
|
334
|
-
workspace,
|
|
335
|
-
...props
|
|
336
|
-
}) {
|
|
337
|
-
const t = useTranslations2();
|
|
338
|
-
const name = workspace?.name;
|
|
339
|
-
const src = workspace?.logo;
|
|
340
|
-
if (isPending) {
|
|
341
|
-
return /* @__PURE__ */ jsx4(
|
|
342
|
-
Skeleton3,
|
|
343
|
-
{
|
|
344
|
-
className: cn4(
|
|
345
|
-
"shrink-0 rounded-full",
|
|
346
|
-
getSizeAvatar(size),
|
|
347
|
-
className,
|
|
348
|
-
classNames?.base,
|
|
349
|
-
classNames?.skeleton
|
|
350
|
-
)
|
|
351
|
-
}
|
|
352
|
-
);
|
|
353
|
-
}
|
|
354
|
-
return /* @__PURE__ */ jsxs4(
|
|
355
|
-
Avatar,
|
|
356
|
-
{
|
|
357
|
-
className: cn4("rounded-full bg-accent", getSizeAvatar(size), className, classNames?.base),
|
|
358
|
-
...props,
|
|
359
|
-
children: [
|
|
360
|
-
/* @__PURE__ */ jsx4(
|
|
361
|
-
AvatarImage,
|
|
362
|
-
{
|
|
363
|
-
src: image || src || void 0,
|
|
364
|
-
alt: name || t("ui.navigation.workspace"),
|
|
365
|
-
className: classNames?.image
|
|
366
|
-
}
|
|
367
|
-
),
|
|
368
|
-
/* @__PURE__ */ jsx4(
|
|
369
|
-
AvatarFallback,
|
|
370
|
-
{
|
|
371
|
-
className: cn4("text-foreground", classNames?.fallback),
|
|
372
|
-
delayMs: src ? 600 : void 0,
|
|
373
|
-
children: /* @__PURE__ */ jsx4(BuildingIcon, { className: cn4("size-[50%]", classNames?.fallbackIcon) })
|
|
374
|
-
}
|
|
375
|
-
)
|
|
376
|
-
]
|
|
377
|
-
}
|
|
378
|
-
);
|
|
379
|
-
}
|
|
380
|
-
|
|
381
1391
|
// src/components/display-id.tsx
|
|
382
1392
|
import { useRef } from "react";
|
|
383
1393
|
import { CheckIcon, CopyIcon } from "lucide-react";
|
|
384
|
-
import { useTranslations as
|
|
385
|
-
import { cn as
|
|
1394
|
+
import { useTranslations as useTranslations12 } from "next-intl";
|
|
1395
|
+
import { cn as cn10 } from "pelatform-ui";
|
|
386
1396
|
import {
|
|
387
|
-
Button as
|
|
1397
|
+
Button as Button7,
|
|
388
1398
|
Input,
|
|
389
|
-
Skeleton as
|
|
1399
|
+
Skeleton as Skeleton6,
|
|
390
1400
|
Tooltip,
|
|
391
1401
|
TooltipContent,
|
|
392
1402
|
TooltipProvider,
|
|
393
1403
|
TooltipTrigger
|
|
394
1404
|
} from "pelatform-ui/default";
|
|
395
1405
|
import { useCopyToClipboard } from "pelatform-ui/hooks";
|
|
396
|
-
import { jsx as
|
|
1406
|
+
import { jsx as jsx21, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
397
1407
|
function DisplayIdCard({
|
|
398
1408
|
className,
|
|
399
1409
|
classNames,
|
|
@@ -403,7 +1413,7 @@ function DisplayIdCard({
|
|
|
403
1413
|
description,
|
|
404
1414
|
...props
|
|
405
1415
|
}) {
|
|
406
|
-
const t =
|
|
1416
|
+
const t = useTranslations12();
|
|
407
1417
|
const { copy, copied } = useCopyToClipboard();
|
|
408
1418
|
const inputRef = useRef(null);
|
|
409
1419
|
const handleCopy = () => {
|
|
@@ -411,209 +1421,125 @@ function DisplayIdCard({
|
|
|
411
1421
|
copy(inputRef.current.value);
|
|
412
1422
|
}
|
|
413
1423
|
};
|
|
414
|
-
return /* @__PURE__ */
|
|
1424
|
+
return /* @__PURE__ */ jsx21(
|
|
415
1425
|
CardComponent,
|
|
416
|
-
{
|
|
417
|
-
className,
|
|
418
|
-
classNames,
|
|
419
|
-
title,
|
|
420
|
-
description,
|
|
421
|
-
isPending,
|
|
422
|
-
...props,
|
|
423
|
-
children: isPending ? /* @__PURE__ */
|
|
424
|
-
"div",
|
|
425
|
-
{
|
|
426
|
-
className:
|
|
427
|
-
"flex w-full max-w-md items-center justify-between rounded-md border p-2",
|
|
428
|
-
classNames?.grid
|
|
429
|
-
),
|
|
430
|
-
children: [
|
|
431
|
-
/* @__PURE__ */
|
|
432
|
-
/* @__PURE__ */
|
|
433
|
-
/* @__PURE__ */
|
|
434
|
-
/* @__PURE__ */
|
|
435
|
-
] }) })
|
|
436
|
-
]
|
|
437
|
-
}
|
|
438
|
-
)
|
|
439
|
-
}
|
|
440
|
-
);
|
|
441
|
-
}
|
|
442
|
-
|
|
443
|
-
// src/components/empty-state.tsx
|
|
444
|
-
import Link from "next/link";
|
|
445
|
-
import { useTranslations as useTranslations4 } from "next-intl";
|
|
446
|
-
import { cn as cn6 } from "pelatform-ui";
|
|
447
|
-
import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
448
|
-
function EmptyState({
|
|
449
|
-
className,
|
|
450
|
-
icon: Icon,
|
|
451
|
-
title,
|
|
452
|
-
description,
|
|
453
|
-
learnMore,
|
|
454
|
-
learnMoreText,
|
|
455
|
-
children
|
|
456
|
-
}) {
|
|
457
|
-
const t = useTranslations4();
|
|
458
|
-
return /* @__PURE__ */ jsxs6("div", { className: cn6("flex flex-col items-center justify-center gap-y-4", className), children: [
|
|
459
|
-
Icon && /* @__PURE__ */ jsx6("div", { className: "flex size-14 items-center justify-center rounded-2xl border bg-muted", children: /* @__PURE__ */ jsx6(Icon, { className: "size-6 text-foreground" }) }),
|
|
460
|
-
/* @__PURE__ */ jsx6("p", { className: "text-center font-medium text-base text-foreground", children: title }),
|
|
461
|
-
description && /* @__PURE__ */ jsxs6("p", { className: "max-w-sm text-balance text-center text-muted-foreground text-sm", children: [
|
|
462
|
-
description,
|
|
463
|
-
" ",
|
|
464
|
-
learnMore && /* @__PURE__ */ jsxs6(
|
|
465
|
-
Link,
|
|
466
|
-
{
|
|
467
|
-
href: learnMore,
|
|
468
|
-
className: "text-foreground underline underline-offset-2 transition-colors hover:text-primary",
|
|
469
|
-
children: [
|
|
470
|
-
learnMoreText ?? t("ui.common.learnMore"),
|
|
471
|
-
" \u2197"
|
|
472
|
-
]
|
|
473
|
-
}
|
|
474
|
-
)
|
|
475
|
-
] }),
|
|
476
|
-
children
|
|
477
|
-
] });
|
|
478
|
-
}
|
|
479
|
-
|
|
480
|
-
// src/components/language-switcher.tsx
|
|
481
|
-
import Image from "next/image";
|
|
482
|
-
import { useRouter } from "next/navigation";
|
|
483
|
-
import { useLocale, useTranslations as useTranslations5 } from "next-intl";
|
|
484
|
-
import { useConfig } from "@pelatform/starter.hook";
|
|
485
|
-
import {
|
|
486
|
-
LanguageSwitcher as LanguageSwitcherBase
|
|
487
|
-
} from "pelatform-ui/components";
|
|
488
|
-
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
489
|
-
function LanguageSwitcher({
|
|
490
|
-
className,
|
|
491
|
-
type,
|
|
492
|
-
variant,
|
|
493
|
-
size,
|
|
494
|
-
showNames,
|
|
495
|
-
showFlags
|
|
496
|
-
}) {
|
|
497
|
-
const { i18n } = useConfig();
|
|
498
|
-
const router = useRouter();
|
|
499
|
-
const t = useTranslations5();
|
|
500
|
-
const currentLocale = useLocale();
|
|
501
|
-
const availableLocales = (() => {
|
|
502
|
-
if (!i18n.enabled) {
|
|
503
|
-
return [i18n.defaultLocale];
|
|
504
|
-
}
|
|
505
|
-
const availableLocales2 = Object.keys(i18n.locales);
|
|
506
|
-
return availableLocales2;
|
|
507
|
-
})();
|
|
508
|
-
const languages = availableLocales.map((locale) => {
|
|
509
|
-
const localeConfig = i18n.locales[locale] || null;
|
|
510
|
-
return {
|
|
511
|
-
code: locale,
|
|
512
|
-
name: localeConfig?.name || locale.toUpperCase(),
|
|
513
|
-
flag: `/flags/${localeConfig?.flag}.svg` || ""
|
|
514
|
-
};
|
|
515
|
-
});
|
|
516
|
-
function handleLanguageChange(newLocale) {
|
|
517
|
-
if (newLocale === currentLocale) {
|
|
518
|
-
return;
|
|
519
|
-
}
|
|
520
|
-
document.cookie = `${i18n.localeCookieName}=${newLocale}; max-age=${60 * 60 * 24 * 365}; path=/`;
|
|
521
|
-
router.refresh();
|
|
522
|
-
}
|
|
523
|
-
return /* @__PURE__ */ jsx7(
|
|
524
|
-
LanguageSwitcherBase,
|
|
525
|
-
{
|
|
526
|
-
className,
|
|
527
|
-
type,
|
|
528
|
-
variant,
|
|
529
|
-
size,
|
|
530
|
-
showNames,
|
|
531
|
-
showFlags,
|
|
532
|
-
label: t("ui.common.language"),
|
|
533
|
-
i18nEnabled: i18n.enabled,
|
|
534
|
-
currentLocale,
|
|
535
|
-
locales: languages,
|
|
536
|
-
onLocaleChange: handleLanguageChange,
|
|
537
|
-
customFlagUrl: true,
|
|
538
|
-
Image
|
|
1426
|
+
{
|
|
1427
|
+
className,
|
|
1428
|
+
classNames,
|
|
1429
|
+
title,
|
|
1430
|
+
description,
|
|
1431
|
+
isPending,
|
|
1432
|
+
...props,
|
|
1433
|
+
children: isPending ? /* @__PURE__ */ jsx21(Skeleton6, { className: cn10("h-11.5 w-full max-w-md", classNames?.skeleton) }) : /* @__PURE__ */ jsxs17(
|
|
1434
|
+
"div",
|
|
1435
|
+
{
|
|
1436
|
+
className: cn10(
|
|
1437
|
+
"flex w-full max-w-md items-center justify-between rounded-md border p-2",
|
|
1438
|
+
classNames?.grid
|
|
1439
|
+
),
|
|
1440
|
+
children: [
|
|
1441
|
+
/* @__PURE__ */ jsx21(Input, { value: id, ref: inputRef, disabled: true, className: "border-none! bg-transparent!" }),
|
|
1442
|
+
/* @__PURE__ */ jsx21(TooltipProvider, { delayDuration: 0, children: /* @__PURE__ */ jsxs17(Tooltip, { children: [
|
|
1443
|
+
/* @__PURE__ */ jsx21(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx21(Button7, { variant: "dim", onClick: handleCopy, disabled: copied, children: copied ? /* @__PURE__ */ jsx21(CheckIcon, { className: cn10("stroke-green-600", classNames?.icon) }) : /* @__PURE__ */ jsx21(CopyIcon, { className: classNames?.icon }) }) }),
|
|
1444
|
+
/* @__PURE__ */ jsx21(TooltipContent, { className: "px-2 py-1 text-xs", children: t("common.actions.copy") })
|
|
1445
|
+
] }) })
|
|
1446
|
+
]
|
|
1447
|
+
}
|
|
1448
|
+
)
|
|
539
1449
|
}
|
|
540
1450
|
);
|
|
541
1451
|
}
|
|
542
1452
|
|
|
543
|
-
// src/components/
|
|
544
|
-
import
|
|
545
|
-
import {
|
|
546
|
-
import { cn as
|
|
547
|
-
import {
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
const
|
|
558
|
-
return /* @__PURE__ */
|
|
559
|
-
/* @__PURE__ */
|
|
560
|
-
/* @__PURE__ */
|
|
1453
|
+
// src/components/empty-state.tsx
|
|
1454
|
+
import Link8 from "next/link";
|
|
1455
|
+
import { useTranslations as useTranslations13 } from "next-intl";
|
|
1456
|
+
import { cn as cn11 } from "pelatform-ui";
|
|
1457
|
+
import { jsx as jsx22, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
1458
|
+
function EmptyState({
|
|
1459
|
+
className,
|
|
1460
|
+
icon: Icon,
|
|
1461
|
+
title,
|
|
1462
|
+
description,
|
|
1463
|
+
learnMore,
|
|
1464
|
+
learnMoreText,
|
|
1465
|
+
children
|
|
1466
|
+
}) {
|
|
1467
|
+
const t = useTranslations13();
|
|
1468
|
+
return /* @__PURE__ */ jsxs18("div", { className: cn11("flex flex-col items-center justify-center gap-y-4", className), children: [
|
|
1469
|
+
Icon && /* @__PURE__ */ jsx22("div", { className: "flex size-14 items-center justify-center rounded-2xl border bg-muted", children: /* @__PURE__ */ jsx22(Icon, { className: "size-6 text-foreground" }) }),
|
|
1470
|
+
/* @__PURE__ */ jsx22("p", { className: "text-center font-medium text-base text-foreground", children: title }),
|
|
1471
|
+
description && /* @__PURE__ */ jsxs18("p", { className: "max-w-sm text-balance text-center text-muted-foreground text-sm", children: [
|
|
1472
|
+
description,
|
|
1473
|
+
" ",
|
|
1474
|
+
learnMore && /* @__PURE__ */ jsxs18(
|
|
1475
|
+
Link8,
|
|
1476
|
+
{
|
|
1477
|
+
href: learnMore,
|
|
1478
|
+
className: "text-foreground underline underline-offset-2 transition-colors hover:text-primary",
|
|
1479
|
+
children: [
|
|
1480
|
+
learnMoreText ?? t("ui.common.learnMore"),
|
|
1481
|
+
" \u2197"
|
|
1482
|
+
]
|
|
1483
|
+
}
|
|
1484
|
+
)
|
|
1485
|
+
] }),
|
|
1486
|
+
children
|
|
561
1487
|
] });
|
|
562
1488
|
}
|
|
563
1489
|
|
|
564
1490
|
// src/components/otp-input-group.tsx
|
|
565
1491
|
import { InputOTPGroup, InputOTPSeparator, InputOTPSlot } from "pelatform-ui/default";
|
|
566
|
-
import { Fragment as
|
|
1492
|
+
import { Fragment as Fragment7, jsx as jsx23, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
567
1493
|
function OTPInputGroup({ otpSeparators = 0 }) {
|
|
568
1494
|
if (otpSeparators === 0) {
|
|
569
|
-
return /* @__PURE__ */
|
|
570
|
-
/* @__PURE__ */
|
|
571
|
-
/* @__PURE__ */
|
|
572
|
-
/* @__PURE__ */
|
|
573
|
-
/* @__PURE__ */
|
|
574
|
-
/* @__PURE__ */
|
|
575
|
-
/* @__PURE__ */
|
|
1495
|
+
return /* @__PURE__ */ jsxs19(InputOTPGroup, { children: [
|
|
1496
|
+
/* @__PURE__ */ jsx23(InputOTPSlot, { index: 0 }),
|
|
1497
|
+
/* @__PURE__ */ jsx23(InputOTPSlot, { index: 1 }),
|
|
1498
|
+
/* @__PURE__ */ jsx23(InputOTPSlot, { index: 2 }),
|
|
1499
|
+
/* @__PURE__ */ jsx23(InputOTPSlot, { index: 3 }),
|
|
1500
|
+
/* @__PURE__ */ jsx23(InputOTPSlot, { index: 4 }),
|
|
1501
|
+
/* @__PURE__ */ jsx23(InputOTPSlot, { index: 5 })
|
|
576
1502
|
] });
|
|
577
1503
|
}
|
|
578
1504
|
if (otpSeparators === 1) {
|
|
579
|
-
return /* @__PURE__ */
|
|
580
|
-
/* @__PURE__ */
|
|
581
|
-
/* @__PURE__ */
|
|
582
|
-
/* @__PURE__ */
|
|
583
|
-
/* @__PURE__ */
|
|
1505
|
+
return /* @__PURE__ */ jsxs19(Fragment7, { children: [
|
|
1506
|
+
/* @__PURE__ */ jsxs19(InputOTPGroup, { children: [
|
|
1507
|
+
/* @__PURE__ */ jsx23(InputOTPSlot, { index: 0 }),
|
|
1508
|
+
/* @__PURE__ */ jsx23(InputOTPSlot, { index: 1 }),
|
|
1509
|
+
/* @__PURE__ */ jsx23(InputOTPSlot, { index: 2 })
|
|
584
1510
|
] }),
|
|
585
|
-
/* @__PURE__ */
|
|
586
|
-
/* @__PURE__ */
|
|
587
|
-
/* @__PURE__ */
|
|
588
|
-
/* @__PURE__ */
|
|
589
|
-
/* @__PURE__ */
|
|
1511
|
+
/* @__PURE__ */ jsx23(InputOTPSeparator, {}),
|
|
1512
|
+
/* @__PURE__ */ jsxs19(InputOTPGroup, { children: [
|
|
1513
|
+
/* @__PURE__ */ jsx23(InputOTPSlot, { index: 3 }),
|
|
1514
|
+
/* @__PURE__ */ jsx23(InputOTPSlot, { index: 4 }),
|
|
1515
|
+
/* @__PURE__ */ jsx23(InputOTPSlot, { index: 5 })
|
|
590
1516
|
] })
|
|
591
1517
|
] });
|
|
592
1518
|
}
|
|
593
|
-
return /* @__PURE__ */
|
|
594
|
-
/* @__PURE__ */
|
|
595
|
-
/* @__PURE__ */
|
|
596
|
-
/* @__PURE__ */
|
|
1519
|
+
return /* @__PURE__ */ jsxs19(Fragment7, { children: [
|
|
1520
|
+
/* @__PURE__ */ jsxs19(InputOTPGroup, { children: [
|
|
1521
|
+
/* @__PURE__ */ jsx23(InputOTPSlot, { index: 0 }),
|
|
1522
|
+
/* @__PURE__ */ jsx23(InputOTPSlot, { index: 1 })
|
|
597
1523
|
] }),
|
|
598
|
-
/* @__PURE__ */
|
|
599
|
-
/* @__PURE__ */
|
|
600
|
-
/* @__PURE__ */
|
|
601
|
-
/* @__PURE__ */
|
|
1524
|
+
/* @__PURE__ */ jsx23(InputOTPSeparator, {}),
|
|
1525
|
+
/* @__PURE__ */ jsxs19(InputOTPGroup, { children: [
|
|
1526
|
+
/* @__PURE__ */ jsx23(InputOTPSlot, { index: 2 }),
|
|
1527
|
+
/* @__PURE__ */ jsx23(InputOTPSlot, { index: 3 })
|
|
602
1528
|
] }),
|
|
603
|
-
/* @__PURE__ */
|
|
604
|
-
/* @__PURE__ */
|
|
605
|
-
/* @__PURE__ */
|
|
606
|
-
/* @__PURE__ */
|
|
1529
|
+
/* @__PURE__ */ jsx23(InputOTPSeparator, {}),
|
|
1530
|
+
/* @__PURE__ */ jsxs19(InputOTPGroup, { children: [
|
|
1531
|
+
/* @__PURE__ */ jsx23(InputOTPSlot, { index: 4 }),
|
|
1532
|
+
/* @__PURE__ */ jsx23(InputOTPSlot, { index: 5 })
|
|
607
1533
|
] })
|
|
608
1534
|
] });
|
|
609
1535
|
}
|
|
610
1536
|
|
|
611
1537
|
// src/components/password-input.tsx
|
|
612
|
-
import { useState } from "react";
|
|
1538
|
+
import { useState as useState5 } from "react";
|
|
613
1539
|
import { EyeIcon, EyeOffIcon } from "lucide-react";
|
|
614
|
-
import { cn as
|
|
615
|
-
import { Button as
|
|
616
|
-
import { Fragment as
|
|
1540
|
+
import { cn as cn12 } from "pelatform-ui";
|
|
1541
|
+
import { Button as Button8, Input as Input2 } from "pelatform-ui/default";
|
|
1542
|
+
import { Fragment as Fragment8, jsx as jsx24, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
617
1543
|
function PasswordInput({
|
|
618
1544
|
className,
|
|
619
1545
|
variant,
|
|
@@ -621,15 +1547,15 @@ function PasswordInput({
|
|
|
621
1547
|
onChange,
|
|
622
1548
|
...props
|
|
623
1549
|
}) {
|
|
624
|
-
const [disabled, setDisabled] =
|
|
625
|
-
const [isVisible, setIsVisible] =
|
|
626
|
-
return /* @__PURE__ */
|
|
627
|
-
/* @__PURE__ */
|
|
1550
|
+
const [disabled, setDisabled] = useState5(true);
|
|
1551
|
+
const [isVisible, setIsVisible] = useState5(false);
|
|
1552
|
+
return /* @__PURE__ */ jsxs20("div", { className: "relative", children: [
|
|
1553
|
+
/* @__PURE__ */ jsx24(
|
|
628
1554
|
Input2,
|
|
629
1555
|
{
|
|
630
1556
|
type: isVisible && enableToggle ? "text" : "password",
|
|
631
1557
|
variant,
|
|
632
|
-
className:
|
|
1558
|
+
className: cn12(enableToggle && "pe-10", className),
|
|
633
1559
|
...props,
|
|
634
1560
|
onChange: (event) => {
|
|
635
1561
|
setDisabled(!event.target.value);
|
|
@@ -637,9 +1563,9 @@ function PasswordInput({
|
|
|
637
1563
|
}
|
|
638
1564
|
}
|
|
639
1565
|
),
|
|
640
|
-
enableToggle && /* @__PURE__ */
|
|
641
|
-
/* @__PURE__ */
|
|
642
|
-
|
|
1566
|
+
enableToggle && /* @__PURE__ */ jsxs20(Fragment8, { children: [
|
|
1567
|
+
/* @__PURE__ */ jsx24(
|
|
1568
|
+
Button8,
|
|
643
1569
|
{
|
|
644
1570
|
type: "button",
|
|
645
1571
|
variant: "ghost",
|
|
@@ -647,10 +1573,10 @@ function PasswordInput({
|
|
|
647
1573
|
className: "absolute end-0 top-0 bg-transparent!",
|
|
648
1574
|
onClick: () => setIsVisible(!isVisible),
|
|
649
1575
|
disabled,
|
|
650
|
-
children: isVisible ? /* @__PURE__ */
|
|
1576
|
+
children: isVisible ? /* @__PURE__ */ jsx24(EyeIcon, {}) : /* @__PURE__ */ jsx24(EyeOffIcon, {})
|
|
651
1577
|
}
|
|
652
1578
|
),
|
|
653
|
-
/* @__PURE__ */
|
|
1579
|
+
/* @__PURE__ */ jsx24("style", { children: `
|
|
654
1580
|
.hide-password-toggle::-ms-reveal,
|
|
655
1581
|
.hide-password-toggle::-ms-clear {
|
|
656
1582
|
visibility: hidden;
|
|
@@ -661,330 +1587,43 @@ function PasswordInput({
|
|
|
661
1587
|
] })
|
|
662
1588
|
] });
|
|
663
1589
|
}
|
|
664
|
-
|
|
665
|
-
// src/components/signed-in-hint.tsx
|
|
666
|
-
import Link3 from "next/link";
|
|
667
|
-
import { useTranslations as useTranslations6 } from "next-intl";
|
|
668
|
-
import { useSession } from "@pelatform/starter.hook";
|
|
669
|
-
import { Button as Button5 } from "pelatform-ui/default";
|
|
670
|
-
import { jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
671
|
-
function SignedInHint({ linkHref = "/signin" }) {
|
|
672
|
-
const t = useTranslations6("ui.common.signed");
|
|
673
|
-
const { isPending, user } = useSession();
|
|
674
|
-
return /* @__PURE__ */ jsxs10("div", { className: "fixed start-0 bottom-0 z-40 m-5 flex flex-col gap-2", children: [
|
|
675
|
-
/* @__PURE__ */ jsxs10("div", { className: "flex items-center gap-1 text-muted-foreground text-xs", children: [
|
|
676
|
-
t("text"),
|
|
677
|
-
" ",
|
|
678
|
-
isPending || !user ? /* @__PURE__ */ jsx11("span", { className: "h-3 w-32 animate-pulse rounded-md border bg-muted-foreground" }) : /* @__PURE__ */ jsx11("b", { className: "text-foreground", children: user.email })
|
|
679
|
-
] }),
|
|
680
|
-
/* @__PURE__ */ jsx11(Button5, { variant: "mono", className: "h-8 w-fit rounded-lg px-3 text-xs shadow-sm", children: /* @__PURE__ */ jsx11(Link3, { href: linkHref, children: t("button") }) })
|
|
681
|
-
] });
|
|
682
|
-
}
|
|
683
|
-
|
|
684
|
-
// src/components/user-menu.tsx
|
|
685
|
-
import { Fragment as Fragment5, useCallback, useEffect, useState as useState2 } from "react";
|
|
686
|
-
import Link4 from "next/link";
|
|
687
|
-
import { useRouter as useRouter2 } from "next/navigation";
|
|
688
|
-
import { LogOut, PlusCircleIcon, Settings, Shield, UserStar } from "lucide-react";
|
|
689
|
-
import { useTranslations as useTranslations8 } from "next-intl";
|
|
690
|
-
import {
|
|
691
|
-
useConfig as useConfig3,
|
|
692
|
-
useListDeviceSessions,
|
|
693
|
-
useSession as useSession2,
|
|
694
|
-
useSetActiveSession
|
|
695
|
-
} from "@pelatform/starter.hook";
|
|
696
|
-
import { getUserName as getUserName3 } from "@pelatform/starter.utils";
|
|
697
|
-
import { ModeSwitcher, UserAvatar as UserAvatar2 } from "pelatform-ui/components";
|
|
698
|
-
import {
|
|
699
|
-
Badge,
|
|
700
|
-
DropdownMenu,
|
|
701
|
-
DropdownMenuContent,
|
|
702
|
-
DropdownMenuItem,
|
|
703
|
-
DropdownMenuSeparator,
|
|
704
|
-
DropdownMenuTrigger,
|
|
705
|
-
Skeleton as Skeleton6
|
|
706
|
-
} from "pelatform-ui/default";
|
|
707
|
-
|
|
708
|
-
// src/components/view.tsx
|
|
709
|
-
import { KeyRoundIcon } from "lucide-react";
|
|
710
|
-
import { useLocale as useLocale2, useTranslations as useTranslations7 } from "next-intl";
|
|
711
|
-
import { getUserName as getUserName2 } from "@pelatform/starter.utils";
|
|
712
|
-
import { cn as cn9 } from "pelatform-ui";
|
|
713
|
-
import { Skeleton as Skeleton5 } from "pelatform-ui/default";
|
|
714
|
-
import { Fragment as Fragment4, jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
715
|
-
function UserView({ className, classNames, isPending, size, user }) {
|
|
716
|
-
const t = useTranslations7();
|
|
717
|
-
return /* @__PURE__ */ jsxs11("div", { className: cn9("flex items-center gap-2", className, classNames?.base), children: [
|
|
718
|
-
/* @__PURE__ */ jsx12(
|
|
719
|
-
UserAvatar,
|
|
720
|
-
{
|
|
721
|
-
className: cn9(size !== "sm" && "my-0.5"),
|
|
722
|
-
classNames: classNames?.avatar,
|
|
723
|
-
isPending,
|
|
724
|
-
size,
|
|
725
|
-
user
|
|
726
|
-
}
|
|
727
|
-
),
|
|
728
|
-
/* @__PURE__ */ jsx12("div", { className: cn9("grid flex-1 text-start leading-tight", classNames?.content), children: isPending ? /* @__PURE__ */ jsxs11(Fragment4, { children: [
|
|
729
|
-
/* @__PURE__ */ jsx12(
|
|
730
|
-
Skeleton5,
|
|
731
|
-
{
|
|
732
|
-
className: cn9(
|
|
733
|
-
"max-w-full",
|
|
734
|
-
size === "lg" ? "h-4.5 w-32" : "h-3.5 w-24",
|
|
735
|
-
classNames?.title,
|
|
736
|
-
classNames?.skeleton
|
|
737
|
-
)
|
|
738
|
-
}
|
|
739
|
-
),
|
|
740
|
-
size !== "sm" && /* @__PURE__ */ jsx12(
|
|
741
|
-
Skeleton5,
|
|
742
|
-
{
|
|
743
|
-
className: cn9(
|
|
744
|
-
"mt-1.5 max-w-full",
|
|
745
|
-
size === "lg" ? "h-3.5 w-40" : "h-3 w-32",
|
|
746
|
-
classNames?.subtitle,
|
|
747
|
-
classNames?.skeleton
|
|
748
|
-
)
|
|
749
|
-
}
|
|
750
|
-
)
|
|
751
|
-
] }) : /* @__PURE__ */ jsxs11(Fragment4, { children: [
|
|
752
|
-
/* @__PURE__ */ jsx12(
|
|
753
|
-
"span",
|
|
754
|
-
{
|
|
755
|
-
className: cn9(
|
|
756
|
-
"truncate font-semibold",
|
|
757
|
-
size === "lg" ? "text-base" : "text-sm",
|
|
758
|
-
classNames?.title
|
|
759
|
-
),
|
|
760
|
-
children: getUserName2(user) || t("ui.navigation.user")
|
|
761
|
-
}
|
|
762
|
-
),
|
|
763
|
-
!user?.isAnonymous && size !== "sm" && (user?.name || user?.username) && /* @__PURE__ */ jsx12(
|
|
764
|
-
"span",
|
|
765
|
-
{
|
|
766
|
-
className: cn9(
|
|
767
|
-
"truncate opacity-70",
|
|
768
|
-
size === "lg" ? "text-sm" : "text-xs",
|
|
769
|
-
classNames?.subtitle
|
|
770
|
-
),
|
|
771
|
-
children: user?.email
|
|
772
|
-
}
|
|
773
|
-
)
|
|
774
|
-
] }) })
|
|
775
|
-
] });
|
|
776
|
-
}
|
|
777
|
-
function ApiKeyView({ className, classNames, apiKey }) {
|
|
778
|
-
const t = useTranslations7();
|
|
779
|
-
const locale = useLocale2();
|
|
780
|
-
const formatExpiration = () => {
|
|
781
|
-
if (!apiKey.expiresAt) return t("common.time.neverExpires");
|
|
782
|
-
const expiresDate = new Date(apiKey.expiresAt);
|
|
783
|
-
return `${t("common.time.expires")} ${expiresDate.toLocaleDateString(locale ?? "en", {
|
|
784
|
-
month: "short",
|
|
785
|
-
day: "numeric",
|
|
786
|
-
year: "numeric"
|
|
787
|
-
})}`;
|
|
788
|
-
};
|
|
789
|
-
return /* @__PURE__ */ jsxs11("div", { className: cn9("flex items-center gap-3 truncate", className, classNames?.base), children: [
|
|
790
|
-
/* @__PURE__ */ jsx12(KeyRoundIcon, { className: cn9("size-4 shrink-0", classNames?.icon) }),
|
|
791
|
-
/* @__PURE__ */ jsxs11("div", { className: "flex flex-col truncate text-start", children: [
|
|
792
|
-
/* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-2", children: [
|
|
793
|
-
/* @__PURE__ */ jsx12("span", { className: "truncate font-semibold text-sm", children: apiKey.name }),
|
|
794
|
-
/* @__PURE__ */ jsxs11("span", { className: "flex-1 truncate text-muted-foreground text-sm", children: [
|
|
795
|
-
apiKey.start,
|
|
796
|
-
"******"
|
|
797
|
-
] })
|
|
798
|
-
] }),
|
|
799
|
-
/* @__PURE__ */ jsx12("div", { className: "truncate text-muted-foreground text-xs", children: formatExpiration() })
|
|
800
|
-
] })
|
|
801
|
-
] });
|
|
802
|
-
}
|
|
803
|
-
function WorkspaceView({ className, classNames, isPending, size, workspace }) {
|
|
804
|
-
const t = useTranslations7();
|
|
805
|
-
return /* @__PURE__ */ jsxs11("div", { className: cn9("flex items-center gap-2 truncate", className, classNames?.base), children: [
|
|
806
|
-
/* @__PURE__ */ jsx12(
|
|
807
|
-
WorkspaceLogo,
|
|
808
|
-
{
|
|
809
|
-
className: cn9(size !== "sm" && "my-0.5"),
|
|
810
|
-
classNames: classNames?.avatar,
|
|
811
|
-
isPending,
|
|
812
|
-
workspace,
|
|
813
|
-
size
|
|
814
|
-
}
|
|
815
|
-
),
|
|
816
|
-
/* @__PURE__ */ jsx12("div", { className: cn9("flex flex-col truncate text-start leading-tight", classNames?.content), children: isPending ? /* @__PURE__ */ jsxs11(Fragment4, { children: [
|
|
817
|
-
/* @__PURE__ */ jsx12(
|
|
818
|
-
Skeleton5,
|
|
819
|
-
{
|
|
820
|
-
className: cn9(
|
|
821
|
-
"max-w-full",
|
|
822
|
-
size === "lg" ? "h-4.5 w-32" : "h-3.5 w-24",
|
|
823
|
-
classNames?.title,
|
|
824
|
-
classNames?.skeleton
|
|
825
|
-
)
|
|
826
|
-
}
|
|
827
|
-
),
|
|
828
|
-
size !== "sm" && /* @__PURE__ */ jsx12(
|
|
829
|
-
Skeleton5,
|
|
830
|
-
{
|
|
831
|
-
className: cn9(
|
|
832
|
-
"mt-1.5 max-w-full",
|
|
833
|
-
size === "lg" ? "h-3.5 w-24" : "h-3 w-16",
|
|
834
|
-
classNames?.subtitle,
|
|
835
|
-
classNames?.skeleton
|
|
836
|
-
)
|
|
837
|
-
}
|
|
838
|
-
)
|
|
839
|
-
] }) : /* @__PURE__ */ jsxs11(Fragment4, { children: [
|
|
840
|
-
/* @__PURE__ */ jsx12(
|
|
841
|
-
"span",
|
|
842
|
-
{
|
|
843
|
-
className: cn9(
|
|
844
|
-
"truncate font-semibold",
|
|
845
|
-
size === "lg" ? "text-base" : "text-sm",
|
|
846
|
-
classNames?.title
|
|
847
|
-
),
|
|
848
|
-
children: workspace?.name || t("ui.navigation.workspace")
|
|
849
|
-
}
|
|
850
|
-
),
|
|
851
|
-
size !== "sm" && workspace?.slug && /* @__PURE__ */ jsx12(
|
|
852
|
-
"span",
|
|
853
|
-
{
|
|
854
|
-
className: cn9(
|
|
855
|
-
"truncate opacity-70",
|
|
856
|
-
size === "lg" ? "text-sm" : "text-xs",
|
|
857
|
-
classNames?.subtitle
|
|
858
|
-
),
|
|
859
|
-
children: workspace.slug
|
|
860
|
-
}
|
|
861
|
-
)
|
|
862
|
-
] }) })
|
|
863
|
-
] });
|
|
864
|
-
}
|
|
865
|
-
|
|
866
|
-
// src/components/user-menu.tsx
|
|
867
|
-
import { Fragment as Fragment6, jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
868
|
-
function UserMenu({ hiddenSwitcher = false }) {
|
|
869
|
-
const { features, path } = useConfig3();
|
|
870
|
-
const router = useRouter2();
|
|
871
|
-
const t = useTranslations8();
|
|
872
|
-
const { isPending: sessionPending, user } = useSession2();
|
|
873
|
-
const { setActiveSessionAsync } = useSetActiveSession();
|
|
874
|
-
const { data: deviceSessions, isPending: deviceSessionsPending } = useListDeviceSessions({
|
|
875
|
-
enabled: features.multiSession
|
|
876
|
-
});
|
|
877
|
-
const [activeSessionPending, setActiveSessionPending] = useState2(false);
|
|
878
|
-
const isPending = sessionPending || activeSessionPending;
|
|
879
|
-
const switchAccount = useCallback(
|
|
880
|
-
async (sessionToken) => {
|
|
881
|
-
setActiveSessionPending(true);
|
|
882
|
-
try {
|
|
883
|
-
await setActiveSessionAsync({ sessionToken });
|
|
884
|
-
router.refresh();
|
|
885
|
-
setActiveSessionPending(false);
|
|
886
|
-
} catch (error) {
|
|
887
|
-
console.error("Error switching account:", error);
|
|
888
|
-
setActiveSessionPending(false);
|
|
889
|
-
}
|
|
890
|
-
},
|
|
891
|
-
[router, setActiveSessionAsync]
|
|
892
|
-
);
|
|
893
|
-
useEffect(() => {
|
|
894
|
-
if (!features.multiSession) return;
|
|
895
|
-
setActiveSessionPending(false);
|
|
896
|
-
}, [features.multiSession, user?.id]);
|
|
897
|
-
const userEmail = user?.email || "user@example.com";
|
|
898
|
-
const userName = getUserName3(user);
|
|
899
|
-
const userAvatar = user?.image || void 0;
|
|
900
|
-
const userRole = user?.role || "user";
|
|
901
|
-
return /* @__PURE__ */ jsxs12(DropdownMenu, { children: [
|
|
902
|
-
/* @__PURE__ */ jsx13(DropdownMenuTrigger, { className: "focus:outline-none focus:ring-0", children: isPending ? /* @__PURE__ */ jsx13(Skeleton6, { className: "size-8 shrink-0 rounded-full" }) : /* @__PURE__ */ jsx13(UserAvatar2, { className: "size-8", indicator: true, src: userAvatar, alt: userName }) }),
|
|
903
|
-
/* @__PURE__ */ jsxs12(DropdownMenuContent, { className: "w-56", side: "bottom", align: "end", sideOffset: 11, children: [
|
|
904
|
-
/* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-3 px-3 py-2", children: [
|
|
905
|
-
/* @__PURE__ */ jsx13(UserAvatar2, { src: userAvatar, alt: userName }),
|
|
906
|
-
/* @__PURE__ */ jsxs12("div", { className: "flex min-w-0 flex-1 flex-col items-start", children: [
|
|
907
|
-
/* @__PURE__ */ jsx13("span", { className: "truncate font-semibold text-foreground text-sm", children: userName }),
|
|
908
|
-
/* @__PURE__ */ jsx13("span", { className: "block w-full truncate text-muted-foreground text-xs", children: userEmail }),
|
|
909
|
-
/* @__PURE__ */ jsx13(Badge, { variant: "success", appearance: "outline", size: "sm", className: "mt-1", children: userRole.toUpperCase() })
|
|
910
|
-
] })
|
|
911
|
-
] }),
|
|
912
|
-
/* @__PURE__ */ jsx13(DropdownMenuSeparator, {}),
|
|
913
|
-
/* @__PURE__ */ jsx13(DropdownMenuItem, { asChild: true, children: /* @__PURE__ */ jsxs12(Link4, { href: path.account.SETTINGS, children: [
|
|
914
|
-
/* @__PURE__ */ jsx13(Settings, {}),
|
|
915
|
-
/* @__PURE__ */ jsx13("span", { children: t("ui.navigation.preferences") })
|
|
916
|
-
] }) }),
|
|
917
|
-
/* @__PURE__ */ jsx13(DropdownMenuItem, { asChild: true, children: /* @__PURE__ */ jsxs12(Link4, { href: path.account.SECURITY, children: [
|
|
918
|
-
/* @__PURE__ */ jsx13(Shield, {}),
|
|
919
|
-
/* @__PURE__ */ jsx13("span", { children: t("ui.navigation.security") })
|
|
920
|
-
] }) }),
|
|
921
|
-
"admin" === userRole && /* @__PURE__ */ jsx13(DropdownMenuItem, { asChild: true, children: /* @__PURE__ */ jsxs12(Link4, { href: path.admin.OVERVIEW, children: [
|
|
922
|
-
/* @__PURE__ */ jsx13(UserStar, {}),
|
|
923
|
-
/* @__PURE__ */ jsx13("span", { children: "Admin Dashboard" })
|
|
924
|
-
] }) }),
|
|
925
|
-
!hiddenSwitcher && /* @__PURE__ */ jsxs12(Fragment6, { children: [
|
|
926
|
-
/* @__PURE__ */ jsx13(DropdownMenuSeparator, {}),
|
|
927
|
-
/* @__PURE__ */ jsx13(
|
|
928
|
-
ModeSwitcher,
|
|
929
|
-
{
|
|
930
|
-
type: "sub-dropdown",
|
|
931
|
-
label: {
|
|
932
|
-
system: t("ui.common.system"),
|
|
933
|
-
dark: t("ui.common.dark"),
|
|
934
|
-
light: t("ui.common.light")
|
|
935
|
-
}
|
|
936
|
-
}
|
|
937
|
-
),
|
|
938
|
-
/* @__PURE__ */ jsx13(LanguageSwitcher, { type: "sub-dropdown" })
|
|
939
|
-
] }),
|
|
940
|
-
/* @__PURE__ */ jsx13(DropdownMenuSeparator, {}),
|
|
941
|
-
/* @__PURE__ */ jsx13(DropdownMenuItem, { asChild: true, children: /* @__PURE__ */ jsxs12(Link4, { href: path.auth.SIGN_OUT, children: [
|
|
942
|
-
/* @__PURE__ */ jsx13(LogOut, {}),
|
|
943
|
-
/* @__PURE__ */ jsx13("span", { children: t("ui.navigation.signOut") })
|
|
944
|
-
] }) }),
|
|
945
|
-
user && features.multiSession && /* @__PURE__ */ jsxs12(Fragment6, { children: [
|
|
946
|
-
/* @__PURE__ */ jsx13(DropdownMenuSeparator, {}),
|
|
947
|
-
!deviceSessions && deviceSessionsPending && /* @__PURE__ */ jsxs12(Fragment6, { children: [
|
|
948
|
-
/* @__PURE__ */ jsx13(DropdownMenuItem, { disabled: true, children: /* @__PURE__ */ jsx13(UserView, { isPending: true }) }),
|
|
949
|
-
/* @__PURE__ */ jsx13(DropdownMenuSeparator, {})
|
|
950
|
-
] }),
|
|
951
|
-
deviceSessions?.filter((sessionData) => sessionData.user.id !== user?.id).map(({ session, user: multiUser }) => /* @__PURE__ */ jsxs12(Fragment5, { children: [
|
|
952
|
-
/* @__PURE__ */ jsxs12(DropdownMenuItem, { onClick: () => switchAccount(session.token), children: [
|
|
953
|
-
/* @__PURE__ */ jsx13(UserAvatar2, { src: multiUser?.image || void 0, alt: getUserName3(multiUser) }),
|
|
954
|
-
/* @__PURE__ */ jsxs12("div", { className: "flex min-w-0 flex-1 flex-col items-start", children: [
|
|
955
|
-
/* @__PURE__ */ jsx13("span", { className: "truncate font-semibold text-foreground text-xs", children: getUserName3(multiUser) }),
|
|
956
|
-
/* @__PURE__ */ jsx13("span", { className: "block w-full truncate text-muted-foreground text-xs", children: multiUser?.email })
|
|
957
|
-
] })
|
|
958
|
-
] }),
|
|
959
|
-
/* @__PURE__ */ jsx13(DropdownMenuSeparator, {})
|
|
960
|
-
] }, session.id)),
|
|
961
|
-
/* @__PURE__ */ jsx13(DropdownMenuItem, { asChild: true, children: /* @__PURE__ */ jsxs12(Link4, { href: path.auth.SIGN_IN, children: [
|
|
962
|
-
/* @__PURE__ */ jsx13(PlusCircleIcon, {}),
|
|
963
|
-
t("common.actions.addAccount")
|
|
964
|
-
] }) })
|
|
965
|
-
] })
|
|
966
|
-
] })
|
|
967
|
-
] });
|
|
968
|
-
}
|
|
969
1590
|
export {
|
|
970
1591
|
ApiKeyView,
|
|
1592
|
+
AuthLayout,
|
|
971
1593
|
CardActionComponent,
|
|
972
1594
|
CardComponent,
|
|
973
1595
|
CardFooterComponent,
|
|
974
1596
|
CardHeaderComponent,
|
|
1597
|
+
ConfigProvider,
|
|
975
1598
|
DialogComponent,
|
|
976
1599
|
DialogFooterComponent,
|
|
977
1600
|
DisplayIdCard,
|
|
978
1601
|
EmptyState,
|
|
1602
|
+
Header,
|
|
1603
|
+
HeaderLeft,
|
|
1604
|
+
HeaderRight,
|
|
1605
|
+
HeaderSidebarMobile,
|
|
979
1606
|
LanguageSwitcher,
|
|
1607
|
+
LayoutLoader,
|
|
1608
|
+
LayoutProvider,
|
|
1609
|
+
LayoutWrapper,
|
|
980
1610
|
Logo as LogoDefault,
|
|
981
1611
|
LogoWithHref,
|
|
982
1612
|
LogoWithName,
|
|
983
1613
|
OTPInputGroup,
|
|
984
1614
|
PasswordInput,
|
|
1615
|
+
SharedProviders,
|
|
1616
|
+
Sidebar,
|
|
1617
|
+
SidebarContent,
|
|
1618
|
+
SidebarContentMenu,
|
|
1619
|
+
SidebarHeaderBack,
|
|
985
1620
|
SignedInHint,
|
|
1621
|
+
SiteFooter,
|
|
1622
|
+
SiteHeader,
|
|
1623
|
+
SiteHeaderSecondary,
|
|
986
1624
|
SkeletonInputComponent,
|
|
987
1625
|
SkeletonViewComponent,
|
|
1626
|
+
Toolbar,
|
|
988
1627
|
UserAvatar,
|
|
989
1628
|
UserMenu,
|
|
990
1629
|
UserView,
|