Repository: quizzmeup/quizzmeup_frontend
Pull request #1: update global color variables, add global font,  and update style header + update signup modal
Author: login: ByVaincent
Created: 2025-04-01T10:30:40Z | Merged: 2025-04-02T09:02:06Z



Diff:
diff --git a/public/logo.png b/public/logo.png
new file mode 100644
index 0000000..a8de9b6
Binary files /dev/null and b/public/logo.png differ
diff --git a/src/App.css b/src/App.css
index cfbf5ce..9cc8755 100644
--- a/src/App.css
+++ b/src/App.css
@@ -1,8 +1,16 @@
+@import url("./utils/css/font.css");
+
 :root {
-  --primary-color: #e62429;
+  --primary-color: #57b97d;
   --secondary-color: #202020;
-  --font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
-  
+  --reacteur-color: #523ecd;
+  --bg-color: #ffffff;
+  --div-bg-color: #e7f8e9;
+  --text-color: #000000;
+  --error-color: #ff0505;
+  --font-family: "AvertaStd-Regular", sans-serif;
+  --font-bold: "AvertaStd-Bold", sans-serif;
+
   --header-height: 80px;
 }
 
@@ -15,15 +23,23 @@
 body {
   font-family: var(--font-family);
   background-color: #fff;
-  color: var(--secondary-color);
+  color: var(--text-color);
   line-height: 1.6;
 }
 
