Skip to content

Commit 021ea95

Browse files
authored
Merge pull request #19 from CS3219-AY2425S1/sign-up
Add Login and sign up FE and sign up FE
2 parents db13630 + 94b9523 commit 021ea95

File tree

8 files changed

+394
-7
lines changed

8 files changed

+394
-7
lines changed

Frontend/src/App.js

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,33 @@
11
import './App.css';
2-
import {BrowserRouter, Routes, Route} from 'react-router-dom'
3-
import 'bootstrap/dist/css/bootstrap.min.css'
2+
import { BrowserRouter, Routes, Route, Navigate } from 'react-router-dom';
3+
import 'bootstrap/dist/css/bootstrap.min.css';
44
import CreateQn from './components/question/CreateQn';
55
import EditQn from './components/question/EditQn';
66
import Home from './components/Home';
7+
import Login from './components/auth/Login';
8+
import SignUp from './components/auth/SignUp';
79

810
function App() {
911
return (
1012
<div>
1113
<BrowserRouter>
12-
<Routes>
13-
<Route path='/' element={<Home/>}></Route>
14-
<Route path='/create' element={<CreateQn/>}></Route>
15-
<Route path='/update/:question_db_id' element={<EditQn/>}></Route>
16-
</Routes>
14+
<Routes>
15+
{/* Default route to Login page */}
16+
<Route path='/' element={<Navigate to='/login' />} />
17+
18+
{/* Login page route */}
19+
<Route path='/login' element={<Login />} />
20+
21+
{/* Sign-up page route */}
22+
<Route path='/signup' element={<SignUp />} />
23+
24+
{/* Home page route */}
25+
<Route path='/home' element={<Home />} />
26+
27+
{/* Create and Edit question routes */}
28+
<Route path='/create' element={<CreateQn />} />
29+
<Route path='/update/:question_db_id' element={<EditQn />} />
30+
</Routes>
1731
</BrowserRouter>
1832
</div>
1933
);
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import React from 'react';
2+
import '../../css/InputField.css'; // Import the CSS file for styling
3+
4+
const InputField = ({ label, type = "text", placeholder, value, onChange }) => {
5+
return (
6+
<div className="input-container">
7+
<div className="input-title">{label}</div>
8+
<input
9+
className="input-element"
10+
type={type}
11+
placeholder={placeholder}
12+
value={value}
13+
onChange={onChange} // Call the onChange function passed from SignUp
14+
/>
15+
</div>
16+
);
17+
};
18+
19+
export default InputField;
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
// import React from 'react';
2+
// import { useNavigate } from 'react-router-dom';
3+
// import { Button, Container, Row, Col } from 'react-bootstrap';
4+
5+
// function Login() {
6+
// const navigate = useNavigate();
7+
8+
// const goToSignUp = () => {
9+
// navigate('/signup'); // Redirects to the sign-up page
10+
// };
11+
12+
// return (
13+
// <Container className="d-flex align-items-center justify-content-center" style={{ height: '100vh' }}>
14+
// <Row>
15+
// <Col md={6} className="text-center">
16+
// <h2>Login Page</h2>
17+
// <p>If you don't have an account, click the button below to sign up!</p>
18+
// <Button variant="primary" onClick={goToSignUp}>
19+
// Go to Sign Up
20+
// </Button>
21+
// </Col>
22+
// </Row>
23+
// </Container>
24+
// );
25+
// }
26+
27+
// export default Login;
28+
29+
import React, { useState } from 'react';
30+
import { Link } from 'react-router-dom'; // Import Link for navigation
31+
import '../../css/Login.css'; // Import the CSS for styling
32+
import InputField from './InputField';
33+
34+
const Login = () => {
35+
const [email, setEmail] = useState('');
36+
const [password, setPassword] = useState('');
37+
38+
const handleLogin = (e) => {
39+
e.preventDefault();
40+
// Add your login logic here
41+
console.log('Logging in with:', { email, password });
42+
};
43+
44+
return (
45+
<div className="login-container">
46+
<div className="left-side">
47+
<h1 className="title">PeerPrep</h1>
48+
<h2 className="subtitle">Sign In</h2>
49+
</div>
50+
<div className="right-side">
51+
<div className="input-container">
52+
<form onSubmit={handleLogin}>
53+
<div>
54+
<InputField label="Email" type="email" placeholder="Enter your email" />
55+
<InputField label="Password" type="password" placeholder="Enter your password" />
56+
</div>
57+
<div className="button-container">
58+
<Link to="/signup" className="create-account-link">Create Account</Link>
59+
<button type="submit" className="login-button">Sign In</button>
60+
</div>
61+
</form>
62+
</div>
63+
</div>
64+
</div>
65+
);
66+
};
67+
68+
export default Login;
69+
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
import React, { useState } from 'react';
2+
import { useNavigate } from 'react-router-dom'; // Import useNavigate for routing
3+
import userService from '../../services/users';
4+
import InputField from './InputField'; // Import the InputField component
5+
import '../../css/SignUp.css'; // Import the CSS for styling
6+
7+
function SignUp() {
8+
const [username, setUsername] = useState('');
9+
const [email, setEmail] = useState('');
10+
const [password, setPassword] = useState('');
11+
const [errorMessage, setErrorMessage] = useState('');
12+
const [successMessage, setSuccessMessage] = useState('');
13+
14+
const navigate = useNavigate(); // Initialize useNavigate
15+
16+
const handleSignUp = async (e) => {
17+
e.preventDefault();
18+
setErrorMessage('');
19+
setSuccessMessage('');
20+
21+
const newUser = {
22+
username,
23+
email,
24+
password
25+
};
26+
27+
try {
28+
const response = await userService.createUser(newUser);
29+
if (response.status === 201) {
30+
setSuccessMessage('User created successfully!');
31+
setUsername('');
32+
setEmail('');
33+
setPassword('');
34+
// Redirect to the login page
35+
setTimeout(() => {
36+
navigate('/login'); // Redirect to login after a short delay
37+
}, 2000); // Delay for 2 seconds to show success message
38+
}
39+
} catch (error) {
40+
// Check the error response status code and set appropriate error messages
41+
if (error.response) {
42+
switch (error.response.status) {
43+
case 400:
44+
setErrorMessage('Please fill in all required fields.');
45+
break;
46+
case 409:
47+
setErrorMessage('Username or email already exists.');
48+
break;
49+
case 500:
50+
setErrorMessage('Server error. Please try again later.');
51+
break;
52+
default:
53+
setErrorMessage('An unexpected error occurred.');
54+
break;
55+
}
56+
} else {
57+
setErrorMessage('Network error. Please check your connection.');
58+
}
59+
}
60+
};
61+
62+
return (
63+
<div className="signup-container">
64+
<div className="left-side">
65+
<h1 className="title">PeerPrep</h1>
66+
<h2 className="subtitle">Create an Account</h2>
67+
</div>
68+
<div className="right-side">
69+
<div className="input-container">
70+
<form onSubmit={handleSignUp}>
71+
<InputField
72+
label="Username"
73+
type="text"
74+
placeholder="Enter your username"
75+
value={username}
76+
onChange={(e) => setUsername(e.target.value)}
77+
required
78+
/>
79+
<InputField
80+
label="Email"
81+
type="email"
82+
placeholder="Enter your email"
83+
value={email}
84+
onChange={(e) => setEmail(e.target.value)}
85+
required
86+
/>
87+
<InputField
88+
label="Password"
89+
type="password"
90+
placeholder="Enter your password"
91+
value={password}
92+
onChange={(e) => setPassword(e.target.value)}
93+
required
94+
/>
95+
<div className='button-container'>
96+
<button type="submit" className="signup-button">
97+
Sign Up
98+
</button>
99+
</div>
100+
</form>
101+
<div className='notification'>
102+
{/* Success Message */}
103+
{successMessage && <p className="text-success mt-3">{successMessage}</p>}
104+
105+
{/* Error Message */}
106+
{errorMessage && <p className="text-danger mt-3">{errorMessage}</p>}
107+
</div>
108+
</div>
109+
</div>
110+
</div>
111+
);
112+
}
113+
114+
export default SignUp;

Frontend/src/css/InputField.css

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
.input-container {
2+
position: relative;
3+
margin: 30px 0; /* Adjust margin as needed */
4+
}
5+
6+
.input-title {
7+
position: absolute;
8+
top: -10px; /* Adjust as needed for spacing */
9+
left: 10px; /* Adj#ffffffs needed for spacing */
10+
background-color: white; /* Matches the background of the input field */
11+
padding: 0 5px; /* Padding for better spacing */
12+
font-size: 14px; /* Adjust font size as needed */
13+
color: #333; /* Adjust color as needed */
14+
}
15+
16+
.input-element {
17+
border: 1px solid #ccc; /* Border style */
18+
border-radius: 4px; /* Rounded corners */
19+
padding: 10px; /* Input padding */
20+
width: 100%; /* Full width */
21+
box-sizing: border-box; /* Include padding and border in element's total width */
22+
outline: none; /* Remove outline on focus */
23+
transition: border-color 0.3s; /* Transition for focus effect */
24+
}
25+
26+
.input-element:focus {
27+
border-color: #004b9b; /* Change border color on focus */
28+
}

Frontend/src/css/Login.css

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
.login-container {
2+
display: flex;
3+
height: 100vh; /* Full viewport height */
4+
}
5+
6+
.left-side {
7+
flex: 4;
8+
display: flex;
9+
flex-direction: column; /* Stack elements vertically */
10+
justify-content: flex-start; /* Align to the top */
11+
align-items: center; /* Center elements horizontally */
12+
padding-top: 25vh; /* Start from 25% of the viewport height */
13+
}
14+
15+
.title {
16+
font-size: 3rem; /* Adjust font size for the title */
17+
}
18+
19+
.subtitle {
20+
font-size: 2rem; /* Smaller font size for subtitle */
21+
}
22+
23+
.right-side {
24+
flex: 6;
25+
padding: 20px;
26+
padding-top: 25vh; /* Start from 25% of the viewport height */
27+
display: flex;
28+
justify-content: left;
29+
align-items: flex-start;
30+
}
31+
32+
.input-container {
33+
width: 100%; /* Set the width to 60% of the right-side container */
34+
max-width: 500px;
35+
}
36+
37+
38+
.button-container {
39+
display: flex;
40+
flex-direction: row; /* Arrange buttons in a row */
41+
justify-content: flex-end; /* Align buttons to the right */
42+
gap: 10px; /* Space between buttons */
43+
margin-top: 20px; /* Add some margin above the buttons */
44+
}
45+
46+
.login-button {
47+
padding: 10px 20px; /* Button padding */
48+
border: none; /* Remove default border */
49+
border-radius: 4px; /* Rounded corners */
50+
cursor: pointer; /* Pointer on hover */
51+
background-color: #004b9b; /* Primary color for Sign In */
52+
color: white; /* Text color */
53+
}
54+
55+
.create-account-link {
56+
align-self: center; /* Center align vertically */
57+
padding: 10px 20px; /* Add some padding */
58+
border: 1px solid #004b9b; /* Add a border */
59+
border-radius: 4px; /* Rounded corners */
60+
color: #004b9b; /* Link color */
61+
text-decoration: none; /* Remove underline */
62+
display: flex; /* To center the text vertically */
63+
align-items: center; /* Center vertically */
64+
justify-content: center; /* Center horizontally */
65+
}
66+
67+
.create-account-link:hover {
68+
background-color: #f0f0f0; /* Light background on hover */
69+
}

0 commit comments

Comments
 (0)