Skip to content

Commit da92a9e

Browse files
committed
Add error display for signup and signin
1 parent 6c658ab commit da92a9e

File tree

4 files changed

+146
-4
lines changed

4 files changed

+146
-4
lines changed

authentication-service/README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ docker run -p 4040:4040 --env-file .env acc account-creation-service
1212
## Example Usage
1313

1414
1. Make sure your json struct has a similar structure:
15-
``` {
15+
16+
```{
1617
"email": "[email protected]",
1718
"name": "exampleUser",
1819
"password": "securePassword123",
@@ -44,3 +45,4 @@ fetch("http://localhost:4040/register", requestOptions)
4445
.then((response) => response.text())
4546
.then((result) => console.log(result))
4647
.catch((error) => console.error(error));```
48+
```

peerprep-fe/src/app/signin/page.tsx

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,62 @@
11
'use client';
22
import { useState } from 'react';
3+
import { useRouter } from 'next/navigation';
34
import { Button } from '@/components/ui/button';
45
import { Checkbox } from '@/components/ui/checkbox';
56
import { Input } from '@/components/ui/input';
67
import Link from 'next/link';
78
import { GithubIcon } from 'lucide-react';
9+
import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert';
810

911
export default function LoginForm() {
1012
const [email, setEmail] = useState('');
1113
const [password, setPassword] = useState('');
14+
const [error, setError] = useState('');
15+
// const [error, setError] = useState('');
16+
const router = useRouter();
17+
// handle login here
18+
const handleLogin = async (e: React.FormEvent) => {
19+
e.preventDefault();
20+
// setError('');
21+
// const apiEndpoint = 'http://localhost:4040/api/auth/login';
22+
// const result = await fetch(apiEndpoint, {
23+
// method: 'POST',
24+
// headers: {
25+
// 'Content-Type': 'application/json',
26+
// },
27+
// body: JSON.stringify({ email, password }),
28+
// });
29+
30+
// const data = await result.json();
31+
// const message = data.message;
32+
// const isAuth = message === "Login successful";
33+
const isAuth = false;
34+
if (isAuth) {
35+
// const token = data.token;
36+
// localStorage.setItem('token', token);
37+
// go to homepage
38+
router.push('/');
39+
} else {
40+
setError('Please provide correct email and password');
41+
console.error('Login failed');
42+
}
43+
};
1244

1345
return (
1446
<div className="flex min-h-screen items-center justify-center bg-gray-900">
1547
<div className="w-full max-w-md space-y-6 rounded-lg bg-gray-800 p-8 shadow-xl">
48+
{error && (
49+
<Alert variant="destructive" className="mb-4">
50+
{/* <AlertCircle className="h-4 w-4" /> */}
51+
<AlertTitle>Error</AlertTitle>
52+
<AlertDescription>{error}</AlertDescription>
53+
</Alert>
54+
)}
1655
<div className="text-center">
1756
<h2 className="text-3xl font-bold text-white">PeerPrep</h2>
1857
<p className="text-sm text-gray-400">Sign in to your account</p>
1958
</div>
20-
<form className="space-y-4">
59+
<form onSubmit={handleLogin} className="space-y-4">
2160
<div>
2261
<Input
2362
type="email"
@@ -86,7 +125,7 @@ export default function LoginForm() {
86125
</Button>
87126
</div>
88127
<div className="flex justify-center text-center text-sm text-gray-400">
89-
Don't have an account?
128+
Do not have an account?
90129
<span className="mx-1" />
91130
<Link href="/signup" className="text-blue-500 hover:underline">
92131
Sign up

peerprep-fe/src/app/signup/page.tsx

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,59 @@ import { Button } from '@/components/ui/button';
44
import { Checkbox } from '@/components/ui/checkbox';
55
import { Input } from '@/components/ui/input';
66
import { GithubIcon } from 'lucide-react';
7+
import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert';
8+
import { useRouter } from 'next/navigation';
79
import Link from 'next/link';
810

911
export default function SignUpPage() {
1012
const [email, setEmail] = useState('');
1113
const [password, setPassword] = useState('');
1214
const [confirmPassword, setConfirmPassword] = useState('');
1315
const [agreeTerms, setAgreeTerms] = useState(false);
16+
const [error, setError] = useState('');
17+
const router = useRouter();
18+
19+
const handleSignUp = async (e: React.FormEvent) => {
20+
e.preventDefault();
21+
// setError('');
22+
// const apiEndpoint = 'http://localhost:4040/api/auth/signup';
23+
// const result = await fetch(apiEndpoint, {
24+
// method: 'POST',
25+
// headers: {
26+
// 'Content-Type': 'application/json',
27+
// },
28+
// body: JSON.stringify({ email, password }),
29+
// });
30+
31+
// const data = await result.json();
32+
// const message = data.message;
33+
// const isAuth = message === "Login successful";
34+
const isAuth = true;
35+
if (password !== confirmPassword) {
36+
setError('Passwords do not match');
37+
return;
38+
}
39+
if (isAuth) {
40+
// const token = data.token;
41+
// localStorage.setItem('token', token);
42+
// go to homepage
43+
router.push('/');
44+
} else {
45+
setError('Account creation failed');
46+
console.error('Login failed');
47+
}
48+
};
1449

1550
return (
1651
<div className="flex min-h-screen items-center justify-center bg-gray-900">
1752
<div className="w-full max-w-md space-y-6 rounded-lg bg-gray-800 p-8 shadow-xl">
53+
{error && (
54+
<Alert variant="destructive" className="mb-4">
55+
{/* <AlertCircle className="h-4 w-4" /> */}
56+
<AlertTitle>Error</AlertTitle>
57+
<AlertDescription>{error}</AlertDescription>
58+
</Alert>
59+
)}
1860
<div className="text-center">
1961
<h2 className="text-3xl font-bold text-white">Create your account</h2>
2062
<p className="text-sm text-gray-400">
@@ -25,7 +67,7 @@ export default function SignUpPage() {
2567
</Link>
2668
</p>
2769
</div>
28-
<form className="space-y-4">
70+
<form onSubmit={handleSignUp} className="space-y-4">
2971
<div>
3072
<Input
3173
type="email"
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import * as React from 'react';
2+
import { cva, type VariantProps } from 'class-variance-authority';
3+
4+
import { cn } from '@/lib/utils';
5+
6+
const alertVariants = cva(
7+
'relative w-full rounded-lg border px-4 py-3 text-sm [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground [&>svg~*]:pl-7',
8+
{
9+
variants: {
10+
variant: {
11+
default: 'bg-background text-foreground',
12+
destructive:
13+
'border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive',
14+
},
15+
},
16+
defaultVariants: {
17+
variant: 'default',
18+
},
19+
},
20+
);
21+
22+
const Alert = React.forwardRef<
23+
HTMLDivElement,
24+
React.HTMLAttributes<HTMLDivElement> & VariantProps<typeof alertVariants>
25+
>(({ className, variant, ...props }, ref) => (
26+
<div
27+
ref={ref}
28+
role="alert"
29+
className={cn(alertVariants({ variant }), className)}
30+
{...props}
31+
/>
32+
));
33+
Alert.displayName = 'Alert';
34+
35+
const AlertTitle = React.forwardRef<
36+
HTMLParagraphElement,
37+
React.HTMLAttributes<HTMLHeadingElement>
38+
>(({ className, ...props }, ref) => (
39+
<h5
40+
ref={ref}
41+
className={cn('mb-1 font-medium leading-none tracking-tight', className)}
42+
{...props}
43+
/>
44+
));
45+
AlertTitle.displayName = 'AlertTitle';
46+
47+
const AlertDescription = React.forwardRef<
48+
HTMLParagraphElement,
49+
React.HTMLAttributes<HTMLParagraphElement>
50+
>(({ className, ...props }, ref) => (
51+
<div
52+
ref={ref}
53+
className={cn('text-sm [&_p]:leading-relaxed', className)}
54+
{...props}
55+
/>
56+
));
57+
AlertDescription.displayName = 'AlertDescription';
58+
59+
export { Alert, AlertTitle, AlertDescription };

0 commit comments

Comments
 (0)