Skip to content

Commit

Permalink
added svg for checks
Browse files Browse the repository at this point in the history
  • Loading branch information
rachaelch3n committed Dec 8, 2024
1 parent 0b8030d commit ab3dead
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 27 deletions.
23 changes: 17 additions & 6 deletions app/(auth)/login/page.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use client';

import { useState } from 'react';
// import { useRouter } from 'next/navigation';
import { useRouter } from 'next/navigation';
import TextInput from '@/components/TextInput';
import { StyledButton, StyledForm } from '@/components/TextInput/styles';
import COLORS from '@/styles/colors';
Expand All @@ -18,11 +18,21 @@ export default function Login() {

const isFormValid = email && password;

// const { push } = useRouter();
const router = useRouter();

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

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

const handleLogin = async () => {
try {
const { error } = await signIn(email, password);
// push('/');

if (error) {
// Match error messages from Supabase
Expand All @@ -36,6 +46,7 @@ export default function Login() {
// 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.');
Expand All @@ -45,13 +56,13 @@ export default function Login() {
return (
<StyledForm onSubmit={handleLogin}>
<div style={{ display: 'flex', flexDirection: 'column', gap: '1.5rem' }}>
<H2 style={{ color: COLORS.shrub }}>Log In</H2>
<H2 $color={COLORS.shrub}>Log In</H2>
<div>
<TextInput
id="email-input"
type="email"
label="Email"
onChange={setEmail}
onChange={handleEmailChange}
value={email}
error={!!invalidEmailError}
/>
Expand All @@ -63,7 +74,7 @@ export default function Login() {
id="password-input"
label="Password"
type="password"
onChange={setPassword}
onChange={handlePasswordChange}
value={password}
isVisible={showPassword}
toggleVisibility={() => setShowPassword(!showPassword)}
Expand Down
60 changes: 40 additions & 20 deletions app/(auth)/signup/page.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
'use client';

import { useState } from 'react';
import { useRouter } from 'next/navigation';
import Icon from '@/components/Icon';
import PasswordComplexity from '@/components/PasswordComplexity';
import TextInput from '@/components/TextInput';
import { StyledButton, StyledForm } from '@/components/TextInput/styles';
Expand All @@ -14,17 +16,17 @@ export default function SignUp() {
const [password, setPassword] = useState<string>('');
const [confirmPassword, setConfirmPassword] = useState<string>('');
const [samePasswordCheck, setSamePasswordCheck] = useState('');
const [mismatchError, setMismatchError] = useState('');
const [isPasswordComplexityMet, setIsPasswordComplexityMet] =
useState<boolean>(false);
const [showPassword, setShowPassword] = useState(false);
const [showConfirmPassword, setShowConfirmPassword] = useState(false);
const [checkEmailExistsError] = useState('');
const [checkEmailExistsError, setCheckEmailExistsError] = useState('');
const [checkValidEmailError, setCheckValidEmailError] = useState('');
const [isSubmitted, setIsSubmitted] = useState(false);
const [isEmailValid, setIsEmailValid] = useState(true);

const isFormValid = email && password && confirmPassword;
const router = useRouter();

const isValidEmail = (email: string): boolean => {
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
Expand All @@ -33,6 +35,7 @@ export default function SignUp() {

const handleEmailChange = async (newEmail: string) => {
setEmail(newEmail);
setCheckEmailExistsError('');

// Validate email format
if (!isValidEmail(newEmail)) {
Expand All @@ -49,22 +52,18 @@ export default function SignUp() {
const handlePasswordChange = (newPassword: string) => {
setPassword(newPassword);

validateIsPasswordComplexityMet(newPassword);
if (!newPassword || !confirmPassword) {
setMismatchError('');
setSamePasswordCheck('');
return;
}

// Set mismatch error if passwords do not match
if (newPassword !== confirmPassword) {
setMismatchError('✗ Passwords do not match');
setSamePasswordCheck('');
} else {
setMismatchError('');
setSamePasswordCheck('✓ Passwords match');
}

validateIsPasswordComplexityMet(newPassword);
};

// Handles input to confirm password
Expand All @@ -73,17 +72,14 @@ export default function SignUp() {

// Clear mismatch error if either field is empty
if (!password || !newConfirmPassword) {
setMismatchError('');
setSamePasswordCheck('');
return;
}

// Set mismatch error if passwords do not match
if (password !== newConfirmPassword) {
setMismatchError('✗ Passwords do not match');
setSamePasswordCheck('');
} else {
setMismatchError('');
setSamePasswordCheck('✓ Passwords match');
}
};
Expand All @@ -94,11 +90,9 @@ export default function SignUp() {
const hasNumber = /\d/.test(password || '');
const longEnough = (password || '').length >= 8;

if (password && hasLowerCase && hasNumber && longEnough) {
setIsPasswordComplexityMet(true);
} else {
setIsPasswordComplexityMet(false);
}
setIsPasswordComplexityMet(
!!password && hasLowerCase && hasNumber && longEnough,
);
};

const handleSignUp = async () => {
Expand All @@ -111,7 +105,19 @@ export default function SignUp() {
}

try {
await signUp(email, password);
const result = await signUp(email, password);
if (result.error) {
// Handle the specific error (e.g., duplicate email)
if (result.error.message === 'Account already exists for this email') {
setCheckEmailExistsError(result.error.message);
} else if (checkValidEmailError == 'false') {
alert(result.error.message); // Show a generic alert for other errors
}
} else {
// Handle successful sign-up (e.g., navigate to another page)
setCheckEmailExistsError('');
router.push('/onboarding');
}
} catch (error) {
console.error('Sign up failed:', error);
alert('There was an error during sign up. Please try again.');
Expand All @@ -121,7 +127,7 @@ export default function SignUp() {
return (
<StyledForm onSubmit={handleSignUp}>
<div style={{ display: 'flex', flexDirection: 'column', gap: '1.5rem' }}>
<H2 style={{ color: COLORS.shrub }}>Sign Up</H2>
<H2 $color={COLORS.shrub}>Sign Up</H2>
<div>
<TextInput
id="email-input"
Expand All @@ -132,7 +138,7 @@ export default function SignUp() {
error={!!checkEmailExistsError || (!isEmailValid && isSubmitted)}
/>
{/* Email input*/}
{checkEmailExistsError && (
{checkEmailExistsError && isSubmitted && (
<P3 style={{ color: COLORS.errorRed }}>{checkEmailExistsError}</P3>
)}
{!isEmailValid && isSubmitted && (
Expand Down Expand Up @@ -176,11 +182,25 @@ export default function SignUp() {
{/* Confirm password input with toggle visibility */}

{samePasswordCheck && (
<P3 style={{ color: '#0D8817' }}>{samePasswordCheck}</P3>
<P3 style={{ color: '#0D8817' }}>
<div
style={{ display: 'flex', alignItems: 'center', gap: '8px' }}
>
<Icon type="check" />
{'Passwords match'}
</div>
</P3>
)}

{isSubmitted && !samePasswordCheck && (
<P3 style={{ color: COLORS.errorRed }}>{mismatchError}</P3>
<P3 style={{ color: COLORS.errorRed }}>
<div
style={{ display: 'flex', alignItems: 'center', gap: '8px' }}
>
<Icon type="x" />
{'Passwords do not match'}
</div>
</P3>
)}
{/* Conditional password validation error message */}
</div>
Expand Down
6 changes: 5 additions & 1 deletion components/PasswordComplexity.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import COLORS from '@/styles/colors';
import { P3 } from '@/styles/text';
import Icon from './Icon';

export default function PasswordComplexity({ password }: { password: string }) {
// Define complexity rules with their check logic
Expand Down Expand Up @@ -45,7 +46,10 @@ function Requirement({ met, text }: { met: boolean; text: string }) {
color: met ? '#0D8817' : COLORS.errorRed,
}}
>
{met ? '✓' : '✗'} {text}
<div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
<Icon type={met ? 'check' : 'x'} />
{text}
</div>
</P3>
);
}
27 changes: 27 additions & 0 deletions lib/icons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,33 @@ export const IconSvgs = {
</defs>
</svg>
),

check: (
<svg
width="12"
height="9"
viewBox="0 0 12 9"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M3.81353 7.10067L0.968732 4.30201L0 5.24832L3.81353 9L12 0.946309L11.0381 0L3.81353 7.10067Z"
fill="#0D8817"
/>
</svg>
),
x: (
<svg
width="11"
height="11"
viewBox="0 0 11 11"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path d="M10 1L1 10" stroke="#E94444" stroke-width="1.5" />
<path d="M1 1L10 10" stroke="#E94444" stroke-width="1.5" />
</svg>
),
};

export type IconType = keyof typeof IconSvgs;

0 comments on commit ab3dead

Please sign in to comment.