Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,6 @@ NEXT_PUBLIC_SUPABASE_ANON_KEY=

NEXT_PUBLIC_HCAPTCHA_SITE_KEY=

SENTRY_AUTH_TOKEN=
SENTRY_ORG=
SENTRY_PROJECT=
SENTRY_DNS=

NEXT_PUBLIC_NORTON_SAFEWEB_SITE_VERIFICATION=

SUPABASE_ACCESS_TOKEN=
Expand Down
3 changes: 0 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,3 @@ supabase/*

yarn.lock
pnpm-lock.yaml

# Sentry Config File
.env.sentry-build-plugin
55 changes: 55 additions & 0 deletions app/(public)/(auth)/forgot-password/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import ForgotPassword from "@/app/components/auth/ForgotPassword";
import { Metadata } from "next/types";
import { Suspense } from "react";

export const metadata: Metadata = {
title: "Forgot Password - Devpulse",
description:
"Lost access to your Devpulse account? Enter your email address to receive a password reset link and get back to tracking your coding activity and competing on leaderboards.",
alternates: {
canonical: "https://devpulse.hallofcodes.org/forgot-password",
},
openGraph: {
title: "Forgot Password - Devpulse",
description:
"Lost access to your Devpulse account? Enter your email address to receive a password reset link and get back to tracking your coding activity and competing on leaderboards.",
url: "https://devpulse.hallofcodes.org/forgot-password",
siteName: "Devpulse",
images: [
{
url: "https://devpulse.hallofcodes.org/images/devpulse.cover.png",
width: 1200,
height: 630,
alt: "Devpulse Cover Image",
},
],
locale: "en_US",
type: "website",
},
twitter: {
card: "summary_large_image",
title: "Forgot Password - Devpulse",
description:
"Lost access to your Devpulse account? Enter your email address to receive a password reset link and get back to tracking your coding activity and competing on leaderboards.",
images: [
{
url: "https://devpulse.hallofcodes.org/images/devpulse.cover.png",
alt: "Devpulse Cover Image",
},
],
},
};

export default function ForgotPasswordPage() {
return (
<Suspense
fallback={
<div className="min-h-screen flex items-center justify-center bg-[#0a0a1a] text-white">
Loading...
</div>
}
>
<ForgotPassword />
</Suspense>
);
}
129 changes: 11 additions & 118 deletions app/(public)/(auth)/login/page.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import Link from "next/link";
import Image from "next/image";
import LoginForm from "@/app/components/auth/LoginForm";
import { Metadata } from "next/types";
import { Suspense } from "react";
import Login from "@/app/components/auth/Login";

export const metadata: Metadata = {
title: "Login - Devpulse",
Expand Down Expand Up @@ -54,122 +53,16 @@ export const metadata: Metadata = {
},
};

export default async function Login(props: {
searchParams?: Promise<{ redirect?: string }>;
}) {
const redirectParam = (await props.searchParams)?.redirect;
const redirectTo =
redirectParam &&
redirectParam.startsWith("/") &&
!redirectParam.startsWith("//")
? redirectParam
: undefined;

export default async function LoginPage() {
return (
<div className="min-h-screen flex bg-[#0a0a1a] text-white relative">
{/* Left Side - Visual / Branding */}
<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">
{/* Background elements */}
<div className="absolute inset-0 grid-bg opacity-30" />

<div className="relative z-10">
<Link
href="/"
className="flex items-center gap-3 w-fit hover:opacity-80 transition"
>
<Image src="/logo.svg" alt="Devpulse Logo" width={40} height={40} />
<span className="text-2xl font-bold tracking-tight text-white">
Devpulse
</span>
</Link>
</div>

<div className="relative z-10 max-w-md">
<h1 className="text-4xl font-extrabold mb-5 leading-tight text-transparent bg-clip-text bg-gradient-to-r from-white to-gray-400">
Welcome back to your dashboard.
</h1>
<p className="text-gray-400 text-lg leading-relaxed mb-8">
Access your personalized coding metrics, compare your stats, and
keep your productivity streak alive.
</p>

