From 0cd7c968a92ad839fcd30ba3f6d9b38bd5211f84 Mon Sep 17 00:00:00 2001 From: Melvin Jones Repol Date: Thu, 26 Mar 2026 09:14:07 +0800 Subject: [PATCH] feat(auth): add OAuth provider buttons - Refactor OAuth handlers to accept a provider arg for sign-in/up - Add Google, Microsoft, and GitHub buttons with inline SVG icons and per-provider click handlers - Replace single GitHub CTA with three-provider UI and layout - Add responsive .flex-row-321 utility in globals.css for column layout on small screens and row on larger screens - Clean up redirectParam formatting and add FontAwesome/Image imports --- app/components/auth/LoginForm.tsx | 83 ++++++++++++++++++++++++++---- app/components/auth/SignupForm.tsx | 76 +++++++++++++++++++++++---- app/globals.css | 12 +++++ 3 files changed, 151 insertions(+), 20 deletions(-) diff --git a/app/components/auth/LoginForm.tsx b/app/components/auth/LoginForm.tsx index 9a0399c..3f2e522 100644 --- a/app/components/auth/LoginForm.tsx +++ b/app/components/auth/LoginForm.tsx @@ -6,6 +6,11 @@ import { toast } from "react-toastify"; import { useRouter } from "next/navigation"; import { useSearchParams } from "next/navigation"; import HCaptcha from "@hcaptcha/react-hcaptcha"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { faGoogle } from "@fortawesome/free-brands-svg-icons/faGoogle"; +import { faMicrosoft } from "@fortawesome/free-brands-svg-icons/faMicrosoft"; +import { faGithub } from "@fortawesome/free-brands-svg-icons"; +import Image from "next/image"; export default function LoginForm() { const supabase = createClient(); @@ -13,7 +18,9 @@ export default function LoginForm() { const searchParams = useSearchParams(); const redirectParam = searchParams.get("redirect"); const redirectTo = - redirectParam && redirectParam.startsWith("/") && !redirectParam.startsWith("//") + redirectParam && + redirectParam.startsWith("/") && + !redirectParam.startsWith("//") ? redirectParam : "/dashboard"; const [email, setEmail] = useState(""); @@ -27,10 +34,10 @@ export default function LoginForm() { setShowCaptcha(true); }; - const handleOAuthSignIn = async () => { + const handleOAuthSignIn = async (provider: "google" | "azure" | "github") => { document.cookie = `devpulse_redirect=${encodeURIComponent(redirectTo)}; path=/; max-age=600; samesite=lax`; await supabase.auth.signInWithOAuth({ - provider: "github", + provider: provider, options: { redirectTo: `${location.origin}/api/auth/callback`, }, @@ -76,6 +83,10 @@ export default function LoginForm() { }); }; + const handleGoogleSignIn = () => handleOAuthSignIn("google"); + const handleMicrosoftSignIn = () => handleOAuthSignIn("azure"); + const handleGitHubSignIn = () => handleOAuthSignIn("github"); + return ( <>
@@ -107,13 +118,65 @@ export default function LoginForm() { Login - +
+ Or continue with +
+ +
+ + + + + +
{showCaptcha && ( diff --git a/app/components/auth/SignupForm.tsx b/app/components/auth/SignupForm.tsx index 32f8517..a012f48 100644 --- a/app/components/auth/SignupForm.tsx +++ b/app/components/auth/SignupForm.tsx @@ -11,7 +11,9 @@ export default function AuthPage() { const searchParams = useSearchParams(); const redirectParam = searchParams.get("redirect"); const redirectTo = - redirectParam && redirectParam.startsWith("/") && !redirectParam.startsWith("//") + redirectParam && + redirectParam.startsWith("/") && + !redirectParam.startsWith("//") ? redirectParam : "/dashboard"; const [email, setEmail] = useState(""); @@ -26,10 +28,10 @@ export default function AuthPage() { setShowCaptcha(true); }; - const handleOAuthSignUp = async () => { + const handleOAuthSignUp = async (provider: "google" | "azure" | "github") => { document.cookie = `devpulse_redirect=${encodeURIComponent(redirectTo)}; path=/; max-age=600; samesite=lax`; await supabase.auth.signInWithOAuth({ - provider: "github", + provider: provider, options: { redirectTo: `${location.origin}/api/auth/callback`, }, @@ -82,6 +84,10 @@ export default function AuthPage() { }); }; + const handleGoogleSignUp = () => handleOAuthSignUp("google"); + const handleMicrosoftSignUp = () => handleOAuthSignUp("azure"); + const handleGitHubSignUp = () => handleOAuthSignUp("github"); + return ( <>
@@ -124,13 +130,63 @@ export default function AuthPage() { Sign Up - +
+ Or continue with +
+ +
+ + + +
{showCaptcha && ( diff --git a/app/globals.css b/app/globals.css index ce381e5..8282354 100644 --- a/app/globals.css +++ b/app/globals.css @@ -134,3 +134,15 @@ body { border-color: rgba(99, 102, 241, 0.2); background: rgba(15, 15, 40, 0.7); } + +@media (min-width: 376px) { + .flex-row-321 { + flex-direction: row; + } +} + +@media (max-width: 375px) { + .flex-row-321 { + flex-direction: column; + } +}