Skip to content
Snippets Groups Projects
Commit 4e2c212d authored by Zink Hannah's avatar Zink Hannah
Browse files

#22 #24 CSS für Register.tsx und Login.tsx

parent 1c66bbb8
No related branches found
No related tags found
1 merge request!29final login and registration process
......@@ -12,11 +12,13 @@
"jwt-decode": "^4.0.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-modal": "^3.16.1",
"react-router-dom": "^6.18.0"
},
"devDependencies": {
"@types/react": "^18.2.15",
"@types/react-dom": "^18.2.7",
"@types/react-modal": "^3.16.3",
"@typescript-eslint/eslint-plugin": "^6.0.0",
"@typescript-eslint/parser": "^6.0.0",
"@vitejs/plugin-react-swc": "^3.3.2",
......@@ -773,6 +775,15 @@
"@types/react": "*"
}
},
"node_modules/@types/react-modal": {
"version": "3.16.3",
"resolved": "https://registry.npmjs.org/@types/react-modal/-/react-modal-3.16.3.tgz",
"integrity": "sha512-xXuGavyEGaFQDgBv4UVm8/ZsG+qxeQ7f77yNrW3n+1J6XAstUy5rYHeIHPh1KzsGc6IkCIdu6lQ2xWzu1jBTLg==",
"dev": true,
"dependencies": {
"@types/react": "*"
}
},
"node_modules/@types/scheduler": {
"version": "0.16.5",
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.5.tgz",
......@@ -1424,6 +1435,11 @@
"node": ">=0.10.0"
}
},
"node_modules/exenv": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/exenv/-/exenv-1.2.2.tgz",
"integrity": "sha512-Z+ktTxTwv9ILfgKCk32OX3n/doe+OcLTRtqK9pcL+JsP3J1/VW8Uvl4ZjLlKqeW4rzK4oesDOGMEMRIZqtP4Iw=="
},
"node_modules/fast-deep-equal": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
......@@ -1917,6 +1933,14 @@
"integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
"dev": true
},
"node_modules/object-assign": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
"integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
......@@ -2076,6 +2100,16 @@
"node": ">= 0.8.0"
}
},
"node_modules/prop-types": {
"version": "15.8.1",
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
"integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
"dependencies": {
"loose-envify": "^1.4.0",
"object-assign": "^4.1.1",
"react-is": "^16.13.1"
}
},
"node_modules/punycode": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz",
......@@ -2128,6 +2162,34 @@
"react": "^18.2.0"
}
},
"node_modules/react-is": {
"version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
},
"node_modules/react-lifecycles-compat": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz",
"integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA=="
},
"node_modules/react-modal": {
"version": "3.16.1",
"resolved": "https://registry.npmjs.org/react-modal/-/react-modal-3.16.1.tgz",
"integrity": "sha512-VStHgI3BVcGo7OXczvnJN7yT2TWHJPDXZWyI/a0ssFNhGZWsPmB8cF0z33ewDXq4VfYMO1vXgiv/g8Nj9NDyWg==",
"dependencies": {
"exenv": "^1.2.0",
"prop-types": "^15.7.2",
"react-lifecycles-compat": "^3.0.0",
"warning": "^4.0.3"
},
"engines": {
"node": ">=8"
},
"peerDependencies": {
"react": "^0.14.0 || ^15.0.0 || ^16 || ^17 || ^18",
"react-dom": "^0.14.0 || ^15.0.0 || ^16 || ^17 || ^18"
}
},
"node_modules/react-router": {
"version": "6.20.1",
"resolved": "https://registry.npmjs.org/react-router/-/react-router-6.20.1.tgz",
......@@ -2468,6 +2530,14 @@
}
}
},
"node_modules/warning": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz",
"integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==",
"dependencies": {
"loose-envify": "^1.0.0"
}
},
"node_modules/which": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
......
......@@ -14,11 +14,13 @@
"jwt-decode": "^4.0.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-modal": "^3.16.1",
"react-router-dom": "^6.18.0"
},
"devDependencies": {
"@types/react": "^18.2.15",
"@types/react-dom": "^18.2.7",
"@types/react-modal": "^3.16.3",
"@typescript-eslint/eslint-plugin": "^6.0.0",
"@typescript-eslint/parser": "^6.0.0",
"@vitejs/plugin-react-swc": "^3.3.2",
......
......@@ -22,12 +22,12 @@ export function getCookie(name: string | any[]) {
}
export function deleteJwtCookie() {
document.cookie = `Jwt=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;`;
console.log("deleted Cookie ")
}
export function checkJwtStatus(setIsLoggedIn: { (value: SetStateAction<boolean>): void; (arg0: boolean): void; }) {
const location = useLocation();
return useEffect(() => {
......@@ -45,6 +45,7 @@ export function checkJwtStatus(setIsLoggedIn: { (value: SetStateAction<boolean>)
// Der JWT-Cookie ist vorhanden - Überprüfe die Gültigkeit
// @ts-ignore
const tokenParts = jwtCookie.split('.');
if (tokenParts.length !== 3) {
// Ungültiges JWT-Format (nicht genau 3 Teile)
setIsLoggedIn(false);
......@@ -53,7 +54,7 @@ export function checkJwtStatus(setIsLoggedIn: { (value: SetStateAction<boolean>)
}
const payload = JSON.parse(atob(tokenParts[1]));
const expirationTime = payload.exp * 1000; //Umwandlung in Millisekunden
const expirationTime = payload.exp*1000; //Umwandlung in Millisekunden
console.log(expirationTime)
console.log(Date.now())
......
import "../stylesheets/RegisterAndLogin.css";
import {useState} from "react";
import {deleteJwtCookie, setCookie} from "../jwt/Cookies.ts";
import {jwtDecode} from "jwt-decode";
......@@ -50,26 +51,26 @@ function Login() {
return (
<main>
<div>
<h2>Login</h2>
<h2 className="h2">Login</h2>
<form onSubmit={handleSubmit}>
<div>
<label>E-Mail:</label>
<input
<div className="form-group">
<input className="input"
type="text"
value={email}
onChange={(e) => setEmail(e.target.value)}
placeholder="Email"
/>
</div>
<div>
<label>Passwort:</label>
<input
<div className="form-group">
<input className="input"
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
placeholder="Passwort"
/>
</div>
<div>
<button type="submit">Anmelden</button>
<button className="submitButton" type="submit">Anmelden</button>
</div>
</form>
</div>
......
import "../stylesheets/Register.css";
import "../stylesheets/RegisterAndLogin.css";
import {FormEvent, useState} from "react";
import {setCookie} from "../jwt/Cookies.ts";
import { useNavigate } from 'react-router-dom';
import { jwtDecode } from 'jwt-decode';
import Modal from 'react-modal';
function Register() {
......@@ -13,8 +14,49 @@ function Register() {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [errorModalIsOpen, setErrorModalIsOpen] = useState(false);
const [errorMessage, setErrorMessage] = useState('');
const isValidEmail = (email: string): boolean => {
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return emailRegex.test(email);
};
const isValidName = (name: string): boolean => {
return name.trim() !== ''; // Prüfe, ob der Name nicht leer ist
};
const isValidPassword = (password: string): boolean => {
return password.length >= 4; // Prüfe, ob das Passwort mindestens 4 Zeichen lang ist
};
const openErrorModal = (message: string) => {
setErrorMessage(message);
setErrorModalIsOpen(true);
};
const closeErrorModal = () => {
setErrorModalIsOpen(false);
setErrorMessage('');
};
const handleSubmit = async (e: FormEvent<HTMLFormElement>) => {
e.preventDefault(); //verhindert, dass die Seite neu geladen wird, wenn das Formular abgeschickt wird
if (!isValidEmail(email)) {
openErrorModal('Ungültige E-Mail-Adresse');
return;
}
if (!isValidName(firstname) || !isValidName(lastname)) {
openErrorModal('Vorname und Nachname dürfen nicht leer sein');
return;
}
if (!isValidPassword(password)) {
openErrorModal('Das Passwort muss mindestens 4 Zeichen lang sein');
return;
}
await handleRegister();
};
......@@ -53,46 +95,56 @@ function Register() {
return (
<main>
<div className="register">
<h2>Registrierung</h2>
<h2 className="h2">REGISTRIERUNG</h2>
<form onSubmit={handleSubmit}>
<div>
<label>Vorname:</label>
<input
<div className="form-group">
<input className="input"
type="text"
value={firstname}
onChange={(e) => setFirstname(e.target.value)}
placeholder="Name"
/>
</div>
<div>
<label>Nachname:</label>
<input
<div className="form-group">
<input className="input"
type="text"
value={lastname}
onChange={(e) => setLastname(e.target.value)}
placeholder="Nachname"
/>
</div>
<div >
<label>Mailadresse:</label>
<input
<div className="form-group">
<input className="input"
type="text"
value={email}
onChange={(e) => setEmail(e.target.value)}
placeholder="Mailadresse"
/>
</div>
<div>
<label>Passwort:</label>
<input
<div className="form-group">
<input className="input"
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
placeholder="Passwort (mindestens 4 Zeichen)"
/>
</div>
<div className="submitButton">
<button type="submit">Anmelden</button>
<div>
<button className="submitButton" type="submit">Anmelden</button>
</div>
</form>
</div>
<Modal
isOpen={errorModalIsOpen}
onRequestClose={closeErrorModal}
contentLabel="Fehlermeldung"
className="errorField"
>
<div className="error-message">
<p>{errorMessage}</p>
<button onClick={closeErrorModal}>Schließen</button>
</div>
</Modal>
</main>
);
}
......
.register {
display: flex;
justify-content: center;
flex-direction: column;
padding-left: 40px;
/*height: 100vh;*/
}
form {
display: flex;
flex-direction: column;
width: 600px;
border-radius: 5px;
background-color: dimgrey;
margin-top: 10px;
}
label {
margin:20px;
}
input {
padding: 8px;
margin-bottom: 16px;
background-color: #e0e0e0;
border: 1px solid #ccc;
border-radius: 3px;
}
.submitButton {
padding: 10px;
border-radius: 3px;
cursor: pointer;
}
h2 {
padding-top: 50px;
padding-bottom: 10px;
}
.register {
display: flex;
flex-direction: column;
align-items: stretch;
}
form {
display: flex;
flex-direction: column;
padding: 25px;
}
.h2 {
background-color: rgb(120, 147, 81);
padding: 15px;
}
.form-group {
display: flex;
flex-direction: row;
align-content: stretch;
}
label {
margin:20px;
}
.input {
background-color: #ffffff;
border-radius: 5px;
color: #1a1a1a;
transition: none;
}
.input:hover{
border-color: darkgrey;
}
.submitButton {
border-radius: 5px;
cursor: pointer;
background-color: rgb(120, 147, 81);
color: #fcfdf7;
border: none;
font-size: 1em;
font-weight: 500;
line-height: unset;
transition: none;
}
.submitButton:hover {
border-color: #f2f2f2;
background-color: rgb(252, 253, 247);
color: rgb(120, 147, 81);
}
.error-message {
color: #ac3838;
text-align: center;
}
.errorField {
margin: auto;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
......@@ -21,3 +21,15 @@ content-type: application/json
"email": "lukas.karsch@gmx.de",
"password": "12345678"
}
### Create account
POST http://localhost:8080/api/v1/auth/register
content-type: application/json
{
"email": "hannah.zing@icloud.com",
"firstname": "Hännah",
"lastname": "Zink",
"password": "hhh"
}
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