<div className="glass-card border border-white/5 rounded-2xl p-5 bg-white/5 backdrop-blur-md shadow-2xl">
<div className="flex items-center gap-2 mb-4">
<div className="w-3 h-3 rounded-full bg-red-500/80"></div>
<div className="w-3 h-3 rounded-full bg-yellow-500/80"></div>
<div className="w-3 h-3 rounded-full bg-green-500/80"></div>
<span className="ml-2 text-xs font-mono text-gray-500">
devpulse-auth.ts
</span>
</div>
<div className="space-y-1.5 font-mono text-sm">
<div className="flex">
<span className="text-indigo-400 mr-2">import</span>
<span className="text-gray-200">{"{ Metrics }"}</span>
<span className="text-indigo-400 mx-2">from</span>
<span className="text-green-400">
&apos;@devpulse/core&apos;
</span>
<span className="text-gray-400">;</span>
</div>
<div className="flex mt-2">
<span className="text-purple-400 mr-2">await</span>
<span className="text-blue-400">Metrics</span>
<span className="text-gray-200">.</span>
<span className="text-yellow-200">syncToday</span>
<span className="text-gray-200">();</span>
</div>
<div className="flex mt-3">
<span className="text-emerald-400/80">
{"// Connection established. Ready to track. ⚡"}
</span>
</div>
</div>
</div>
</div>

<div className="relative z-10 text-sm text-gray-500 font-medium">
&copy; {new Date().getFullYear()} Devpulse. All rights reserved.
</div>
</div>

{/* Right Side - Form */}
<div className="w-full lg:w-1/2 flex flex-col justify-center items-center p-8 sm:p-12 xl:p-20 relative">
<div className="absolute inset-0 grid-bg opacity-20 lg:hidden" />

<div className="w-full max-w-sm relative z-10">
<Link
href="/"
className="lg:hidden flex items-center justify-center gap-3 mb-10"
>
<Image src="/logo.svg" alt="Devpulse Logo" width={40} height={40} />
<h2 className="text-3xl font-bold text-white">Devpulse</h2>
</Link>

<div className="mb-8 text-left">
<h2 className="text-3xl font-bold text-white mb-2">Log in</h2>
<p className="text-gray-400">
Enter your credentials to access your account.
</p>
</div>

<LoginForm />

<p className="mt-8 text-center text-sm text-gray-400">
Don&apos;t have an account?{" "}
<Link
href={
redirectTo
? `/signup?redirect=${encodeURIComponent(redirectTo)}`
: "/signup"
}
className="text-indigo-400 hover:text-indigo-300 font-semibold transition-colors underline-offset-4 hover:underline"
>
Sign up
</Link>
</p>
<Suspense
fallback={
<div className="min-h-screen flex items-center justify-center bg-[#0a0a1a] text-white">
Loading...
</div>
</div>
</div>
}
>
<Login />
</Suspense>
);
}
164 changes: 164 additions & 0 deletions app/(public)/(auth)/reset-password/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
import Link from "next/link";
import Image from "next/image";
import { Metadata } from "next/types";
import ResetPasswordForm from "@/app/components/auth/form/ResetPasswordForm";
import { Suspense } from "react";

// doesnt need description or keywords since this page is only accessible via a link in the email sent to the user,
// and we dont want it indexed by search engines
export const metadata: Metadata = {
title: "Reset Password - Devpulse",
description: "",
alternates: {
canonical: "https://devpulse.hallofcodes.org/reset-password",
},
robots: {
index: false,
follow: false,
},
openGraph: {
title: "Reset Password - Devpulse",
description: "",
url: "https://devpulse.hallofcodes.org/reset-password",
siteName: "Devpulse",
images: [
{
url: "https://devpulse.hallofcodes.org/images/devpulse.cover.png",
width: 1200,
height: 630,
alt: "Devpulse Cover Image",
},
],
locale: "en_US",
type: "website",
},
twitter: {
card: "summary_large_image",
title: "Reset Password - Devpulse",
description: "",
images: [
{
url: "https://devpulse.hallofcodes.org/images/devpulse.cover.png",
alt: "Devpulse Cover Image",
},
],
},
};

