Skip to content

Commit

Permalink
feat: error messages in login screen
Browse files Browse the repository at this point in the history
  • Loading branch information
celinechoiii committed Dec 7, 2024
1 parent e2a3ceb commit 091c25f
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 48 deletions.
29 changes: 12 additions & 17 deletions app/(auth)/auth-styles.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import Image from 'next/image';
import NextLink from 'next/link';
import styled from 'styled-components';
import COLORS from '@/styles/colors';
import { Sans } from '@/styles/fonts';
Expand Down Expand Up @@ -39,8 +40,9 @@ export const Header = styled(H3)`
export const Card = styled.div`
background-color: ${COLORS.bread1};
padding: 2rem;
border-radius: 12px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
border-radius: 16px;
border: 1px solid ${COLORS.gray2};
box-shadow: 0px 6px 15px -2px rgba(0, 0, 0, 0.08);
max-width: 400px;
width: 100%;
box-sizing: border-box;
Expand All @@ -49,7 +51,7 @@ export const Card = styled.div`
align-items: center;
`;

export const Form = styled.div`
export const Form = styled.form`
display: flex;
flex-direction: column;
align-items: stretch;
Expand All @@ -59,7 +61,7 @@ export const Form = styled.div`
export const Fields = styled.div`
display: flex;
flex-direction: column;
gap: 1.75rem;
gap: 1.5rem;
`;

export const Label = styled(P)`
Expand All @@ -75,6 +77,7 @@ export const Input = styled.input`
border-radius: 8px;
width: 100%;
box-sizing: border-box;
margin-bottom: 0.2rem;
`;

export const Button = styled.button`
Expand All @@ -90,13 +93,7 @@ export const Button = styled.button`
width: 100%;
`;

export const ForgotPassword = styled(SMALL)`
margin-top: 0.25rem;
font-weight: 400;
text-align: right;
`;

export const Link = styled.a`
export const Link = styled(NextLink)`
color: ${COLORS.lilac9};
text-decoration: none;
Expand All @@ -105,18 +102,16 @@ export const Link = styled.a`
}
`;

// TODO: Temporarily added to verify that supabase login functionality actually works
export const LoginMessage = styled(SMALL)<{ $isError: boolean }>`
color: ${({ $isError }) => ($isError ? 'red' : 'green')};
export const ErrorMessage = styled(SMALL)<{ $isError: boolean }>`
color: ${COLORS.rose11};
font-weight: 400;
text-align: left;
margin-bottom: 1.5rem;
margin-bottom: 1rem;
`;

export const Footer = styled.div`
font-family: ${Sans.style.fontFamily};
text-align: center;
margin-top: 1rem;
margin-top: 2rem;
width: 100%;
padding: 0.5rem;
`;
Expand Down
93 changes: 68 additions & 25 deletions app/(auth)/signin/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,22 @@

