Skip to content
Snippets Groups Projects
Commit ae06cc01 authored by Daniel Pettersson's avatar Daniel Pettersson
Browse files

Frontend: Added Components directory containing Sign In and Sign Up forms that...

Frontend: Added Components directory containing Sign In and Sign Up forms that can be switched between. UI functionality supported but backend API calls and authentication missing
parent 924326f6
No related branches found
No related tags found
No related merge requests found
...@@ -13,6 +13,8 @@ ...@@ -13,6 +13,8 @@
"@testing-library/user-event": "^13.5.0", "@testing-library/user-event": "^13.5.0",
"react": "^18.2.0", "react": "^18.2.0",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
"react-icons": "^5.0.1",
"react-router-dom": "^6.22.3",
"react-scripts": "5.0.1", "react-scripts": "5.0.1",
"web-vitals": "^2.1.4" "web-vitals": "^2.1.4"
} }
...@@ -3352,6 +3354,14 @@ ...@@ -3352,6 +3354,14 @@
} }
} }
}, },
"node_modules/@remix-run/router": {
"version": "1.15.3",
"resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.15.3.tgz",
"integrity": "sha512-Oy8rmScVrVxWZVOpEF57ovlnhpZ8CCPlnIIumVcV9nFdiSIrus99+Lw78ekXyGvVDlIsFJbSfmSovJUhCWYV3w==",
"engines": {
"node": ">=14.0.0"
}
},
"node_modules/@rollup/plugin-babel": { "node_modules/@rollup/plugin-babel": {
"version": "5.3.1", "version": "5.3.1",
"resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz", "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz",
...@@ -15089,6 +15099,14 @@ ...@@ -15089,6 +15099,14 @@
"resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz", "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz",
"integrity": "sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg==" "integrity": "sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg=="
}, },
"node_modules/react-icons": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.0.1.tgz",
"integrity": "sha512-WqLZJ4bLzlhmsvme6iFdgO8gfZP17rfjYEJ2m9RsZjZ+cc4k1hTzknEz63YS1MeT50kVzoa1Nz36f4BEx+Wigw==",
"peerDependencies": {
"react": "*"
}
},
"node_modules/react-is": { "node_modules/react-is": {
"version": "17.0.2", "version": "17.0.2",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
...@@ -15102,6 +15120,36 @@ ...@@ -15102,6 +15120,36 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/react-router": {
"version": "6.22.3",
"resolved": "https://registry.npmjs.org/react-router/-/react-router-6.22.3.tgz",
"integrity": "sha512-dr2eb3Mj5zK2YISHK++foM9w4eBnO23eKnZEDs7c880P6oKbrjz/Svg9+nxqtHQK+oMW4OtjZca0RqPglXxguQ==",
"dependencies": {
"@remix-run/router": "1.15.3"
},
"engines": {
"node": ">=14.0.0"
},
"peerDependencies": {
"react": ">=16.8"
}
},
"node_modules/react-router-dom": {
"version": "6.22.3",
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.22.3.tgz",
"integrity": "sha512-7ZILI7HjcE+p31oQvwbokjk6OA/bnFxrhJ19n82Ex9Ph8fNAq+Hm/7KchpMGlTgWhUxRHMMCut+vEtNpWpowKw==",
"dependencies": {
"@remix-run/router": "1.15.3",
"react-router": "6.22.3"
},
"engines": {
"node": ">=14.0.0"
},
"peerDependencies": {
"react": ">=16.8",
"react-dom": ">=16.8"
}
},
"node_modules/react-scripts": { "node_modules/react-scripts": {
"version": "5.0.1", "version": "5.0.1",
"resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-5.0.1.tgz", "resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-5.0.1.tgz",
......
...@@ -8,6 +8,8 @@ ...@@ -8,6 +8,8 @@
"@testing-library/user-event": "^13.5.0", "@testing-library/user-event": "^13.5.0",
"react": "^18.2.0", "react": "^18.2.0",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
"react-icons": "^5.0.1",
"react-router-dom": "^6.22.3",
"react-scripts": "5.0.1", "react-scripts": "5.0.1",
"web-vitals": "^2.1.4" "web-vitals": "^2.1.4"
}, },
......
frontend/src/Components/Assets/background3.jpg

1.52 MiB

import React from 'react'
export const Dashboard = () => {
return (
<div>
DASHBOARD!
</div>
)
}
* {
margin :0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: "Poppins", sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
background: url('../Assets/background3.jpg')
no-repeat;
background-size: cover;
background-position: center;
}
code {
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
monospace;
}
\ No newline at end of file
import React, { useState } from 'react';
import { Routes, Route } from "react-router-dom";
import './Form.css';
import { SignInForm } from './SignInForm';
import { SignUpForm } from './SignUpForm';
function Form() {
const [isLoginFormVisible, setIsLoginFormVisible] = useState(true);
const toggleForm = () => {
setIsLoginFormVisible(!isLoginFormVisible);
};
return (
/* <Routes>
<Route path="/" element={<RegisterForm />} />
<Route path="/Dashboard" element={<Dashboard />} />
</Routes>*/
<div>
{isLoginFormVisible ? (
<SignInForm onRegisterClick={toggleForm} />
) : (
<SignUpForm onLoginClick={toggleForm} />
)}
</div>
);
}
export default Form;
.wrapper {
width: 420px;
background: transparent;
border: 2px solid rgba(255, 255, 255, .2);
box-shadow: 0 0 10px rgba(0, 0, 0, .2);
backdrop-filter: blur(30px);
color: white;
border-radius: 10px;
padding: 30px 40px;
}
.wrapper h1{
font-size: 36px;
text-align: center;
}
.wrapper .input-box{
position: relative;
width: 100%;
height: 50px;
margin: 30px 0;
}
.input-box input{
width: 100%;
height: 100%;
background: transparent;
border: 2px solid rgba(255, 255, 255, .2);
outline: none;
border-radius: 40px;
font-size: 16px;
color: white;
padding: 20px 45px 20px 20px;
}
.input-box input::placeholder{
color:white
}
.input-box .icon{
position: absolute;
right: 20px;
top: 35%;
transform: translate(-50%);
font-size: 16px;
}
.wrapper .remember-forget{
display: flex;
justify-content: space-between;
font-size: 14.5px;
margin: -15px 0 15px;
}
.remember-forget label input{
accent-color: white;
margin-right: 4px;
}
.remember-forget a{
color: white;
text-decoration: none;
}
.remember-forget a:hover{
text-decoration: underline;
}
.wrapper button{
width: 100%;
height: 45px;
background: white;
border: none;
outline: none;
border-radius: 40px;
box-shadow: 0 0 10px rgba(0, 0, 0, .1);
cursor: pointer;
font-size: 16px;
color: #333;
font-weight: 700;
}
.wrapper .register-link{
font-size: 14.5px;
text-align: center;
margin-top: 20px;
}
.register-link p a{
color: white;
text-decoration: none;
font-weight: 600;
}
.register-link p a:hover{
text-decoration: underline;
}
\ No newline at end of file
import React, { useState } from 'react';
import './SignForm.css';
//React-icons imports
import { FaUser } from "react-icons/fa";
import { FaLock } from "react-icons/fa";
export const SignInForm = ({ onRegisterClick }) => {
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
const handleLoginClick = () => {
// Call the onLoginClick function passed as prop
onRegisterClick();
};
const handleUsernameChange = (e) => {
setUsername(e.target.value);
};
const handlePasswordChange = (e) => {
setPassword(e.target.value);
};
const handleSubmit = async (e) => {
e.preventDefault();
/*
try {
const response = await REST.post('your-api-endpoint/login', {
username,
password
});
console.log('Login successful!', response.data);
// Redirect user to another page upon successful login
history.push('/dashboard'); // Example: redirect to '/dashboard' route
} catch (error) {
console.error('Login failed!', error);
// Handle login error, display message to the user, etc.
}
*/
console.log("Login attempt with username: " + username+ " and password:" +password);
// Redirect user to another page upon successful login
};
return (
<div className='wrapper'>
<form onSubmit={handleSubmit}>
<h1>Login</h1>
<div className="input-box">
<input type="text" placeholder='Username' value={username} onChange={handleUsernameChange} required/>
<FaUser className='icon'/>
</div>
<div className="input-box">
<input type="password" placeholder='Password' value={password} onChange={handlePasswordChange} required/>
<FaLock className='icon'/>
</div>
<div className="remember-forget">
<label><input type="checkbox" />Remember me</label>
<a href="#">Forget password?</a>
</div>
<button type='submit'>Login</button>
<div className="register-link">
<p>Don't have an account? <a href="#" onClick={handleLoginClick}>Register</a></p>
</div>
</form>
</div>
);
};
import React, { useState } from 'react';
import './SignForm.css';
//React-icons imports
import { MdEmail } from "react-icons/md";
import { FaUser } from "react-icons/fa";
import { FaLock } from "react-icons/fa";
export const SignUpForm = ({ onLoginClick }) => {
const [username, setUsername] = useState('');
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [passwordRepeat, setPasswordRepeat] = useState('');
const handleLoginClick = () => {
// Call the onLoginClick function passed as prop
onLoginClick();
};
// State reactive handler functions
const handleUsernameChange = (e) => {
setUsername(e.target.value);
};
const handleEmailChange = (e) => {
setEmail(e.target.value);
};
const handlePasswordChange = (e) => {
setPassword(e.target.value);
};
const handlePasswordRepeatChange = (e) => {
setPasswordRepeat(e.target.value);
};
const handleRegister = async (e) => {
e.preventDefault();
/*
try {
const response = await REST.post('your-api-endpoint/login', {
username,
password
});
console.log('Login successful!', response.data);
// Redirect user to another page upon successful login
history.push('/dashboard'); // Example: redirect to '/dashboard' route
} catch (error) {
console.error('Login failed!', error);
// Handle login error, display message to the user, etc.
}
*/
console.log("Register attempt with username: " + username+ " and password:" +password);
// Redirect user to another page upon successful login
};
return (
<div className='wrapper'>
<form onSubmit={handleRegister}>
<h1>Register</h1>
<div className="input-box">
<input type="email" placeholder='Email' value={email} onChange={handleEmailChange} required/>
<MdEmail className='icon'/>
</div>
<div className="input-box">
<input type="text" placeholder='Username' value={username} onChange={handleUsernameChange} required/>
<FaUser className='icon'/>
</div>
<div className="input-box">
<input type="password" placeholder='Password' value={password} onChange={handlePasswordChange} required/>
<FaLock className='icon'/>
</div>
<div className="input-box">
<input type="password" placeholder='Repeat Password' value={passwordRepeat} onChange={handlePasswordRepeatChange} required/>
<FaLock className='icon'/>
</div>
<div className="register-link">
<p>Already have an account? <a href="#" onClick={handleLoginClick}>Log in</a></p>
</div>
<button style={{marginTop: 20 }} type='submit'>Register</button>
</form>
</div>
)
}
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;600;700&display=swap');
body { body {
margin: 0; font-family: "Poppins", sans-serif;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
sans-serif;
-webkit-font-smoothing: antialiased; -webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale; -moz-osx-font-smoothing: grayscale;
} }
code { code {
......
import React from 'react'; import React from 'react';
import ReactDOM from 'react-dom/client'; import ReactDOM from 'react-dom/client';
import './index.css'; import './index.css';
import App from './App'; import Form from './Components/SignupSigninForms/Form';
import reportWebVitals from './reportWebVitals'; import { BrowserRouter } from "react-router-dom";
const root = ReactDOM.createRoot(document.getElementById('root')); const root = ReactDOM.createRoot(document.getElementById('root'));
root.render( root.render(
<React.StrictMode> <React.StrictMode>
<App />
<Form />
</React.StrictMode> </React.StrictMode>
); );
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment