@pelatform/starter.shared 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/extend.d.ts +107 -0
- package/dist/extend.js +117 -0
- package/dist/index.d.ts +132 -90
- package/dist/index.js +1313 -669
- package/dist/view-B1v2TRLo.d.ts +96 -0
- package/package.json +12 -8
package/dist/index.js
CHANGED
|
@@ -1,10 +1,1138 @@
|
|
|
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 }) => {
|
|
598
|
+
const userData = multiUser;
|
|
599
|
+
return /* @__PURE__ */ jsxs7(Fragment2, { children: [
|
|
600
|
+
/* @__PURE__ */ jsxs7(DropdownMenuItem, { onClick: () => switchAccount(session.token), children: [
|
|
601
|
+
/* @__PURE__ */ jsx9(UserAvatar2, { src: userData?.image || void 0, alt: getUserName3(userData) }),
|
|
602
|
+
/* @__PURE__ */ jsxs7("div", { className: "flex min-w-0 flex-1 flex-col items-start", children: [
|
|
603
|
+
/* @__PURE__ */ jsx9("span", { className: "truncate font-semibold text-foreground text-xs", children: getUserName3(userData) }),
|
|
604
|
+
/* @__PURE__ */ jsx9("span", { className: "block w-full truncate text-muted-foreground text-xs", children: userData?.email })
|
|
605
|
+
] })
|
|
606
|
+
] }),
|
|
607
|
+
/* @__PURE__ */ jsx9(DropdownMenuSeparator, {})
|
|
608
|
+
] }, session.id);
|
|
609
|
+
}),
|
|
610
|
+
/* @__PURE__ */ jsx9(DropdownMenuItem, { asChild: true, children: /* @__PURE__ */ jsxs7(Link4, { href: path.auth.SIGN_IN, children: [
|
|
611
|
+
/* @__PURE__ */ jsx9(PlusCircleIcon, {}),
|
|
612
|
+
t("common.actions.add"),
|
|
613
|
+
" ",
|
|
614
|
+
t("ui.navigation.account")
|
|
615
|
+
] }) })
|
|
616
|
+
] })
|
|
617
|
+
] })
|
|
618
|
+
] });
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
// src/components/layouts/header.tsx
|
|
622
|
+
import { jsx as jsx10, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
623
|
+
function Header({ children }) {
|
|
624
|
+
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 }) });
|
|
625
|
+
}
|
|
626
|
+
function HeaderLeft() {
|
|
627
|
+
const { logoHeader, sidebarToggle } = useLayout();
|
|
628
|
+
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: [
|
|
629
|
+
logoHeader,
|
|
630
|
+
/* @__PURE__ */ jsx10(
|
|
631
|
+
Button2,
|
|
632
|
+
{
|
|
633
|
+
mode: "icon",
|
|
634
|
+
variant: "ghost",
|
|
635
|
+
onClick: sidebarToggle,
|
|
636
|
+
className: "hidden text-muted-foreground hover:text-foreground lg:inline-flex",
|
|
637
|
+
children: /* @__PURE__ */ jsx10(PanelRight, { className: "-rotate-180 in-data-[sidebar-open=false]:rotate-0 opacity-100" })
|
|
638
|
+
}
|
|
639
|
+
)
|
|
640
|
+
] }) });
|
|
641
|
+
}
|
|
642
|
+
function HeaderRight({ sidebar, button }) {
|
|
643
|
+
const { isMobile } = useLayout();
|
|
644
|
+
return /* @__PURE__ */ jsxs8("nav", { className: "flex items-center gap-1.5 lg:gap-2.5", children: [
|
|
645
|
+
button,
|
|
646
|
+
isMobile && sidebar,
|
|
647
|
+
/* @__PURE__ */ jsx10(UserMenu, {})
|
|
648
|
+
] });
|
|
649
|
+
}
|
|
650
|
+
function HeaderSidebarMobile({ children }) {
|
|
651
|
+
const pathname = usePathname2();
|
|
652
|
+
const [isSheetOpen, setIsSheetOpen] = useState2(false);
|
|
653
|
+
useEffect2(() => {
|
|
654
|
+
setIsSheetOpen(false);
|
|
655
|
+
}, [pathname]);
|
|
656
|
+
return /* @__PURE__ */ jsxs8(Sheet, { open: isSheetOpen, onOpenChange: setIsSheetOpen, children: [
|
|
657
|
+
/* @__PURE__ */ jsx10(SheetTrigger, { asChild: true, children: /* @__PURE__ */ jsx10(Button2, { variant: "ghost", mode: "icon", size: "icon", children: /* @__PURE__ */ jsx10(Menu, { className: "size-4" }) }) }),
|
|
658
|
+
/* @__PURE__ */ jsxs8(SheetContent, { className: "w-(--sidebar-width) gap-0 p-0", side: "left", close: false, children: [
|
|
659
|
+
/* @__PURE__ */ jsxs8(SheetHeader, { className: "hidden space-y-0 p-0", children: [
|
|
660
|
+
/* @__PURE__ */ jsx10(SheetTitle, { className: "sr-only", children: "Navigation menu" }),
|
|
661
|
+
/* @__PURE__ */ jsx10(SheetDescription, { className: "sr-only", children: "NavigatSheet Description" })
|
|
662
|
+
] }),
|
|
663
|
+
/* @__PURE__ */ jsx10(SheetBody, { className: "flex grow flex-col p-0", children })
|
|
664
|
+
] })
|
|
665
|
+
] });
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
// src/components/layouts/sidebar.tsx
|
|
669
|
+
import { useCallback as useCallback2, useMemo } from "react";
|
|
670
|
+
import Link5 from "next/link";
|
|
671
|
+
import { usePathname as usePathname3 } from "next/navigation";
|
|
672
|
+
import { useTranslations as useTranslations8 } from "next-intl";
|
|
673
|
+
import { useLayout as useLayout2 } from "@pelatform/starter.hook";
|
|
674
|
+
import { BackLink } from "pelatform-ui/components";
|
|
675
|
+
import {
|
|
676
|
+
AccordionMenu,
|
|
677
|
+
AccordionMenuGroup,
|
|
678
|
+
AccordionMenuIndicator,
|
|
679
|
+
AccordionMenuItem,
|
|
680
|
+
AccordionMenuLabel,
|
|
681
|
+
AccordionMenuSub,
|
|
682
|
+
AccordionMenuSubContent,
|
|
683
|
+
AccordionMenuSubTrigger,
|
|
684
|
+
Badge as Badge2,
|
|
685
|
+
ScrollArea
|
|
686
|
+
} from "pelatform-ui/default";
|
|
687
|
+
import { Fragment as Fragment4, jsx as jsx11, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
688
|
+
function Sidebar({ children }) {
|
|
689
|
+
const { isMobile } = useLayout2();
|
|
690
|
+
if (isMobile) {
|
|
691
|
+
return null;
|
|
692
|
+
}
|
|
693
|
+
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: [
|
|
694
|
+
children,
|
|
695
|
+
/* @__PURE__ */ jsx11("div", {})
|
|
696
|
+
] });
|
|
697
|
+
}
|
|
698
|
+
function SidebarHeaderBack({
|
|
699
|
+
linkHref = "/",
|
|
700
|
+
admin = false
|
|
701
|
+
}) {
|
|
702
|
+
const t = useTranslations8();
|
|
703
|
+
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") }) });
|
|
704
|
+
}
|
|
705
|
+
function SidebarContent({ children }) {
|
|
706
|
+
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 });
|
|
707
|
+
}
|
|
708
|
+
function SidebarContentMenu({
|
|
709
|
+
menu,
|
|
710
|
+
type = "default"
|
|
711
|
+
}) {
|
|
712
|
+
const pathname = usePathname3();
|
|
713
|
+
const normalize = useCallback2((p) => {
|
|
714
|
+
if (!p) return "/";
|
|
715
|
+
if (p !== "/" && p.endsWith("/")) return p.replace(/\/+$/, "");
|
|
716
|
+
return p;
|
|
717
|
+
}, []);
|
|
718
|
+
const current = useMemo(() => normalize(pathname), [pathname, normalize]);
|
|
719
|
+
const allPaths = useMemo(
|
|
720
|
+
() => menu.flatMap(
|
|
721
|
+
(g) => (g.children ?? []).map((c) => c.path).filter((p) => !!p && p !== "#")
|
|
722
|
+
),
|
|
723
|
+
[menu]
|
|
724
|
+
);
|
|
725
|
+
const activePath = useMemo(() => {
|
|
726
|
+
const candidates = allPaths.map(normalize);
|
|
727
|
+
let best = "";
|
|
728
|
+
for (const p of candidates) {
|
|
729
|
+
if (p === "/") {
|
|
730
|
+
if (current === "/") {
|
|
731
|
+
best = "/";
|
|
732
|
+
}
|
|
733
|
+
continue;
|
|
734
|
+
}
|
|
735
|
+
if (current === p || current.startsWith(`${p}/`)) {
|
|
736
|
+
if (p.length > best.length) {
|
|
737
|
+
best = p;
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
}
|
|
741
|
+
return best;
|
|
742
|
+
}, [allPaths, current, normalize]);
|
|
743
|
+
const matchPath = useCallback2(
|
|
744
|
+
(path) => normalize(path) === activePath,
|
|
745
|
+
[activePath, normalize]
|
|
746
|
+
);
|
|
747
|
+
if (type === "toggle") {
|
|
748
|
+
return /* @__PURE__ */ jsx11(
|
|
749
|
+
AccordionMenu,
|
|
750
|
+
{
|
|
751
|
+
type: "single",
|
|
752
|
+
selectedValue: "menu-trigger",
|
|
753
|
+
defaultValue: "menu-trigger",
|
|
754
|
+
matchPath,
|
|
755
|
+
collapsible: true,
|
|
756
|
+
className: "space-y-7.5 px-2.5",
|
|
757
|
+
classNames: {
|
|
758
|
+
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",
|
|
759
|
+
subTrigger: "text-xs font-normal text-muted-foreground hover:bg-transparent",
|
|
760
|
+
subContent: "ps-0"
|
|
761
|
+
},
|
|
762
|
+
children: menu.map((item, index) => /* @__PURE__ */ jsxs9(AccordionMenuSub, { value: item.title || "menu", children: [
|
|
763
|
+
/* @__PURE__ */ jsxs9(AccordionMenuSubTrigger, { value: "menu-trigger", children: [
|
|
764
|
+
/* @__PURE__ */ jsx11("span", { children: item.title }),
|
|
765
|
+
/* @__PURE__ */ jsx11(AccordionMenuIndicator, {})
|
|
766
|
+
] }),
|
|
767
|
+
/* @__PURE__ */ jsx11(AccordionMenuSubContent, { type: "single", collapsible: true, parentValue: "menu-trigger", children: item.children?.map((child, idx) => {
|
|
768
|
+
const content = /* @__PURE__ */ jsxs9(Fragment4, { children: [
|
|
769
|
+
child.icon && /* @__PURE__ */ jsx11(child.icon, {}),
|
|
770
|
+
/* @__PURE__ */ jsx11("span", { children: child.title }),
|
|
771
|
+
child.badge && /* @__PURE__ */ jsx11(
|
|
772
|
+
Badge2,
|
|
773
|
+
{
|
|
774
|
+
size: "sm",
|
|
775
|
+
variant: child.badgeVariant ?? "destructive",
|
|
776
|
+
appearance: "light",
|
|
777
|
+
children: child.badge
|
|
778
|
+
}
|
|
779
|
+
)
|
|
780
|
+
] });
|
|
781
|
+
if (child.external && child.path) {
|
|
782
|
+
return /* @__PURE__ */ jsx11(
|
|
783
|
+
Link5,
|
|
784
|
+
{
|
|
785
|
+
href: child.path,
|
|
786
|
+
target: "_blank",
|
|
787
|
+
rel: "noopener noreferrer",
|
|
788
|
+
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",
|
|
789
|
+
children: content
|
|
790
|
+
},
|
|
791
|
+
child.path || `ext-${idx}`
|
|
792
|
+
);
|
|
793
|
+
}
|
|
794
|
+
return /* @__PURE__ */ jsx11(AccordionMenuItem, { value: child.path || "#", children: /* @__PURE__ */ jsx11(Link5, { href: child.path || "#", children: content }) }, idx);
|
|
795
|
+
}) })
|
|
796
|
+
] }, index))
|
|
797
|
+
}
|
|
798
|
+
);
|
|
799
|
+
}
|
|
800
|
+
return /* @__PURE__ */ jsx11(
|
|
801
|
+
AccordionMenu,
|
|
802
|
+
{
|
|
803
|
+
type: "multiple",
|
|
804
|
+
selectedValue: pathname,
|
|
805
|
+
matchPath,
|
|
806
|
+
className: "space-y-7.5 px-2.5",
|
|
807
|
+
classNames: {
|
|
808
|
+
label: "text-xs font-normal text-muted-foreground mb-2",
|
|
809
|
+
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",
|
|
810
|
+
group: ""
|
|
811
|
+
},
|
|
812
|
+
children: menu.map((item, index) => {
|
|
813
|
+
return /* @__PURE__ */ jsxs9(AccordionMenuGroup, { children: [
|
|
814
|
+
/* @__PURE__ */ jsx11(AccordionMenuLabel, { children: item.title }),
|
|
815
|
+
item.children?.map((child, idx) => {
|
|
816
|
+
const content = /* @__PURE__ */ jsxs9(Fragment4, { children: [
|
|
817
|
+
child.icon && /* @__PURE__ */ jsx11(child.icon, {}),
|
|
818
|
+
/* @__PURE__ */ jsx11("span", { children: child.title }),
|
|
819
|
+
child.badge && /* @__PURE__ */ jsx11(
|
|
820
|
+
Badge2,
|
|
821
|
+
{
|
|
822
|
+
size: "sm",
|
|
823
|
+
variant: child.badgeVariant ?? "destructive",
|
|
824
|
+
appearance: "light",
|
|
825
|
+
children: child.badge
|
|
826
|
+
}
|
|
827
|
+
)
|
|
828
|
+
] });
|
|
829
|
+
if (child.external && child.path) {
|
|
830
|
+
return /* @__PURE__ */ jsx11(
|
|
831
|
+
Link5,
|
|
832
|
+
{
|
|
833
|
+
href: child.path,
|
|
834
|
+
target: "_blank",
|
|
835
|
+
rel: "noopener noreferrer",
|
|
836
|
+
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",
|
|
837
|
+
children: content
|
|
838
|
+
},
|
|
839
|
+
child.path || `ext-${idx}`
|
|
840
|
+
);
|
|
841
|
+
}
|
|
842
|
+
return /* @__PURE__ */ jsx11(AccordionMenuItem, { value: child.path || "#", children: /* @__PURE__ */ jsx11(Link5, { href: child.path || "#", children: content }) }, idx);
|
|
843
|
+
})
|
|
844
|
+
] }, index);
|
|
845
|
+
})
|
|
846
|
+
}
|
|
847
|
+
);
|
|
848
|
+
}
|
|
849
|
+
|
|
850
|
+
// src/components/layouts/site-footer.tsx
|
|
851
|
+
import Link6 from "next/link";
|
|
852
|
+
import { useTranslations as useTranslations9 } from "next-intl";
|
|
853
|
+
import { useConfig as useConfig5 } from "@pelatform/starter.hook";
|
|
854
|
+
import { cn as cn5 } from "pelatform-ui";
|
|
855
|
+
import { SiteFooter as UISiteFooter } from "pelatform-ui/components";
|
|
856
|
+
import { Button as Button3 } from "pelatform-ui/default";
|
|
857
|
+
import { jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
858
|
+
function SiteFooter({ disableProjectBy = false }) {
|
|
859
|
+
const { app } = useConfig5();
|
|
860
|
+
const t = useTranslations9();
|
|
861
|
+
return /* @__PURE__ */ jsxs10(UISiteFooter, { className: cn5("*:gap-2! *:py-0!", disableProjectBy ? "*:justify-center!" : ""), children: [
|
|
862
|
+
/* @__PURE__ */ jsxs10("div", { className: "text-balance text-center text-muted-foreground text-sm leading-loose md:text-left", children: [
|
|
863
|
+
"\xA9 ",
|
|
864
|
+
(/* @__PURE__ */ new Date()).getFullYear(),
|
|
865
|
+
" ",
|
|
866
|
+
app.name,
|
|
867
|
+
". ",
|
|
868
|
+
t("ui.common.copyright")
|
|
869
|
+
] }),
|
|
870
|
+
!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: [
|
|
871
|
+
/* @__PURE__ */ jsx12("span", { className: "text-muted-foreground", children: t("ui.common.projectBy") }),
|
|
872
|
+
" ",
|
|
873
|
+
/* @__PURE__ */ jsx12(Button3, { mode: "link", underline: "dashed", children: /* @__PURE__ */ jsx12(
|
|
874
|
+
Link6,
|
|
875
|
+
{
|
|
876
|
+
href: "https://pelatform.com",
|
|
877
|
+
target: "_blank",
|
|
878
|
+
className: "font-medium text-foreground",
|
|
879
|
+
children: "Pelatform"
|
|
880
|
+
}
|
|
881
|
+
) })
|
|
882
|
+
] }) })
|
|
883
|
+
] });
|
|
884
|
+
}
|
|
885
|
+
|
|
886
|
+
// src/components/layouts/site-header.tsx
|
|
887
|
+
import { useState as useState3 } from "react";
|
|
888
|
+
import Link7 from "next/link";
|
|
889
|
+
import { usePathname as usePathname4, useRouter as useRouter3 } from "next/navigation";
|
|
890
|
+
import { useTranslations as useTranslations10 } from "next-intl";
|
|
891
|
+
import { useConfig as useConfig6, useSession as useSession4 } from "@pelatform/starter.hook";
|
|
892
|
+
import {
|
|
893
|
+
MainNav,
|
|
894
|
+
MobileNav,
|
|
895
|
+
MobileNavItemRenderer,
|
|
896
|
+
ModeSwitcher as ModeSwitcher3,
|
|
897
|
+
SiteHeader as UISiteHeader
|
|
898
|
+
} from "pelatform-ui/components";
|
|
899
|
+
import { Button as Button4, Separator } from "pelatform-ui/default";
|
|
900
|
+
import { jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
901
|
+
function SiteHeader({
|
|
902
|
+
menu,
|
|
903
|
+
logo = /* @__PURE__ */ jsx13(LogoWithHref, { href: "/home" })
|
|
904
|
+
}) {
|
|
905
|
+
const { path } = useConfig6();
|
|
906
|
+
const pathname = usePathname4();
|
|
907
|
+
const router = useRouter3();
|
|
908
|
+
const t = useTranslations10();
|
|
909
|
+
const { isPending, session, user } = useSession4();
|
|
910
|
+
const [, setMobileNavOpen] = useState3(false);
|
|
911
|
+
const isAuthenticated = !isPending && session && user;
|
|
912
|
+
return /* @__PURE__ */ jsxs11(UISiteHeader, { className: "backdrop-blur-none supports-backdrop-filter:bg-background", children: [
|
|
913
|
+
/* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-4.5", children: [
|
|
914
|
+
logo,
|
|
915
|
+
/* @__PURE__ */ jsx13(MainNav, { Link: Link7, pathname, items: menu })
|
|
916
|
+
] }),
|
|
917
|
+
/* @__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: [
|
|
918
|
+
/* @__PURE__ */ jsx13(ModeSwitcher3, {}),
|
|
919
|
+
/* @__PURE__ */ jsx13(LanguageSwitcher, {}),
|
|
920
|
+
/* @__PURE__ */ jsx13(Separator, { orientation: "vertical", className: "mx-3 h-5 max-lg:hidden" }),
|
|
921
|
+
/* @__PURE__ */ jsx13(MobileNav, { children: /* @__PURE__ */ jsxs11("div", { className: "flex flex-col space-y-3", children: [
|
|
922
|
+
menu?.map(
|
|
923
|
+
(item, navIndex) => item.href || item.children ? /* @__PURE__ */ jsx13(
|
|
924
|
+
MobileNavItemRenderer,
|
|
925
|
+
{
|
|
926
|
+
item,
|
|
927
|
+
Link: Link7,
|
|
928
|
+
pathname,
|
|
929
|
+
level: 1,
|
|
930
|
+
onOpenChange: setMobileNavOpen
|
|
931
|
+
},
|
|
932
|
+
`nav-${navIndex}-${item.href}`
|
|
933
|
+
) : null
|
|
934
|
+
),
|
|
935
|
+
/* @__PURE__ */ jsx13("div", { className: "border-t pt-3", children: isAuthenticated ? /* @__PURE__ */ jsx13(
|
|
936
|
+
Button4,
|
|
937
|
+
{
|
|
938
|
+
variant: "outline",
|
|
939
|
+
size: "sm",
|
|
940
|
+
className: "w-full",
|
|
941
|
+
onClick: () => router.push(path.auth.SIGN_OUT),
|
|
942
|
+
children: t("ui.navigation.signOut")
|
|
943
|
+
}
|
|
944
|
+
) : /* @__PURE__ */ jsx13(Button4, { variant: "secondary", size: "sm", className: "w-full", children: /* @__PURE__ */ jsx13(Link7, { href: path.auth.SIGN_IN, children: t("ui.navigation.signIn") }) }) })
|
|
945
|
+
] }) }),
|
|
946
|
+
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") }) })
|
|
947
|
+
] }) })
|
|
948
|
+
] });
|
|
949
|
+
}
|
|
950
|
+
function SiteHeaderSecondary({
|
|
951
|
+
menu,
|
|
952
|
+
logo = /* @__PURE__ */ jsx13(LogoWithHref, { href: "/home" }),
|
|
953
|
+
loginLink
|
|
954
|
+
}) {
|
|
955
|
+
const pathname = usePathname4();
|
|
956
|
+
const t = useTranslations10();
|
|
957
|
+
const [, setMobileNavOpen] = useState3(false);
|
|
958
|
+
return /* @__PURE__ */ jsxs11(UISiteHeader, { className: "backdrop-blur-none supports-backdrop-filter:bg-background", children: [
|
|
959
|
+
/* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-4.5", children: [
|
|
960
|
+
logo,
|
|
961
|
+
/* @__PURE__ */ jsx13(MainNav, { Link: Link7, pathname, items: menu })
|
|
962
|
+
] }),
|
|
963
|
+
/* @__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: [
|
|
964
|
+
/* @__PURE__ */ jsx13(ModeSwitcher3, {}),
|
|
965
|
+
/* @__PURE__ */ jsx13(LanguageSwitcher, {}),
|
|
966
|
+
/* @__PURE__ */ jsx13(Separator, { orientation: "vertical", className: "mx-3 h-5 max-lg:hidden" }),
|
|
967
|
+
/* @__PURE__ */ jsx13(MobileNav, { children: /* @__PURE__ */ jsxs11("div", { className: "flex flex-col space-y-3", children: [
|
|
968
|
+
menu?.map(
|
|
969
|
+
(item, navIndex) => item.href || item.children ? /* @__PURE__ */ jsx13(
|
|
970
|
+
MobileNavItemRenderer,
|
|
971
|
+
{
|
|
972
|
+
item,
|
|
973
|
+
Link: Link7,
|
|
974
|
+
pathname,
|
|
975
|
+
level: 1,
|
|
976
|
+
onOpenChange: setMobileNavOpen
|
|
977
|
+
},
|
|
978
|
+
`nav-${navIndex}-${item.href}`
|
|
979
|
+
) : null
|
|
980
|
+
),
|
|
981
|
+
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") }) }) })
|
|
982
|
+
] }) }),
|
|
983
|
+
loginLink && /* @__PURE__ */ jsx13(Button4, { variant: "secondary", size: "sm", className: "hidden md:flex", children: /* @__PURE__ */ jsx13(Link7, { href: loginLink, children: t("ui.navigation.signIn") }) })
|
|
984
|
+
] }) })
|
|
985
|
+
] });
|
|
986
|
+
}
|
|
987
|
+
|
|
988
|
+
// src/components/providers/layout.tsx
|
|
989
|
+
import { useEffect as useEffect3, useState as useState4 } from "react";
|
|
990
|
+
import { LayoutContext } from "@pelatform/starter.hook";
|
|
991
|
+
import { cn as cn6 } from "pelatform-ui";
|
|
992
|
+
import { useIsMobile } from "pelatform-ui/hooks";
|
|
993
|
+
import { jsx as jsx14 } from "react/jsx-runtime";
|
|
994
|
+
var SIDEBAR_WIDTH = "240px";
|
|
995
|
+
var HEADER_HEIGHT = "54px";
|
|
996
|
+
var SIDEBAR_WIDTH_MOBILE = "240px";
|
|
997
|
+
var HEADER_HEIGHT_MOBILE = "54px";
|
|
998
|
+
function LayoutProvider({
|
|
999
|
+
children,
|
|
1000
|
+
style: customStyle,
|
|
1001
|
+
bodyClassName = "",
|
|
1002
|
+
className = "",
|
|
1003
|
+
logoHeader = /* @__PURE__ */ jsx14(LogoWithHref, {})
|
|
1004
|
+
}) {
|
|
1005
|
+
const isMobile = useIsMobile();
|
|
1006
|
+
const [isSidebarOpen, setIsSidebarOpen] = useState4(true);
|
|
1007
|
+
const defaultStyle = {
|
|
1008
|
+
"--sidebar-width": SIDEBAR_WIDTH,
|
|
1009
|
+
"--header-height": HEADER_HEIGHT,
|
|
1010
|
+
"--sidebar-width-mobile": SIDEBAR_WIDTH_MOBILE,
|
|
1011
|
+
"--header-height-mobile": HEADER_HEIGHT_MOBILE
|
|
1012
|
+
};
|
|
1013
|
+
const style = {
|
|
1014
|
+
...defaultStyle,
|
|
1015
|
+
...customStyle
|
|
1016
|
+
};
|
|
1017
|
+
const sidebarToggle = () => setIsSidebarOpen((open) => !open);
|
|
1018
|
+
useEffect3(() => {
|
|
1019
|
+
if (bodyClassName) {
|
|
1020
|
+
const body = document.body;
|
|
1021
|
+
const existingClasses = body.className;
|
|
1022
|
+
body.className = `${existingClasses} ${bodyClassName}`.trim();
|
|
1023
|
+
return () => {
|
|
1024
|
+
body.className = existingClasses;
|
|
1025
|
+
};
|
|
1026
|
+
}
|
|
1027
|
+
}, [bodyClassName]);
|
|
1028
|
+
return /* @__PURE__ */ jsx14(
|
|
1029
|
+
LayoutContext.Provider,
|
|
1030
|
+
{
|
|
1031
|
+
value: {
|
|
1032
|
+
bodyClassName,
|
|
1033
|
+
style,
|
|
1034
|
+
isMobile,
|
|
1035
|
+
isSidebarOpen,
|
|
1036
|
+
sidebarToggle,
|
|
1037
|
+
logoHeader
|
|
1038
|
+
},
|
|
1039
|
+
children: /* @__PURE__ */ jsx14(
|
|
1040
|
+
"div",
|
|
1041
|
+
{
|
|
1042
|
+
"data-slot": "layout-wrapper",
|
|
1043
|
+
className: cn6("flex grow", className),
|
|
1044
|
+
"data-sidebar-open": isSidebarOpen,
|
|
1045
|
+
style,
|
|
1046
|
+
children
|
|
1047
|
+
}
|
|
1048
|
+
)
|
|
1049
|
+
}
|
|
1050
|
+
);
|
|
1051
|
+
}
|
|
1052
|
+
|
|
1053
|
+
// src/components/layouts/wrapper.tsx
|
|
1054
|
+
import { Fragment as Fragment5, jsx as jsx15, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
1055
|
+
function LayoutWrapper({
|
|
1056
|
+
children,
|
|
1057
|
+
sidebarHeader,
|
|
1058
|
+
sidebarMenu,
|
|
1059
|
+
logoHeader
|
|
1060
|
+
}) {
|
|
1061
|
+
const sidebarContent = /* @__PURE__ */ jsxs12(Fragment5, { children: [
|
|
1062
|
+
sidebarHeader,
|
|
1063
|
+
/* @__PURE__ */ jsx15(SidebarContent, { children: sidebarMenu })
|
|
1064
|
+
] });
|
|
1065
|
+
return /* @__PURE__ */ jsxs12(LayoutProvider, { logoHeader, children: [
|
|
1066
|
+
/* @__PURE__ */ jsxs12(Header, { children: [
|
|
1067
|
+
/* @__PURE__ */ jsx15(HeaderLeft, {}),
|
|
1068
|
+
/* @__PURE__ */ jsx15(HeaderRight, { sidebar: /* @__PURE__ */ jsx15(HeaderSidebarMobile, { children: sidebarContent }) })
|
|
1069
|
+
] }),
|
|
1070
|
+
/* @__PURE__ */ jsxs12("div", { className: "flex grow pt-(--header-height-mobile) lg:pt-(--header-height)", children: [
|
|
1071
|
+
/* @__PURE__ */ jsx15(Sidebar, { children: sidebarContent }),
|
|
1072
|
+
/* @__PURE__ */ jsx15("main", { className: "grow transition-all duration-300 lg:in-data-[sidebar-open=false]:ps-0 lg:ps-(--sidebar-width)", children })
|
|
1073
|
+
] })
|
|
1074
|
+
] });
|
|
1075
|
+
}
|
|
1076
|
+
|
|
1077
|
+
// src/components/providers/config.tsx
|
|
1078
|
+
import { useMemo as useMemo2 } from "react";
|
|
1079
|
+
import { defaultConfig, mergeConfig } from "@pelatform/starter.config";
|
|
1080
|
+
import {
|
|
1081
|
+
ConfigContext,
|
|
1082
|
+
defaultAuthQueryOptions,
|
|
1083
|
+
QueryContext
|
|
1084
|
+
} from "@pelatform/starter.hook";
|
|
1085
|
+
import { jsx as jsx16 } from "react/jsx-runtime";
|
|
1086
|
+
function ConfigProvider({ config, authClient, children, ...props }) {
|
|
1087
|
+
const mergedConfig = useMemo2(() => {
|
|
1088
|
+
return mergeConfig(defaultConfig, config);
|
|
1089
|
+
}, [config]);
|
|
1090
|
+
const configWithAuth = {
|
|
1091
|
+
...mergedConfig,
|
|
1092
|
+
authClient
|
|
1093
|
+
};
|
|
1094
|
+
return /* @__PURE__ */ jsx16(
|
|
1095
|
+
QueryContext.Provider,
|
|
1096
|
+
{
|
|
1097
|
+
value: {
|
|
1098
|
+
...defaultAuthQueryOptions,
|
|
1099
|
+
...props
|
|
1100
|
+
},
|
|
1101
|
+
children: /* @__PURE__ */ jsx16(ConfigContext.Provider, { value: configWithAuth, children })
|
|
1102
|
+
}
|
|
1103
|
+
);
|
|
1104
|
+
}
|
|
1105
|
+
|
|
1106
|
+
// src/components/providers/shared.tsx
|
|
1107
|
+
import { Suspense as Suspense2 } from "react";
|
|
1108
|
+
import { ReactQueryDevtools } from "@tanstack/react-query-devtools";
|
|
1109
|
+
import { NextIntlClientProvider } from "next-intl";
|
|
1110
|
+
import { useConfig as useConfig7 } from "@pelatform/starter.hook";
|
|
1111
|
+
import { QueryProvider, ThemeProvider } from "pelatform-ui/components";
|
|
1112
|
+
import { Toaster as Sonner } from "pelatform-ui/default";
|
|
1113
|
+
import { jsx as jsx17, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
1114
|
+
function SharedProviders({
|
|
1115
|
+
children,
|
|
1116
|
+
locale,
|
|
1117
|
+
messages,
|
|
1118
|
+
timeZone = "Asia/Jakarta",
|
|
1119
|
+
sonnerPosition = "top-center"
|
|
1120
|
+
}) {
|
|
1121
|
+
const config = useConfig7();
|
|
1122
|
+
return /* @__PURE__ */ jsxs13(QueryProvider, { children: [
|
|
1123
|
+
/* @__PURE__ */ jsx17(ThemeProvider, { defaultTheme: config.ui.defaultTheme, children: /* @__PURE__ */ jsx17(NextIntlClientProvider, { locale, messages, timeZone, children: /* @__PURE__ */ jsxs13(Suspense2, { children: [
|
|
1124
|
+
children,
|
|
1125
|
+
/* @__PURE__ */ jsx17(Sonner, { position: sonnerPosition })
|
|
1126
|
+
] }) }) }),
|
|
1127
|
+
/* @__PURE__ */ jsx17(ReactQueryDevtools, { initialIsOpen: false })
|
|
1128
|
+
] });
|
|
1129
|
+
}
|
|
1130
|
+
|
|
3
1131
|
// src/components/utils/card.tsx
|
|
4
1132
|
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";
|
|
1133
|
+
import { cn as cn7 } from "pelatform-ui";
|
|
1134
|
+
import { Button as Button5, Card, CardContent, CardFooter, Skeleton as Skeleton4, Spinner } from "pelatform-ui/default";
|
|
1135
|
+
import { Fragment as Fragment6, jsx as jsx18, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
8
1136
|
function CardComponent({
|
|
9
1137
|
children,
|
|
10
1138
|
className,
|
|
@@ -20,10 +1148,10 @@ function CardComponent({
|
|
|
20
1148
|
isSubmitting,
|
|
21
1149
|
...props
|
|
22
1150
|
}) {
|
|
23
|
-
return /* @__PURE__ */
|
|
1151
|
+
return /* @__PURE__ */ jsxs14(
|
|
24
1152
|
Card,
|
|
25
1153
|
{
|
|
26
|
-
className:
|
|
1154
|
+
className: cn7(
|
|
27
1155
|
"w-full overflow-hidden",
|
|
28
1156
|
isDestructive && "border-destructive/70",
|
|
29
1157
|
className,
|
|
@@ -31,8 +1159,8 @@ function CardComponent({
|
|
|
31
1159
|
),
|
|
32
1160
|
...props,
|
|
33
1161
|
children: [
|
|
34
|
-
/* @__PURE__ */
|
|
35
|
-
/* @__PURE__ */
|
|
1162
|
+
/* @__PURE__ */ jsxs14(CardContent, { className: cn7("space-y-6 p-5 sm:p-10", classNames?.content), children: [
|
|
1163
|
+
/* @__PURE__ */ jsx18(
|
|
36
1164
|
CardHeaderComponent,
|
|
37
1165
|
{
|
|
38
1166
|
classNames,
|
|
@@ -43,7 +1171,7 @@ function CardComponent({
|
|
|
43
1171
|
),
|
|
44
1172
|
children
|
|
45
1173
|
] }),
|
|
46
|
-
/* @__PURE__ */
|
|
1174
|
+
/* @__PURE__ */ jsx18(
|
|
47
1175
|
CardFooterComponent,
|
|
48
1176
|
{
|
|
49
1177
|
classNames,
|
|
@@ -67,12 +1195,12 @@ function CardHeaderComponent({
|
|
|
67
1195
|
description,
|
|
68
1196
|
isPending
|
|
69
1197
|
}) {
|
|
70
|
-
return /* @__PURE__ */
|
|
71
|
-
/* @__PURE__ */
|
|
72
|
-
description && /* @__PURE__ */
|
|
73
|
-
] }) : /* @__PURE__ */
|
|
74
|
-
/* @__PURE__ */
|
|
75
|
-
description && /* @__PURE__ */
|
|
1198
|
+
return /* @__PURE__ */ jsx18("div", { className: cn7("flex flex-col space-y-2", className, classNames?.header), children: isPending ? /* @__PURE__ */ jsxs14(Fragment6, { children: [
|
|
1199
|
+
/* @__PURE__ */ jsx18(Skeleton4, { className: cn7("h-7 w-1/3", classNames?.skeleton) }),
|
|
1200
|
+
description && /* @__PURE__ */ jsx18(Skeleton4, { className: cn7("h-5 w-2/3", classNames?.skeleton) })
|
|
1201
|
+
] }) : /* @__PURE__ */ jsxs14(Fragment6, { children: [
|
|
1202
|
+
/* @__PURE__ */ jsx18("h2", { className: cn7("font-medium text-xl", classNames?.title), children: title }),
|
|
1203
|
+
description && /* @__PURE__ */ jsx18("p", { className: cn7("text-muted-foreground text-sm", classNames?.description), children: description })
|
|
76
1204
|
] }) });
|
|
77
1205
|
}
|
|
78
1206
|
function CardFooterComponent({
|
|
@@ -86,40 +1214,40 @@ function CardFooterComponent({
|
|
|
86
1214
|
isPending,
|
|
87
1215
|
isSubmitting
|
|
88
1216
|
}) {
|
|
89
|
-
return /* @__PURE__ */
|
|
1217
|
+
return /* @__PURE__ */ jsx18(
|
|
90
1218
|
CardFooter,
|
|
91
1219
|
{
|
|
92
|
-
className:
|
|
1220
|
+
className: cn7(
|
|
93
1221
|
"flex items-center justify-between space-x-4 bg-muted p-3 sm:px-10",
|
|
94
1222
|
isDestructive && "border-destructive/70",
|
|
95
1223
|
className,
|
|
96
1224
|
classNames?.footer
|
|
97
1225
|
),
|
|
98
|
-
children: isPending ? /* @__PURE__ */
|
|
99
|
-
instructions && /* @__PURE__ */
|
|
100
|
-
|
|
1226
|
+
children: isPending ? /* @__PURE__ */ jsxs14(Fragment6, { children: [
|
|
1227
|
+
instructions && /* @__PURE__ */ jsx18(
|
|
1228
|
+
Skeleton4,
|
|
101
1229
|
{
|
|
102
|
-
className:
|
|
1230
|
+
className: cn7(
|
|
103
1231
|
"h-4 w-48 max-w-full bg-muted-foreground/10 md:h-5 md:w-60",
|
|
104
1232
|
classNames?.skeleton
|
|
105
1233
|
)
|
|
106
1234
|
}
|
|
107
1235
|
),
|
|
108
|
-
actionLabel && /* @__PURE__ */
|
|
109
|
-
|
|
1236
|
+
actionLabel && /* @__PURE__ */ jsx18(
|
|
1237
|
+
Skeleton4,
|
|
110
1238
|
{
|
|
111
|
-
className:
|
|
1239
|
+
className: cn7("h-8 w-20 bg-muted-foreground/10 md:ms-auto", classNames?.skeleton)
|
|
112
1240
|
}
|
|
113
1241
|
)
|
|
114
|
-
] }) : /* @__PURE__ */
|
|
115
|
-
instructions && /* @__PURE__ */
|
|
1242
|
+
] }) : /* @__PURE__ */ jsxs14(Fragment6, { children: [
|
|
1243
|
+
instructions && /* @__PURE__ */ jsx18(
|
|
116
1244
|
"div",
|
|
117
1245
|
{
|
|
118
|
-
className:
|
|
1246
|
+
className: cn7("text-muted-foreground text-xs md:text-sm", classNames?.instructions),
|
|
119
1247
|
children: instructions
|
|
120
1248
|
}
|
|
121
1249
|
),
|
|
122
|
-
actionLabel && /* @__PURE__ */
|
|
1250
|
+
actionLabel && /* @__PURE__ */ jsx18(
|
|
123
1251
|
CardActionComponent,
|
|
124
1252
|
{
|
|
125
1253
|
classNames,
|
|
@@ -147,13 +1275,13 @@ function CardActionComponent({
|
|
|
147
1275
|
const formState = useFormState();
|
|
148
1276
|
isSubmitting = formState.isSubmitting;
|
|
149
1277
|
}
|
|
150
|
-
return /* @__PURE__ */
|
|
151
|
-
|
|
1278
|
+
return /* @__PURE__ */ jsxs14(
|
|
1279
|
+
Button5,
|
|
152
1280
|
{
|
|
153
1281
|
type: onClick ? "button" : "submit",
|
|
154
1282
|
variant: isDestructive ? "destructive" : "primary",
|
|
155
1283
|
size: "sm",
|
|
156
|
-
className:
|
|
1284
|
+
className: cn7(
|
|
157
1285
|
"ms-auto",
|
|
158
1286
|
isSubmitting || disabled ? "pointer-events-auto! cursor-not-allowed" : "",
|
|
159
1287
|
classNames?.button,
|
|
@@ -163,7 +1291,7 @@ function CardActionComponent({
|
|
|
163
1291
|
disabled: isSubmitting || disabled,
|
|
164
1292
|
...props,
|
|
165
1293
|
children: [
|
|
166
|
-
isSubmitting && /* @__PURE__ */
|
|
1294
|
+
isSubmitting && /* @__PURE__ */ jsx18(Spinner, {}),
|
|
167
1295
|
actionLabel
|
|
168
1296
|
]
|
|
169
1297
|
}
|
|
@@ -171,10 +1299,10 @@ function CardActionComponent({
|
|
|
171
1299
|
}
|
|
172
1300
|
|
|
173
1301
|
// src/components/utils/dialog.tsx
|
|
174
|
-
import { useTranslations } from "next-intl";
|
|
175
|
-
import { cn as
|
|
1302
|
+
import { useTranslations as useTranslations11 } from "next-intl";
|
|
1303
|
+
import { cn as cn8 } from "pelatform-ui";
|
|
176
1304
|
import {
|
|
177
|
-
Button as
|
|
1305
|
+
Button as Button6,
|
|
178
1306
|
Dialog,
|
|
179
1307
|
DialogContent,
|
|
180
1308
|
DialogDescription,
|
|
@@ -182,7 +1310,7 @@ import {
|
|
|
182
1310
|
DialogHeader,
|
|
183
1311
|
DialogTitle
|
|
184
1312
|
} from "pelatform-ui/default";
|
|
185
|
-
import { jsx as
|
|
1313
|
+
import { jsx as jsx19, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
186
1314
|
function DialogComponent({
|
|
187
1315
|
children,
|
|
188
1316
|
classNames,
|
|
@@ -195,18 +1323,18 @@ function DialogComponent({
|
|
|
195
1323
|
button,
|
|
196
1324
|
...props
|
|
197
1325
|
}) {
|
|
198
|
-
return /* @__PURE__ */
|
|
1326
|
+
return /* @__PURE__ */ jsx19(Dialog, { onOpenChange, ...props, children: /* @__PURE__ */ jsxs15(
|
|
199
1327
|
DialogContent,
|
|
200
1328
|
{
|
|
201
1329
|
onOpenAutoFocus: (e) => e.preventDefault(),
|
|
202
1330
|
className: classNames?.dialog?.content,
|
|
203
1331
|
children: [
|
|
204
|
-
/* @__PURE__ */
|
|
205
|
-
/* @__PURE__ */
|
|
206
|
-
description && /* @__PURE__ */
|
|
1332
|
+
/* @__PURE__ */ jsxs15(DialogHeader, { className: cn8("space-y-2", classNames?.header), children: [
|
|
1333
|
+
/* @__PURE__ */ jsx19(DialogTitle, { className: classNames?.title, children: title }),
|
|
1334
|
+
description && /* @__PURE__ */ jsx19(DialogDescription, { className: classNames?.description, children: description })
|
|
207
1335
|
] }),
|
|
208
1336
|
children,
|
|
209
|
-
!disableFooter && /* @__PURE__ */
|
|
1337
|
+
!disableFooter && /* @__PURE__ */ jsx19(
|
|
210
1338
|
DialogFooterComponent,
|
|
211
1339
|
{
|
|
212
1340
|
classNames,
|
|
@@ -228,14 +1356,14 @@ function DialogFooterComponent({
|
|
|
228
1356
|
cancelButtonDisabled,
|
|
229
1357
|
button
|
|
230
1358
|
}) {
|
|
231
|
-
const t =
|
|
232
|
-
return /* @__PURE__ */
|
|
233
|
-
cancelButton && /* @__PURE__ */
|
|
234
|
-
|
|
1359
|
+
const t = useTranslations11();
|
|
1360
|
+
return /* @__PURE__ */ jsxs15(DialogFooter, { className: cn8(className, classNames?.dialog?.footer), children: [
|
|
1361
|
+
cancelButton && /* @__PURE__ */ jsx19(
|
|
1362
|
+
Button6,
|
|
235
1363
|
{
|
|
236
1364
|
type: "button",
|
|
237
1365
|
variant: "secondary",
|
|
238
|
-
className:
|
|
1366
|
+
className: cn8(classNames?.button, classNames?.secondaryButton),
|
|
239
1367
|
onClick: () => onOpenChange?.(false),
|
|
240
1368
|
disabled: cancelButtonDisabled,
|
|
241
1369
|
children: t("common.actions.cancel")
|
|
@@ -246,154 +1374,41 @@ function DialogFooterComponent({
|
|
|
246
1374
|
}
|
|
247
1375
|
|
|
248
1376
|
// src/components/utils/skeleton.tsx
|
|
249
|
-
import { cn as
|
|
250
|
-
import { Card as Card2, Skeleton as
|
|
251
|
-
import { jsx as
|
|
1377
|
+
import { cn as cn9 } from "pelatform-ui";
|
|
1378
|
+
import { Card as Card2, Skeleton as Skeleton5 } from "pelatform-ui/default";
|
|
1379
|
+
import { jsx as jsx20, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
252
1380
|
function SkeletonViewComponent({ classNames }) {
|
|
253
|
-
return /* @__PURE__ */
|
|
254
|
-
/* @__PURE__ */
|
|
255
|
-
/* @__PURE__ */
|
|
256
|
-
/* @__PURE__ */
|
|
1381
|
+
return /* @__PURE__ */ jsxs16(Card2, { className: cn9("flex-row items-center gap-3 px-4 py-3", classNames?.cell), children: [
|
|
1382
|
+
/* @__PURE__ */ jsxs16("div", { className: "flex items-center gap-2", children: [
|
|
1383
|
+
/* @__PURE__ */ jsx20(Skeleton5, { className: cn9("size-5 rounded-full", classNames?.skeleton) }),
|
|
1384
|
+
/* @__PURE__ */ jsx20("div", { children: /* @__PURE__ */ jsx20(Skeleton5, { className: cn9("h-4 w-32", classNames?.skeleton) }) })
|
|
257
1385
|
] }),
|
|
258
|
-
/* @__PURE__ */
|
|
1386
|
+
/* @__PURE__ */ jsx20(Skeleton5, { className: cn9("ms-auto size-8 w-16", classNames?.skeleton) })
|
|
259
1387
|
] });
|
|
260
1388
|
}
|
|
261
1389
|
function SkeletonInputComponent({ classNames }) {
|
|
262
|
-
return /* @__PURE__ */
|
|
263
|
-
/* @__PURE__ */
|
|
264
|
-
/* @__PURE__ */
|
|
1390
|
+
return /* @__PURE__ */ jsxs16("div", { className: "flex flex-col gap-1.5", children: [
|
|
1391
|
+
/* @__PURE__ */ jsx20(Skeleton5, { className: cn9("h-4 w-32", classNames?.skeleton) }),
|
|
1392
|
+
/* @__PURE__ */ jsx20(Skeleton5, { className: cn9("h-9 w-full", classNames?.skeleton) })
|
|
265
1393
|
] });
|
|
266
1394
|
}
|
|
267
1395
|
|
|
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
1396
|
// src/components/display-id.tsx
|
|
382
1397
|
import { useRef } from "react";
|
|
383
1398
|
import { CheckIcon, CopyIcon } from "lucide-react";
|
|
384
|
-
import { useTranslations as
|
|
385
|
-
import { cn as
|
|
1399
|
+
import { useTranslations as useTranslations12 } from "next-intl";
|
|
1400
|
+
import { cn as cn10 } from "pelatform-ui";
|
|
386
1401
|
import {
|
|
387
|
-
Button as
|
|
1402
|
+
Button as Button7,
|
|
388
1403
|
Input,
|
|
389
|
-
Skeleton as
|
|
1404
|
+
Skeleton as Skeleton6,
|
|
390
1405
|
Tooltip,
|
|
391
1406
|
TooltipContent,
|
|
392
1407
|
TooltipProvider,
|
|
393
1408
|
TooltipTrigger
|
|
394
1409
|
} from "pelatform-ui/default";
|
|
395
1410
|
import { useCopyToClipboard } from "pelatform-ui/hooks";
|
|
396
|
-
import { jsx as
|
|
1411
|
+
import { jsx as jsx21, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
397
1412
|
function DisplayIdCard({
|
|
398
1413
|
className,
|
|
399
1414
|
classNames,
|
|
@@ -403,217 +1418,133 @@ function DisplayIdCard({
|
|
|
403
1418
|
description,
|
|
404
1419
|
...props
|
|
405
1420
|
}) {
|
|
406
|
-
const t =
|
|
1421
|
+
const t = useTranslations12();
|
|
407
1422
|
const { copy, copied } = useCopyToClipboard();
|
|
408
1423
|
const inputRef = useRef(null);
|
|
409
1424
|
const handleCopy = () => {
|
|
410
1425
|
if (inputRef.current) {
|
|
411
1426
|
copy(inputRef.current.value);
|
|
412
1427
|
}
|
|
413
|
-
};
|
|
414
|
-
return /* @__PURE__ */
|
|
415
|
-
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
|
|
539
|
-
}
|
|
1428
|
+
};
|
|
1429
|
+
return /* @__PURE__ */ jsx21(
|
|
1430
|
+
CardComponent,
|
|
1431
|
+
{
|
|
1432
|
+
className,
|
|
1433
|
+
classNames,
|
|
1434
|
+
title,
|
|
1435
|
+
description,
|
|
1436
|
+
isPending,
|
|
1437
|
+
...props,
|
|
1438
|
+
children: isPending ? /* @__PURE__ */ jsx21(Skeleton6, { className: cn10("h-11.5 w-full max-w-md", classNames?.skeleton) }) : /* @__PURE__ */ jsxs17(
|
|
1439
|
+
"div",
|
|
1440
|
+
{
|
|
1441
|
+
className: cn10(
|
|
1442
|
+
"flex w-full max-w-md items-center justify-between rounded-md border p-2",
|
|
1443
|
+
classNames?.grid
|
|
1444
|
+
),
|
|
1445
|
+
children: [
|
|
1446
|
+
/* @__PURE__ */ jsx21(Input, { value: id, ref: inputRef, disabled: true, className: "border-none! bg-transparent!" }),
|
|
1447
|
+
/* @__PURE__ */ jsx21(TooltipProvider, { delayDuration: 0, children: /* @__PURE__ */ jsxs17(Tooltip, { children: [
|
|
1448
|
+
/* @__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 }) }) }),
|
|
1449
|
+
/* @__PURE__ */ jsx21(TooltipContent, { className: "px-2 py-1 text-xs", children: t("common.actions.copy") })
|
|
1450
|
+
] }) })
|
|
1451
|
+
]
|
|
1452
|
+
}
|
|
1453
|
+
)
|
|
1454
|
+
}
|
|
540
1455
|
);
|
|
541
1456
|
}
|
|
542
1457
|
|
|
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__ */
|
|
1458
|
+
// src/components/empty-state.tsx
|
|
1459
|
+
import Link8 from "next/link";
|
|
1460
|
+
import { useTranslations as useTranslations13 } from "next-intl";
|
|
1461
|
+
import { cn as cn11 } from "pelatform-ui";
|
|
1462
|
+
import { jsx as jsx22, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
1463
|
+
function EmptyState({
|
|
1464
|
+
className,
|
|
1465
|
+
icon: Icon,
|
|
1466
|
+
title,
|
|
1467
|
+
description,
|
|
1468
|
+
learnMore,
|
|
1469
|
+
learnMoreText,
|
|
1470
|
+
children
|
|
1471
|
+
}) {
|
|
1472
|
+
const t = useTranslations13();
|
|
1473
|
+
return /* @__PURE__ */ jsxs18("div", { className: cn11("flex flex-col items-center justify-center gap-y-4", className), children: [
|
|
1474
|
+
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" }) }),
|
|
1475
|
+
/* @__PURE__ */ jsx22("p", { className: "text-center font-medium text-base text-foreground", children: title }),
|
|
1476
|
+
description && /* @__PURE__ */ jsxs18("p", { className: "max-w-sm text-balance text-center text-muted-foreground text-sm", children: [
|
|
1477
|
+
description,
|
|
1478
|
+
" ",
|
|
1479
|
+
learnMore && /* @__PURE__ */ jsxs18(
|
|
1480
|
+
Link8,
|
|
1481
|
+
{
|
|
1482
|
+
href: learnMore,
|
|
1483
|
+
className: "text-foreground underline underline-offset-2 transition-colors hover:text-primary",
|
|
1484
|
+
children: [
|
|
1485
|
+
learnMoreText ?? t("ui.common.learnMore"),
|
|
1486
|
+
" \u2197"
|
|
1487
|
+
]
|
|
1488
|
+
}
|
|
1489
|
+
)
|
|
1490
|
+
] }),
|
|
1491
|
+
children
|
|
561
1492
|
] });
|
|
562
1493
|
}
|
|
563
1494
|
|
|
564
1495
|
// src/components/otp-input-group.tsx
|
|
565
1496
|
import { InputOTPGroup, InputOTPSeparator, InputOTPSlot } from "pelatform-ui/default";
|
|
566
|
-
import { Fragment as
|
|
1497
|
+
import { Fragment as Fragment7, jsx as jsx23, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
567
1498
|
function OTPInputGroup({ otpSeparators = 0 }) {
|
|
568
1499
|
if (otpSeparators === 0) {
|
|
569
|
-
return /* @__PURE__ */
|
|
570
|
-
/* @__PURE__ */
|
|
571
|
-
/* @__PURE__ */
|
|
572
|
-
/* @__PURE__ */
|
|
573
|
-
/* @__PURE__ */
|
|
574
|
-
/* @__PURE__ */
|
|
575
|
-
/* @__PURE__ */
|
|
1500
|
+
return /* @__PURE__ */ jsxs19(InputOTPGroup, { children: [
|
|
1501
|
+
/* @__PURE__ */ jsx23(InputOTPSlot, { index: 0 }),
|
|
1502
|
+
/* @__PURE__ */ jsx23(InputOTPSlot, { index: 1 }),
|
|
1503
|
+
/* @__PURE__ */ jsx23(InputOTPSlot, { index: 2 }),
|
|
1504
|
+
/* @__PURE__ */ jsx23(InputOTPSlot, { index: 3 }),
|
|
1505
|
+
/* @__PURE__ */ jsx23(InputOTPSlot, { index: 4 }),
|
|
1506
|
+
/* @__PURE__ */ jsx23(InputOTPSlot, { index: 5 })
|
|
576
1507
|
] });
|
|
577
1508
|
}
|
|
578
1509
|
if (otpSeparators === 1) {
|
|
579
|
-
return /* @__PURE__ */
|
|
580
|
-
/* @__PURE__ */
|
|
581
|
-
/* @__PURE__ */
|
|
582
|
-
/* @__PURE__ */
|
|
583
|
-
/* @__PURE__ */
|
|
1510
|
+
return /* @__PURE__ */ jsxs19(Fragment7, { children: [
|
|
1511
|
+
/* @__PURE__ */ jsxs19(InputOTPGroup, { children: [
|
|
1512
|
+
/* @__PURE__ */ jsx23(InputOTPSlot, { index: 0 }),
|
|
1513
|
+
/* @__PURE__ */ jsx23(InputOTPSlot, { index: 1 }),
|
|
1514
|
+
/* @__PURE__ */ jsx23(InputOTPSlot, { index: 2 })
|
|
584
1515
|
] }),
|
|
585
|
-
/* @__PURE__ */
|
|
586
|
-
/* @__PURE__ */
|
|
587
|
-
/* @__PURE__ */
|
|
588
|
-
/* @__PURE__ */
|
|
589
|
-
/* @__PURE__ */
|
|
1516
|
+
/* @__PURE__ */ jsx23(InputOTPSeparator, {}),
|
|
1517
|
+
/* @__PURE__ */ jsxs19(InputOTPGroup, { children: [
|
|
1518
|
+
/* @__PURE__ */ jsx23(InputOTPSlot, { index: 3 }),
|
|
1519
|
+
/* @__PURE__ */ jsx23(InputOTPSlot, { index: 4 }),
|
|
1520
|
+
/* @__PURE__ */ jsx23(InputOTPSlot, { index: 5 })
|
|
590
1521
|
] })
|
|
591
1522
|
] });
|
|
592
1523
|
}
|
|
593
|
-
return /* @__PURE__ */
|
|
594
|
-
/* @__PURE__ */
|
|
595
|
-
/* @__PURE__ */
|
|
596
|
-
/* @__PURE__ */
|
|
1524
|
+
return /* @__PURE__ */ jsxs19(Fragment7, { children: [
|
|
1525
|
+
/* @__PURE__ */ jsxs19(InputOTPGroup, { children: [
|
|
1526
|
+
/* @__PURE__ */ jsx23(InputOTPSlot, { index: 0 }),
|
|
1527
|
+
/* @__PURE__ */ jsx23(InputOTPSlot, { index: 1 })
|
|
597
1528
|
] }),
|
|
598
|
-
/* @__PURE__ */
|
|
599
|
-
/* @__PURE__ */
|
|
600
|
-
/* @__PURE__ */
|
|
601
|
-
/* @__PURE__ */
|
|
1529
|
+
/* @__PURE__ */ jsx23(InputOTPSeparator, {}),
|
|
1530
|
+
/* @__PURE__ */ jsxs19(InputOTPGroup, { children: [
|
|
1531
|
+
/* @__PURE__ */ jsx23(InputOTPSlot, { index: 2 }),
|
|
1532
|
+
/* @__PURE__ */ jsx23(InputOTPSlot, { index: 3 })
|
|
602
1533
|
] }),
|
|
603
|
-
/* @__PURE__ */
|
|
604
|
-
/* @__PURE__ */
|
|
605
|
-
/* @__PURE__ */
|
|
606
|
-
/* @__PURE__ */
|
|
1534
|
+
/* @__PURE__ */ jsx23(InputOTPSeparator, {}),
|
|
1535
|
+
/* @__PURE__ */ jsxs19(InputOTPGroup, { children: [
|
|
1536
|
+
/* @__PURE__ */ jsx23(InputOTPSlot, { index: 4 }),
|
|
1537
|
+
/* @__PURE__ */ jsx23(InputOTPSlot, { index: 5 })
|
|
607
1538
|
] })
|
|
608
1539
|
] });
|
|
609
1540
|
}
|
|
610
1541
|
|
|
611
1542
|
// src/components/password-input.tsx
|
|
612
|
-
import { useState } from "react";
|
|
1543
|
+
import { useState as useState5 } from "react";
|
|
613
1544
|
import { EyeIcon, EyeOffIcon } from "lucide-react";
|
|
614
|
-
import { cn as
|
|
615
|
-
import { Button as
|
|
616
|
-
import { Fragment as
|
|
1545
|
+
import { cn as cn12 } from "pelatform-ui";
|
|
1546
|
+
import { Button as Button8, Input as Input2 } from "pelatform-ui/default";
|
|
1547
|
+
import { Fragment as Fragment8, jsx as jsx24, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
617
1548
|
function PasswordInput({
|
|
618
1549
|
className,
|
|
619
1550
|
variant,
|
|
@@ -621,15 +1552,15 @@ function PasswordInput({
|
|
|
621
1552
|
onChange,
|
|
622
1553
|
...props
|
|
623
1554
|
}) {
|
|
624
|
-
const [disabled, setDisabled] =
|
|
625
|
-
const [isVisible, setIsVisible] =
|
|
626
|
-
return /* @__PURE__ */
|
|
627
|
-
/* @__PURE__ */
|
|
1555
|
+
const [disabled, setDisabled] = useState5(true);
|
|
1556
|
+
const [isVisible, setIsVisible] = useState5(false);
|
|
1557
|
+
return /* @__PURE__ */ jsxs20("div", { className: "relative", children: [
|
|
1558
|
+
/* @__PURE__ */ jsx24(
|
|
628
1559
|
Input2,
|
|
629
1560
|
{
|
|
630
1561
|
type: isVisible && enableToggle ? "text" : "password",
|
|
631
1562
|
variant,
|
|
632
|
-
className:
|
|
1563
|
+
className: cn12(enableToggle && "pe-10", className),
|
|
633
1564
|
...props,
|
|
634
1565
|
onChange: (event) => {
|
|
635
1566
|
setDisabled(!event.target.value);
|
|
@@ -637,9 +1568,9 @@ function PasswordInput({
|
|
|
637
1568
|
}
|
|
638
1569
|
}
|
|
639
1570
|
),
|
|
640
|
-
enableToggle && /* @__PURE__ */
|
|
641
|
-
/* @__PURE__ */
|
|
642
|
-
|
|
1571
|
+
enableToggle && /* @__PURE__ */ jsxs20(Fragment8, { children: [
|
|
1572
|
+
/* @__PURE__ */ jsx24(
|
|
1573
|
+
Button8,
|
|
643
1574
|
{
|
|
644
1575
|
type: "button",
|
|
645
1576
|
variant: "ghost",
|
|
@@ -647,10 +1578,10 @@ function PasswordInput({
|
|
|
647
1578
|
className: "absolute end-0 top-0 bg-transparent!",
|
|
648
1579
|
onClick: () => setIsVisible(!isVisible),
|
|
649
1580
|
disabled,
|
|
650
|
-
children: isVisible ? /* @__PURE__ */
|
|
1581
|
+
children: isVisible ? /* @__PURE__ */ jsx24(EyeIcon, {}) : /* @__PURE__ */ jsx24(EyeOffIcon, {})
|
|
651
1582
|
}
|
|
652
1583
|
),
|
|
653
|
-
/* @__PURE__ */
|
|
1584
|
+
/* @__PURE__ */ jsx24("style", { children: `
|
|
654
1585
|
.hide-password-toggle::-ms-reveal,
|
|
655
1586
|
.hide-password-toggle::-ms-clear {
|
|
656
1587
|
visibility: hidden;
|
|
@@ -661,330 +1592,43 @@ function PasswordInput({
|
|
|
661
1592
|
] })
|
|
662
1593
|
] });
|
|
663
1594
|
}
|
|
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
1595
|
export {
|
|
970
1596
|
ApiKeyView,
|
|
1597
|
+
AuthLayout,
|
|
971
1598
|
CardActionComponent,
|
|
972
1599
|
CardComponent,
|
|
973
1600
|
CardFooterComponent,
|
|
974
1601
|
CardHeaderComponent,
|
|
1602
|
+
ConfigProvider,
|
|
975
1603
|
DialogComponent,
|
|
976
1604
|
DialogFooterComponent,
|
|
977
1605
|
DisplayIdCard,
|
|
978
1606
|
EmptyState,
|
|
1607
|
+
Header,
|
|
1608
|
+
HeaderLeft,
|
|
1609
|
+
HeaderRight,
|
|
1610
|
+
HeaderSidebarMobile,
|
|
979
1611
|
LanguageSwitcher,
|
|
1612
|
+
LayoutLoader,
|
|
1613
|
+
LayoutProvider,
|
|
1614
|
+
LayoutWrapper,
|
|
980
1615
|
Logo as LogoDefault,
|
|
981
1616
|
LogoWithHref,
|
|
982
1617
|
LogoWithName,
|
|
983
1618
|
OTPInputGroup,
|
|
984
1619
|
PasswordInput,
|
|
1620
|
+
SharedProviders,
|
|
1621
|
+
Sidebar,
|
|
1622
|
+
SidebarContent,
|
|
1623
|
+
SidebarContentMenu,
|
|
1624
|
+
SidebarHeaderBack,
|
|
985
1625
|
SignedInHint,
|
|
1626
|
+
SiteFooter,
|
|
1627
|
+
SiteHeader,
|
|
1628
|
+
SiteHeaderSecondary,
|
|
986
1629
|
SkeletonInputComponent,
|
|
987
1630
|
SkeletonViewComponent,
|
|
1631
|
+
Toolbar,
|
|
988
1632
|
UserAvatar,
|
|
989
1633
|
UserMenu,
|
|
990
1634
|
UserView,
|