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] fixed auth context + sessionDemo #23

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
4 changes: 2 additions & 2 deletions app/(auth)/auth-styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,9 @@ export const SmallBuffer = styled.div`
`;

// TODO: Temporarily added to verify that supabase login functionality actually works
export const LoginMessage = styled(P)<{ isError: boolean }>`
export const LoginMessage = styled(P)<{ $isError: boolean }>`
font-family: ${Sans.style.fontFamily};
color: ${({ isError }) => (isError ? 'red' : 'green')};
color: ${({ $isError }) => ($isError ? 'red' : 'green')};
text-align: center;
margin-top: 0.5rem;
`;
Expand Down
23 changes: 23 additions & 0 deletions app/(auth)/sessionDemo/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.

thanks for the including this file for testing! can you unadd it so that i can merge it to main?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

oop yeah

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

// import { useRouter } from 'next/navigation';
import { useSession } from '@/utils/AuthProvider';

export default function SessionDemo() {
const { session, signOut } = useSession();

if (session === undefined) return <p>Loading...</p>;

return (
<div>
{session ? (
<>
<h1>Welcome, {session.user?.email}!</h1>
<button onClick={() => signOut()}>Logout</button>
</>
) : (
<p>You are not logged in.</p>
)}
</div>
);
}
31 changes: 26 additions & 5 deletions app/(auth)/signin/page.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
'use client';

import { useState } from 'react';
import { useRouter } from 'next/navigation';
import supabase from '@/api/supabase/createClient';
import { H5 } from '@/styles/text';
import { useSession } from '@/utils/AuthProvider';
import {
Button,
Card,
Expand All @@ -20,6 +22,8 @@ import {
} from '../auth-styles';

export default function SignIn() {
const router = useRouter();
const sessionHandler = useSession();
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [message, setMessage] = useState('');
Expand All @@ -29,18 +33,35 @@ export default function SignIn() {
const handleSignIn = async () => {
setMessage('');
setIsError(false);

const { error } = await supabase.auth.signInWithPassword({
email,
password,
});

// Ik this wasn't part of the sprint but I added so I could verify that supabase functionality is working
if (error) {
setMessage(`Login failed: ${error.message}`);
setIsError(true);
} else {
setMessage('Login successful!');
setIsError(false);
try {
const { error } = await sessionHandler.signInWithEmail(email, password);
if (error) {
setMessage(`Login failed: ${error.message}`);
setIsError(true);
} else {
setMessage('Login successful!');
setIsError(false);
setTimeout(() => {
router.push('/sessionDemo');
Copy link
Collaborator

Choose a reason for hiding this comment

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

can you push onboarding/general to the router instead of the sessionDemo?

}, 1000);
}
} catch (error) {
if (error instanceof Error) {
setMessage(`Login failed: ${error.message}`);
} else {
setMessage('Login failed: An unknown error occurred');
}
setIsError(true);
}
}
};

Expand Down Expand Up @@ -77,7 +98,7 @@ export default function SignIn() {
<span>or</span>
</Separator>
<GoogleButton>Continue with Google</GoogleButton>
{message && <LoginMessage isError={isError}>{message}</LoginMessage>}
{message && <LoginMessage $isError={isError}>{message}</LoginMessage>}
</Form>
</Card>
<SmallBuffer />
Expand Down
44 changes: 31 additions & 13 deletions app/(auth)/signup/page.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
'use client';

import { useState } from 'react';
import supabase from '@/api/supabase/createClient';
import { useRouter } from 'next/navigation';
// import supabase from '@/api/supabase/createClient';
import { H5 } from '@/styles/text';
import { useSession } from '@/utils/AuthProvider';
import {
Button,
Card,
Expand All @@ -20,6 +22,8 @@ import {
} from '../auth-styles';

export default function SignUp() {
const router = useRouter();
const { signUp } = useSession();
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [confirmedPassword, setConfirmedPassword] = useState('');
Expand All @@ -36,18 +40,32 @@ export default function SignUp() {
return;
}

const { error } = await supabase.auth.signUp({
email,
password,
});

// Ik this wasn't part of the sprint but I added so I could verify that supabase functionality is working
if (error) {
setMessage(`Sign-up failed: ${error.message}`);
try {
const { data, error } = await signUp(email, password);
if (error) {
setMessage(`Sign-up failed: ${error.message}`);
setIsError(true);
} else {
if (data.user?.email_confirmed_at === null) {
setMessage(
'Sign-up successful! Please confirm your email to complete registration.',
);
setIsError(false);
} else {
setMessage('Sign-up successful!');
setIsError(false);
setTimeout(() => {
router.push('/signin');
}, 1500);
}
}
} catch (error) {
if (error instanceof Error) {
setMessage(`Sign-up failed: ${error.message}`);
} else {
setMessage('Sign-up failed: An unknown error occurred');
}
setIsError(true);
} else {
setMessage('Sign-up successful!');
setIsError(false);
}
};

Expand Down Expand Up @@ -94,7 +112,7 @@ export default function SignUp() {
<span>or</span>
</Separator>
<GoogleButton>Continue with Google</GoogleButton>
{message && <LoginMessage isError={isError}>{message}</LoginMessage>}
{message && <LoginMessage $isError={isError}>{message}</LoginMessage>}
</Form>
</Card>
<SmallBuffer />
Expand Down
5 changes: 4 additions & 1 deletion app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import StyledComponentsRegistry from '@/lib/registry';
import COLORS from '@/styles/colors';
import { Sans } from '../styles/fonts';
import '../styles/global.css';
import { AuthContextProvider } from '../utils/AuthProvider';
import { OnboardingProvider } from '../utils/onboardingContext';

// site metadata - what shows up on embeds
Expand All @@ -20,7 +21,9 @@ export default function RootLayout({
<html lang="en">
<body className={Sans.className} style={{ background: COLORS.gray1 }}>
<StyledComponentsRegistry>
<OnboardingProvider>{children}</OnboardingProvider>
<AuthContextProvider>
<OnboardingProvider>{children}</OnboardingProvider>
</AuthContextProvider>
</StyledComponentsRegistry>
</body>
</html>
Expand Down
92 changes: 92 additions & 0 deletions utils/AuthProvider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
'use client';

import React, {
createContext,
useContext,
useEffect,
useMemo,
useState,
} from 'react';
import { AuthResponse, Session } from '@supabase/supabase-js';
import supabase from '@/api/supabase/createClient';

export interface AuthState {
session: Session | null;
signIn: (newSession: Session | null) => void;
signUp: (email: string, password: string) => Promise<AuthResponse>;
signInWithEmail: (email: string, password: string) => Promise<AuthResponse>;
signOut: () => void;
}

const AuthContext = createContext({} as AuthState);

export function useSession() {
const value = useContext(AuthContext);
return value;
}

export function AuthContextProvider({
children,
}: {
children: React.ReactNode;
}) {
const [session, setSession] = useState<Session | null>(null);

/* useEffect(() => {
Copy link
Collaborator

Choose a reason for hiding this comment

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

can you delete the comments?

supabase.auth.getSession().then(({ data: { session: newSession } }) => {
setSession(newSession);
});

supabase.auth.onAuthStateChange((_event, newSession) => {
setSession(newSession);
});
}, []); */

useEffect(() => {
supabase.auth.getSession().then(({ data: { session: newSession } }) => {
console.log('Initial session:', newSession);
setSession(newSession);
});

supabase.auth.onAuthStateChange((_event, newSession) => {
console.log('Session change event:', newSession);
setSession(newSession);
});
}, []);

const signIn = (newSession: Session | null) => {
setSession(newSession);
};

const signInWithEmail = async (email: string, password: string) =>
supabase.auth.signInWithPassword({
email,
password,
}); // will trigger the use effect to update the session
const signUp = async (email: string, password: string) =>
supabase.auth.signUp({
email,
password,
}); // will trigger the use effect to update the session
const signOut = () => {
supabase.auth.signOut();
setSession(null);
};

const authContextValue = useMemo(
() => ({
session,
signIn,
signUp,
signInWithEmail,
signOut,
}),
[session],
);

return (
<AuthContext.Provider value={authContextValue}>
{children}
</AuthContext.Provider>
);
}