Skip to content

Commit dcba740

Browse files
committed
refactor(auth,leaderboard): restructure components to save production
cost allowing certain UI to be SSG, Static and Dynamic without burning active fluid cpu. - move auth forms into app/components/auth/form and update imports - add client auth components: Login, Signup, ForgotPassword - create createPublicClient in app/lib/supabase/public.ts - switch public pages and sitemap to use the public supabase client - refactor leaderboard pages: add generateStaticParams, banner, invite button, back button, and use notFound/internal error handling - recreate leaderboard table component and update stats/podium layout - add internal-server-error page and return it on supabase errors - mark legal pages as force-static - adjust proxy matcher and protectedRoutes for api and d routes - normalize imports to use absolute "@/app/..." paths and cleanups
1 parent fbbacc4 commit dcba740

28 files changed

Lines changed: 1097 additions & 914 deletions

File tree

Lines changed: 11 additions & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
import Link from "next/link";
2-
import Image from "next/image";
1+
import ForgotPassword from "@/app/components/auth/ForgotPassword";
32
import { Metadata } from "next/types";
4-
import ForgotPasswordForm from "@/app/components/auth/ForgotPasswordForm";
3+
import { Suspense } from "react";
54

65
export const metadata: Metadata = {
76
title: "Forgot Password - Devpulse",
@@ -41,126 +40,16 @@ export const metadata: Metadata = {
4140
},
4241
};
4342

