diff --git a/frontend/src/components/Login.jsx b/frontend/src/components/Login.jsx new file mode 100644 index 0000000..dea660d --- /dev/null +++ b/frontend/src/components/Login.jsx @@ -0,0 +1,122 @@ +import TextField from '@mui/material/TextField'; +import { useState } from 'react'; +import { Link, useNavigate } from 'react-router-dom'; +import Button from '@mui/material/Button'; +import { styled } from '@mui/material/styles'; + +const Login = () => { + const navigate = useNavigate(); + const [formData, setFormData] = useState({ + email: '', + password: '', + }); + const [error, setError] = useState(null); + const [isLoading, setIsLoading] = useState(false); + + const handleChange = (e) => { + const { name, value } = e.target; + setFormData({ + ...formData, + [name]: value, + }); + }; + + const handleSubmit = async (e) => { + e.preventDefault(); + setError(null); + setIsLoading(true); + try { + const response = await fetch("http://localhost:3500/auth/login", { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(formData), + }); + if (!response.ok) { + const errData = await response.json(); + throw new Error(errData.message || "Failed to login"); + } + const { token, user } = await response.json(); + localStorage.setItem('token', token); + navigate("/"); + } catch (err) { + setError(err.message); + } finally { + setIsLoading(false); + } + }; + + const ColorButton = styled(Button)(() => ({ + color: '#FFFFFF', + backgroundColor: '#8D538D', + '&:hover': { + backgroundColor: '#514ACD', + }, + borderRadius: '8px', + })); + + return ( +
+
+

+ Welcome to JobNode! +

+

Your gateway to career opportunities

+
+ +
+
+

Login

+ + + + Forgot Password? + + {error &&

{error}

} + + {isLoading ? 'Logging in...' : 'Login'} + +
+
+
+

+ Don't have an account?{' '} + + Register + +

+ +
+ Illustration +
+
+
+ ); +}; + +export default Login; \ No newline at end of file diff --git a/frontend/src/components/RegistrationModal.jsx b/frontend/src/components/RegistrationModal.jsx new file mode 100644 index 0000000..a8c3e60 --- /dev/null +++ b/frontend/src/components/RegistrationModal.jsx @@ -0,0 +1,104 @@ +import React from 'react'; +import Dialog from '@mui/material/Dialog'; +import DialogActions from '@mui/material/DialogActions'; +import DialogContent from '@mui/material/DialogContent'; +import DialogContentText from '@mui/material/DialogContentText'; +import DialogTitle from '@mui/material/DialogTitle'; +import Button from '@mui/material/Button'; +import { styled } from '@mui/material/styles'; +import CheckCircleOutlineIcon from '@mui/icons-material/CheckCircleOutline'; +import Divider from '@mui/material/Divider'; + +// You can use this styled button or import your existing ColorButton +const ColorButton = styled(Button)(() => ({ + color: '#FFFFFF', + backgroundColor: '#8D538D', + '&:hover': { + backgroundColor: '#514ACD', + }, + borderRadius: '8px', +})); + +// Standalone Registration Success Modal component +const RegistrationSuccessModal = ({ + open, + onClose, + userType = 'JobSeeker' // Default value in case it's not provided +}) => { + return ( + + + Registration Successful + + + + + +
+ + + + Your account has been successfully created! Please log in to start exploring opportunities. + + + + {userType === 'JobSeeker' + ? "You're now ready to find your dream job!" + : "You're now ready to find talented candidates!"} + +
+
+ + + + Proceed to Login + + +
+ ); +}; + +export default RegistrationSuccessModal; \ No newline at end of file diff --git a/frontend/src/components/SignUp.jsx b/frontend/src/components/SignUp.jsx new file mode 100644 index 0000000..061a297 --- /dev/null +++ b/frontend/src/components/SignUp.jsx @@ -0,0 +1,174 @@ +import TextField from '@mui/material/TextField'; +import { useState } from 'react'; +import Button from '@mui/material/Button'; +import { styled } from '@mui/material/styles'; +import Select from '@mui/material/Select'; +import MenuItem from '@mui/material/MenuItem'; +import InputLabel from '@mui/material/InputLabel'; +import FormControl from '@mui/material/FormControl'; +import { Link, useNavigate } from 'react-router-dom'; +import RegistrationModal from '../components/RegistrationModal' + +const SignUp = () => { + const navigate = useNavigate(); + const [formData, setFormData] = useState({ + email: '', + name: '', + password: '', + userType: 'JobSeeker', + }); + const [error, setError] = useState(null); + const [isLoading, setIsLoading] = useState(false); + const [openModal, setOpenModal] = useState(false); // State to manage modal visibility + + + const handleChange = (e) => { + const { name, value } = e.target; + setFormData({ + ...formData, + [name]: value, + }); + }; + + const handleSubmit = async (e) => { + e.preventDefault(); + setError(null); + setIsLoading(true); + + try { + const response = await fetch("http://localhost:3500/auth/register", { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(formData), + }); + + if (!response.ok) { + const errData = await response.json(); + throw new Error(errData.message || "Registration failed"); + } + + // Show modal on successful registration + setOpenModal(true); + setFormData({ + email: '', + name: '', + password: '', + userType: 'JobSeeker', + }); + setError(null); + } catch (error) { + setError(error.message); + } finally { + setIsLoading(false); + } + }; + + const handleCloseModal = () => { + setOpenModal(false); + navigate("/login"); + }; + + const ColorButton = styled(Button)(() => ({ + color: '#FFFFFF', + backgroundColor: '#8D538D', + '&:hover': { + backgroundColor: '#514ACD', + }, + borderRadius: '8px', + })); + + return ( +
+
+

+ Join JobNode Today! +

+

Start your professional journey with us

+
+ +
+
+

SignUp

+ + + + + User Type + + + + {error &&

{error}

} + + {isLoading ? 'Signing up...' : 'SignUp'} + +
+
+
+

+ Already have an account?{' '} + + Login + +

+ + +
+ Illustration +
+
+ + {/* Modal for successful registration */} + +
+ ); +}; + +export default SignUp; \ No newline at end of file