Merge branch 'features/loginPage' into 'dev'

Features/loginpage

See merge request sae-but2/2025-26/gestion-benevoles-association/Frontend!11
This commit is contained in:
LEBLOND MALO p2405951
2025-11-07 10:49:00 +00:00
6 changed files with 199 additions and 35 deletions
+47 -7
View File
@@ -1,15 +1,55 @@
import styles from "./background.module.css"; import styles from "./background.module.css";
import { useEffect, useRef } from "react";
const Background = ({ children, className }) => { const Background = ({ children, className }) => {
const circlesRef = useRef([]);
const getRandomTranslation = () => {
const randomX = Math.floor(Math.random() * 100) - 30;
const randomY = Math.floor(Math.random() * 100) - 30;
return { x: randomX, y: randomY };
};
useEffect(() => {
circlesRef.current.forEach((circle) => {
if (circle) {
const { x, y } = getRandomTranslation();
circle.style.setProperty('--random-x', `${x}px`);
circle.style.setProperty('--random-y', `${y}px`);
}
});
}, []);
return ( return (
<div className={`${styles["background-container"]} ${className || ''}`}> <div className={`${styles["background-container"]} ${className || ''}`}>
<div className={styles["circle"] + " " + styles["circle-1"]}></div> <div
<div className={styles["circle"] + " " + styles["circle-2"]}></div> ref={(el) => (circlesRef.current[0] = el)}
<div className={styles["circle"] + " " + styles["circle-3"]}></div> className={`${styles["circle"]} ${styles["circle-1"]}`}
<div className={styles["circle"] + " " + styles["circle-4"]}></div> style={{ "--random-x": "0px", "--random-y": "0px" }}
<div className={styles["circle"] + " " + styles["circle-5"]}></div> ></div>
<div
ref={(el) => (circlesRef.current[1] = el)}
className={`${styles["circle"]} ${styles["circle-2"]}`}
style={{ "--random-x": "0px", "--random-y": "0px" }}
></div>
<div
ref={(el) => (circlesRef.current[2] = el)}
className={`${styles["circle"]} ${styles["circle-3"]}`}
style={{ "--random-x": "0px", "--random-y": "0px" }}
></div>
<div
ref={(el) => (circlesRef.current[3] = el)}
className={`${styles["circle"]} ${styles["circle-4"]}`}
style={{ "--random-x": "0px", "--random-y": "0px" }}
></div>
<div
ref={(el) => (circlesRef.current[4] = el)}
className={`${styles["circle"]} ${styles["circle-5"]}`}
style={{ "--random-x": "0px", "--random-y": "0px" }}
></div>
{children} {children}
</div> </div>
); );
}; };
export default Background; export default Background;
@@ -40,7 +40,7 @@
width: 280px; width: 280px;
height: 280px; height: 280px;
background-color: #91FCFF; background-color: #91FCFF;
top: 17%; top: 28%;
right: 9%; right: 9%;
} }
@@ -58,4 +58,65 @@
background-color: #015AFF; background-color: #015AFF;
top: 2%; top: 2%;
right: 2%; right: 2%;
}
.circle-1,.circle-2, .circle-3, .circle-4, .circle-5 {
animation: float 6s ease-in-out infinite;
}
.circle {
animation: float 6s ease-in-out infinite;
}
@keyframes float {
0%, 100% {
transform: translate(0, 0);
}
50% {
transform: translate(var(--random-x), var(--random-y));
}
}
@media (max-width:600px) {
.circle-1 {
width: 300px;
height: 300px;
background-color: #019AFF;
top: -5%;
left: -5%;
}
.circle-2 {
width: 175px;
height: 175px;
background-color: #91FCFF;
top: 58%;
left: 10%;
}
.circle-3 {
width: 140px;
height: 140px;
background-color: #91FCFF;
top: 29%;
right: 9%;
}
.circle-4 {
width: 250px;
height: 250px;
background-color: #019AFF;
bottom: 0;
right: 0;
}
.circle-5 {
width: 240px;
height: 240px;
background-color: #015AFF;
top: 2%;
right: 10%;
}
} }
+75 -2
View File
@@ -1,4 +1,4 @@
import { useState } from "react"; /*import { useState } from "react";
import login from "../../utils/login.js"; import login from "../../utils/login.js";
import getUser from "../../utils/getUser.js"; import getUser from "../../utils/getUser.js";
import styles from "./form.module.css"; import styles from "./form.module.css";
@@ -17,7 +17,7 @@ function LoginForm({ className }) {
</div> </div>
<div className={styles.formgroup}> <div className={styles.formgroup}>
<input type="password" id="password" value={password} placeholder="Adresse mail" onChange={e => setPassword(e.target.value)} required/> <input type="password" id="password" value={password} placeholder="Mot de passe" onChange={e => setPassword(e.target.value)} required/>
<br/> <br/>
</div> </div>
<div className={styles.logButton} > <div className={styles.logButton} >
@@ -26,5 +26,78 @@ function LoginForm({ className }) {
</div> </div>
); );
} }
export default LoginForm;*/
import { useState } from "react";
import login from "../../utils/login.js";
import getUser from "../../utils/getUser.js";
import styles from "./form.module.css";
function LoginForm({ className }) {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [showPassword, setShowPassword] = useState(false);
async function handleSubmit(e) {
e.preventDefault();
await login(email, password);
getUser();
}
const toggleShowPassword = () => {
setShowPassword(!showPassword);
};
return (
<div className={`${className} ${"glassCard"}`}>
<div className={styles.formgroup}>
<input
type="email"
id="email"
className={styles.input}
value={email}
placeholder="Adresse mail"
onChange={e => setEmail(e.target.value)}
required
/>
</div>
<div className={styles.formgroup}>
<div style={{ position: 'relative', width: '100%' }}>
<input
type={showPassword ? "text" : "password"}
id="password"
className={styles.input}
value={password}
placeholder="Mot de passe"
onChange={e => setPassword(e.target.value)}
required
style={{ width: '100%', paddingRight: '40px' }}
/>
<button
type="button"
onClick={toggleShowPassword}
style={{
position: 'absolute',
width: '30px',
right: '10px',
top: '50%',
transform: 'translateY(-50%)',
background: 'none',
border: 'none',
cursor: 'pointer',
fontSize: '16px',
}}
>
{showPassword ? '👁️' : '🔒'}
</button>
</div>
</div>
<div className={styles.logButton}>
<button className={styles.loginButton} onClick={handleSubmit}>Se connecter</button>
</div>
</div>
);
}
export default LoginForm; export default LoginForm;
+14 -21
View File
@@ -1,3 +1,6 @@
:global(.glassCard) {
--glass-bg: #ffffff9f;
}
input { input {
width: 100%; width: 100%;
@@ -5,9 +8,10 @@ input {
padding: 0px 10px; padding: 0px 10px;
border: none; border: none;
border-radius: 10px; border-radius: 10px;
font-size: 16px; font-size: 19px;
color: #111; color: #111;
box-shadow: 0 2px 6px rgba(0,0,0,0.06) inset; background: var(--glass-bg);
box-shadow: 0 2px 6px rgba(91, 90, 90, 0.06) inset;
} }
input::placeholder{ input::placeholder{
@@ -27,21 +31,22 @@ input::placeholder{
/* style scoped (module) */ /* style scoped (module) */
.loginButton { .loginButton {
display: inline-block; display: inline-block;
padding: 0.55rem 1rem; height: 50px;
height: 55px; width:90%;
border-radius: 6px; border-radius: 16px;
background-color: #2b6cb0; margin-bottom:3%;
color: #fff; margin-top:3%;
background-color: rgba(255, 255, 255, 0.335);
color: #000000;
font-weight: 600; font-weight: 600;
border: none; border: none;
box-shadow: 0 2px 6px rgba(43,108,176,0.15);
cursor: pointer; cursor: pointer;
transition: background-color 160ms ease, transform 120ms ease, box-shadow 160ms ease; transition: background-color 160ms ease, transform 120ms ease, box-shadow 160ms ease;
font-size: 15px; font-size: 15px;
} }
.loginButton:hover { .loginButton:hover {
background-color: #235a9a; background-color: #54585e;
transform: translateY(-2px); transform: translateY(-2px);
box-shadow: 0 6px 14px rgba(43,108,176,0.18); box-shadow: 0 6px 14px rgba(43,108,176,0.18);
} }
@@ -51,18 +56,6 @@ input::placeholder{
box-shadow: 0 3px 8px rgba(43,108,176,0.12); box-shadow: 0 3px 8px rgba(43,108,176,0.12);
} }
.loginButton:focus {
outline: 2px solid rgba(43,108,176,0.24);
outline-offset: 2px;
}
.loginButton:active {
transform: translateY(0);
box-shadow: 0 3px 8px rgba(43,108,176,0.12);
}
.loginButton:focus {
outline: 2px solid rgba(43,108,176,0.24);
outline-offset: 2px;
}
-3
View File
@@ -1,14 +1,11 @@
import styles from "./LoginPage.module.css"; import styles from "./LoginPage.module.css";
import LoginForm from "../../components/form/form.jsx"; import LoginForm from "../../components/form/form.jsx";
import Background from "../../components/background/background.jsx";
function LoginPage() { function LoginPage() {
return ( return (
<Background>
<div className={styles.container}> <div className={styles.container}>
<LoginForm /> <LoginForm />
</div> </div>
</Background>
); );
} }
+1 -1
View File
@@ -2,7 +2,7 @@
position: relative; position: relative;
z-index: 2; z-index: 2;
display: flex; display: flex;
width: 30%; width: 600px;
overflow: hidden; overflow: hidden;
max-height: 80%; max-height: 80%;
justify-content: center; justify-content: center;