Repository: klee97/directory-app
Pull request #34: Fix login and signup bugs
Author: login: klee97
Created: 2025-04-17T21:28:07Z | Merged: 2025-04-17T23:21:54Z

Email verification flow:
1. User creates account or requests another verification link
2. Send email link
3. Email link goes to confirm-signup page. If the user is not logged in, the page has a button to "confirm" 
4. Pressing confirm button performs the supabase verification and redirects to callback page
5. Based on supabase verification, callback page displays success/error message, then redirects user to appropriate page

The extra confirm-signup page is necessary for a couple reasons. Many email providers will visit the verification link, which will verify the account without any user action... not what we want. The link is also one-time-use, so the verification invalid when the user clicks on it later, which is confusing. Also, clicking an invalid/expired verification link will sign user out if they happen to be logged in, since supabase tried and failed to authenticate. The confirm-signup page prevents these problems.

Note: supabase is configured to use localhost for the confirmation domain. This needs to be updated to our website once we release the feature


Diff:
diff --git a/frontend/src/app/auth/callback/confirm-signup/page.tsx b/frontend/src/app/auth/callback/confirm-signup/page.tsx
new file mode 100644
index 00000000..a67447b7
--- /dev/null
+++ b/frontend/src/app/auth/callback/confirm-signup/page.tsx
@@ -0,0 +1,98 @@
+'use client';
+
+import { useState, useEffect, Suspense } from 'react';
+import { useSearchParams } from 'next/navigation';
+import { Button, Container, Typography, Box, Paper, CircularProgress } from '@mui/material';
+import { createClient } from '@/lib/supabase/client';
+
+function ConfirmSignUpContent() {
+  const searchParams = useSearchParams();
+  const confirmationUrl = searchParams.get('confirmation_url');
+  const [isAlreadyAuthenticated, setIsAlreadyAuthenticated] = useState(false);
+
+  useEffect(() => {
+    // Check if user is already authenticated
+    const checkAuthStatus = async () => {
+      const supabase = createClient();
+      const { data: { session } } = await supabase.auth.getSession();
+      if (session) {
+        setIsAlreadyAuthenticated(true);
+      }
+    };
+
+    checkAuthStatus();
+  }, []);
+  return (
+    <Container maxWidth="md">
+      <Paper elevation={3} sx={{ p: 4, mt: 8, borderRadius: 2 }}>
+        <Box sx={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 3 }}>
+          <Typography variant="h4" component="h1" align="center" gutterBottom>
+            Confirm Sign Up
+          </Typography>
+
+          {isAlreadyAuthenticated ? (
+            <>
+              <Typography variant="body1" align="center" component={'p'}>
+                You are already verified and signed in to your account.
+              </Typography>
+
+              <Button
+                variant="contained"
+                color="primary"
+                href="/"
+                size="large"
+              >
+                Go to Directory
+              </Button>
+            </>
+          ) : (
+            <>
+
+              {confirmationUrl ? (
+                <>
+                  <Typography variant="body1" align="center" component={'p'}>
+                    Please click the button below to verify your email address and set up your account.
+                  </Typography>
+
+                  <Button
+                    variant="contained"
+                    color="primary"
+                    component="a"
+                    href={confirmationUrl}
+                    size="large"
+                  >
+                    Confirm Now
+                  </Button>
+                </>
+              ) : (
+                <Typography color="error">
+                  There was an error verifying your email address. Please check the link and try again.
+                </Typography>
+              )}
+            </>
+          )}
+        </Box>
+      </Paper>
+    </Container>
+  );
+}
+
+// A loading component to show while suspense is resolving
+function LoadingState() {
+  return (
+    <Box sx={{ display: 'flex', justifyContent: 'center', my: 4 }}>
+      <CircularProgress />
+    </Box>
+  );
+}
+
+// Main page component with Suspense boundary
+export default function ConfirmSignUpPage() {
+  return (
+    <Container maxWidth="md">
+      <Suspense fallback={<LoadingState />}>
+        <ConfirmSignUpContent />
+      </Suspense>
+    </Container>
+  );
+}
\ No newline at end of file
diff --git a/frontend/src/app/auth/callback/page.tsx b/frontend/src/app/auth/callback/page.tsx
index d7f0083f..6b006166 100644
--- a/frontend/src/app/auth/callback/page.tsx
+++ b/frontend/src/app/auth/callback/page.tsx
@@ -17,17 +17,26 @@ export default function AuthCallbackPage() {
       const supabase = createClient();
       const { data: { session }, error } = await supabase.auth.getSession();
 
-      // Get the hash and search params from the URL
-      const hash = window.location.hash;
+
+      // If we have a session, redirect to home
+      if (session) {
+        setMessage("Authentication successful! Redirecting to homepage...");
+        setTimeout(() => {
+          router.push("/");
+        }, 2000);
+        return;
+      }
+
+      // Get the search params from the URL
       const searchParams = new URLSearchParams(window.location.search);
+      const type = searchParams.get('type');
       const errorCode = searchParams.get('error_code');
 
       if (errorCode === 'otp_expired') {
         setIsError(true);
-        setMessage("Verification link has expired");
-        addNotification("The verification link has expired. Please request a new one.", "error");
+        setMessage("The verification link has expired. Please request a new one.");
         setTimeout(() => {
-          router.push("/auth/resend-verification");
+          router.push("/auth/verify-email");
         }, 2000);
         return;
       }
@@ -35,25 +44,19 @@ export default function AuthCallbackPage() {
       if (error) {
         setIsError(true);
         setMessage("Authentication error: " + error.message);
-        addNotification("Authentication failed: " + error.message, "error");
-        return;
-      }
 
-      // If this was an email verification
-      if (hash && hash.includes("type=signup")) {
-        addNotification("Email verified successfully! You can now log in with your account.");
-        setMessage("Email verified successfully!");
-        
         // Redirect to login after 2 seconds
         setTimeout(() => {
-          router.push("/login");
+          router.push("/");
         }, 2000);
         return;
       }
 
-      // If we have a session, redirect to home
-      if (session) {
-        setMessage("Authentication successful!");
+      if (type === 'signup') {
+        // email is successfully verified
+        setMessage("Email is verified! Redirecting to homepage...");
+
+        // Redirect to homepage after 2 seconds
         setTimeout(() => {
           router.push("/");
         }, 2000);
@@ -61,9 +64,10 @@ export default function AuthCallbackPage() {
       }
 
       // If no session and no specific error, show a generic message
-      setMessage("Processing authentication...");
+      setIsError(true);
+      setMessage("Authentication failed. Redirecting to homepage... ");
       setTimeout(() => {
-        router.push("/login");
+        router.push("/");
       }, 2000);
     };
 
diff --git a/frontend/src/app/auth/verify-email/page.tsx b/frontend/src/app/auth/verify-email/page.tsx
index 5c7c4f8c..d4a67446 100644
--- a/frontend/src/app/auth/verify-email/page.tsx
+++ b/frontend/src/app/auth/verify-email/page.tsx
@@ -1,4 +1,4 @@
-import { Container, Typography, Paper, Box, Button, Alert } from "@mui/material";
+import { Container, Typography, Paper, Box, Button } from "@mui/material";
 import Link from "next/link";
 import { ResendVerificationForm } from "@/features/login/components/ResendVerificationForm";
 
@@ -10,14 +10,11 @@ export default function VerifyEmailPage() {
           <Typography variant="h4" component="h1" align="center" gutterBottom>
             Verify Your Email
           </Typography>
+          <Typography variant="body1" component={"p"}>
+            Please check your email for a verification link.
+          </Typography>
           
-          <Alert severity="info" sx={{ mb: 3 }}>
-            <Typography variant="body1">
-              We&apos;ve sent a verification email to your inbox. Please check your email and click the verification link to complete your signup.
-            </Typography>
-          </Alert>
-          
-          <Typography variant="body1" paragraph>
+          <Typography variant="body1">
             If you don&apos;t see the email:
           </Typography>
           
@@ -34,7 +31,7 @@ export default function VerifyEmailPage() {
           </Box>
 
           <Typography variant="h6" gutterBottom>
-            Need a new verification link?
+            Need a new verification link? Enter your email below:
           </Typography>
           
           <ResendVerificationForm />
diff --git a/frontend/src/features/login/components/LoginForm.tsx b/frontend/src/features/login/components/LoginForm.tsx
index 249ccf68..0ff9c23b 100644
--- a/frontend/src/features/login/components/LoginForm.tsx
+++ b/frontend/src/features/login/components/LoginForm.tsx
@@ -64,7 +64,7 @@ export function LoginForm() {
                   component={NextLink}
                   href="/auth/verify-email"
                 >
-                  Resend verification email
+                  Get a new verification link
                 </Button>
               </Box>
             </Alert>
diff --git a/frontend/src/features/login/components/ResendVerificationForm.tsx b/frontend/src/features/login/components/ResendVerificationForm.tsx
index f5a6cd89..6d83065f 100644
--- a/frontend/src/features/login/components/ResendVerificationForm.tsx
+++ b/frontend/src/features/login/components/ResendVerificationForm.tsx
@@ -33,7 +33,6 @@ export function ResendVerificationForm() {
       if (error) {
         addNotification(error.message || 'Failed to send verification email', 'error');
       } else {
-        addNotification('If your email is associated with an account, we will send a verification email to you! Please check your inbox');
         setIsSuccess(true);
       }
     } catch (error) {
diff --git a/frontend/src/features/login/components/SignupForm.tsx b/frontend/src/features/login/components/SignupForm.tsx
index ae77afeb..d1ef9a9e 100644
--- a/frontend/src/features/login/components/SignupForm.tsx
+++ b/frontend/src/features/login/components/SignupForm.tsx
@@ -46,7 +46,6 @@ export function SignupForm() {
 
     try {
       const result = await signup(formData);
-      
       if (result && result.error) {
         addNotification(result.error, 'error');
         if (result.action === 'login') {


Reviews:
user: login: imalao
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-04-17T22:45:37Z
user: login: imalao
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-04-17T22:46:29Z
user: login: imalao
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-04-17T22:48:06Z
user: login: imalao
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-04-17T22:48:32Z
user: login: imalao
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-04-17T22:49:12Z
user: login: imalao
body: Some nits but looks good otherwise!
state: APPROVED
author_association: COLLABORATOR
submitted_at: 2025-04-17T22:49:43Z
user: login: klee97
state: COMMENTED
author_association: OWNER
submitted_at: 2025-04-17T23:13:00Z
user: login: klee97
state: COMMENTED
author_association: OWNER
submitted_at: 2025-04-17T23:13:21Z
user: login: klee97
state: COMMENTED
author_association: OWNER
submitted_at: 2025-04-17T23:17:18Z
user: login: klee97
state: COMMENTED
author_association: OWNER
submitted_at: 2025-04-17T23:17:23Z
user: login: klee97
state: COMMENTED
author_association: OWNER
submitted_at: 2025-04-17T23:18:04Z

Review comments:
diff_hunk: @@ -0,0 +1,95 @@
+'use client';
+
+import { useState, useEffect, Suspense } from 'react';
+import { useSearchParams } from 'next/navigation';
+import { Button, Container, Typography, Box, Paper, CircularProgress } from '@mui/material';
+import { createClient } from '@/lib/supabase/client';
+
+function ConfirmSignUpContent() {
+  const searchParams = useSearchParams();
+  const confirmationUrl = searchParams.get('confirmation_url');
+  const [isAlreadyAuthenticated, setIsAlreadyAuthenticated] = useState(false);
+
+  useEffect(() => {
+    // Check if user is already authenticated
+    const checkAuthStatus = async () => {
+      const supabase = createClient();
+      const { data: { session } } = await supabase.auth.getSession();
+      if (session) {
+        setIsAlreadyAuthenticated(true);
+      }
+    };
+
+    checkAuthStatus();
+  }, []);
+  return (
+    <Container maxWidth="md">
+      <Paper elevation={3} sx={{ p: 4, mt: 8, borderRadius: 2 }}>
+        <Box sx={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 3 }}>
+          <Typography variant="h4" component="h1" align="center" gutterBottom>
+            Confirm Sign Up
+          </Typography>
+
+          {isAlreadyAuthenticated ? (
+            <>
+              <Typography variant="body1" align="center" component={'p'}>
+                You are already verified and signed in to your account.
+              </Typography>
+
+              <Button
+                variant="contained"
+                color="primary"
+                href="/"
+                size="large"
+              >
+                Go to Directory
+              </Button>
+            </>
+          ) : (
+            <>
+              <Typography variant="body1" align="center" component={'p'}>
+                Please click the button below to verify your email address and set up your account.
+              </Typography>
path: frontend/src/app/auth/callback/confirm-signup/page.tsx
user: login: imalao
body: Should we move this into the ternary so it's only displayed with the confirm now button when the confirmation url exists?
created_at: 2025-04-17T22:45:37Z
author_association: COLLABORATOR
diff_hunk: @@ -0,0 +1,95 @@
+'use client';
+
+import { useState, useEffect, Suspense } from 'react';
+import { useSearchParams } from 'next/navigation';
+import { Button, Container, Typography, Box, Paper, CircularProgress } from '@mui/material';
+import { createClient } from '@/lib/supabase/client';
+
+function ConfirmSignUpContent() {
+  const searchParams = useSearchParams();
+  const confirmationUrl = searchParams.get('confirmation_url');
+  const [isAlreadyAuthenticated, setIsAlreadyAuthenticated] = useState(false);
+
+  useEffect(() => {
+    // Check if user is already authenticated
+    const checkAuthStatus = async () => {
+      const supabase = createClient();
+      const { data: { session } } = await supabase.auth.getSession();
+      if (session) {
+        setIsAlreadyAuthenticated(true);
+      }
+    };
+
+    checkAuthStatus();
+  }, []);
+  return (
+    <Container maxWidth="md">
+      <Paper elevation={3} sx={{ p: 4, mt: 8, borderRadius: 2 }}>
+        <Box sx={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 3 }}>
+          <Typography variant="h4" component="h1" align="center" gutterBottom>
+            Confirm Sign Up
+          </Typography>
+
+          {isAlreadyAuthenticated ? (
+            <>
+              <Typography variant="body1" align="center" component={'p'}>
+                You are already verified and signed in to your account.
+              </Typography>
+
+              <Button
+                variant="contained"
+                color="primary"
+                href="/"
+                size="large"
+              >
+                Go to Directory
+              </Button>
+            </>
+          ) : (
+            <>
+              <Typography variant="body1" align="center" component={'p'}>
+                Please click the button below to verify your email address and set up your account.
+              </Typography>
+
+              {confirmationUrl ? (
+                <Button
+                  variant="contained"
+                  color="primary"
+                  component="a"
+                  href={confirmationUrl}
+                  size="large"
+                >
+                  Confirm Now
+                </Button>
+              ) : (
+                <Typography color="error">
+                  No confirmation URL provided. Please check the link and try again.
path: frontend/src/app/auth/callback/confirm-signup/page.tsx
user: login: imalao
body: ```suggestion
                  There was an error verifying your email address. Please check the link and try again.
```

Making it a bit more user friendly by removing the reference to the "confirmation url" 
created_at: 2025-04-17T22:46:29Z
author_association: COLLABORATOR
diff_hunk: @@ -17,53 +17,57 @@ export default function AuthCallbackPage() {
       const supabase = createClient();
       const { data: { session }, error } = await supabase.auth.getSession();
 
-      // Get the hash and search params from the URL
-      const hash = window.location.hash;
+
+      // If we have a session, redirect to home
+      if (session) {
+        setMessage("Account is verified! Redirecting to homepage...");
path: frontend/src/app/auth/callback/page.tsx
user: login: imalao
body: should this be `"Authentication successful! Redirecting to homepage..."` ?
created_at: 2025-04-17T22:48:05Z
author_association: COLLABORATOR
diff_hunk: @@ -17,53 +17,57 @@ export default function AuthCallbackPage() {
       const supabase = createClient();
       const { data: { session }, error } = await supabase.auth.getSession();
 
-      // Get the hash and search params from the URL
-      const hash = window.location.hash;
+
+      // If we have a session, redirect to home
+      if (session) {
+        setMessage("Account is verified! Redirecting to homepage...");
+        setTimeout(() => {
+          router.push("/");
+        }, 2000);
+        return;
+      }
+
+      // Get the search params from the URL
       const searchParams = new URLSearchParams(window.location.search);
+      const type = searchParams.get('type');
       const errorCode = searchParams.get('error_code');
 
       if (errorCode === 'otp_expired') {
         setIsError(true);
-        setMessage("Verification link has expired");
-        addNotification("The verification link has expired. Please request a new one.", "error");
+        setMessage("The verification link has expired. Please request a new one.");
         setTimeout(() => {
-          router.push("/auth/resend-verification");
+          router.push("/auth/verify-email");
         }, 2000);
         return;
       }
 
       if (error) {
         setIsError(true);
         setMessage("Authentication error: " + error.message);
-        addNotification("Authentication failed: " + error.message, "error");
-        return;
-      }
 
-      // If this was an email verification
-      if (hash && hash.includes("type=signup")) {
-        addNotification("Email verified successfully! You can now log in with your account.");
-        setMessage("Email verified successfully!");
-        
         // Redirect to login after 2 seconds
         setTimeout(() => {
-          router.push("/login");
+          router.push("/");
         }, 2000);
         return;
       }
 
-      // If we have a session, redirect to home
-      if (session) {
-        setMessage("Authentication successful!");
+      if (type === 'signup') {
+        // email is successfully verified
+        setMessage("Authentication successful! Redirecting to homepage...");
path: frontend/src/app/auth/callback/page.tsx
user: login: imalao
body: should this be `"Email is verified! Redirecting to homepage..."`
created_at: 2025-04-17T22:48:32Z
author_association: COLLABORATOR
diff_hunk: @@ -10,14 +10,11 @@ export default function VerifyEmailPage() {
           <Typography variant="h4" component="h1" align="center" gutterBottom>
             Verify Your Email
           </Typography>
+          <Typography variant="body1" component={"p"}>
+            Please check your inbox for a verification link from us.
path: frontend/src/app/auth/verify-email/page.tsx
user: login: imalao
body: nit:

```suggestion
            Please check your email for a verification link.
```
created_at: 2025-04-17T22:49:11Z
author_association: COLLABORATOR
diff_hunk: @@ -0,0 +1,95 @@
+'use client';
+
+import { useState, useEffect, Suspense } from 'react';
+import { useSearchParams } from 'next/navigation';
+import { Button, Container, Typography, Box, Paper, CircularProgress } from '@mui/material';
+import { createClient } from '@/lib/supabase/client';
+
+function ConfirmSignUpContent() {
+  const searchParams = useSearchParams();
+  const confirmationUrl = searchParams.get('confirmation_url');
+  const [isAlreadyAuthenticated, setIsAlreadyAuthenticated] = useState(false);
+
+  useEffect(() => {
+    // Check if user is already authenticated
+    const checkAuthStatus = async () => {
+      const supabase = createClient();
+      const { data: { session } } = await supabase.auth.getSession();
+      if (session) {
+        setIsAlreadyAuthenticated(true);
+      }
+    };
+
+    checkAuthStatus();
+  }, []);
+  return (
+    <Container maxWidth="md">
+      <Paper elevation={3} sx={{ p: 4, mt: 8, borderRadius: 2 }}>
+        <Box sx={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 3 }}>
+          <Typography variant="h4" component="h1" align="center" gutterBottom>
+            Confirm Sign Up
+          </Typography>
+
+          {isAlreadyAuthenticated ? (
+            <>
+              <Typography variant="body1" align="center" component={'p'}>
+                You are already verified and signed in to your account.
+              </Typography>
+
+              <Button
+                variant="contained"
+                color="primary"
+                href="/"
+                size="large"
+              >
+                Go to Directory
+              </Button>
+            </>
+          ) : (
+            <>
+              <Typography variant="body1" align="center" component={'p'}>
+                Please click the button below to verify your email address and set up your account.
+              </Typography>
path: frontend/src/app/auth/callback/confirm-signup/page.tsx
user: login: klee97
body: good point!
created_at: 2025-04-17T23:13:00Z
author_association: OWNER
diff_hunk: @@ -0,0 +1,95 @@
+'use client';
+
+import { useState, useEffect, Suspense } from 'react';
+import { useSearchParams } from 'next/navigation';
+import { Button, Container, Typography, Box, Paper, CircularProgress } from '@mui/material';
+import { createClient } from '@/lib/supabase/client';
+
+function ConfirmSignUpContent() {
+  const searchParams = useSearchParams();
+  const confirmationUrl = searchParams.get('confirmation_url');
+  const [isAlreadyAuthenticated, setIsAlreadyAuthenticated] = useState(false);
+
+  useEffect(() => {
+    // Check if user is already authenticated
+    const checkAuthStatus = async () => {
+      const supabase = createClient();
+      const { data: { session } } = await supabase.auth.getSession();
+      if (session) {
+        setIsAlreadyAuthenticated(true);
+      }
+    };
+
+    checkAuthStatus();
+  }, []);
+  return (
+    <Container maxWidth="md">
+      <Paper elevation={3} sx={{ p: 4, mt: 8, borderRadius: 2 }}>
+        <Box sx={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 3 }}>
+          <Typography variant="h4" component="h1" align="center" gutterBottom>
+            Confirm Sign Up
+          </Typography>
+
+          {isAlreadyAuthenticated ? (
+            <>
+              <Typography variant="body1" align="center" component={'p'}>
+                You are already verified and signed in to your account.
+              </Typography>
+
+              <Button
+                variant="contained"
+                color="primary"
+                href="/"
+                size="large"
+              >
+                Go to Directory
+              </Button>
+            </>
+          ) : (
+            <>
+              <Typography variant="body1" align="center" component={'p'}>
+                Please click the button below to verify your email address and set up your account.
+              </Typography>
+
+              {confirmationUrl ? (
+                <Button
+                  variant="contained"
+                  color="primary"
+                  component="a"
+                  href={confirmationUrl}
+                  size="large"
+                >
+                  Confirm Now
+                </Button>
+              ) : (
+                <Typography color="error">
+                  No confirmation URL provided. Please check the link and try again.
path: frontend/src/app/auth/callback/confirm-signup/page.tsx
user: login: klee97
body: updated!
created_at: 2025-04-17T23:13:21Z
author_association: OWNER
diff_hunk: @@ -17,53 +17,57 @@ export default function AuthCallbackPage() {
       const supabase = createClient();
       const { data: { session }, error } = await supabase.auth.getSession();
 
-      // Get the hash and search params from the URL
-      const hash = window.location.hash;
+
+      // If we have a session, redirect to home
+      if (session) {
+        setMessage("Account is verified! Redirecting to homepage...");
path: frontend/src/app/auth/callback/page.tsx
user: login: klee97
body: updated
created_at: 2025-04-17T23:17:18Z
author_association: OWNER
diff_hunk: @@ -17,53 +17,57 @@ export default function AuthCallbackPage() {
       const supabase = createClient();
       const { data: { session }, error } = await supabase.auth.getSession();
 
-      // Get the hash and search params from the URL
-      const hash = window.location.hash;
+
+      // If we have a session, redirect to home
+      if (session) {
+        setMessage("Account is verified! Redirecting to homepage...");
+        setTimeout(() => {
+          router.push("/");
+        }, 2000);
+        return;
+      }
+
+      // Get the search params from the URL
       const searchParams = new URLSearchParams(window.location.search);
+      const type = searchParams.get('type');
       const errorCode = searchParams.get('error_code');
 
       if (errorCode === 'otp_expired') {
         setIsError(true);
-        setMessage("Verification link has expired");
-        addNotification("The verification link has expired. Please request a new one.", "error");
+        setMessage("The verification link has expired. Please request a new one.");
         setTimeout(() => {
-          router.push("/auth/resend-verification");
+          router.push("/auth/verify-email");
         }, 2000);
         return;
       }
 
       if (error) {
         setIsError(true);
         setMessage("Authentication error: " + error.message);
-        addNotification("Authentication failed: " + error.message, "error");
-        return;
-      }
 
-      // If this was an email verification
-      if (hash && hash.includes("type=signup")) {
-        addNotification("Email verified successfully! You can now log in with your account.");
-        setMessage("Email verified successfully!");
-        
         // Redirect to login after 2 seconds
         setTimeout(() => {
-          router.push("/login");
+          router.push("/");
         }, 2000);
         return;
       }
 
-      // If we have a session, redirect to home
-      if (session) {
-        setMessage("Authentication successful!");
+      if (type === 'signup') {
+        // email is successfully verified
+        setMessage("Authentication successful! Redirecting to homepage...");
path: frontend/src/app/auth/callback/page.tsx
user: login: klee97
body: updated
created_at: 2025-04-17T23:17:23Z
author_association: OWNER
diff_hunk: @@ -10,14 +10,11 @@ export default function VerifyEmailPage() {
           <Typography variant="h4" component="h1" align="center" gutterBottom>
             Verify Your Email
           </Typography>
+          <Typography variant="body1" component={"p"}>
+            Please check your inbox for a verification link from us.
path: frontend/src/app/auth/verify-email/page.tsx
user: login: klee97
body: updated
created_at: 2025-04-17T23:18:04Z
author_association: OWNER

PR comments:
user: login: vercel[bot]
created_at: 2025-04-17T21:28:13Z
body: [vc]: #7FoaLdFby6HoShtTnGmVq87xdgfXt+4Vm3dJoTk2wYA=:eyJpc01vbm9yZXBvIjp0cnVlLCJ0eXBlIjoiZ2l0aHViIiwicHJvamVjdHMiOlt7Im5hbWUiOiJkaXJlY3RvcnktYXBwIiwibGl2ZUZlZWRiYWNrIjp7InJlc29sdmVkIjowLCJ1bnJlc29sdmVkIjowLCJ0b3RhbCI6MCwibGluayI6ImRpcmVjdG9yeS1hcHAtZ2l0LWtsZWU5Ny1zaWdudXAta2F0cmluYXMtcHJvamVjdHMtMmQxYTJhYzIudmVyY2VsLmFwcCJ9LCJpbnNwZWN0b3JVcmwiOiJodHRwczovL3ZlcmNlbC5jb20va2F0cmluYXMtcHJvamVjdHMtMmQxYTJhYzIvZGlyZWN0b3J5LWFwcC9CNVpqVGc3Z2kyeExBWDRqWjl6RG5uclRGMjN3IiwicHJldmlld1VybCI6ImRpcmVjdG9yeS1hcHAtZ2l0LWtsZWU5Ny1zaWdudXAta2F0cmluYXMtcHJvamVjdHMtMmQxYTJhYzIudmVyY2VsLmFwcCIsIm5leHRDb21taXRTdGF0dXMiOiJERVBMT1lFRCIsInJvb3REaXJlY3RvcnkiOiJmcm9udGVuZCJ9XX0=
**The latest updates on your projects**. Learn more about [Vercel for Git ↗︎](https://vercel.link/github-learn-more)

| Name | Status | Preview | Comments | Updated (UTC) |
| :--- | :----- | :------ | :------- | :------ |
| **directory-app** | ✅ Ready ([Inspect](https://vercel.com/katrinas-projects-2d1a2ac2/directory-app/B5ZjTg7gi2xLAX4jZ9zDnnrTF23w)) | [Visit Preview](https://directory-app-git-klee97-signup-katrinas-projects-2d1a2ac2.vercel.app) | 💬 [**Add feedback**](https://vercel.live/open-feedback/directory-app-git-klee97-signup-katrinas-projects-2d1a2ac2.vercel.app?via=pr-comment-feedback-link) | Apr 17, 2025 11:20pm |


author_association: NONE
user: login: imalao
created_at: 2025-04-17T22:42:49Z
body: good to know re the confirm-signup page! Was this a recommendation by supabase?
author_association: COLLABORATOR
user: login: klee97
created_at: 2025-04-17T23:07:53Z
body: > good to know re the confirm-signup page! Was this a recommendation by supabase?

yup, here: https://supabase.com/docs/guides/auth/auth-email-templates
author_association: OWNER