-h1, h2, h3, h4 {
-  color: var(--primary-color);
+h1,
+h2,
+h3,
+h4 {
+  font-family: var(--font-bold);
+  color: var(--text-color);
   margin-bottom: 1rem;
 }
 
+h1 {
+  font-size: 1.8em;
+}
+
 p {
   margin-bottom: 1rem;
 }
@@ -72,3 +88,7 @@ textarea {
   background-color: #f39c12;
 }
 
+.container {
+  max-width: 1024px;
+  margin: auto;
+}
diff --git a/src/components/Header/AuthButtons.css b/src/components/Header/AuthButtons.css
index 5d8df4b..cb1929a 100644
--- a/src/components/Header/AuthButtons.css
+++ b/src/components/Header/AuthButtons.css
@@ -1,29 +1,27 @@
 .auth-buttons {
   display: flex;
-  gap: 0.5rem;
+  gap: 1rem;
 }
 
 .auth-btn {
-  color: white;
+  color: var(--bg-color);
   padding: 0.4rem 0.8rem;
-  border-radius: 3px;
+  border-radius: 5px;
   cursor: pointer;
   font-weight: 700;
-  font-size: 1.3rem;
-  border: none;
-}
-
-.auth-btn.login {
-  background-color: var(--secondary-color);
+  font-size: 1.1rem;
+  border: 2px solid var(--primary-color);
+  background-color: var(--primary-color);
 }
 
-.auth-btn.signup {
-  background-color: var(--primary-color);
+.student-auth {
+  display: flex;
+  gap: 0.5rem;
 }
 
 .auth-btn:hover {
   background-color: white;
-  color: var(--secondary-color);
+  color: var(--primary-color);
 }
 
 .auth-btn.logout {
diff --git a/src/components/Header/AuthButtons.jsx b/src/components/Header/AuthButtons.jsx
index ce233df..0cf74e5 100644
--- a/src/components/Header/AuthButtons.jsx
+++ b/src/components/Header/AuthButtons.jsx
@@ -10,37 +10,40 @@ const AuthButtons = () => {
 
   return (
     <div className="auth-buttons">
-      {token ? (
-        <>
-          <button
-            type="button"
-            className="auth-btn logout"
-            onClick={() => {
-              handleLogout();
-              showToast("Logged out successfully", "success");
-            }}
-          >
-            Logout
-          </button>
-        </>
-      ) : (
-        <>
-          <button
-            type="button"
-            className="auth-btn login"
-            onClick={openLoginModal}
-          >
-            Login
-          </button>
-          <button
-            type="button"
-            className="auth-btn signup"
-            onClick={openSignupModal}
-          >
-            Signup
-          </button>
-        </>
-      )}
+      <div className="student-auth">
+        {token ? (
+          <>
+            <button
+              type="button"
+              className="auth-btn "
+              onClick={() => {
+                handleLogout();
+                showToast("Vous êtes déconnecté", "success");
+              }}
+            >
+              Logout
+            </button>
+          </>
+        ) : (
+          <>
+            <button type="button" className="auth-btn" onClick={openLoginModal}>
+              Se connecter
+            </button>
+            <button
+              type="button"
+              className="auth-btn"
+              onClick={openSignupModal}
+            >
+              S'enregister
+            </button>
+          </>
+        )}
+      </div>
+      <div className="admin-auth">
+        <button type="button" className="auth-btn backoff-btn">
+          Espace formateur
+        </button>
+      </div>
     </div>
   );
 };
diff --git a/src/components/Header/Header.css b/src/components/Header/Header.css
index 2cd2827..f33acdf 100644
--- a/src/components/Header/Header.css
+++ b/src/components/Header/Header.css
@@ -2,16 +2,17 @@
   position: sticky;
   top: 0;
   z-index: 10;
+  box-shadow: 0 0 2px rgba(0, 0, 0, 0.3);
+}
 
+.header .container {
   height: var(--header-height);
   display: flex;
   justify-content: space-between;
   align-items: center;
   padding: 1rem 2rem;
   margin-bottom: 30px;
-  box-shadow: 0 3px 8px rgba(0, 0, 0, 1);
-
-  background-color: var(--primary-color);
+  background-color: var(--tertiary-color);
   overflow: hidden;
   flex-wrap: wrap;
   gap: 2em;
diff --git a/src/components/Header/Header.jsx b/src/components/Header/Header.jsx
index df9b2a0..84ef551 100644
--- a/src/components/Header/Header.jsx
+++ b/src/components/Header/Header.jsx
@@ -5,8 +5,10 @@ import AuthButtons from "./AuthButtons";
 const Header = () => {
   return (
     <header className="header">
-      <Logo />
-      <AuthButtons />
+      <div className="container">
+        <Logo />
+        <AuthButtons />
+      </div>
     </header>
   );
 };
diff --git a/src/components/Header/Logo.css b/src/components/Header/Logo.css
index 2cd3304..2561fa5 100644
--- a/src/components/Header/Logo.css
+++ b/src/components/Header/Logo.css
@@ -1,6 +1,12 @@
 .logo-link {
-  display: block;
   height: 100%;
+  display: flex;
+  align-items: center;
+  gap: 0.5em;
+}
+
+.logo-link:hover {
+  text-decoration: none;
 }
 
 .logo {
@@ -8,3 +14,7 @@
   width: auto;
   display: block;
 }
+
+.logo-link h1 {
+  margin: 0;
+}
diff --git a/src/components/Header/Logo.jsx b/src/components/Header/Logo.jsx
index dba4b4a..3c94a4e 100644
--- a/src/components/Header/Logo.jsx
+++ b/src/components/Header/Logo.jsx
@@ -4,11 +4,8 @@ import { Link } from "react-router-dom";
 const Logo = () => {
   return (
     <Link className="logo-link" to="/">
-      <img
-        src="/logo-marvel-nicosek.png"
-        alt="Marvel by NicoSek"
-        className="logo"
-      />
+      <img src="/logo.png" alt="Logo du Réacteur" className="logo" />
+      <h1>QuizMeUp</h1>
     </Link>
   );
 };
diff --git a/src/components/LoginModal/LoginModal.jsx b/src/components/LoginModal/LoginModal.jsx
index 80143cf..6cd54bc 100644
--- a/src/components/LoginModal/LoginModal.jsx
+++ b/src/components/LoginModal/LoginModal.jsx
@@ -32,9 +32,9 @@ const LoginModal = () => {
     if (data.token && data.user) {
       handleLogin(data.token, data.user);
       handleClose();
-      showToast("Logged in successfully", "success");
+      showToast("Vous êtes connecté", "success");
     } else {
-      setError("No token received.");
+      setError("Aucun token reçu.");
     }
   };
 
@@ -55,7 +55,7 @@ const LoginModal = () => {
         <form className="modal-form" onSubmit={handleSubmit}>
           <input
             type="email"
-            placeholder="Email address"
+            placeholder="Email"
             value={email}
             onChange={(e) => setEmail(e.target.value)}
             required
@@ -63,7 +63,7 @@ const LoginModal = () => {
 
           <input
             type="password"
-            placeholder="Password"
+            placeholder="Mot de passe"
             value={password}
             onChange={(e) => setPassword(e.target.value)}
             required
@@ -74,7 +74,7 @@ const LoginModal = () => {
           <button type="submit">Login</button>
 
           <p className="modal-footer">
-            Don't have an account?{" "}
+            Pas encore de compte?{" "}
             <span
               className="switch-modal"
               onClick={() => {
@@ -82,7 +82,7 @@ const LoginModal = () => {
                 openSignupModal();
               }}
             >
-              Sign up!
+              S'enregistrer!
             </span>
           </p>
         </form>
@@ -92,4 +92,3 @@ const LoginModal = () => {
 };
 
 export default LoginModal;
-
diff --git a/src/components/SignupModal/SignupModal.css b/src/components/SignupModal/SignupModal.css
index e7c4c4f..d40238d 100644
--- a/src/components/SignupModal/SignupModal.css
+++ b/src/components/SignupModal/SignupModal.css
@@ -31,6 +31,11 @@
   background: transparent;
   font-size: 20px;
   cursor: pointer;
+  color: var(--primary-color);
+}
+
+.modal-content h2 {
+  color: var(--primary-color);
 }
 
 .modal-form {
diff --git a/src/components/SignupModal/SignupModal.jsx b/src/components/SignupModal/SignupModal.jsx
index a6718aa..98cab6d 100644
--- a/src/components/SignupModal/SignupModal.jsx
+++ b/src/components/SignupModal/SignupModal.jsx
@@ -1,4 +1,4 @@
-import { useState } from "react";
+import { useEffect, useState } from "react";
 import { signup } from "../../api/auth";
 import { useAuth } from "../../contexts/AuthContext";
 import { useModal } from "../../contexts/ModalContext";
@@ -11,10 +11,23 @@ const SignupModal = () => {
   const { handleLogin } = useAuth();
   const { showToast } = useToast();
 
+  const [name, setName] = useState("");
   const [email, setEmail] = useState("");
   const [password, setPassword] = useState("");
+  const [confirmPassword, setConfirmPassword] = useState("");
   const [error, setError] = useState("");
 
+  //check if passwords match
+  useEffect(() => {
+    if (confirmPassword) {
+      if (password !== confirmPassword) {
+        setError("Les deux mots de passe doivent être identiques");
+      } else {
+        setError("");
+      }
+    }
+  }, [password, confirmPassword]);
+
   if (!isSignupModalOpen) return null;
 
   const handleSubmit = async (event) => {
@@ -23,7 +36,7 @@ const SignupModal = () => {
 
     let data;
     try {
-      data = await signup({ email, password });
+      data = await signup({ name, email, password });
     } catch (err) {
       setError(handleApiError(err));
       return;
@@ -32,9 +45,9 @@ const SignupModal = () => {
     if (data.token && data.user) {
       handleLogin(data.token, data.user);
       handleClose();
-      showToast("Signed up successfully", "success");
+      showToast("Vous êtes connecté", "success");
     } else {
-      setError("No token received.");
+      setError("Aucun token reçu.");
     }
   };
 
@@ -53,9 +66,17 @@ const SignupModal = () => {
         </button>
         <h2>Sign up</h2>
         <form className="modal-form" onSubmit={handleSubmit}>
+          <input
+            type="text"
+            placeholder="Nom prénom"
+            value={name}
+            onChange={(e) => setName(e.target.value)}
+            required
+          />
+
           <input
             type="email"
-            placeholder="Email address"
+            placeholder="Email"
             value={email}
             onChange={(e) => setEmail(e.target.value)}
             required
@@ -63,25 +84,26 @@ const SignupModal = () => {
 
           <input
             type="password"
-            placeholder="Password"
+            placeholder="Mot de passe"
             value={password}
             onChange={(e) => setPassword(e.target.value)}
             required
           />
 
-          <p className="newsletter-info">
-            By signing up, I confirm I have read and agree to the{" "}
-            <a href="#">Terms & Conditions</a> and{" "}
-            <a href="#">Privacy Policy</a>. <br />I confirm I am at least 18
-            years old.
-          </p>
+          <input
+            type="password"
+            placeholder="Confirmez le mot de passe"
+            value={confirmPassword}
+            onChange={(e) => setConfirmPassword(e.target.value)}
+            required
+          />
 
           {error && <p className="error-message">{error}</p>}
 
-          <button type="submit">Sign up</button>
+          <button type="submit">Créer un compte</button>
 
           <p className="modal-footer">
-            Already have an account?{" "}
+            Déjà un compte?{" "}
             <span
               className="switch-modal"
               onClick={() => {
@@ -89,7 +111,7 @@ const SignupModal = () => {
                 openLoginModal();
               }}
             >
-              Log in here
+              Se connecter
             </span>
           </p>
         </form>
@@ -99,4 +121,3 @@ const SignupModal = () => {
 };
 
 export default SignupModal;
-
diff --git a/src/utils/css/font.css b/src/utils/css/font.css
new file mode 100644
index 0000000..2136bb8
--- /dev/null
+++ b/src/utils/css/font.css
@@ -0,0 +1,29 @@
+@font-face {
+  font-family: "AvertaStd-Regular";
+  src: url("https://db.onlinewebfonts.com/t/19b8f54eb1f074fb01efb1c4f02e9623.eot");
+  src: url("https://db.onlinewebfonts.com/t/19b8f54eb1f074fb01efb1c4f02e9623.eot?#iefix")
+      format("embedded-opentype"),
+    url("https://db.onlinewebfonts.com/t/19b8f54eb1f074fb01efb1c4f02e9623.woff2")
+      format("woff2"),
+    url("https://db.onlinewebfonts.com/t/19b8f54eb1f074fb01efb1c4f02e9623.woff")
+      format("woff"),
+    url("https://db.onlinewebfonts.com/t/19b8f54eb1f074fb01efb1c4f02e9623.ttf")
+      format("truetype"),
+    url("https://db.onlinewebfonts.com/t/19b8f54eb1f074fb01efb1c4f02e9623.svg#AvertaStd-Regular")
+      format("svg");
+}
+
+@font-face {
+  font-family: "AvertaStd-Bold";
+  src: url("https://db.onlinewebfonts.com/t/447315c0c330fd423c8e1cc18024669d.eot");
+  src: url("https://db.onlinewebfonts.com/t/447315c0c330fd423c8e1cc18024669d.eot?#iefix")
+      format("embedded-opentype"),
+    url("https://db.onlinewebfonts.com/t/447315c0c330fd423c8e1cc18024669d.woff2")
+      format("woff2"),
+    url("https://db.onlinewebfonts.com/t/447315c0c330fd423c8e1cc18024669d.woff")
+      format("woff"),
+    url("https://db.onlinewebfonts.com/t/447315c0c330fd423c8e1cc18024669d.ttf")
+      format("truetype"),
+    url("https://db.onlinewebfonts.com/t/447315c0c330fd423c8e1cc18024669d.svg#AvertaStd-Bold")
+      format("svg");
+}


Reviews:
user: login: nicosek
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-04-02T08:08:36Z
user: login: nicosek
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-04-02T08:09:38Z
user: login: nicosek
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-04-02T08:13:45Z
user: login: ByVaincent
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-04-02T08:35:29Z
user: login: nicosek
state: APPROVED
author_association: COLLABORATOR
submitted_at: 2025-04-02T08:56:54Z

Review comments:
diff_hunk: @@ -5,8 +5,13 @@ import AuthButtons from "./AuthButtons";
 const Header = () => {
   return (
     <header className="header">
-      <Logo />
-      <AuthButtons />
+      <div className="container">
+        <div className="header-title">
+          <Logo />
path: src/components/Header/Header.jsx
user: login: nicosek
body: Peut-être mettre le Logo en-dehors de cette div, juste avant, puisque le div a la class "header-title" ?
created_at: 2025-04-02T08:08:35Z
author_association: COLLABORATOR
diff_hunk: @@ -11,10 +11,23 @@ const SignupModal = () => {
   const { handleLogin } = useAuth();
   const { showToast } = useToast();
 
+  const [name, setName] = useState("");
   const [email, setEmail] = useState("");
   const [password, setPassword] = useState("");
+  const [confirmPassword, setConfirmPassword] = useState("");
   const [error, setError] = useState("");
 
+  //check if passwords match
+  useEffect(() => {
+    if (confirmPassword) {
+      if (password !== confirmPassword) {
+        setError("The passwords must be equal");
path: src/components/SignupModal/SignupModal.jsx
user: login: nicosek
body: On renvoie le texte en français plutôt ?
created_at: 2025-04-02T08:09:38Z
author_association: COLLABORATOR
diff_hunk: @@ -69,6 +90,14 @@ const SignupModal = () => {
             required
           />
 
+          <input
+            type="password"
+            placeholder="Confirm password"
+            value={confirmPassword}
+            onChange={(e) => setConfirmPassword(e.target.value)}
+            required
+          />
+
           <p className="newsletter-info">
path: src/components/SignupModal/SignupModal.jsx
user: login: nicosek
body: Je pense qu'on peut virer cet élément, il prend de la place et ne sert à rien.
created_at: 2025-04-02T08:13:45Z
author_association: COLLABORATOR
diff_hunk: @@ -5,8 +5,13 @@ import AuthButtons from "./AuthButtons";
 const Header = () => {
   return (
     <header className="header">
-      <Logo />
-      <AuthButtons />
+      <div className="container">
+        <div className="header-title">
+          <Logo />
path: src/components/Header/Header.jsx
user: login: ByVaincent
body: J'avais mis cette div pour regrouper le logo et le titre par rapport au flex du header.
J'ai finalement directement mis le titre dans le composent logo, ce qui permet d'avoir le lien cliquable aussi sur le titre (Je ne pense pas que l'on va se servir du logo seul autre part).
created_at: 2025-04-02T08:35:29Z
author_association: COLLABORATOR

PR comments:
user: login: sandrarampal
created_at: 2025-04-02T08:11:40Z
body: <img width="830" alt="Capture d’écran 2025-04-02 à 10 09 46" src="https://github.com/user-attachments/assets/de92bccc-f166-4cd2-b53c-ff5a2e3108d3" />

Il vaudrait mieux mettre Name ou Nom à la place de username, il vaut mieux que les élèves ne mettent pas n'importe quel nom dans name, pour que les admin puissent les rechercher facilement
author_association: COLLABORATOR
user: login: nicosek
created_at: 2025-04-02T08:20:57Z
body: Il y a une petit défaut d'affichage au signup : Lorsqu'on reçoit une erreur de l'API, ca occupe de l'espace et il faut scroller pour voir le bouton Signup. A mon avis il faut étendre la height de la fenetre
author_association: COLLABORATOR
user: login: nicosek
created_at: 2025-04-02T08:22:02Z
body: Ou diminuer la hauteur des inputs pour gagner de la place. Ceci dit quand on aura viré le texte sur les conditions generales on va regagner pas mal d'espace et ça suffira peut être
author_association: COLLABORATOR
user: login: nicosek
created_at: 2025-04-02T08:23:09Z
body: Il faut songer à mettre tous les textes affichés en français
author_association: COLLABORATOR
user: login: nicosek
created_at: 2025-04-02T08:36:21Z
body: > <img alt="Capture d’écran 2025-04-02 à 10 09 46" width="830" src="https://private-user-images.githubusercontent.com/196931482/429379101-de92bccc-f166-4cd2-b53c-ff5a2e3108d3.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NDM1ODMxNjIsIm5iZiI6MTc0MzU4Mjg2MiwicGF0aCI6Ii8xOTY5MzE0ODIvNDI5Mzc5MTAxLWRlOTJiY2NjLWYxNjYtNGNkMi1iNTNjLWZmNWEyZTMxMDhkMy5wbmc_WC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BS0lBVkNPRFlMU0E1M1BRSzRaQSUyRjIwMjUwNDAyJTJGdXMtZWFzdC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDI1MDQwMlQwODM0MjJaJlgtQW16LUV4cGlyZXM9MzAwJlgtQW16LVNpZ25hdHVyZT00MmZlODUxYjU1MzdkNWU2NGU2ZDQ0ZGE1OTk1YmI4OGU3OTgxYmVmOGIxM2JmMGJmNzdhOTQxZWU3NGFhYWY2JlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCJ9.BivgaSgiWBJ7bLSclpv84tJqkV8V57tyHYDw61FbQFA">
> Il vaudrait mieux mettre Name ou Nom à la place de username, il vaut mieux que les élèves ne mettent pas n'importe quel nom dans name, pour que les admin puissent les rechercher facilement

Voire "Nom et Prénom" ou l'inverse
author_association: COLLABORATOR