import { useState } from 'react';
import { useRouter } from 'next/navigation';
import isEmail from 'validator/lib/isEmail';
import { handleSignIn as signInUser } from '@/api/supabase/queries/auth';
import BRLogo from '@/public/images/b&r-logo.png';
import { H5 } from '@/styles/text';
import COLORS from '@/styles/colors';
import { H5, SMALL } from '@/styles/text';
import {
Button,
Card,
Container,
ErrorMessage,
Fields,
Footer,
ForgotPassword,
Form,
Input,
Label,
Link,
LoginMessage,
Logo,
TitleUnderline,
} from '../auth-styles';
Expand All @@ -25,36 +26,61 @@ export default function SignIn() {
const router = useRouter();
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [message, setMessage] = useState('');
const [isError, setIsError] = useState(false);
const [emailError, setEmailError] = useState('');
const [passwordError, setPasswordError] = useState('');
const [errorMessage, setErrorMessage] = useState('');
const [isLoggingIn, setIsLoggingIn] = useState(false);

const handleSignIn = async () => {
setMessage('');
setIsError(false);
const validEmail = (e: string) => e !== '' && isEmail(e);

const { success, message } = await signInUser(email, password);
const handleSignIn = async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
setEmailError('');
setPasswordError('');
setErrorMessage('');

setMessage(message);
setIsError(!success);
let hasError = false;
if (!email) {
setEmailError('Email is required');
hasError = true;
} else if (!validEmail(email)) {
setEmailError('Invalid email');
hasError = true;
}

if (success) {
router.push('/discover');
if (!password) {
setPasswordError('Password is required');
hasError = true;
}

if (hasError) return;

setIsLoggingIn(true);

const { success, message } = await signInUser(email, password);

if (!success) {
setErrorMessage(message);
setIsLoggingIn(false);
return;
}

// Navigate on success
setErrorMessage('');
router.push('/discover');
setIsLoggingIn(false);
};

return (
<Container>
<Logo src={BRLogo} alt="Bread & Roses logo" />
<Card>
<Form>
<Form onSubmit={handleSignIn}>
<H5>Login</H5>
<TitleUnderline />

{/* Show error or success message */}
{message && (
<LoginMessage $isError={isError} role="alert">
{message}
</LoginMessage>
{errorMessage && (
<ErrorMessage $isError={true}>{errorMessage}</ErrorMessage>
)}

<Fields>
Expand All @@ -70,6 +96,15 @@ export default function SignIn() {
value={email}
aria-label="Email"
/>
{emailError && (
<SMALL
$color={COLORS.rose11}
$fontWeight={100}
$text-align="left"
>
{emailError}
</SMALL>
)}
</div>

<div>
Expand All @@ -84,20 +119,28 @@ export default function SignIn() {
value={password}
aria-label="Password"
/>
{passwordError && (
<SMALL
$color={COLORS.rose11}
$font-weight={100}
$text-align="left"
>
{password}
</SMALL>
)}
</div>
</Fields>

{/* Forgot Password Link */}
<ForgotPassword>
<SMALL $fontWeight={400} $align="right">
<Link href="/forgotpassword">Forgot Password?</Link>
</ForgotPassword>
</SMALL>

{/* Submit Button */}
<Button onClick={handleSignIn}>Login</Button>
<Button type="submit" disabled={isLoggingIn}>
{isLoggingIn ? 'Logging In...' : 'Login'}
</Button>
</Form>
</Card>

{/* Footer */}
<Footer>
Don’t have an account? <Link href="/signup">Sign up!</Link>
</Footer>
Expand Down
4 changes: 2 additions & 2 deletions app/(auth)/signup/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ import {
Button,
Card,
Container,
ErrorMessage,
Fields,
Footer,
Form,
Input,
Label,
Link,
LoginMessage,
Logo,
TitleUnderline,
} from '../auth-styles';
Expand Down Expand Up @@ -56,7 +56,7 @@ export default function SignUp() {
<Form>
<H5>Sign Up</H5>
<TitleUnderline width="90px" />
{message && <LoginMessage $isError={isError}>{message}</LoginMessage>}
{message && <ErrorMessage $isError={isError}>{message}</ErrorMessage>}

<Fields>
<div>
Expand Down
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,15 @@
"react": "^18",
"react-dom": "^18",
"react-select": "^5.8.3",
"styled-components": "^6.1.13"
"styled-components": "^6.1.13",
"validator": "^13.12.0"
},
"devDependencies": {
"@ianvs/prettier-plugin-sort-imports": "^4.3.1",
"@types/node": "^20.16.5",
"@types/react": "^18.3.5",
"@types/react-dom": "^18.3.0",
"@types/validator": "^13.12.2",
"eslint": "^8",
"eslint-config-next": "14.2.8",
"eslint-config-prettier": "^9.1.0",
Expand Down
23 changes: 20 additions & 3 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 091c25f

Please sign in to comment.