From 988bdad1c20b68142fc9b8c42684e29708ce19d5 Mon Sep 17 00:00:00 2001 From: Eric Zhang Date: Wed, 26 Nov 2025 18:28:34 -0500 Subject: [PATCH 1/5] feat: add google and github buttons frontend --- src/app/login/page.tsx | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/app/login/page.tsx b/src/app/login/page.tsx index 5e886a3..3aa3cbe 100644 --- a/src/app/login/page.tsx +++ b/src/app/login/page.tsx @@ -43,7 +43,7 @@ export default function AuthPage() { className="min-h-dvh flex items-center justify-center bg-cover bg-center bg-no-repeat p-6 font-cinzel text-white" style={{ backgroundImage: "url('/geminiblurred.png')" }} > -
+

{mode === "login" ? "Welcome Back" : "Create Your Account"}

@@ -92,6 +92,26 @@ export default function AuthPage() { +
+
+

Or continue with

+
+ + {/* Google */} +
+ +
+ + {/* Github */} +
+ +
+
+
{/* Github */}
-
diff --git a/src/lib/supabase/handle-oauth-login.ts b/src/lib/supabase/handle-oauth-login.ts new file mode 100644 index 0000000..8dc9feb --- /dev/null +++ b/src/lib/supabase/handle-oauth-login.ts @@ -0,0 +1,19 @@ +"use server"; + +import { redirect } from "next/navigation"; +import { createClient } from "./server"; +import { headers } from "next/headers"; +export default async function handleOAuthLogin(provider: "github" | "google") { + const supabase = await createClient(); + const headersList = await headers(); + const origin = headersList.get("origin") ?? `https://${headersList.get("host")}`;; + const { error, data } = await supabase.auth.signInWithOAuth({ + provider: provider, + options: { redirectTo: `${origin}/auth/callback?next=/dashboard` }, + }); + + if (error) throw error; + else { + return redirect(data.url); + } +} diff --git a/src/lib/supabase/middleware.ts b/src/lib/supabase/middleware.ts index 93f6021..fbd8b8a 100644 --- a/src/lib/supabase/middleware.ts +++ b/src/lib/supabase/middleware.ts @@ -1,10 +1,10 @@ -import { createServerClient } from '@supabase/ssr' -import { NextResponse, type NextRequest } from 'next/server' +import { createServerClient } from "@supabase/ssr"; +import { NextResponse, type NextRequest } from "next/server"; export async function updateSession(request: NextRequest) { let supabaseResponse = NextResponse.next({ request, - }) + }); const supabase = createServerClient( process.env.NEXT_PUBLIC_SUPABASE_URL!, @@ -12,35 +12,36 @@ export async function updateSession(request: NextRequest) { { cookies: { getAll() { - return request.cookies.getAll() + return request.cookies.getAll(); }, setAll(cookiesToSet) { - cookiesToSet.forEach(({ name, value, options }) => request.cookies.set(name, value)) + cookiesToSet.forEach(({ name, value, options }) => request.cookies.set(name, value)); supabaseResponse = NextResponse.next({ request, - }) + }); cookiesToSet.forEach(({ name, value, options }) => supabaseResponse.cookies.set(name, value, options) - ) + ); }, }, } - ) + ); const { data: { user }, - } = await supabase.auth.getUser() + } = await supabase.auth.getUser(); if ( !user && - !request.nextUrl.pathname.startsWith('/login') && - !request.nextUrl.pathname.startsWith('/error') + !request.nextUrl.pathname.startsWith("/login") && + !request.nextUrl.pathname.startsWith("/error") && + !request.nextUrl.pathname.startsWith("/auth") ) { // no user, potentially respond by redirecting the user to the login page - const url = request.nextUrl.clone() - url.pathname = '/login' - return NextResponse.redirect(url) + const url = request.nextUrl.clone(); + url.pathname = "/login"; + return NextResponse.redirect(url); } - return supabaseResponse -} \ No newline at end of file + return supabaseResponse; +} From 2a2271af76f6013343abbba0e1fbebd21fae6460 Mon Sep 17 00:00:00 2001 From: Eric Zhang Date: Wed, 26 Nov 2025 21:27:40 -0500 Subject: [PATCH 3/5] feat: auth error page --- src/app/auth/auth-code-error/page.tsx | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 src/app/auth/auth-code-error/page.tsx diff --git a/src/app/auth/auth-code-error/page.tsx b/src/app/auth/auth-code-error/page.tsx new file mode 100644 index 0000000..5a1c40e --- /dev/null +++ b/src/app/auth/auth-code-error/page.tsx @@ -0,0 +1,24 @@ +import Link from "next/link"; + +export default function AuthCodeError() { + return ( +
+
+

⚠️ Authentication Failed

+

+ Something went wrong while signing you in. This could happen if the login was cancelled or + took too long. +

+ + Try Again + +
+
+ ); +} From 0c5d2cb45309bb40fa63c9a76bbf85aea4991f61 Mon Sep 17 00:00:00 2001 From: Eric Zhang Date: Wed, 26 Nov 2025 21:45:19 -0500 Subject: [PATCH 4/5] style: add icons to OAuth buttons --- package-lock.json | 24 +++++++++++++++++------- package.json | 1 + src/app/login/page.tsx | 15 +++++++++++---- 3 files changed, 29 insertions(+), 11 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4b97cce..6dd4612 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,6 +15,7 @@ "next": "15.5.3", "react": "19.1.0", "react-dom": "19.1.0", + "react-icons": "^5.5.0", "react-youtube": "^10.1.0" }, "devDependencies": { @@ -6347,9 +6348,9 @@ "license": "MIT" }, "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", "dev": true, "license": "MIT", "dependencies": { @@ -7549,6 +7550,15 @@ "react": "^19.1.0" } }, + "node_modules/react-icons": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.5.0.tgz", + "integrity": "sha512-MEFcXdkP3dLo8uumGI5xN3lDFNsRtrjbOEKDLD7yv76v4wpnEq2Lt2qeHaQOr34I/wPN3s3+N08WkQ+CW37Xiw==", + "license": "MIT", + "peerDependencies": { + "react": "*" + } + }, "node_modules/react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", @@ -8354,11 +8364,11 @@ } }, "node_modules/tar": { - "version": "7.5.1", - "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.1.tgz", - "integrity": "sha512-nlGpxf+hv0v7GkWBK2V9spgactGOp0qvfWRxUMjqHyzrt3SgwE48DIv/FhqPHJYLHpgW1opq3nERbz5Anq7n1g==", + "version": "7.5.2", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.2.tgz", + "integrity": "sha512-7NyxrTE4Anh8km8iEy7o0QYPs+0JKBTj5ZaqHg6B39erLg0qYXN3BijtShwbsNSvQ+LN75+KV+C4QR/f6Gwnpg==", "dev": true, - "license": "ISC", + "license": "BlueOak-1.0.0", "dependencies": { "@isaacs/fs-minipass": "^4.0.0", "chownr": "^3.0.0", diff --git a/package.json b/package.json index c80c556..7876773 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "next": "15.5.3", "react": "19.1.0", "react-dom": "19.1.0", + "react-icons": "^5.5.0", "react-youtube": "^10.1.0" }, "devDependencies": { diff --git a/src/app/login/page.tsx b/src/app/login/page.tsx index 3fb5f14..7c65204 100644 --- a/src/app/login/page.tsx +++ b/src/app/login/page.tsx @@ -4,6 +4,7 @@ import { useState } from "react"; import { useRouter } from "next/navigation"; import { createClient } from "../../lib/supabase/client"; import handleOAuthLogin from "@/lib/supabase/handle-oauth-login"; +import { FaGoogle, FaGithub } from "react-icons/fa"; export default function AuthPage() { const router = useRouter(); @@ -99,12 +100,15 @@ export default function AuthPage() {
{/* Google */} -
+
@@ -114,7 +118,10 @@ export default function AuthPage() { className="w-full p-2 rounded-md bg-transparent border border-white/40 focus:border-indigo-400 focus:shadow-[0_0_12px_rgba(140,120,255,0.8)] outline-none transition" onClick={() => handleOAuthLogin("github")} > - Github +
+ + Github +
From e680e154012872b6f18ec2c61a41f0a903375066 Mon Sep 17 00:00:00 2001 From: Eric Zhang Date: Wed, 26 Nov 2025 21:52:03 -0500 Subject: [PATCH 5/5] style: change cursor pointer to hover on login --- src/app/login/page.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/app/login/page.tsx b/src/app/login/page.tsx index 7c65204..21f34eb 100644 --- a/src/app/login/page.tsx +++ b/src/app/login/page.tsx @@ -84,7 +84,7 @@ export default function AuthPage() {