Skip to content

Commit

Permalink
[feat] create a textinput component + style auth flows (#61)
Browse files Browse the repository at this point in the history
Co-authored-by: Catherine Tan <[email protected]>
  • Loading branch information
rachaelch3n and ccatherinetan authored Dec 13, 2024
1 parent cde9039 commit 379c69a
Show file tree
Hide file tree
Showing 15 changed files with 851 additions and 219 deletions.
2 changes: 1 addition & 1 deletion api/supabase/queries/profiles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export async function fetchProfileById(userId: UUID) {
.from('profiles')
.select('*')
.eq('user_id', userId)
.single();
.maybeSingle();

if (error)
throw new Error(`Error fetching profile id ${userId}: ${error.message}`);
Expand Down
13 changes: 13 additions & 0 deletions api/supabase/queries/users.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import supabase from '../createClient';

export async function checkEmailExists(email: string): Promise<boolean> {
const { data, error } = await supabase.rpc('check_email_exists', {
p_email: email,
});

if (error) {
throw new Error(`Error checking email existence: ${error.message}`);
}

return data;
}
111 changes: 85 additions & 26 deletions app/(auth)/login/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,46 +2,105 @@

import { useState } from 'react';
import { useRouter } from 'next/navigation';
import { BigButton, StyledLinkButton } from '@/components/Buttons';
import TextInput from '@/components/TextInput';
import COLORS from '@/styles/colors';
import { H2, P3 } from '@/styles/text';
import { useAuth } from '../../../utils/AuthProvider';
import { StyledForm } from '../styles';

export default function Login() {
const { signIn } = useAuth(); // Use `signIn` function from AuthProvider
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [showPassword, setShowPassword] = useState(false);
const [invalidEmailError, setInvalidEmailError] = useState('');
const [invalidPasswordError, setInvalidPasswordError] = useState('');

const canSubmitForm = email && password;

const router = useRouter();

const handleEmailChange = async (newEmail: string) => {
setEmail(newEmail);
setInvalidEmailError('');
setInvalidPasswordError('');
};

const handlePasswordChange = (newPassword: string) => {
setPassword(newPassword);
};

const handleLogin = async () => {
// Define handleLogin
try {
await signIn(email, password);
router.push('/'); // Redirect to the home page on success
} catch (error) {
if (error instanceof Error) {
console.error('Login Error:', error.message);
const { error } = await signIn(email, password);

if (error) {
setInvalidEmailError(error.message);
// TODO: use error.code rather than error.messsage
// if (error.message.includes('Invalid login credentials')) {
// setInvalidEmailError('Invalid email address');
// setInvalidPasswordError('Invalid password');
// }
return;
}
// Clear errors on success
setInvalidEmailError('');
setInvalidPasswordError('');
router.push('/view-plants');
} catch (err) {
console.error('Login Error:', err);
setInvalidEmailError('An unexpected error occurred. Please try again.');
}
};

return (
<>
<input
name="email"
onChange={e => setEmail(e.target.value)}
value={email}
placeholder="Email"
/>
{/* Email input*/}
<input
type="password"
name="password"
onChange={e => setPassword(e.target.value)}
value={password}
placeholder="Password"
/>
<button type="button" onClick={handleLogin}>
Sign in
</button>{' '}
{/* Sign in button */}
</>
<StyledForm onSubmit={handleLogin}>
<H2 $color={COLORS.shrub} style={{ marginBottom: '8px' }}>
Log In
</H2>
<div style={{ display: 'flex', flexDirection: 'column', gap: '1.5rem' }}>
<P3 as="span" $color={COLORS.midgray}>
Don’t have an account?
<StyledLinkButton href="/signup" style={{ padding: '4px' }}>
Sign up
</StyledLinkButton>
</P3>
<div>
<TextInput
id="email-input"
type="email"
label="Email"
onChange={handleEmailChange}
value={email}
error={!!invalidEmailError}
/>
{/* Email input*/}
<P3 $color={COLORS.errorRed}>{invalidEmailError}</P3>
</div>
<div>
<TextInput
id="password-input"
label="Password"
type="password"
onChange={handlePasswordChange}
value={password}
isVisible={showPassword}
toggleVisibility={() => setShowPassword(!showPassword)}
error={!!invalidPasswordError}
/>
<P3 $color={COLORS.errorRed}>{invalidPasswordError}</P3>
{/* Password input*/}
</div>
<BigButton
type="button"
onClick={handleLogin}
disabled={!canSubmitForm}
>
Log In
</BigButton>
{/* Sign in button */}
</div>
</StyledForm>
);
}
Loading

0 comments on commit 379c69a

Please sign in to comment.