Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feat] new success and verification pages with full functionality EXC… #37

Merged
merged 10 commits into from
Dec 30, 2024
61 changes: 60 additions & 1 deletion api/supabase/queries/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@ export async function handleSignUp(
password: string,
): Promise<{ success: boolean; message: string }> {
try {
const { data, error } = await supabase.auth.signUp({ email, password });
await ensureLoggedOutForNewUser(email);
const { data, error } = await supabase.auth.signUp({
email,
password,
});

if (error) {
return { success: false, message: `Sign-up failed: ${error.message}` };
Expand Down Expand Up @@ -37,6 +41,8 @@ export async function handleSignUp(
};
}

localStorage.setItem('tempEmail', email);

return { success: true, message: 'Sign-up successful!' };
} catch (err) {
if (err instanceof Error) {
Expand All @@ -54,6 +60,7 @@ export async function handleSignIn(
password: string,
): Promise<{ success: boolean; message: string }> {
try {
await ensureLoggedOutForNewUser(email);
const { error: signInError } = await supabase.auth.signInWithPassword({
email,
password,
Expand Down Expand Up @@ -96,6 +103,37 @@ export async function handleSignIn(
}
}

export const handleSignOut = async () => {
const { error } = await supabase.auth.signOut();
if (error) {
console.error('Error during logout:', error.message);
return;
}
};

export async function ensureLoggedOutForNewUser(
newEmail: string,
): Promise<void> {
const { data, error } = await supabase.auth.getSession();

if (error) {
console.error('Error fetching session:', error.message);
throw new Error('Failed to fetch session.');
}

const session = data.session;

if (
session &&
session.user &&
session.user.email &&
session.user.email !== newEmail
) {
console.log(`Logging out current user: ${session.user.email}`);
await handleSignOut();
}
}

export async function checkUserExists(
userId: string,
userType: 'volunteer' | 'facility',
Expand All @@ -118,3 +156,24 @@ export async function checkUserExists(
return false;
}
}

export async function resendVerificationEmail(email: string): Promise<string> {
try {
const { error } = await supabase.auth.resend({
type: 'signup',
email: email,
});

if (error) {
return `Error: ${error.message}`;
}

return 'Verification email resent successfully!';
} catch (err) {
return 'Unexpected error while resending verification email.';
}
}

export function getTempEmail(): string | null {
return localStorage.getItem('tempEmail');
}
2 changes: 1 addition & 1 deletion app/(auth)/signup/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export default function SignUp() {
setIsError(!success);

if (success) {
router.push('/onboarding/role-selection');
router.push('/verification');
}
};

Expand Down
38 changes: 38 additions & 0 deletions app/(auth)/success/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
'use client';

import { useRouter } from 'next/navigation';
import Rose from '@/public/images/rose-greenbg.svg';
import {
Background,
Image,
InlineContainer,
ReviewContainer,
RoundedCornerButton,
Title,
} from '../../../styles/styles';

export default function Success() {
const router = useRouter(); // Initialize useRouter

const handleContinue = () => {
router.push('/onboarding/role-selection'); // Navigate to the onboarding/general page
};

return (
<Background>
<Image src={Rose} alt="Rose" />
<InlineContainer>
<ReviewContainer>
<Title>Successfully verified!</Title>
<text>
Your email has been verified. Please use this email address to login
in the future.
</text>
<RoundedCornerButton onClick={handleContinue}>
Continue
</RoundedCornerButton>
</ReviewContainer>
</InlineContainer>
</Background>
);
}
115 changes: 115 additions & 0 deletions app/(auth)/verification/page.tsx
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

instead of using <text> tags, import this line on the top of the file import { P } from '@/styles/text; and then use the <P> tag. you can adjust the font weight by passing in weight as a prop: <P $fontWeight={300}>. also, since styling such as EmailContainer, EmailText etc. are not being used in any other files, create a separate styles.ts file under verification since styles/styles.ts file is only for GLOBALLY used styled components.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed in latest commit!

Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
'use client';

import { useEffect, useState } from 'react';
import { useRouter } from 'next/navigation';
import {
getTempEmail,
resendVerificationEmail,
} from '@/api/supabase/queries/auth';
import Bud from '@/public/images/bud.svg';
import EmailIcon from '@/public/images/email.svg';
// import supabase from '@/api/supabase/createClient';
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

delete the commented line

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed in latest commit!

import { useSession } from '@/utils/AuthProvider';
import {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

replace ../../../styles/styles to @/styles/styles

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed in latest commit!

Background,
EmailContainer,
EmailIconStyled,
EmailText,
Footer,
Image,
InlineContainer,
Link,
ResendMessage,
ReviewContainer,
RoundedCornerButton,
Title,
} from '../../../styles/styles';

export default function Verification() {
const router = useRouter(); // Initialize useRouter
const [tempEmail, setTempEmail] = useState<string | null>(null);
const [resendStatus, setResendStatus] = useState<string>('');
const [isError, setIsError] = useState<boolean>(false);
const { session } = useSession();

useEffect(() => {
if (session) {
router.push('/success');
}
}, [session, router]);

useEffect(() => {
const email = getTempEmail();
setTempEmail(email);
}, []);

const handleResendLink = async () => {
if (tempEmail) {
const message = await resendVerificationEmail(tempEmail);
setIsError(message.includes('Error'));
setResendStatus(message);
} else {
setIsError(true);
}
};

const handleUseAnotherAccount = () => {
router.push('/signin');
localStorage.removeItem('tempEmail');
};

// TODO: Restyle error message on lines 95-100 (the message containing link back to sign-up)

return (
<Background>
<Image src={Bud} alt="Bud" />
<InlineContainer>
<ReviewContainer>
<Title>Verification Needed</Title>
<text>Thanks for signing up!</text>
<text>
A verification link has been sent to the email you specified, please
check your inbox for next steps.
</text>

<EmailContainer>
<EmailIconStyled src={EmailIcon} alt="Email Icon" />
<EmailText>
{tempEmail ? tempEmail : 'Email address not found'}
</EmailText>
</EmailContainer>

<RoundedCornerButton
onClick={handleUseAnotherAccount}
width="70%"
bgColor="white"
textColor="black"
>
Use another account
</RoundedCornerButton>

<Footer>
Didn&apos;t receive it?{' '}
<Link href="#" onClick={handleResendLink}>
Resend link
</Link>
</Footer>

{isError && !tempEmail && (
<ResendMessage $isError={isError}>
Email address not found!{' '}
<Link href="#" onClick={() => router.push('/signup')}>
Return to the sign-up page
</Link>{' '}
to restart the sign-up process.
</ResendMessage>
)}

{resendStatus && tempEmail && (
<ResendMessage $isError={isError}>{resendStatus}</ResendMessage>
)}
</ReviewContainer>
</InlineContainer>
</Background>
);
}
4 changes: 2 additions & 2 deletions app/onboarding/finalize/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@
import { useRouter } from 'next/navigation';
import Rose from '@/public/images/rose.svg';
import { SMALL } from '@/styles/text';
import { Background } from '../styles';
import {
ContinueButton,
Image,
InlineContainer,
ReviewContainer,
Title,
} from './styles';
} from '../../../styles/styles';
import { Background } from '../styles';

export default function Onboarding() {
const router = useRouter(); // Initialize useRouter
Expand Down
8 changes: 8 additions & 0 deletions public/images/bud.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions public/images/email.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 8 additions & 0 deletions public/images/rose-greenbg.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading