@lukoweb/apitogo-module-user-panel 0.2.22 → 0.2.24

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.
@@ -1,126 +1,126 @@
1
- import type { ResolvedDashboardContent } from "@lukoweb/apitogo";
2
- import { Head, Link } from "@lukoweb/apitogo/components";
3
- import { useAuth } from "@lukoweb/apitogo/hooks";
4
- import { ArrowRightIcon, LayoutDashboardIcon } from "@lukoweb/apitogo/icons";
5
- import { Button } from "@lukoweb/apitogo/ui/Button.js";
6
-
7
- export type DefaultDashboardPageProps = {
8
- content: ResolvedDashboardContent;
9
- };
10
-
11
- function StatCard({
12
- label,
13
- value,
14
- sub,
15
- }: {
16
- label: string;
17
- value: string;
18
- sub: string;
19
- }) {
20
- return (
21
- <div className="rounded-xl border border-border bg-card p-5">
22
- <div className="text-xs font-medium uppercase tracking-[0.05em] text-muted-foreground">
23
- {label}
24
- </div>
25
- <div className="mt-1.5 text-[1.7rem] font-bold tracking-[-0.02em] text-foreground">
26
- {value}
27
- </div>
28
- <div className="mt-1 text-xs text-muted-foreground">{sub}</div>
29
- </div>
30
- );
31
- }
32
-
33
- export const DefaultDashboardPage = ({
34
- content,
35
- }: DefaultDashboardPageProps) => {
36
- const auth = useAuth();
37
- const title = content.title ?? "Overview";
38
- const description =
39
- content.description ??
40
- "Overview of your account activity, documentation shortcuts, and next steps.";
41
-
42
- const greeting = auth.isAuthenticated
43
- ? auth.profile?.name || auth.profile?.email
44
- : undefined;
45
-
46
- return (
47
- <div className="px-8 py-7">
48
- <Head>
49
- <title>{title}</title>
50
- </Head>
51
-
52
- <div className="mb-6 flex items-start gap-4">
53
- <div className="flex size-12 shrink-0 items-center justify-center rounded-xl bg-primary/10 text-primary">
54
- <LayoutDashboardIcon size={24} />
55
- </div>
56
- <div className="space-y-1">
57
- <h1 className="text-[1.6rem] font-bold tracking-[-0.01em]">
58
- {greeting ? `Welcome back, ${greeting}` : title}
59
- </h1>
60
- <p className="max-w-2xl text-muted-foreground">{description}</p>
61
- </div>
62
- </div>
63
-
64
- <div className="mb-6 grid grid-cols-1 gap-4 sm:grid-cols-2 xl:grid-cols-4">
65
- <StatCard
66
- label="Requests (30d)"
67
- value="—"
68
- sub="Connect billing for usage metrics"
69
- />
70
- <StatCard label="Active keys" value="—" sub="Enable API credentials" />
71
- <StatCard label="Plan" value="—" sub="Add plans in your manifest" />
72
- <StatCard label="Uptime" value="—" sub="Telemetry coming soon" />
73
- </div>
74
-
75
- <div className="mb-5 grid grid-cols-1 gap-5 lg:grid-cols-2">
76
- <div className="rounded-xl border border-border bg-card p-6">
77
- <h2 className="mb-4 text-lg font-semibold">Requests, last 14 days</h2>
78
- <div className="flex min-h-[150px] items-center justify-center rounded-lg border border-dashed border-border bg-muted/30 px-4 text-center text-sm text-muted-foreground">
79
- Usage charts appear when the dev-portal billing plugin is
80
- configured.
81
- </div>
82
- </div>
83
- <div className="rounded-xl border border-border bg-card p-6">
84
- <h2 className="mb-4 text-lg font-semibold">Quick links</h2>
85
- <div className="flex flex-col gap-3">
86
- {(content.quickLinks ?? []).length > 0 ? (
87
- content.quickLinks?.map((link) => (
88
- <Button
89
- key={link.href}
90
- asChild
91
- variant="outline"
92
- className="justify-between"
93
- >
94
- <Link to={link.href}>
95
- {link.label}
96
- <ArrowRightIcon size={16} />
97
- </Link>
98
- </Button>
99
- ))
100
- ) : (
101
- <Button asChild variant="outline" className="justify-between">
102
- <Link to="/introduction">
103
- Documentation
104
- <ArrowRightIcon size={16} />
105
- </Link>
106
- </Button>
107
- )}
108
- </div>
109
- </div>
110
- </div>
111
-
112
- <div className="rounded-xl border border-border bg-card p-6">
113
- <h2 className="mb-4 text-lg font-semibold">Recent requests</h2>
114
- <p className="text-sm text-muted-foreground">
115
- Request logs will appear when usage analytics is available.
116
- </p>
117
- </div>
118
-
119
- {!auth.isAuthenticated && auth.isAuthEnabled ? (
120
- <p className="mt-6 text-sm text-muted-foreground">
121
- Sign in to see personalized account information on your dashboard.
122
- </p>
123
- ) : null}
124
- </div>
125
- );
126
- };
1
+ import type { ResolvedDashboardContent } from "@lukoweb/apitogo";
2
+ import { Head, Link } from "@lukoweb/apitogo/components";
3
+ import { useAuth } from "@lukoweb/apitogo/hooks";
4
+ import { ArrowRightIcon, LayoutDashboardIcon } from "@lukoweb/apitogo/icons";
5
+ import { Button } from "@lukoweb/apitogo/ui/Button.js";
6
+
7
+ export type DefaultDashboardPageProps = {
8
+ content: ResolvedDashboardContent;
9
+ };
10
+
11
+ function StatCard({
12
+ label,
13
+ value,
14
+ sub,
15
+ }: {
16
+ label: string;
17
+ value: string;
18
+ sub: string;
19
+ }) {
20
+ return (
21
+ <div className="rounded-xl border border-border bg-card p-5">
22
+ <div className="text-xs font-medium uppercase tracking-[0.05em] text-muted-foreground">
23
+ {label}
24
+ </div>
25
+ <div className="mt-1.5 text-[1.7rem] font-bold tracking-[-0.02em] text-foreground">
26
+ {value}
27
+ </div>
28
+ <div className="mt-1 text-xs text-muted-foreground">{sub}</div>
29
+ </div>
30
+ );
31
+ }
32
+
33
+ export const DefaultDashboardPage = ({
34
+ content,
35
+ }: DefaultDashboardPageProps) => {
36
+ const auth = useAuth();
37
+ const title = content.title ?? "Overview";
38
+ const description =
39
+ content.description ??
40
+ "Overview of your account activity, documentation shortcuts, and next steps.";
41
+
42
+ const greeting = auth.isAuthenticated
43
+ ? auth.profile?.name || auth.profile?.email
44
+ : undefined;
45
+
46
+ return (
47
+ <div className="px-8 py-7">
48
+ <Head>
49
+ <title>{title}</title>
50
+ </Head>
51
+
52
+ <div className="mb-6 flex items-start gap-4">
53
+ <div className="flex size-12 shrink-0 items-center justify-center rounded-xl bg-primary/10 text-primary">
54
+ <LayoutDashboardIcon size={24} />
55
+ </div>
56
+ <div className="space-y-1">
57
+ <h1 className="text-[1.6rem] font-bold tracking-[-0.01em]">
58
+ {greeting ? `Welcome back, ${greeting}` : title}
59
+ </h1>
60
+ <p className="max-w-2xl text-muted-foreground">{description}</p>
61
+ </div>
62
+ </div>
63
+
64
+ <div className="mb-6 grid grid-cols-1 gap-4 sm:grid-cols-2 xl:grid-cols-4">
65
+ <StatCard
66
+ label="Requests (30d)"
67
+ value="—"
68
+ sub="Connect billing for usage metrics"
69
+ />
70
+ <StatCard label="Active keys" value="—" sub="Enable API credentials" />
71
+ <StatCard label="Plan" value="—" sub="Add plans in your manifest" />
72
+ <StatCard label="Uptime" value="—" sub="Telemetry coming soon" />
73
+ </div>
74
+
75
+ <div className="mb-5 grid grid-cols-1 gap-5 lg:grid-cols-2">
76
+ <div className="rounded-xl border border-border bg-card p-6">
77
+ <h2 className="mb-4 text-lg font-semibold">Requests, last 14 days</h2>
78
+ <div className="flex min-h-[150px] items-center justify-center rounded-lg border border-dashed border-border bg-muted/30 px-4 text-center text-sm text-muted-foreground">
79
+ Usage charts appear when the dev-portal billing plugin is
80
+ configured.
81
+ </div>
82
+ </div>
83
+ <div className="rounded-xl border border-border bg-card p-6">
84
+ <h2 className="mb-4 text-lg font-semibold">Quick links</h2>
85
+ <div className="flex flex-col gap-3">
86
+ {(content.quickLinks ?? []).length > 0 ? (
87
+ content.quickLinks?.map((link) => (
88
+ <Button
89
+ key={link.href}
90
+ asChild
91
+ variant="outline"
92
+ className="justify-between"
93
+ >
94
+ <Link to={link.href}>
95
+ {link.label}
96
+ <ArrowRightIcon size={16} />
97
+ </Link>
98
+ </Button>
99
+ ))
100
+ ) : (
101
+ <Button asChild variant="outline" className="justify-between">
102
+ <Link to="/introduction">
103
+ Documentation
104
+ <ArrowRightIcon size={16} />
105
+ </Link>
106
+ </Button>
107
+ )}
108
+ </div>
109
+ </div>
110
+ </div>
111
+
112
+ <div className="rounded-xl border border-border bg-card p-6">
113
+ <h2 className="mb-4 text-lg font-semibold">Recent requests</h2>
114
+ <p className="text-sm text-muted-foreground">
115
+ Request logs will appear when usage analytics is available.
116
+ </p>
117
+ </div>
118
+
119
+ {!auth.isAuthenticated && auth.isAuthEnabled ? (
120
+ <p className="mt-6 text-sm text-muted-foreground">
121
+ Sign in to see personalized account information on your dashboard.
122
+ </p>
123
+ ) : null}
124
+ </div>
125
+ );
126
+ };
@@ -1,62 +1,62 @@
1
- import type { ResolvedPlansContent } from "@lukoweb/apitogo";
2
- import { Head } from "@lukoweb/apitogo/components";
3
- import { CreditCardIcon } from "lucide-react";
4
-
5
- export type DefaultPlansPageProps = {
6
- content: ResolvedPlansContent;
7
- };
8
-
9
- export const DefaultPlansPage = ({ content }: DefaultPlansPageProps) => {
10
- const title = content.title ?? "Your subscription";
11
- const description =
12
- content.description ??
13
- "Review billing details, manage your subscription, and change plans.";
14
- const tiers = content.tiers ?? [];
15
-
16
- return (
17
- <div className="mx-auto max-w-screen-xl px-4 pb-16 pt-(--padding-content-top) lg:px-8">
18
- <Head>
19
- <title>{title}</title>
20
- </Head>
21
-
22
- <div className="mb-8 flex flex-wrap items-start justify-between gap-4">
23
- <div className="flex items-start gap-4">
24
- <div className="flex size-12 shrink-0 items-center justify-center rounded-xl bg-primary/10 text-primary">
25
- <CreditCardIcon size={24} />
26
- </div>
27
- <div className="space-y-1">
28
- <h1 className="text-3xl font-semibold tracking-tight">{title}</h1>
29
- <p className="max-w-2xl text-muted-foreground">{description}</p>
30
- </div>
31
- </div>
32
- </div>
33
-
34
- {tiers.length > 0 ? (
35
- <div className="grid gap-4 md:grid-cols-2 lg:grid-cols-3">
36
- {tiers.map((tier) => (
37
- <article
38
- key={tier.name}
39
- className="rounded-xl border bg-card/60 p-6 shadow-xs"
40
- >
41
- <h2 className="text-lg font-medium">{tier.name}</h2>
42
- {tier.price ? (
43
- <p className="mt-2 text-2xl font-semibold">{tier.price}</p>
44
- ) : null}
45
- {tier.description ? (
46
- <p className="mt-3 text-sm text-muted-foreground">
47
- {tier.description}
48
- </p>
49
- ) : null}
50
- </article>
51
- ))}
52
- </div>
53
- ) : (
54
- <div className="rounded-xl border border-dashed bg-muted/20 p-8 text-center">
55
- <p className="text-sm text-muted-foreground">
56
- No plans are configured for this page yet.
57
- </p>
58
- </div>
59
- )}
60
- </div>
61
- );
62
- };
1
+ import type { ResolvedPlansContent } from "@lukoweb/apitogo";
2
+ import { Head } from "@lukoweb/apitogo/components";
3
+ import { CreditCardIcon } from "lucide-react";
4
+
5
+ export type DefaultPlansPageProps = {
6
+ content: ResolvedPlansContent;
7
+ };
8
+
9
+ export const DefaultPlansPage = ({ content }: DefaultPlansPageProps) => {
10
+ const title = content.title ?? "Your subscription";
11
+ const description =
12
+ content.description ??
13
+ "Review billing details, manage your subscription, and change plans.";
14
+ const tiers = content.tiers ?? [];
15
+
16
+ return (
17
+ <div className="mx-auto max-w-screen-xl px-4 pb-16 pt-(--padding-content-top) lg:px-8">
18
+ <Head>
19
+ <title>{title}</title>
20
+ </Head>
21
+
22
+ <div className="mb-8 flex flex-wrap items-start justify-between gap-4">
23
+ <div className="flex items-start gap-4">
24
+ <div className="flex size-12 shrink-0 items-center justify-center rounded-xl bg-primary/10 text-primary">
25
+ <CreditCardIcon size={24} />
26
+ </div>
27
+ <div className="space-y-1">
28
+ <h1 className="text-3xl font-semibold tracking-tight">{title}</h1>
29
+ <p className="max-w-2xl text-muted-foreground">{description}</p>
30
+ </div>
31
+ </div>
32
+ </div>
33
+
34
+ {tiers.length > 0 ? (
35
+ <div className="grid gap-4 md:grid-cols-2 lg:grid-cols-3">
36
+ {tiers.map((tier) => (
37
+ <article
38
+ key={tier.name}
39
+ className="rounded-xl border bg-card/60 p-6 shadow-xs"
40
+ >
41
+ <h2 className="text-lg font-medium">{tier.name}</h2>
42
+ {tier.price ? (
43
+ <p className="mt-2 text-2xl font-semibold">{tier.price}</p>
44
+ ) : null}
45
+ {tier.description ? (
46
+ <p className="mt-3 text-sm text-muted-foreground">
47
+ {tier.description}
48
+ </p>
49
+ ) : null}
50
+ </article>
51
+ ))}
52
+ </div>
53
+ ) : (
54
+ <div className="rounded-xl border border-dashed bg-muted/20 p-8 text-center">
55
+ <p className="text-sm text-muted-foreground">
56
+ No plans are configured for this page yet.
57
+ </p>
58
+ </div>
59
+ )}
60
+ </div>
61
+ );
62
+ };
@@ -1,79 +1,79 @@
1
- import type { ResolvedProfileContent } from "@lukoweb/apitogo";
2
- import { Head, Link } from "@lukoweb/apitogo/components";
3
- import { useAuth } from "@lukoweb/apitogo/hooks";
4
- import { Button } from "@lukoweb/apitogo/ui/Button.js";
5
- import { UserIcon } from "lucide-react";
6
-
7
- export type DefaultProfilePageProps = {
8
- content: ResolvedProfileContent;
9
- };
10
-
11
- export const DefaultProfilePage = ({ content }: DefaultProfilePageProps) => {
12
- const auth = useAuth();
13
- const title = content.title ?? "Profile";
14
- const description =
15
- content.description ??
16
- "View your account details and manage profile settings.";
17
-
18
- return (
19
- <div className="mx-auto max-w-3xl px-4 pb-16 pt-(--padding-content-top) lg:px-8">
20
- <Head>
21
- <title>{title}</title>
22
- </Head>
23
-
24
- <div className="mb-8 flex items-start gap-4">
25
- <div className="flex size-12 shrink-0 items-center justify-center rounded-xl bg-primary/10 text-primary">
26
- <UserIcon size={24} />
27
- </div>
28
- <div className="space-y-1">
29
- <h1 className="text-3xl font-semibold tracking-tight">{title}</h1>
30
- <p className="text-muted-foreground">{description}</p>
31
- </div>
32
- </div>
33
-
34
- {auth.isAuthenticated && auth.profile ? (
35
- <dl className="divide-y rounded-xl border">
36
- {auth.profile.name ? (
37
- <div className="grid gap-1 px-4 py-4 sm:grid-cols-3">
38
- <dt className="text-sm font-medium text-muted-foreground">
39
- Name
40
- </dt>
41
- <dd className="text-sm sm:col-span-2">{auth.profile.name}</dd>
42
- </div>
43
- ) : null}
44
- {auth.profile.email ? (
45
- <div className="grid gap-1 px-4 py-4 sm:grid-cols-3">
46
- <dt className="text-sm font-medium text-muted-foreground">
47
- Email
48
- </dt>
49
- <dd className="text-sm sm:col-span-2">{auth.profile.email}</dd>
50
- </div>
51
- ) : null}
52
- {typeof auth.profile.emailVerified === "boolean" ? (
53
- <div className="grid gap-1 px-4 py-4 sm:grid-cols-3">
54
- <dt className="text-sm font-medium text-muted-foreground">
55
- Email verified
56
- </dt>
57
- <dd className="text-sm sm:col-span-2">
58
- {auth.profile.emailVerified ? "Yes" : "No"}
59
- </dd>
60
- </div>
61
- ) : null}
62
- </dl>
63
- ) : (
64
- <div className="rounded-xl border bg-muted/30 p-6">
65
- <p className="text-sm text-muted-foreground">
66
- {auth.isAuthEnabled
67
- ? "Sign in to view your profile details."
68
- : "Configure authentication in apitogo.config.tsx to enable sign-in and profile management."}
69
- </p>
70
- {auth.isAuthEnabled ? (
71
- <Button asChild className="mt-4">
72
- <Link to="/signin">Sign in</Link>
73
- </Button>
74
- ) : null}
75
- </div>
76
- )}
77
- </div>
78
- );
79
- };
1
+ import type { ResolvedProfileContent } from "@lukoweb/apitogo";
2
+ import { Head, Link } from "@lukoweb/apitogo/components";
3
+ import { useAuth } from "@lukoweb/apitogo/hooks";
4
+ import { Button } from "@lukoweb/apitogo/ui/Button.js";
5
+ import { UserIcon } from "lucide-react";
6
+
7
+ export type DefaultProfilePageProps = {
8
+ content: ResolvedProfileContent;
9
+ };
10
+
11
+ export const DefaultProfilePage = ({ content }: DefaultProfilePageProps) => {
12
+ const auth = useAuth();
13
+ const title = content.title ?? "Profile";
14
+ const description =
15
+ content.description ??
16
+ "View your account details and manage profile settings.";
17
+
18
+ return (
19
+ <div className="mx-auto max-w-3xl px-4 pb-16 pt-(--padding-content-top) lg:px-8">
20
+ <Head>
21
+ <title>{title}</title>
22
+ </Head>
23
+
24
+ <div className="mb-8 flex items-start gap-4">
25
+ <div className="flex size-12 shrink-0 items-center justify-center rounded-xl bg-primary/10 text-primary">
26
+ <UserIcon size={24} />
27
+ </div>
28
+ <div className="space-y-1">
29
+ <h1 className="text-3xl font-semibold tracking-tight">{title}</h1>
30
+ <p className="text-muted-foreground">{description}</p>
31
+ </div>
32
+ </div>
33
+
34
+ {auth.isAuthenticated && auth.profile ? (
35
+ <dl className="divide-y rounded-xl border">
36
+ {auth.profile.name ? (
37
+ <div className="grid gap-1 px-4 py-4 sm:grid-cols-3">
38
+ <dt className="text-sm font-medium text-muted-foreground">
39
+ Name
40
+ </dt>
41
+ <dd className="text-sm sm:col-span-2">{auth.profile.name}</dd>
42
+ </div>
43
+ ) : null}
44
+ {auth.profile.email ? (
45
+ <div className="grid gap-1 px-4 py-4 sm:grid-cols-3">
46
+ <dt className="text-sm font-medium text-muted-foreground">
47
+ Email
48
+ </dt>
49
+ <dd className="text-sm sm:col-span-2">{auth.profile.email}</dd>
50
+ </div>
51
+ ) : null}
52
+ {typeof auth.profile.emailVerified === "boolean" ? (
53
+ <div className="grid gap-1 px-4 py-4 sm:grid-cols-3">
54
+ <dt className="text-sm font-medium text-muted-foreground">
55
+ Email verified
56
+ </dt>
57
+ <dd className="text-sm sm:col-span-2">
58
+ {auth.profile.emailVerified ? "Yes" : "No"}
59
+ </dd>
60
+ </div>
61
+ ) : null}
62
+ </dl>
63
+ ) : (
64
+ <div className="rounded-xl border bg-muted/30 p-6">
65
+ <p className="text-sm text-muted-foreground">
66
+ {auth.isAuthEnabled
67
+ ? "Sign in to view your profile details."
68
+ : "Configure authentication in apitogo.config.tsx to enable sign-in and profile management."}
69
+ </p>
70
+ {auth.isAuthEnabled ? (
71
+ <Button asChild className="mt-4">
72
+ <Link to="/signin">Sign in</Link>
73
+ </Button>
74
+ ) : null}
75
+ </div>
76
+ )}
77
+ </div>
78
+ );
79
+ };