export default async function ResetPassword() {
return (
<div className="min-h-screen flex bg-[#0a0a1a] text-white relative">
{/* Left Side - Visual / Branding */}
<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">
{/* Background elements */}
<div className="absolute inset-0 grid-bg opacity-30" />

<div className="relative z-10">
<Link
href="/"
className="flex items-center gap-3 w-fit hover:opacity-80 transition"
>
<Image src="/logo.svg" alt="Devpulse Logo" width={40} height={40} />
<span className="text-2xl font-bold tracking-tight text-white">
Devpulse
</span>
</Link>
</div>

<div className="relative z-10 max-w-md">
<h1 className="text-4xl font-extrabold mb-5 leading-tight text-transparent bg-clip-text bg-gradient-to-r from-white to-gray-400">
Change your password and get back to tracking your coding activity!
</h1>
<p className="text-gray-400 text-lg leading-relaxed mb-8">
Your Devpulse dashboard is waiting for you. Enter a new password to
regain access and continue your coding journey.
</p>

<div className="glass-card border border-white/5 rounded-2xl p-5 bg-white/5 backdrop-blur-md shadow-2xl">
<div className="flex items-center gap-2 mb-4">
<div className="w-3 h-3 rounded-full bg-red-500/80"></div>
<div className="w-3 h-3 rounded-full bg-yellow-500/80"></div>
<div className="w-3 h-3 rounded-full bg-green-500/80"></div>
<span className="ml-2 text-xs font-mono text-gray-500">
setup.ts
</span>
</div>
<div className="space-y-1.5 font-mono text-sm">
<div className="flex">
<span className="text-purple-400 mr-2">const</span>
<span className="text-blue-400">dev</span>
<span className="text-gray-200 mx-2">=</span>
<span className="text-indigo-400">getAccount</span>
<span className="text-gray-200">(</span>
<span className="text-yellow-200">this</span>
<span className="text-gray-200">);</span>
</div>
<div className="flex mt-2">
<span className="text-blue-400">dev</span>
<span className="text-gray-200">.</span>
<span className="text-yellow-200">setNewPassword</span>
<span className="text-gray-200">(</span>
<span className="text-gray-200">
&quot;your-new-password&quot;
</span>
<span className="text-gray-200">);</span>
</div>
<div className="flex mt-3">
<span className="text-emerald-400/80">
{"// And just like that, you&apos;re back in the game. 🎉"}
</span>
</div>
</div>
</div>
</div>

<div className="relative z-10 text-sm text-gray-500 font-medium">
&copy; {new Date().getFullYear()} Devpulse. All rights reserved.
</div>
</div>

{/* Right Side - Form */}
<div className="w-full lg:w-1/2 flex flex-col justify-center items-center p-8 sm:p-12 xl:p-20 relative">
<div className="absolute inset-0 grid-bg opacity-20 lg:hidden" />

<div className="w-full max-w-sm relative z-10">
<Link
href="/"
className="lg:hidden flex items-center justify-center gap-3 mb-10"
>
<Image src="/logo.svg" alt="Devpulse Logo" width={40} height={40} />
<h2 className="text-3xl font-bold text-white">Devpulse</h2>
</Link>

<div className="mb-8 text-left">
<h2 className="text-3xl font-bold text-white mb-2">
Reset your password
</h2>
<p className="text-gray-400">
New password, who dis? Enter a new password to regain access to
your account and get back to tracking your coding stats!
</p>
</div>

<Suspense
fallback={
<div className="text-center text-gray-500">Loading...</div>
}
>
<ResetPasswordForm />
</Suspense>

<p className="mt-8 text-center text-sm text-gray-400">
Already have an account?{" "}
<Link
href="/login"
className="text-blue-500 hover:underline transition"
>
Log in
</Link>
</p>
</div>
</div>
</div>
);
}
Loading
Loading