44-
export default async function Signup(props: {
45-
searchParams?: Promise<{ redirect?: string }>;
46-
}) {
47-
const redirectParam = (await props.searchParams)?.redirect;
48-
const redirectTo =
49-
redirectParam &&
50-
redirectParam.startsWith("/") &&
51-
!redirectParam.startsWith("//")
52-
? redirectParam
53-
: undefined;
54-
43+
export default function ForgotPasswordPage() {
5544
return (
56-
<div className="min-h-screen flex bg-[#0a0a1a] text-white relative">
57-
{/* Left Side - Visual / Branding */}
58-
<div className="hidden lg:flex lg:w-1/2 relative flex-col justify-between p-12 md:p-16 xl:p-24 border-r border-white/5 bg-gradient-to-br from-[#0a0a1a] to-[#0a0a1a] overflow-hidden">
59-
{/* Background elements */}
60-
<div className="absolute inset-0 grid-bg opacity-30" />
61-
62-
<div className="relative z-10">
63-
<Link
64-
href="/"
65-
className="flex items-center gap-3 w-fit hover:opacity-80 transition"
66-
>
67-
<Image src="/logo.svg" alt="Devpulse Logo" width={40} height={40} />
68-
<span className="text-2xl font-bold tracking-tight text-white">
69-
Devpulse
70-
</span>
71-
</Link>
72-
</div>
73-
74-
<div className="relative z-10 max-w-md">
75-
<h1 className="text-4xl font-extrabold mb-5 leading-tight text-transparent bg-clip-text bg-gradient-to-r from-white to-gray-400">
76-
Loss of access? No problem!
77-
</h1>
78-
<p className="text-gray-400 text-lg leading-relaxed mb-8">
79-
We got you covered. All you need to do is enter your email address
80-
and we will send you a password reset link to get you back on track
81-
with monitoring your coding activity and competing on leaderboards.
82-
</p>
83-
84-
<div className="glass-card border border-white/5 rounded-2xl p-5 bg-white/5 backdrop-blur-md shadow-2xl">
85-
<div className="flex items-center gap-2 mb-4">
86-
<div className="w-3 h-3 rounded-full bg-red-500/80"></div>
87-
<div className="w-3 h-3 rounded-full bg-yellow-500/80"></div>
88-
<div className="w-3 h-3 rounded-full bg-green-500/80"></div>
89-
<span className="ml-2 text-xs font-mono text-gray-500">
90-
setup.ts
91-
</span>
92-
</div>
93-
<div className="space-y-1.5 font-mono text-sm">
94-
<div className="flex">
95-
<span className="text-purple-400 mr-2">const</span>
96-
<span className="text-blue-400">auth</span>
97-
<span className="text-gray-200 mx-2">=</span>
98-
<span className="text-indigo-400 mr-2">new</span>
99-
<span className="text-yellow-400">SupabaseAuth</span>
100-
<span className="text-gray-200">();</span>
101-
</div>
102-
<div className="flex mt-2">
103-
<span className="text-blue-400">auth</span>
104-
<span className="text-gray-200">.</span>
105-
<span className="text-yellow-400">sendPasswordResetEmail</span>
106-
<span className="text-gray-200">(</span>
107-
<span className="text-green-400">email</span>
108-
<span className="text-gray-200">);</span>
109-
</div>
110-
<div className="flex mt-3">
111-
<span className="text-emerald-400/80">
112-
{"// Check your inbox. "}
113-
</span>
114-
</div>
115-
</div>
116-
</div>
117-
</div>
118-
119-
<div className="relative z-10 text-sm text-gray-500 font-medium">
120-
&copy; {new Date().getFullYear()} Devpulse. All rights reserved.
121-
</div>
122-
</div>
123-
124-
{/* Right Side - Form */}
125-
<div className="w-full lg:w-1/2 flex flex-col justify-center items-center p-8 sm:p-12 xl:p-20 relative">
126-
<div className="absolute inset-0 grid-bg opacity-20 lg:hidden" />
127-
128-
<div className="w-full max-w-sm relative z-10">
129-
<Link
130-
href="/"
131-
className="lg:hidden flex items-center justify-center gap-3 mb-10"
132-
>
133-
<Image src="/logo.svg" alt="Devpulse Logo" width={40} height={40} />
134-
<h2 className="text-3xl font-bold text-white">Devpulse</h2>
135-
</Link>
136-
137-
<div className="mb-8 text-left">
138-
<h2 className="text-3xl font-bold text-white mb-2">
139-
Forgot your password?
140-
</h2>
141-
<p className="text-gray-400">
142-
No worries! Just enter your email address and we&apos;ll send you
143-
an email.
144-
</p>
145-
</div>
146-
147-
<ForgotPasswordForm />
148-
149-
<p className="mt-8 text-center text-sm text-gray-400">
150-
Already have an account?{" "}
151-
<Link
152-
href={
153-
redirectTo
154-
? `/login?redirect=${encodeURIComponent(redirectTo)}`
155-
: "/login"
156-
}
157-
className="text-indigo-400 hover:text-indigo-300 font-semibold transition-colors underline-offset-4 hover:underline"
158-
>
159-
Log in
160-
</Link>
161-
</p>
45+
<Suspense
46+
fallback={
47+
<div className="min-h-screen flex items-center justify-center bg-[#0a0a1a] text-white">
48+
Loading...
16249
</div>
163-
</div>
164-
</div>
50+
}
51+
>
52+
<ForgotPassword />
53+
</Suspense>
16554
);
16655
}

app/(public)/(auth)/login/page.tsx

Lines changed: 11 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
import Link from "next/link";
2-
import Image from "next/image";
3-
import LoginForm from "@/app/components/auth/LoginForm";
41
import { Metadata } from "next/types";
2+
import { Suspense } from "react";
3+
import Login from "@/app/components/auth/Login";
54

65
export const metadata: Metadata = {
76
title: "Login - Devpulse",
@@ -54,121 +53,16 @@ export const metadata: Metadata = {
5453
},
5554
};
5655

57-
export default async function Login(props: {
58-
searchParams?: Promise<{ redirect?: string }>;
59-
}) {
60-
const redirectParam = (await props.searchParams)?.redirect;
61-
const redirectTo =
62-
redirectParam &&
63-
redirectParam.startsWith("/") &&
64-
!redirectParam.startsWith("//")
65-
? redirectParam
66-
: undefined;
67-
56+
export default async function LoginPage() {
6857
return (
69-
<div className="min-h-screen flex bg-[#0a0a1a] text-white relative">
70-
{/* Left Side - Visual / Branding */}
71-
<div className="hidden lg:flex lg:w-1/2 relative flex-col justify-between p-12 md:p-16 xl:p-24 border-r border-white/5 bg-gradient-to-br from-[#0a0a1a] to-[#0a0a1a] overflow-hidden">
72-
{/* Background elements */}
73-
<div className="absolute inset-0 grid-bg opacity-30" />
74-
75-
<div className="relative z-10">
76-
<Link
77-
href="/"
78-
className="flex items-center gap-3 w-fit hover:opacity-80 transition"
79-
>
80-
<Image src="/logo.svg" alt="Devpulse Logo" width={40} height={40} />
81-
<span className="text-2xl font-bold tracking-tight text-white">
82-
Devpulse
83-
</span>
84-
</Link>
85-
</div>
86-
87-
<div className="relative z-10 max-w-md">
88-
<h1 className="text-4xl font-extrabold mb-5 leading-tight text-transparent bg-clip-text bg-gradient-to-r from-white to-gray-400">
89-
Welcome back to your dashboard.
90-
</h1>
91-
<p className="text-gray-400 text-lg leading-relaxed mb-8">
92-
Access your personalized coding metrics, compare your stats, and
93-
keep your productivity streak alive.
94-
</p>
95-
96-
<div className="glass-card border border-white/5 rounded-2xl p-5 bg-white/5 backdrop-blur-md shadow-2xl">
97-
<div className="flex items-center gap-2 mb-4">
98-
<div className="w-3 h-3 rounded-full bg-red-500/80"></div>
99-
<div className="w-3 h-3 rounded-full bg-yellow-500/80"></div>
100-
<div className="w-3 h-3 rounded-full bg-green-500/80"></div>
101-
<span className="ml-2 text-xs font-mono text-gray-500">
102-
devpulse-auth.ts
103-
</span>
104-
</div>
105-
<div className="space-y-1.5 font-mono text-sm">
106-
<div className="flex">
107-
<span className="text-indigo-400 mr-2">import</span>
108-
<span className="text-gray-200">{"{ Metrics }"}</span>
109-
<span className="text-indigo-400 mx-2">from</span>
110-
<span className="text-green-400">
111-
&apos;@devpulse/core&apos;
112-
</span>
113-
<span className="text-gray-400">;</span>
114-
</div>
115-
<div className="flex mt-2">
116-
<span className="text-purple-400 mr-2">await</span>
117-
<span className="text-blue-400">Metrics</span>
118-
<span className="text-gray-200">.</span>
119-
<span className="text-yellow-200">syncToday</span>
120-
<span className="text-gray-200">();</span>
121-
</div>
122-
<div className="flex mt-3">
123-
<span className="text-emerald-400/80">
124-
{"// Connection established. Ready to track. ⚡"}
125-
</span>
126-
</div>
127-
</div>
128-
</div>
129-
</div>
130-
131-
<div className="relative z-10 text-sm text-gray-500 font-medium">
132-
&copy; {new Date().getFullYear()} Devpulse. All rights reserved.
133-
</div>
134-
</div>
135-
136-
{/* Right Side - Form */}
137-
<div className="w-full lg:w-1/2 flex flex-col justify-center items-center p-8 sm:p-12 xl:p-20 relative">
138-
<div className="absolute inset-0 grid-bg opacity-20 lg:hidden" />
139-
140-
<div className="w-full max-w-sm relative z-10">
141-
<Link
142-
href="/"
143-
className="lg:hidden flex items-center justify-center gap-3 mb-10"
144-
>
145-
<Image src="/logo.svg" alt="Devpulse Logo" width={40} height={40} />
146-
<h2 className="text-3xl font-bold text-white">Devpulse</h2>
147-
</Link>
148-
149-
<div className="mb-8 text-left">
150-
<h2 className="text-3xl font-bold text-white mb-2">Log in</h2>
151-
<p className="text-gray-400">
152-
Enter your credentials to access your account.
153-
</p>
154-
</div>
155-
156-
<LoginForm />
157-
158-
<div className="mt-6 flex items-center gap-3 text-sm text-indigo-300/90">
159-
<Link
160-
href={
161-
redirectTo
162-
? `/forgot-password?redirect=${encodeURIComponent(redirectTo)}`
163-
: "/forgot-password"
164-
}
165-
className="font-semibold transition-colors hover:text-indigo-200 underline-offset-4 hover:underline"
166-
>
167-
Forgot your password?
168-
</Link>
169-
</div>
58+
<Suspense
59+
fallback={
60+
<div className="min-h-screen flex items-center justify-center bg-[#0a0a1a] text-white">
61+
Loading...
17062
</div>
171-
</div>
172-
</div>
63+
}
64+
>
65+
<Login />
66+
</Suspense>
17367
);
17468
}

app/(public)/(auth)/reset-password/page.tsx

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import Link from "next/link";
22
import Image from "next/image";
33
import { Metadata } from "next/types";
4-
import ResetPasswordForm from "@/app/components/auth/ResetPasswordForm";
4+
import ResetPasswordForm from "@/app/components/auth/form/ResetPasswordForm";
5+
import { Suspense } from "react";
56

67
// doesnt need description or keywords since this page is only accessible via a link in the email sent to the user,
78
// and we dont want it indexed by search engines
@@ -139,7 +140,13 @@ export default async function ResetPassword() {
139140
</p>
140141
</div>
141142

142-
<ResetPasswordForm />
143+
<Suspense
144+
fallback={
145+
<div className="text-center text-gray-500">Loading...</div>
146+
}
147+
>
148+
<ResetPasswordForm />
149+
</Suspense>
143150

144151
<p className="mt-8 text-center text-sm text-gray-400">
145152
Already have an account?{" "}

0 commit comments

Comments
 (0)