Skip to content

Commit 894a6de

Browse files
Merge pull request #6 from Learnathon-By-Geeky-Solutions/ismail
authentication related components created
2 parents 6337c5b + a7f543e commit 894a6de

File tree

3 files changed

+400
-0
lines changed

3 files changed

+400
-0
lines changed

frontend/src/components/Login.jsx

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
import TextField from '@mui/material/TextField';
2+
import { useState } from 'react';
3+
import { Link, useNavigate } from 'react-router-dom';
4+
import Button from '@mui/material/Button';
5+
import { styled } from '@mui/material/styles';
6+
7+
const Login = () => {
8+
const navigate = useNavigate();
9+
const [formData, setFormData] = useState({
10+
email: '',
11+
password: '',
12+
});
13+
const [error, setError] = useState(null);
14+
const [isLoading, setIsLoading] = useState(false);
15+
16+
const handleChange = (e) => {
17+
const { name, value } = e.target;
18+
setFormData({
19+
...formData,
20+
[name]: value,
21+
});
22+
};
23+
24+
const handleSubmit = async (e) => {
25+
e.preventDefault();
26+
setError(null);
27+
setIsLoading(true);
28+
try {
29+
const response = await fetch("http://localhost:3500/auth/login", {
30+
method: 'POST',
31+
headers: {
32+
'Content-Type': 'application/json',
33+
},
34+
body: JSON.stringify(formData),
35+
});
36+
if (!response.ok) {
37+
const errData = await response.json();
38+
throw new Error(errData.message || "Failed to login");
39+
}
40+
const { token, user } = await response.json();
41+
localStorage.setItem('token', token);
42+
navigate("/");
43+
} catch (err) {
44+
setError(err.message);
45+
} finally {
46+
setIsLoading(false);
47+
}
48+
};
49+
50+
const ColorButton = styled(Button)(() => ({
51+
color: '#FFFFFF',
52+
backgroundColor: '#8D538D',
53+
'&:hover': {
54+
backgroundColor: '#514ACD',
55+
},
56+
borderRadius: '8px',
57+
}));
58+
59+
return (
60+
<div className='flex flex-col justify-center items-center min-h-screen bg-gray-100'>
61+
<div className='mb-8 text-center'>
62+
<h1 className='text-4xl font-bold text-transparent bg-clip-text bg-gradient-to-r from-[#8D538D] to-[#514ACD]'>
63+
Welcome to JobNode!
64+
</h1>
65+
<p className='text-xl text-gray-700 mt-2'>Your gateway to career opportunities</p>
66+
</div>
67+
68+
<div className='flex items-center bg-white shadow-lg rounded-lg overflow-hidden w-[40em]'>
69+
<form
70+
className='flex flex-col gap-4 w-1/2 p-8'
71+
onSubmit={handleSubmit}
72+
>
73+
<h1 className='text-2xl font-bold text-center text-gray-800 mb-4'>Login</h1>
74+
<TextField
75+
id='login-email'
76+
label='Email'
77+
variant='outlined'
78+
onChange={handleChange}
79+
type='email'
80+
name='email'
81+
value={formData.email}
82+
/>
83+
<TextField
84+
id='login-password'
85+
label='Password'
86+
variant='outlined'
87+
onChange={handleChange}
88+
type='password'
89+
name='password'
90+
value={formData.password}
91+
/>
92+
<Link to='/forgot-password' className='text-sm text-blue-500 hover:underline self-center'>
93+
Forgot Password?
94+
</Link>
95+
{error && <p className='text-red-500 text-center'>{error}</p>}
96+
<ColorButton
97+
variant='contained'
98+
size='large'
99+
type='submit'
100+
disabled={isLoading}
101+
>
102+
{isLoading ? 'Logging in...' : 'Login'}
103+
</ColorButton>
104+
<div className='flex items-center gap-2 text-sm mt-4'>
105+
<div className='w-full h-[1px] bg-gray-300'></div>
106+
</div>
107+
<p className='text-sm text-center mt-4'>
108+
Don't have an account?{' '}
109+
<Link to='/signup' className='text-blue-500 hover:underline'>
110+
Register
111+
</Link>
112+
</p>
113+
</form>
114+
<div className='w-1/2 bg-gray-200 flex items-center justify-center'>
115+
<img src='/loginImg.jpeg' alt='Illustration' className='w-full h-auto' />
116+
</div>
117+
</div>
118+
</div>
119+
);
120+
};
121+
122+
export default Login;
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
import React from 'react';
2+
import Dialog from '@mui/material/Dialog';
3+
import DialogActions from '@mui/material/DialogActions';
4+
import DialogContent from '@mui/material/DialogContent';
5+
import DialogContentText from '@mui/material/DialogContentText';
6+
import DialogTitle from '@mui/material/DialogTitle';
7+
import Button from '@mui/material/Button';
8+
import { styled } from '@mui/material/styles';
9+
import CheckCircleOutlineIcon from '@mui/icons-material/CheckCircleOutline';
10+
import Divider from '@mui/material/Divider';
11+
12+
// You can use this styled button or import your existing ColorButton
13+
const ColorButton = styled(Button)(() => ({
14+
color: '#FFFFFF',
15+
backgroundColor: '#8D538D',
16+
'&:hover': {
17+
backgroundColor: '#514ACD',
18+
},
19+
borderRadius: '8px',
20+
}));
21+
22+
// Standalone Registration Success Modal component
23+
const RegistrationSuccessModal = ({
24+
open,
25+
onClose,
26+
userType = 'JobSeeker' // Default value in case it's not provided
27+
}) => {
28+
return (
29+
<Dialog
30+
open={open}
31+
onClose={onClose}
32+
PaperProps={{
33+
style: {
34+
borderRadius: '12px',
35+
padding: '16px',
36+
maxWidth: '450px'
37+
}
38+
}}
39+
>
40+
<DialogTitle
41+
sx={{
42+
textAlign: 'center',
43+
fontWeight: 'bold',
44+
color: '#8D538D',
45+
fontSize: '1.5rem'
46+
}}
47+
>
48+
Registration Successful
49+
</DialogTitle>
50+
51+
<Divider />
52+
53+
<DialogContent sx={{ padding: '24px 16px' }}>
54+
<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center' }}>
55+
<CheckCircleOutlineIcon
56+
sx={{
57+
fontSize: 80,
58+
color: '#8D538D',
59+
marginBottom: '16px'
60+
}}
61+
/>
62+
63+
<DialogContentText
64+
sx={{
65+
textAlign: 'center',
66+
fontSize: '1.1rem',
67+
color: '#333'
68+
}}
69+
>
70+
Your account has been successfully created! Please log in to start exploring opportunities.
71+
</DialogContentText>
72+
73+
<DialogContentText
74+
sx={{
75+
textAlign: 'center',
76+
fontSize: '0.9rem',
77+
color: '#666',
78+
marginTop: '8px'
79+
}}
80+
>
81+
{userType === 'JobSeeker'
82+
? "You're now ready to find your dream job!"
83+
: "You're now ready to find talented candidates!"}
84+
</DialogContentText>
85+
</div>
86+
</DialogContent>
87+
88+
<DialogActions sx={{ padding: '0 16px 16px', justifyContent: 'center' }}>
89+
<ColorButton
90+
onClick={onClose}
91+
sx={{
92+
minWidth: '120px',
93+
fontWeight: 'bold',
94+
padding: '10px 24px'
95+
}}
96+
>
97+
Proceed to Login
98+
</ColorButton>
99+
</DialogActions>
100+
</Dialog>
101+
);
102+
};
103+
104+
export default RegistrationSuccessModal;

0 commit comments

Comments
 (0)