From 2ff192f103204fd4cf0dcee21e7d383caef8fba2 Mon Sep 17 00:00:00 2001
From: jjgancfer <jjgancfer@gmail.com>
Date: Wed, 14 Feb 2024 10:24:25 +0100
Subject: [PATCH 01/18] chore: fixed some security issues in the packages

---
 webapp/package-lock.json | 50 +++++++++++++++++++++++++---------------
 1 file changed, 31 insertions(+), 19 deletions(-)

diff --git a/webapp/package-lock.json b/webapp/package-lock.json
index 8c42757a..3ec7485c 100644
--- a/webapp/package-lock.json
+++ b/webapp/package-lock.json
@@ -13546,10 +13546,23 @@
         "loose-envify": "^1.0.0"
       }
     },
-    "node_modules/ip": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz",
-      "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==",
+    "node_modules/ip-address": {
+      "version": "9.0.5",
+      "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz",
+      "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==",
+      "dev": true,
+      "dependencies": {
+        "jsbn": "1.1.0",
+        "sprintf-js": "^1.1.3"
+      },
+      "engines": {
+        "node": ">= 12"
+      }
+    },
+    "node_modules/ip-address/node_modules/sprintf-js": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz",
+      "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==",
       "dev": true
     },
     "node_modules/ipaddr.js": {
@@ -19387,6 +19400,12 @@
         "js-yaml": "bin/js-yaml.js"
       }
     },
+    "node_modules/jsbn": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz",
+      "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==",
+      "dev": true
+    },
     "node_modules/jsdom": {
       "version": "16.7.0",
       "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz",
@@ -20945,25 +20964,18 @@
       }
     },
     "node_modules/pac-resolver": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.0.tgz",
-      "integrity": "sha512-Fd9lT9vJbHYRACT8OhCbZBbxr6KRSawSovFpy8nDGshaK99S/EBhVIHp9+crhxrsZOuvLpgL1n23iyPg6Rl2hg==",
+      "version": "7.0.1",
+      "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.1.tgz",
+      "integrity": "sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==",
       "dev": true,
       "dependencies": {
         "degenerator": "^5.0.0",
-        "ip": "^1.1.8",
         "netmask": "^2.0.2"
       },
       "engines": {
         "node": ">= 14"
       }
     },
-    "node_modules/pac-resolver/node_modules/ip": {
-      "version": "1.1.8",
-      "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.8.tgz",
-      "integrity": "sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg==",
-      "dev": true
-    },
     "node_modules/param-case": {
       "version": "3.0.4",
       "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz",
@@ -26097,16 +26109,16 @@
       }
     },
     "node_modules/socks": {
-      "version": "2.7.1",
-      "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz",
-      "integrity": "sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==",
+      "version": "2.7.3",
+      "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.3.tgz",
+      "integrity": "sha512-vfuYK48HXCTFD03G/1/zkIls3Ebr2YNa4qU9gHDZdblHLiqhJrJGkY3+0Nx0JpN9qBhJbVObc1CNciT1bIZJxw==",
       "dev": true,
       "dependencies": {
-        "ip": "^2.0.0",
+        "ip-address": "^9.0.5",
         "smart-buffer": "^4.2.0"
       },
       "engines": {
-        "node": ">= 10.13.0",
+        "node": ">= 10.0.0",
         "npm": ">= 3.0.0"
       }
     },

From d3dc22a9744d2262c876436cb842ee9fc94a4c2f Mon Sep 17 00:00:00 2001
From: jjgancfer <jjgancfer@gmail.com>
Date: Wed, 14 Feb 2024 19:39:10 +0100
Subject: [PATCH 02/18] chore: restore commented login-related code and
 slightly modified the layout

---
 webapp/src/components/Layout.jsx |   6 +-
 webapp/src/components/Router.jsx |   9 +--
 webapp/src/tests/Login.test.js   | 124 +++++++++++++++----------------
 3 files changed, 69 insertions(+), 70 deletions(-)

diff --git a/webapp/src/components/Layout.jsx b/webapp/src/components/Layout.jsx
index 2fd482c0..7d68d23f 100644
--- a/webapp/src/components/Layout.jsx
+++ b/webapp/src/components/Layout.jsx
@@ -34,15 +34,15 @@ export function TopBar() {
       { pages.map(page => parsePage(page)) }
       </GridItem>
       <GridItem as={Flex} justifyContent={"right"} key={"right-navbar"}>
-        <Button as={Link} mr={"1vw"}>{t("nav.login")}</Button>
-        <Button as={Link} mr={"1vw"}>{t("nav.register")}</Button>
+        <Button as={Link} href="/login" mr={"1vw"}>{t("nav.login")}</Button>
+        <Button as={Link} href="/register" mr={"1vw"}>{t("nav.register")}</Button>
       </GridItem>
     </Grid>
 }
 export default function Layout() {
   return <>
     <TopBar />
-    <Container bgColor="#DCF2F1" minW={"100%"} minH={"100%"}>
+    <Container minW={"100%"} minH={"100%"}>
       <Outlet />
     </Container>
   </>
diff --git a/webapp/src/components/Router.jsx b/webapp/src/components/Router.jsx
index d883add9..55cde631 100644
--- a/webapp/src/components/Router.jsx
+++ b/webapp/src/components/Router.jsx
@@ -1,6 +1,6 @@
 import React from "react";
 import Root from "../pages/Root";
-// import Login from "../pages/Login";
+import Login from "../pages/Login";
 // import Register from "../pages/Register";
 import Layout from "./Layout";
 
@@ -12,11 +12,10 @@ const router = [
       {
         path: "/",
         element: <Root />,
+      },{
+      path: "/login",
+      element: <Login />
       }
-      // },{
-      // path: "/login",
-      // element: <Login />
-      // },
       // {
       // path: "/register",
       // element: <Register />
diff --git a/webapp/src/tests/Login.test.js b/webapp/src/tests/Login.test.js
index 4d662a6c..9fe441a3 100644
--- a/webapp/src/tests/Login.test.js
+++ b/webapp/src/tests/Login.test.js
@@ -1,62 +1,62 @@
-// import React from 'react';
-// import { render, fireEvent, screen, waitFor, act } from '@testing-library/react';
-// import axios from 'axios';
-// import MockAdapter from 'axios-mock-adapter';
-// import Login from '../pages/Login';
-
-// const mockAxios = new MockAdapter(axios);
-
-// describe('Login component', () => {
-//   beforeEach(() => {
-//     mockAxios.reset();
-//   });
-
-//   it('should log in successfully', async () => {
-//     render(<Login />);
-
-//     const usernameInput = screen.getByLabelText(/Username/i);
-//     const passwordInput = screen.getByLabelText(/Password/i);
-//     const loginButton = screen.getByRole('button', { name: /Login/i });
-
-//     // Mock the axios.post request to simulate a successful response
-//     mockAxios.onPost('http://localhost:8000/login').reply(200, { createdAt: '2024-01-01T12:34:56Z' });
-
-//     // Simulate user input
-//     await act(async () => {
-//         fireEvent.change(usernameInput, { target: { value: 'testUser' } });
-//         fireEvent.change(passwordInput, { target: { value: 'testPassword' } });
-//         fireEvent.click(loginButton);
-//       });
-
-//     // Verify that the user information is displayed
-//     expect(screen.getByText(/Hello testUser!/i)).toBeInTheDocument();
-//     expect(screen.getByText(/Your account was created on 1\/1\/2024/i)).toBeInTheDocument();
-//   });
-
-//   it('should handle error when logging in', async () => {
-//     render(<Login />);
-
-//     const usernameInput = screen.getByLabelText(/Username/i);
-//     const passwordInput = screen.getByLabelText(/Password/i);
-//     const loginButton = screen.getByRole('button', { name: /Login/i });
-
-//     // Mock the axios.post request to simulate an error response
-//     mockAxios.onPost('http://localhost:8000/login').reply(401, { error: 'Unauthorized' });
-
-//     // Simulate user input
-//     fireEvent.change(usernameInput, { target: { value: 'testUser' } });
-//     fireEvent.change(passwordInput, { target: { value: 'testPassword' } });
-
-//     // Trigger the login button click
-//     fireEvent.click(loginButton);
-
-//     // Wait for the error Snackbar to be open
-//     await waitFor(() => {
-//       expect(screen.getByText(/Error: Unauthorized/i)).toBeInTheDocument();
-//     });
-
-//     // Verify that the user information is not displayed
-//     expect(screen.queryByText(/Hello testUser!/i)).toBeNull();
-//     expect(screen.queryByText(/Your account was created on/i)).toBeNull();
-//   });
-// });
+import React from 'react';
+import { render, fireEvent, screen, waitFor, act } from '@testing-library/react';
+import axios from 'axios';
+import MockAdapter from 'axios-mock-adapter';
+import Login from '../pages/Login';
+
+const mockAxios = new MockAdapter(axios);
+
+describe('Login component', () => {
+  beforeEach(() => {
+    mockAxios.reset();
+  });
+
+  it('should log in successfully', async () => {
+    render(<Login />);
+
+    const usernameInput = screen.getByLabelText(/Username/i);
+    const passwordInput = screen.getByLabelText(/Password/i);
+    const loginButton = screen.getByRole('button', { name: /Login/i });
+
+    // Mock the axios.post request to simulate a successful response
+    mockAxios.onPost('http://localhost:8000/login').reply(200, { createdAt: '2024-01-01T12:34:56Z' });
+
+    // Simulate user input
+    await act(async () => {
+        fireEvent.change(usernameInput, { target: { value: 'testUser' } });
+        fireEvent.change(passwordInput, { target: { value: 'testPassword' } });
+        fireEvent.click(loginButton);
+      });
+
+    // Verify that the user information is displayed
+    expect(screen.getByText(/Hello testUser!/i)).toBeInTheDocument();
+    expect(screen.getByText(/Your account was created on 1\/1\/2024/i)).toBeInTheDocument();
+  });
+
+  it('should handle error when logging in', async () => {
+    render(<Login />);
+
+    const usernameInput = screen.getByLabelText(/Username/i);
+    const passwordInput = screen.getByLabelText(/Password/i);
+    const loginButton = screen.getByRole('button', { name: /Login/i });
+
+    // Mock the axios.post request to simulate an error response
+    mockAxios.onPost('http://localhost:8000/login').reply(401, { error: 'Unauthorized' });
+
+    // Simulate user input
+    fireEvent.change(usernameInput, { target: { value: 'testUser' } });
+    fireEvent.change(passwordInput, { target: { value: 'testPassword' } });
+
+    // Trigger the login button click
+    fireEvent.click(loginButton);
+
+    // Wait for the error Snackbar to be open
+    await waitFor(() => {
+      expect(screen.getByText(/Error: Unauthorized/i)).toBeInTheDocument();
+    });
+
+    // Verify that the user information is not displayed
+    expect(screen.queryByText(/Hello testUser!/i)).toBeNull();
+    expect(screen.queryByText(/Your account was created on/i)).toBeNull();
+  });
+});

From 4efd97f6c00ea15a353778eac51b423ed81aa6b8 Mon Sep 17 00:00:00 2001
From: jjgancfer <jjgancfer@gmail.com>
Date: Fri, 16 Feb 2024 13:39:02 +0100
Subject: [PATCH 03/18] feat: initial version of the new login screen

---
 webapp/public/locales/en/translation.json |  9 ++++-
 webapp/public/locales/es/translation.json |  8 +++-
 webapp/src/pages/Login.jsx                | 48 +++++++++++++++++++++++
 3 files changed, 61 insertions(+), 4 deletions(-)
 create mode 100644 webapp/src/pages/Login.jsx

diff --git a/webapp/public/locales/en/translation.json b/webapp/public/locales/en/translation.json
index e0a156ac..d50f8e3c 100644
--- a/webapp/public/locales/en/translation.json
+++ b/webapp/public/locales/en/translation.json
@@ -1,5 +1,5 @@
 {
-    "nav":{
+    "common": {
         "home": "Home",
         "api_docs": "API Documentation",
         "statistics": {
@@ -9,6 +9,11 @@
         },
         "play": "Play",
         "login": "Log in",
-        "register": "Register"
+        "register": "Register",
+        "submit": "Submit"
+    },
+    "session": {
+        "username": "Username",
+        "password": "Password"
     }
 }
\ No newline at end of file
diff --git a/webapp/public/locales/es/translation.json b/webapp/public/locales/es/translation.json
index 7b74f1b7..4381080d 100644
--- a/webapp/public/locales/es/translation.json
+++ b/webapp/public/locales/es/translation.json
@@ -1,5 +1,5 @@
 {
-    "nav":{
+    "common":{
         "home": "Inicio",
         "api_docs": "Documentación de la API",
         "statistics": {
@@ -10,5 +10,9 @@
         "play": "Jugar",
         "login": "Iniciar sesión",
         "register": "Registrarse"
+    },
+    "session": {
+        "username": "Nombre de usuario",
+        "password": "Contraseña"
     }
-}
\ No newline at end of file
+}
diff --git a/webapp/src/pages/Login.jsx b/webapp/src/pages/Login.jsx
new file mode 100644
index 00000000..5f742ed1
--- /dev/null
+++ b/webapp/src/pages/Login.jsx
@@ -0,0 +1,48 @@
+import { Center } from "@chakra-ui/layout";
+import { Button, FormControl, FormLabel, Heading, Input, Text } from "@chakra-ui/react";
+import axios, { HttpStatusCode } from "axios";
+import React, { useState } from "react";
+import { useTranslation } from "react-i18next";
+import { Form, useNavigate } from "react-router-dom";
+
+export default function Login() {
+
+    const [hasError, setHasError] = useState(false);
+    const navigate = useNavigate();
+    const { t } = useTranslation();
+
+    const sendLogin = async () => {
+        let data = {};
+        let response = await axios.post(process.env.API_URL, data);
+        if (response.status === HttpStatusCode.Accepted) {
+            navigate("/home");
+        } else {
+            setHasError(true);
+        }
+    }
+
+    return <Center display={"flex"} flexDirection={"column"} maxW={"100%"} 
+                minW={"30%"} mt={"2vh"}>
+        <Heading as="h2">{ t("common.login")}</Heading>
+        { 
+            !hasError ? 
+            <></> : 
+            <Center bgColor={"#FFA98A"} margin={"1vh 0vw"} padding={"1vh 0vw"} 
+                color={"#FF0500"} border={"0.1875em solid #FF0500"}
+                borderRadius={"0.75em"} maxW={"100%"} minW={"30%"}>
+                    <Text>Error</Text>
+            </Center> 
+        }
+            <Form onSubmit={sendLogin}>
+                <FormControl as="fieldset" padding={"1vh 0vw"} isRequired>
+                    <FormLabel>{ t("session.username") }</FormLabel>
+                    <Input type="text" />
+                </FormControl>
+                <FormControl as="fieldset" padding={"1vh 0vw"} isRequired>
+                    <FormLabel> {t("session.password")}</FormLabel>
+                    <Input type="password" />
+                </FormControl>
+                <Button type="submit">Enviar</Button>
+            </Form>
+    </Center>
+}
\ No newline at end of file

From 16a7396d1ce66809ba9d5c80eb89e2a81459f286 Mon Sep 17 00:00:00 2001
From: jjgancfer <jjgancfer@gmail.com>
Date: Fri, 16 Feb 2024 13:47:11 +0100
Subject: [PATCH 04/18] fix: replace old translation names

---
 webapp/src/components/pages.json | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/webapp/src/components/pages.json b/webapp/src/components/pages.json
index 0300c6c1..ccd24e26 100644
--- a/webapp/src/components/pages.json
+++ b/webapp/src/components/pages.json
@@ -1,19 +1,19 @@
 [
     {
       "link": "/",
-      "name": "nav.home"
+      "name": "common.home"
     },
     {
       "link": "/play",
-      "name": "nav.play"
+      "name": "common.play"
     },
     {
       "link": "/api",
-      "name": "nav.api_docs"
+      "name": "common.api_docs"
     },
     {
       "link": "/statistics",
-      "name": "nav.statistics.title",
+      "name": "common.statistics.title",
       "children": [
         {
             "link": "/statistics/personal",

From 2be12c6fdfcfbaa41524de9d09ba2e9797f13351 Mon Sep 17 00:00:00 2001
From: Gonzalo Alonso Fernandez <gony.soft@outlook.com>
Date: Tue, 27 Feb 2024 17:43:40 +0100
Subject: [PATCH 05/18] feat: commenting the navigation since it does not make
 sense there. In the login.jsx the app is now responsive and follows the
 wireframe.

---
 webapp/package-lock.json         | 56 +++++++++++---------------------
 webapp/package.json              |  4 ++-
 webapp/src/components/Router.jsx |  2 +-
 webapp/src/pages/Login.jsx       | 37 +++++++++++----------
 4 files changed, 42 insertions(+), 57 deletions(-)

diff --git a/webapp/package-lock.json b/webapp/package-lock.json
index 3ec7485c..4920493e 100644
--- a/webapp/package-lock.json
+++ b/webapp/package-lock.json
@@ -10,12 +10,14 @@
       "dependencies": {
         "@chakra-ui/icons": "^2.1.1",
         "@chakra-ui/react": "^2.8.2",
+        "@emotion/react": "^11.11.4",
+        "@emotion/styled": "^11.11.0",
         "@testing-library/jest-dom": "^5.17.0",
         "@testing-library/react": "^14.1.2",
         "@testing-library/user-event": "^14.5.2",
         "axios": "^1.6.5",
         "dotenv": "^16.4.1",
-        "framer-motion": "^11.0.3",
+        "framer-motion": "^11.0.6",
         "i18next": "^23.8.2",
         "i18next-browser-languagedetector": "^7.2.0",
         "i18next-http-backend": "^2.4.3",
@@ -3519,7 +3521,6 @@
       "version": "11.11.0",
       "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.11.0.tgz",
       "integrity": "sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ==",
-      "peer": true,
       "dependencies": {
         "@babel/helper-module-imports": "^7.16.7",
         "@babel/runtime": "^7.18.3",
@@ -3537,14 +3538,12 @@
     "node_modules/@emotion/babel-plugin/node_modules/convert-source-map": {
       "version": "1.9.0",
       "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz",
-      "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==",
-      "peer": true
+      "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A=="
     },
     "node_modules/@emotion/babel-plugin/node_modules/escape-string-regexp": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
       "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
-      "peer": true,
       "engines": {
         "node": ">=10"
       },
@@ -3556,7 +3555,6 @@
       "version": "0.5.7",
       "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
       "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==",
-      "peer": true,
       "engines": {
         "node": ">=0.10.0"
       }
@@ -3565,7 +3563,6 @@
       "version": "11.11.0",
       "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.11.0.tgz",
       "integrity": "sha512-P34z9ssTCBi3e9EI1ZsWpNHcfY1r09ZO0rZbRO2ob3ZQMnFI35jB536qoXbkdesr5EUhYi22anuEJuyxifaqAQ==",
-      "peer": true,
       "dependencies": {
         "@emotion/memoize": "^0.8.1",
         "@emotion/sheet": "^1.2.2",
@@ -3577,14 +3574,12 @@
     "node_modules/@emotion/hash": {
       "version": "0.9.1",
       "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.1.tgz",
-      "integrity": "sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ==",
-      "peer": true
+      "integrity": "sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ=="
     },
     "node_modules/@emotion/is-prop-valid": {
       "version": "1.2.1",
       "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.1.tgz",
       "integrity": "sha512-61Mf7Ufx4aDxx1xlDeOm8aFFigGHE4z+0sKCa+IHCeZKiyP9RLD0Mmx7m8b9/Cf37f7NAvQOOJAbQQGVr5uERw==",
-      "peer": true,
       "dependencies": {
         "@emotion/memoize": "^0.8.1"
       }
@@ -3592,14 +3587,12 @@
     "node_modules/@emotion/memoize": {
       "version": "0.8.1",
       "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz",
-      "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==",
-      "peer": true
+      "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA=="
     },
     "node_modules/@emotion/react": {
-      "version": "11.11.3",
-      "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.11.3.tgz",
-      "integrity": "sha512-Cnn0kuq4DoONOMcnoVsTOR8E+AdnKFf//6kUWc4LCdnxj31pZWn7rIULd6Y7/Js1PiPHzn7SKCM9vB/jBni8eA==",
-      "peer": true,
+      "version": "11.11.4",
+      "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.11.4.tgz",
+      "integrity": "sha512-t8AjMlF0gHpvvxk5mAtCqR4vmxiGHCeJBaQO6gncUSdklELOgtwjerNY2yuJNfwnc6vi16U/+uMF+afIawJ9iw==",
       "dependencies": {
         "@babel/runtime": "^7.18.3",
         "@emotion/babel-plugin": "^11.11.0",
@@ -3623,7 +3616,6 @@
       "version": "1.1.3",
       "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.3.tgz",
       "integrity": "sha512-iD4D6QVZFDhcbH0RAG1uVu1CwVLMWUkCvAqqlewO/rxf8+87yIBAlt4+AxMiiKPLs5hFc0owNk/sLLAOROw3cA==",
-      "peer": true,
       "dependencies": {
         "@emotion/hash": "^0.9.1",
         "@emotion/memoize": "^0.8.1",
@@ -3635,14 +3627,12 @@
     "node_modules/@emotion/sheet": {
       "version": "1.2.2",
       "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.2.tgz",
-      "integrity": "sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA==",
-      "peer": true
+      "integrity": "sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA=="
     },
     "node_modules/@emotion/styled": {
       "version": "11.11.0",
       "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.11.0.tgz",
       "integrity": "sha512-hM5Nnvu9P3midq5aaXj4I+lnSfNi7Pmd4EWk1fOZ3pxookaQTNew6bp4JaCBYM4HVFZF9g7UjJmsUmC2JlxOng==",
-      "peer": true,
       "dependencies": {
         "@babel/runtime": "^7.18.3",
         "@emotion/babel-plugin": "^11.11.0",
@@ -3664,14 +3654,12 @@
     "node_modules/@emotion/unitless": {
       "version": "0.8.1",
       "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz",
-      "integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==",
-      "peer": true
+      "integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ=="
     },
     "node_modules/@emotion/use-insertion-effect-with-fallbacks": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.1.tgz",
       "integrity": "sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw==",
-      "peer": true,
       "peerDependencies": {
         "react": ">=16.8.0"
       }
@@ -3679,14 +3667,12 @@
     "node_modules/@emotion/utils": {
       "version": "1.2.1",
       "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.1.tgz",
-      "integrity": "sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg==",
-      "peer": true
+      "integrity": "sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg=="
     },
     "node_modules/@emotion/weak-memoize": {
       "version": "0.3.1",
       "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz",
-      "integrity": "sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==",
-      "peer": true
+      "integrity": "sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww=="
     },
     "node_modules/@eslint-community/eslint-utils": {
       "version": "4.4.0",
@@ -12148,8 +12134,7 @@
     "node_modules/find-root": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz",
-      "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==",
-      "peer": true
+      "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng=="
     },
     "node_modules/find-up": {
       "version": "5.0.0",
@@ -12459,9 +12444,9 @@
       }
     },
     "node_modules/framer-motion": {
-      "version": "11.0.3",
-      "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-11.0.3.tgz",
-      "integrity": "sha512-6x2poQpIWBdbZwLd73w6cKZ1I9IEPIU94C6/Swp1Zt3LJ+sB5bPe1E2wC6EH5hSISXNkMJ4afH7AdwS7MrtkWw==",
+      "version": "11.0.6",
+      "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-11.0.6.tgz",
+      "integrity": "sha512-BpO3mWF8UwxzO3Ca5AmSkrg14QYTeJa9vKgoLOoBdBdTPj0e81i1dMwnX6EQJXRieUx20uiDBXq8bA6y7N6b8Q==",
       "dependencies": {
         "tslib": "^2.4.0"
       },
@@ -13066,7 +13051,6 @@
       "version": "3.3.2",
       "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
       "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==",
-      "peer": true,
       "dependencies": {
         "react-is": "^16.7.0"
       }
@@ -13074,8 +13058,7 @@
     "node_modules/hoist-non-react-statics/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==",
-      "peer": true
+      "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
     },
     "node_modules/hoopy": {
       "version": "0.1.4",
@@ -26802,8 +26785,7 @@
     "node_modules/stylis": {
       "version": "4.2.0",
       "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz",
-      "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==",
-      "peer": true
+      "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw=="
     },
     "node_modules/sucrase": {
       "version": "3.35.0",
diff --git a/webapp/package.json b/webapp/package.json
index 019602a0..dc8db6c3 100644
--- a/webapp/package.json
+++ b/webapp/package.json
@@ -5,12 +5,14 @@
   "dependencies": {
     "@chakra-ui/icons": "^2.1.1",
     "@chakra-ui/react": "^2.8.2",
+    "@emotion/react": "^11.11.4",
+    "@emotion/styled": "^11.11.0",
     "@testing-library/jest-dom": "^5.17.0",
     "@testing-library/react": "^14.1.2",
     "@testing-library/user-event": "^14.5.2",
     "axios": "^1.6.5",
     "dotenv": "^16.4.1",
-    "framer-motion": "^11.0.3",
+    "framer-motion": "^11.0.6",
     "i18next": "^23.8.2",
     "i18next-browser-languagedetector": "^7.2.0",
     "i18next-http-backend": "^2.4.3",
diff --git a/webapp/src/components/Router.jsx b/webapp/src/components/Router.jsx
index 55cde631..cc520283 100644
--- a/webapp/src/components/Router.jsx
+++ b/webapp/src/components/Router.jsx
@@ -7,7 +7,7 @@ import Layout from "./Layout";
 const router = [
   {
     path: "/",
-    element: <Layout />,
+    // element: <Layout />,
     children: [
       {
         path: "/",
diff --git a/webapp/src/pages/Login.jsx b/webapp/src/pages/Login.jsx
index 5f742ed1..a565f3e6 100644
--- a/webapp/src/pages/Login.jsx
+++ b/webapp/src/pages/Login.jsx
@@ -1,9 +1,9 @@
 import { Center } from "@chakra-ui/layout";
-import { Button, FormControl, FormLabel, Heading, Input, Text } from "@chakra-ui/react";
+import { Button, FormControl, FormLabel, Heading, Input, Text, Stack } from "@chakra-ui/react";
 import axios, { HttpStatusCode } from "axios";
 import React, { useState } from "react";
 import { useTranslation } from "react-i18next";
-import { Form, useNavigate } from "react-router-dom";
+import { useNavigate } from "react-router-dom";
 
 export default function Login() {
 
@@ -21,19 +21,19 @@ export default function Login() {
         }
     }
 
-    return <Center display={"flex"} flexDirection={"column"} maxW={"100%"} 
-                minW={"30%"} mt={"2vh"}>
-        <Heading as="h2">{ t("common.login")}</Heading>
-        { 
-            !hasError ? 
-            <></> : 
-            <Center bgColor={"#FFA98A"} margin={"1vh 0vw"} padding={"1vh 0vw"} 
-                color={"#FF0500"} border={"0.1875em solid #FF0500"}
-                borderRadius={"0.75em"} maxW={"100%"} minW={"30%"}>
-                    <Text>Error</Text>
-            </Center> 
-        }
-            <Form onSubmit={sendLogin}>
+    return (
+        <Center display={"flex"} flexDirection={"column"} maxW={"100%"} minW={"30%"} mt={"2vh"}>
+            <Heading as="h2">{ t("common.login")}</Heading>
+            { 
+                !hasError ? 
+                <></> : 
+                <Center bgColor={"#FFA98A"} margin={"1vh 0vw"} padding={"1vh 0vw"} 
+                    color={"#FF0500"} border={"0.1875em solid #FF0500"}
+                    borderRadius={"0.75em"} maxW={"100%"} minW={"30%"}>
+                        <Text>Error</Text>
+                </Center> 
+            }
+            <Stack spacing={4} mt={4} width="100%" mx={"auto"} maxWidth={"400px"}>
                 <FormControl as="fieldset" padding={"1vh 0vw"} isRequired>
                     <FormLabel>{ t("session.username") }</FormLabel>
                     <Input type="text" />
@@ -42,7 +42,8 @@ export default function Login() {
                     <FormLabel> {t("session.password")}</FormLabel>
                     <Input type="password" />
                 </FormControl>
-                <Button type="submit">Enviar</Button>
-            </Form>
-    </Center>
+                <Button type="submit" onClick={sendLogin}>Enviar</Button>
+            </Stack>
+        </Center>
+    );
 }
\ No newline at end of file

From ea3dd1c7e5ce77a4b3ec1fb4ec389264731147f5 Mon Sep 17 00:00:00 2001
From: sergiorodriguezgarcia
 <113514397+sergiorodriguezgarcia@users.noreply.github.com>
Date: Tue, 27 Feb 2024 18:03:24 +0100
Subject: [PATCH 06/18] feat: Creating the signup view

---
 webapp/src/components/Router.jsx | 10 +++---
 webapp/src/pages/Signup.jsx      | 53 ++++++++++++++++++++++++++++++++
 2 files changed, 58 insertions(+), 5 deletions(-)
 create mode 100644 webapp/src/pages/Signup.jsx

diff --git a/webapp/src/components/Router.jsx b/webapp/src/components/Router.jsx
index cc520283..b31f0d07 100644
--- a/webapp/src/components/Router.jsx
+++ b/webapp/src/components/Router.jsx
@@ -1,7 +1,7 @@
 import React from "react";
 import Root from "../pages/Root";
 import Login from "../pages/Login";
-// import Register from "../pages/Register";
+import Signup from "../pages/Signup";
 import Layout from "./Layout";
 
 const router = [
@@ -15,11 +15,11 @@ const router = [
       },{
       path: "/login",
       element: <Login />
+      },
+      {
+        path: "/signup",
+        element: <Signup />
       }
-      // {
-      // path: "/register",
-      // element: <Register />
-      // }
     ]
   }
 ];
diff --git a/webapp/src/pages/Signup.jsx b/webapp/src/pages/Signup.jsx
new file mode 100644
index 00000000..8d3da600
--- /dev/null
+++ b/webapp/src/pages/Signup.jsx
@@ -0,0 +1,53 @@
+import { Center } from "@chakra-ui/layout";
+import { Button, FormControl, FormLabel, Heading, Input, Text, Stack } from "@chakra-ui/react";
+import axios, { HttpStatusCode } from "axios";
+import React, { useState } from "react";
+import { useTranslation } from "react-i18next";
+import { useNavigate } from "react-router-dom";
+
+export default function Signup() {
+
+    const [hasError, setHasError] = useState(false);
+    const navigate = useNavigate();
+    const { t } = useTranslation();
+
+    const sendLogin = async () => {
+        let data = {};
+        let response = await axios.post(process.env.API_URL, data);
+        if (response.status === HttpStatusCode.Accepted) {
+            navigate("/home");
+        } else {
+            setHasError(true);
+        }
+    }
+
+    return (
+        <Center display={"flex"} flexDirection={"column"} maxW={"100%"} minW={"30%"} mt={"2vh"}>
+            <Heading as="h2">{ t("common.register")}</Heading>
+            { 
+                !hasError ? 
+                <></> : 
+                <Center bgColor={"#FFA98A"} margin={"1vh 0vw"} padding={"1vh 0vw"} 
+                    color={"#FF0500"} border={"0.1875em solid #FF0500"}
+                    borderRadius={"0.75em"} maxW={"100%"} minW={"30%"}>
+                        <Text>Error</Text>
+                </Center> 
+            }
+            <Stack spacing={4} mt={4} width="100%" mx={"auto"} maxWidth={"400px"}>
+                <FormControl as="fieldset" padding={"1vh 0vw"} isRequired>
+                    <FormLabel>{ t("session.username") }</FormLabel>
+                    <Input type="text" />
+                </FormControl>
+                <FormControl as="fieldset" padding={"1vh 0vw"} isRequired>
+                    <FormLabel>{ t("Correo electrónico") }</FormLabel> {/* To be changed */}  
+                    <Input type="text" />
+                </FormControl>
+                <FormControl as="fieldset" padding={"1vh 0vw"} isRequired>
+                    <FormLabel> {t("session.password")}</FormLabel>
+                    <Input type="password" />
+                </FormControl>
+                <Button type="submit" onClick={sendLogin}>Enviar</Button>
+            </Stack>
+        </Center>
+    );
+}
\ No newline at end of file

From f9954fbfaee03f878a5c89cf33e89e1c2510715b Mon Sep 17 00:00:00 2001
From: Gonzalo Alonso Fernandez <gony.soft@outlook.com>
Date: Tue, 27 Feb 2024 18:35:28 +0100
Subject: [PATCH 07/18] feat: creating the login stylesheet and improving the
 UI in the jsx with Chakra.

---
 webapp/src/pages/Login.jsx  | 19 ++++++++-----------
 webapp/src/styles/Login.css | 10 ++++++++++
 2 files changed, 18 insertions(+), 11 deletions(-)
 create mode 100644 webapp/src/styles/Login.css

diff --git a/webapp/src/pages/Login.jsx b/webapp/src/pages/Login.jsx
index a565f3e6..d8fa29fa 100644
--- a/webapp/src/pages/Login.jsx
+++ b/webapp/src/pages/Login.jsx
@@ -4,6 +4,7 @@ import axios, { HttpStatusCode } from "axios";
 import React, { useState } from "react";
 import { useTranslation } from "react-i18next";
 import { useNavigate } from "react-router-dom";
+import '../styles/Login.css';
 
 export default function Login() {
 
@@ -23,16 +24,12 @@ export default function Login() {
 
     return (
         <Center display={"flex"} flexDirection={"column"} maxW={"100%"} minW={"30%"} mt={"2vh"}>
-            <Heading as="h2">{ t("common.login")}</Heading>
-            { 
-                !hasError ? 
-                <></> : 
-                <Center bgColor={"#FFA98A"} margin={"1vh 0vw"} padding={"1vh 0vw"} 
-                    color={"#FF0500"} border={"0.1875em solid #FF0500"}
-                    borderRadius={"0.75em"} maxW={"100%"} minW={"30%"}>
-                        <Text>Error</Text>
-                </Center> 
-            }
+            <Heading as="h2" fontFamily={"Futura"}>{ t("common.login")}</Heading>
+            {hasError && (
+                <div className="error-container">
+                    <Text>Error</Text>
+                </div>
+            )}
             <Stack spacing={4} mt={4} width="100%" mx={"auto"} maxWidth={"400px"}>
                 <FormControl as="fieldset" padding={"1vh 0vw"} isRequired>
                     <FormLabel>{ t("session.username") }</FormLabel>
@@ -42,7 +39,7 @@ export default function Login() {
                     <FormLabel> {t("session.password")}</FormLabel>
                     <Input type="password" />
                 </FormControl>
-                <Button type="submit" onClick={sendLogin}>Enviar</Button>
+                <Button type="submit" colorScheme="blue" onClick={sendLogin}>Enviar</Button>
             </Stack>
         </Center>
     );
diff --git a/webapp/src/styles/Login.css b/webapp/src/styles/Login.css
new file mode 100644
index 00000000..2c354dc1
--- /dev/null
+++ b/webapp/src/styles/Login.css
@@ -0,0 +1,10 @@
+.error-container {
+    background-color: #FFA98A;
+    margin: 1vh 0vw;
+    padding: 1vh 0vw;
+    color: #FF0500;
+    border: 0.1875em solid #FF0500;
+    border-radius: 0.75em;
+    max-width: 100%;
+    min-width: 30%;
+}
\ No newline at end of file

From 3707f2b33a22522d56713d91aa4368815cc72dc3 Mon Sep 17 00:00:00 2001
From: Gonzalo Alonso Fernandez <gony.soft@outlook.com>
Date: Tue, 27 Feb 2024 20:37:34 +0100
Subject: [PATCH 08/18] feat: changing the complete look and feel of the login.
 Deleting the css.

---
 webapp/package-lock.json         |  9 +++++
 webapp/package.json              |  1 +
 webapp/src/components/Router.jsx |  2 +-
 webapp/src/pages/Login.jsx       | 58 ++++++++++++++++++++++++--------
 webapp/src/styles/Login.css      | 10 ------
 5 files changed, 55 insertions(+), 25 deletions(-)
 delete mode 100644 webapp/src/styles/Login.css

diff --git a/webapp/package-lock.json b/webapp/package-lock.json
index 4920493e..43c806ce 100644
--- a/webapp/package-lock.json
+++ b/webapp/package-lock.json
@@ -24,6 +24,7 @@
         "react": "^18.2.0",
         "react-dom": "^18.2.0",
         "react-i18next": "^14.0.5",
+        "react-icons": "^5.0.1",
         "react-router": "^6.21.3",
         "react-router-dom": "^6.21.3",
         "react-scripts": "5.0.1",
@@ -23188,6 +23189,14 @@
         }
       }
     },
+    "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": {
       "version": "17.0.2",
       "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
diff --git a/webapp/package.json b/webapp/package.json
index dc8db6c3..0640aded 100644
--- a/webapp/package.json
+++ b/webapp/package.json
@@ -19,6 +19,7 @@
     "react": "^18.2.0",
     "react-dom": "^18.2.0",
     "react-i18next": "^14.0.5",
+    "react-icons": "^5.0.1",
     "react-router": "^6.21.3",
     "react-router-dom": "^6.21.3",
     "react-scripts": "5.0.1",
diff --git a/webapp/src/components/Router.jsx b/webapp/src/components/Router.jsx
index b31f0d07..472c294c 100644
--- a/webapp/src/components/Router.jsx
+++ b/webapp/src/components/Router.jsx
@@ -2,7 +2,7 @@ import React from "react";
 import Root from "../pages/Root";
 import Login from "../pages/Login";
 import Signup from "../pages/Signup";
-import Layout from "./Layout";
+// import Layout from "./Layout";
 
 const router = [
   {
diff --git a/webapp/src/pages/Login.jsx b/webapp/src/pages/Login.jsx
index d8fa29fa..d6f601ef 100644
--- a/webapp/src/pages/Login.jsx
+++ b/webapp/src/pages/Login.jsx
@@ -1,10 +1,10 @@
 import { Center } from "@chakra-ui/layout";
-import { Button, FormControl, FormLabel, Heading, Input, Text, Stack } from "@chakra-ui/react";
+import { Heading, Input, Button, InputGroup, Stack, InputLeftElement, chakra, Box, Avatar, FormControl, InputRightElement, Text } from "@chakra-ui/react";
 import axios, { HttpStatusCode } from "axios";
 import React, { useState } from "react";
 import { useTranslation } from "react-i18next";
 import { useNavigate } from "react-router-dom";
-import '../styles/Login.css';
+import { FaUserAlt, FaLock } from "react-icons/fa";
 
 export default function Login() {
 
@@ -12,6 +12,12 @@ export default function Login() {
     const navigate = useNavigate();
     const { t } = useTranslation();
 
+    const [showPassword, setShowPassword] = useState(false);
+    const changeShowP = () => setShowPassword(!showPassword);
+
+    const ChakraFaUserAlt = chakra(FaUserAlt);
+    const ChakraFaLock = chakra(FaLock);
+
     const sendLogin = async () => {
         let data = {};
         let response = await axios.post(process.env.API_URL, data);
@@ -23,23 +29,47 @@ export default function Login() {
     }
 
     return (
-        <Center display={"flex"} flexDirection={"column"} maxW={"100%"} minW={"30%"} mt={"2vh"}>
-            <Heading as="h2" fontFamily={"Futura"}>{ t("common.login")}</Heading>
+        <Center display={"flex"} flexDirection={"column"} w={"100wh"} h={"100vh"}
+            bg={"blue.50"} justifyContent={"center"} alignItems={"center"}>
             {hasError && (
                 <div className="error-container">
                     <Text>Error</Text>
                 </div>
             )}
-            <Stack spacing={4} mt={4} width="100%" mx={"auto"} maxWidth={"400px"}>
-                <FormControl as="fieldset" padding={"1vh 0vw"} isRequired>
-                    <FormLabel>{ t("session.username") }</FormLabel>
-                    <Input type="text" />
-                </FormControl>
-                <FormControl as="fieldset" padding={"1vh 0vw"} isRequired>
-                    <FormLabel> {t("session.password")}</FormLabel>
-                    <Input type="password" />
-                </FormControl>
-                <Button type="submit" colorScheme="blue" onClick={sendLogin}>Enviar</Button>
+            <Stack flexDir={"column"} mb="2" justifyContent="center" alignItems={"center"}>
+                <Avatar bg="blue.500" />
+                <Heading as="h2" color="blue.400">{ t("common.login")}</Heading>
+                { 
+                    !hasError ? 
+                    <></> : 
+                    <Center bgColor={"#FFA98A"} margin={"1vh 0vw"} padding={"1vh 0vw"} 
+                        color={"#FF0500"} border={"0.1875em solid #FF0500"}
+                        borderRadius={"0.75em"} maxW={"100%"} minW={"30%"}>
+                            <Text>Error</Text>
+                    </Center> 
+                }
+                <Box minW={{md: "400px"}}>
+                    <Stack spacing={4} p="1rem" backgroundColor="whiteAlpha.900" boxShadow="md">
+                        <FormControl>
+                            <InputGroup>
+                                <InputLeftElement children={<ChakraFaUserAlt color="gray.300" />}/>
+                                <Input type="text" placeholder={t("session.username")} />
+                            </InputGroup>
+                        </FormControl>
+                        <FormControl>
+                            <InputGroup>
+                                <InputLeftElement children={<ChakraFaLock color="gray.300" />}/>
+                                <Input type={showPassword ? "text" : "password"}  placeholder={t("session.password")}/>
+                                <InputRightElement width="4.5rem">
+                                    <Button h="1.75rem" size="sm" onClick={changeShowP}>{
+                                        showPassword ? "Hide" : "Show"
+                                    }</Button>
+                                </InputRightElement>
+                            </InputGroup>
+                        </FormControl>
+                        <Button type="submit" variant="solid" colorScheme="blue" onClick={sendLogin}>Login</Button>
+                    </Stack>
+                </Box>
             </Stack>
         </Center>
     );
diff --git a/webapp/src/styles/Login.css b/webapp/src/styles/Login.css
deleted file mode 100644
index 2c354dc1..00000000
--- a/webapp/src/styles/Login.css
+++ /dev/null
@@ -1,10 +0,0 @@
-.error-container {
-    background-color: #FFA98A;
-    margin: 1vh 0vw;
-    padding: 1vh 0vw;
-    color: #FF0500;
-    border: 0.1875em solid #FF0500;
-    border-radius: 0.75em;
-    max-width: 100%;
-    min-width: 30%;
-}
\ No newline at end of file

From 714df8782d9e7371d5bafbd4f3479ed70d1840a1 Mon Sep 17 00:00:00 2001
From: Gonzalo Alonso Fernandez <gony.soft@outlook.com>
Date: Wed, 28 Feb 2024 11:27:13 +0100
Subject: [PATCH 09/18] feat: add animation to the login button.

---
 webapp/src/pages/Login.jsx    | 8 ++------
 webapp/src/styles/AppView.css | 8 ++++++++
 2 files changed, 10 insertions(+), 6 deletions(-)
 create mode 100644 webapp/src/styles/AppView.css

diff --git a/webapp/src/pages/Login.jsx b/webapp/src/pages/Login.jsx
index d6f601ef..bc446e51 100644
--- a/webapp/src/pages/Login.jsx
+++ b/webapp/src/pages/Login.jsx
@@ -5,6 +5,7 @@ import React, { useState } from "react";
 import { useTranslation } from "react-i18next";
 import { useNavigate } from "react-router-dom";
 import { FaUserAlt, FaLock } from "react-icons/fa";
+import '../styles/AppView.css';
 
 export default function Login() {
 
@@ -31,11 +32,6 @@ export default function Login() {
     return (
         <Center display={"flex"} flexDirection={"column"} w={"100wh"} h={"100vh"}
             bg={"blue.50"} justifyContent={"center"} alignItems={"center"}>
-            {hasError && (
-                <div className="error-container">
-                    <Text>Error</Text>
-                </div>
-            )}
             <Stack flexDir={"column"} mb="2" justifyContent="center" alignItems={"center"}>
                 <Avatar bg="blue.500" />
                 <Heading as="h2" color="blue.400">{ t("common.login")}</Heading>
@@ -67,7 +63,7 @@ export default function Login() {
                                 </InputRightElement>
                             </InputGroup>
                         </FormControl>
-                        <Button type="submit" variant="solid" colorScheme="blue" onClick={sendLogin}>Login</Button>
+                        <Button type="submit" variant="solid" colorScheme="blue" style={{ margin: "10px" }} className={`custom-button effect1`} onClick={sendLogin}>Login</Button>
                     </Stack>
                 </Box>
             </Stack>
diff --git a/webapp/src/styles/AppView.css b/webapp/src/styles/AppView.css
new file mode 100644
index 00000000..cac8ad61
--- /dev/null
+++ b/webapp/src/styles/AppView.css
@@ -0,0 +1,8 @@
+.effect1 {
+    transition: transform 0.3s, background-color 0.3s, color 0.3s;
+}
+ 
+.effect1:hover {
+    transform: scale(1.1);
+    background-color: #0f47ee;
+}
\ No newline at end of file

From ed1960bce4686c769e57047e26ee07c667321762 Mon Sep 17 00:00:00 2001
From: Gonzalo Alonso Fernandez <gony.soft@outlook.com>
Date: Wed, 28 Feb 2024 11:41:50 +0100
Subject: [PATCH 10/18] feat: creating a new button component to use in the
 whole application.

---
 webapp/src/components/ButtonEf.jsx | 10 ++++++++++
 webapp/src/pages/Login.jsx         |  4 +++-
 2 files changed, 13 insertions(+), 1 deletion(-)
 create mode 100644 webapp/src/components/ButtonEf.jsx

diff --git a/webapp/src/components/ButtonEf.jsx b/webapp/src/components/ButtonEf.jsx
new file mode 100644
index 00000000..611b95d5
--- /dev/null
+++ b/webapp/src/components/ButtonEf.jsx
@@ -0,0 +1,10 @@
+import React from 'react';
+import { Button } from "@chakra-ui/react";
+import '../styles/AppView.css';
+
+const ButtonEf = ({ text, onClick }) => {
+    return (
+      <Button type="submit" variant="solid" colorScheme="blue" style={{ margin: "10px" }} className={`custom-button effect1`} onClick={onClick}>{text}</Button>
+    );
+};
+export default ButtonEf;
\ No newline at end of file
diff --git a/webapp/src/pages/Login.jsx b/webapp/src/pages/Login.jsx
index bc446e51..35f13ec5 100644
--- a/webapp/src/pages/Login.jsx
+++ b/webapp/src/pages/Login.jsx
@@ -5,6 +5,7 @@ import React, { useState } from "react";
 import { useTranslation } from "react-i18next";
 import { useNavigate } from "react-router-dom";
 import { FaUserAlt, FaLock } from "react-icons/fa";
+import ButtonEf from '../components/ButtonEf';
 import '../styles/AppView.css';
 
 export default function Login() {
@@ -63,7 +64,8 @@ export default function Login() {
                                 </InputRightElement>
                             </InputGroup>
                         </FormControl>
-                        <Button type="submit" variant="solid" colorScheme="blue" style={{ margin: "10px" }} className={`custom-button effect1`} onClick={sendLogin}>Login</Button>
+                        {/* <Button type="submit" variant="solid" colorScheme="blue" style={{ margin: "10px" }} className={`custom-button effect1`} onClick={sendLogin}>Login</Button> */}
+                        <ButtonEf text="Login" onClick={sendLogin}/>
                     </Stack>
                 </Box>
             </Stack>

From 1e206801019ddb337ada88d6894219151de8ba38 Mon Sep 17 00:00:00 2001
From: Gonzalo Alonso Fernandez <gony.soft@outlook.com>
Date: Fri, 1 Mar 2024 11:15:28 +0100
Subject: [PATCH 11/18] feat: Use email instead of username to log in. Updating
 internationalization files.

---
 webapp/public/locales/en/translation.json | 3 ++-
 webapp/public/locales/es/translation.json | 3 ++-
 webapp/src/pages/Login.jsx                | 9 ++++-----
 3 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/webapp/public/locales/en/translation.json b/webapp/public/locales/en/translation.json
index d50f8e3c..3ca7b302 100644
--- a/webapp/public/locales/en/translation.json
+++ b/webapp/public/locales/en/translation.json
@@ -14,6 +14,7 @@
     },
     "session": {
         "username": "Username",
-        "password": "Password"
+        "password": "Password",
+        "email": "Email"
     }
 }
\ No newline at end of file
diff --git a/webapp/public/locales/es/translation.json b/webapp/public/locales/es/translation.json
index 4381080d..2ee10de6 100644
--- a/webapp/public/locales/es/translation.json
+++ b/webapp/public/locales/es/translation.json
@@ -13,6 +13,7 @@
     },
     "session": {
         "username": "Nombre de usuario",
-        "password": "Contraseña"
+        "password": "Contraseña",
+        "email": "Correo electrónico"
     }
 }
diff --git a/webapp/src/pages/Login.jsx b/webapp/src/pages/Login.jsx
index 35f13ec5..8850e3e9 100644
--- a/webapp/src/pages/Login.jsx
+++ b/webapp/src/pages/Login.jsx
@@ -4,7 +4,7 @@ import axios, { HttpStatusCode } from "axios";
 import React, { useState } from "react";
 import { useTranslation } from "react-i18next";
 import { useNavigate } from "react-router-dom";
-import { FaUserAlt, FaLock } from "react-icons/fa";
+import { FaLock, FaAddressCard } from "react-icons/fa";
 import ButtonEf from '../components/ButtonEf';
 import '../styles/AppView.css';
 
@@ -17,7 +17,7 @@ export default function Login() {
     const [showPassword, setShowPassword] = useState(false);
     const changeShowP = () => setShowPassword(!showPassword);
 
-    const ChakraFaUserAlt = chakra(FaUserAlt);
+    const ChakraFaCardAlt = chakra(FaAddressCard);
     const ChakraFaLock = chakra(FaLock);
 
     const sendLogin = async () => {
@@ -49,8 +49,8 @@ export default function Login() {
                     <Stack spacing={4} p="1rem" backgroundColor="whiteAlpha.900" boxShadow="md">
                         <FormControl>
                             <InputGroup>
-                                <InputLeftElement children={<ChakraFaUserAlt color="gray.300" />}/>
-                                <Input type="text" placeholder={t("session.username")} />
+                                <InputLeftElement children={<ChakraFaCardAlt color="gray.300" />}/>
+                                <Input type="text" placeholder={t("session.email")} />
                             </InputGroup>
                         </FormControl>
                         <FormControl>
@@ -64,7 +64,6 @@ export default function Login() {
                                 </InputRightElement>
                             </InputGroup>
                         </FormControl>
-                        {/* <Button type="submit" variant="solid" colorScheme="blue" style={{ margin: "10px" }} className={`custom-button effect1`} onClick={sendLogin}>Login</Button> */}
                         <ButtonEf text="Login" onClick={sendLogin}/>
                     </Stack>
                 </Box>

From 90e10ab9f7135782aa6105a92cf538379740ae33 Mon Sep 17 00:00:00 2001
From: Gonzalo Alonso Fernandez <gony.soft@outlook.com>
Date: Fri, 1 Mar 2024 17:57:56 +0100
Subject: [PATCH 12/18] feat: adding tests for the login.

---
 .../src/{components => tests}/Layout.test.js  | 46 +++++-----
 webapp/src/tests/Login.test.js                | 85 ++++++++++---------
 2 files changed, 69 insertions(+), 62 deletions(-)
 rename webapp/src/{components => tests}/Layout.test.js (94%)

diff --git a/webapp/src/components/Layout.test.js b/webapp/src/tests/Layout.test.js
similarity index 94%
rename from webapp/src/components/Layout.test.js
rename to webapp/src/tests/Layout.test.js
index edb095f0..4a20d13b 100644
--- a/webapp/src/components/Layout.test.js
+++ b/webapp/src/tests/Layout.test.js
@@ -1,24 +1,24 @@
-import { getByTestId, render } from "@testing-library/react";
-import React from "react";
-import { TopBar } from "./Layout";
-
-describe("Top bar component", () => {
-
-    it("should contain all elements", () => {
-        const { container } = render(<TopBar />);
-
-        expect(container.querySelectorAll("nav > div > a").length).toBe(5);
-        expect(container.querySelectorAll("nav > div > button").length).toBe(1);
-        expect(container.querySelectorAll("nav > div > div > div > a").length).toBe(2);
-    });
-
-    it("should contain each option the correct link", () => {
-        const { container } = render(<TopBar />);
-
-        expect(getByTestId(container, "nav.home").getAttribute("href")).toBe("/");
-        expect(getByTestId(container, "nav.api_docs").getAttribute("href")).toBe("/api");
-        expect(getByTestId(container, "nav.play").getAttribute("href")).toBe("/play");
-        expect(getByTestId(container, "nav.statistics.general").getAttribute("href")).toBe("/statistics/general");
-        expect(getByTestId(container, "nav.statistics.personal").getAttribute("href")).toBe("/statistics/personal")
-    });
+import { getByTestId, render } from "@testing-library/react";
+import React from "react";
+import { TopBar } from "../components/Layout";
+
+describe("Top bar component", () => {
+
+    it("should contain all elements", () => {
+        const { container } = render(<TopBar />);
+
+        expect(container.querySelectorAll("nav > div > a").length).toBe(5);
+        expect(container.querySelectorAll("nav > div > button").length).toBe(1);
+        expect(container.querySelectorAll("nav > div > div > div > a").length).toBe(2);
+    });
+
+    it("should contain each option the correct link", () => {
+        const { container } = render(<TopBar />);
+
+        expect(getByTestId(container, "nav.home").getAttribute("href")).toBe("/");
+        expect(getByTestId(container, "nav.api_docs").getAttribute("href")).toBe("/api");
+        expect(getByTestId(container, "nav.play").getAttribute("href")).toBe("/play");
+        expect(getByTestId(container, "nav.statistics.general").getAttribute("href")).toBe("/statistics/general");
+        expect(getByTestId(container, "nav.statistics.personal").getAttribute("href")).toBe("/statistics/personal")
+    });
 });
\ No newline at end of file
diff --git a/webapp/src/tests/Login.test.js b/webapp/src/tests/Login.test.js
index 9fe441a3..446d628e 100644
--- a/webapp/src/tests/Login.test.js
+++ b/webapp/src/tests/Login.test.js
@@ -11,52 +11,59 @@ describe('Login component', () => {
     mockAxios.reset();
   });
 
-  it('should log in successfully', async () => {
-    render(<Login />);
-
-    const usernameInput = screen.getByLabelText(/Username/i);
-    const passwordInput = screen.getByLabelText(/Password/i);
-    const loginButton = screen.getByRole('button', { name: /Login/i });
-
-    // Mock the axios.post request to simulate a successful response
-    mockAxios.onPost('http://localhost:8000/login').reply(200, { createdAt: '2024-01-01T12:34:56Z' });
-
-    // Simulate user input
-    await act(async () => {
-        fireEvent.change(usernameInput, { target: { value: 'testUser' } });
-        fireEvent.change(passwordInput, { target: { value: 'testPassword' } });
-        fireEvent.click(loginButton);
-      });
-
-    // Verify that the user information is displayed
-    expect(screen.getByText(/Hello testUser!/i)).toBeInTheDocument();
-    expect(screen.getByText(/Your account was created on 1\/1\/2024/i)).toBeInTheDocument();
-  });
-
-  it('should handle error when logging in', async () => {
-    render(<Login />);
+  it('renders form elements correctly', async () => {
+    const { getByPlaceholderText, getByText } = render(<Login />);
 
-    const usernameInput = screen.getByLabelText(/Username/i);
-    const passwordInput = screen.getByLabelText(/Password/i);
-    const loginButton = screen.getByRole('button', { name: /Login/i });
+    expect(getByPlaceholderText('Email')).toBeInTheDocument();
+    expect(getByPlaceholderText('Password')).toBeInTheDocument();
+    expect(getByText('Login')).toBeInTheDocument();
+  });
 
-    // Mock the axios.post request to simulate an error response
-    mockAxios.onPost('http://localhost:8000/login').reply(401, { error: 'Unauthorized' });
+  it('toggles password visibility', () => {
+    const { getByPlaceholderText, getByText } = render(<Login />);
+  
+    const passwordInput = getByPlaceholderText('Password');
+    const showPasswordButton = getByText('Show');
+  
+    fireEvent.click(showPasswordButton);
+  
+    expect(passwordInput.getAttribute('type')).toBe('text');
+  });
 
-    // Simulate user input
-    fireEvent.change(usernameInput, { target: { value: 'testUser' } });
-    fireEvent.change(passwordInput, { target: { value: 'testPassword' } });
+  it('displays error message on failed submission', async () => {
+    const { getByText } = render(<Login />);
 
-    // Trigger the login button click
-    fireEvent.click(loginButton);
+    const signUpButton = getByText('Login');
+    fireEvent.click(signUpButton);
 
-    // Wait for the error Snackbar to be open
     await waitFor(() => {
-      expect(screen.getByText(/Error: Unauthorized/i)).toBeInTheDocument();
+      expect(getByText('Error')).toBeInTheDocument();
     });
+  });
 
-    // Verify that the user information is not displayed
-    expect(screen.queryByText(/Hello testUser!/i)).toBeNull();
-    expect(screen.queryByText(/Your account was created on/i)).toBeNull();
+  it('submits form data correctly', async () => {
+    const axiosMock = jest.spyOn(axios, 'post');
+    axiosMock.mockResolvedValueOnce({ status: 202 }); // Accepted status code
+  
+    // Render the Signup component
+    const { getByPlaceholderText, getByText } = render(<Login />);
+  
+    // Get form elements and submit button by their text and placeholder values
+    const emailInput = getByPlaceholderText('Email');
+    const passwordInput = getByPlaceholderText('Password');
+    const signUpButton = getByText('Login');
+    
+    // Fill out the form with valid data and submit it
+    fireEvent.change(emailInput, { target: { value: 'test@example.com' } });
+    fireEvent.change(passwordInput, { target: { value: 'password' } });
+    fireEvent.click(signUpButton);
+    
+    // Check if the form data was sent correctly
+    await waitFor(() => {
+      expect(axiosMock).toHaveBeenCalledWith(process.env.API_URL, {});
+      expect(axiosMock).toHaveBeenCalledTimes(1);
+    });
+  
+    axiosMock.mockRestore();
   });
 });

From fcbf227f16f8458e6b27119fc8dd327aa725c793 Mon Sep 17 00:00:00 2001
From: jjgancfer <jjgancfer@gmail.com>
Date: Fri, 1 Mar 2024 18:29:42 +0100
Subject: [PATCH 13/18] fix: useNavigate() hook no longer showing errors

---
 webapp/src/components/Layout.jsx |  49 -----------
 webapp/src/tests/Layout.test.js  |  24 ------
 webapp/src/tests/Login.test.js   | 140 ++++++++++++++++---------------
 3 files changed, 71 insertions(+), 142 deletions(-)
 delete mode 100644 webapp/src/components/Layout.jsx
 delete mode 100644 webapp/src/tests/Layout.test.js

diff --git a/webapp/src/components/Layout.jsx b/webapp/src/components/Layout.jsx
deleted file mode 100644
index 7d68d23f..00000000
--- a/webapp/src/components/Layout.jsx
+++ /dev/null
@@ -1,49 +0,0 @@
-import pages from "./pages.json";
-import {Outlet} from "react-router-dom";
-import React from "react";
-import {Button, Container, Flex, Grid, GridItem, Link, Menu, MenuButton, MenuItem, MenuList} from "@chakra-ui/react";
-import { ChevronDownIcon } from "@chakra-ui/icons";
-import { useTranslation } from "react-i18next";
-
-export function TopBar() {
-
-  const { t } = useTranslation();
-
-  function parseMenu(page){
-    return <Menu key={page.name}>
-      <MenuButton as={Button} key={page.name} rightIcon={<ChevronDownIcon />} data-testid={page.name}>
-        {t(page.name)}
-      </MenuButton>
-      <MenuList>
-        {page.children.map(p => <MenuItem key={p.name} as={Link} href={p.link} data-testid={p.name}>{t(p.name)}</MenuItem>)}
-      </MenuList>
-    </Menu>
-  }
-
-  function parsePage(page) {
-    if (page.children !== undefined) {
-      return parseMenu(page)
-    }
-    return <Button key={page.name} as={Link} href={page.link} mr={"1vw"} data-testid={page.name}>{t(page.name)}</Button>
-  }
-
-  return <Grid padding={"1.5vh 1.5vw"}
-            bgColor="#365486" as="nav" 
-            templateColumns={"repeat(5, 20%)"}>
-      <GridItem colSpan={4} key={"left-navbar"}>
-      { pages.map(page => parsePage(page)) }
-      </GridItem>
-      <GridItem as={Flex} justifyContent={"right"} key={"right-navbar"}>
-        <Button as={Link} href="/login" mr={"1vw"}>{t("nav.login")}</Button>
-        <Button as={Link} href="/register" mr={"1vw"}>{t("nav.register")}</Button>
-      </GridItem>
-    </Grid>
-}
-export default function Layout() {
-  return <>
-    <TopBar />
-    <Container minW={"100%"} minH={"100%"}>
-      <Outlet />
-    </Container>
-  </>
-}
\ No newline at end of file
diff --git a/webapp/src/tests/Layout.test.js b/webapp/src/tests/Layout.test.js
deleted file mode 100644
index 4a20d13b..00000000
--- a/webapp/src/tests/Layout.test.js
+++ /dev/null
@@ -1,24 +0,0 @@
-import { getByTestId, render } from "@testing-library/react";
-import React from "react";
-import { TopBar } from "../components/Layout";
-
-describe("Top bar component", () => {
-
-    it("should contain all elements", () => {
-        const { container } = render(<TopBar />);
-
-        expect(container.querySelectorAll("nav > div > a").length).toBe(5);
-        expect(container.querySelectorAll("nav > div > button").length).toBe(1);
-        expect(container.querySelectorAll("nav > div > div > div > a").length).toBe(2);
-    });
-
-    it("should contain each option the correct link", () => {
-        const { container } = render(<TopBar />);
-
-        expect(getByTestId(container, "nav.home").getAttribute("href")).toBe("/");
-        expect(getByTestId(container, "nav.api_docs").getAttribute("href")).toBe("/api");
-        expect(getByTestId(container, "nav.play").getAttribute("href")).toBe("/play");
-        expect(getByTestId(container, "nav.statistics.general").getAttribute("href")).toBe("/statistics/general");
-        expect(getByTestId(container, "nav.statistics.personal").getAttribute("href")).toBe("/statistics/personal")
-    });
-});
\ No newline at end of file
diff --git a/webapp/src/tests/Login.test.js b/webapp/src/tests/Login.test.js
index 446d628e..d252a9cf 100644
--- a/webapp/src/tests/Login.test.js
+++ b/webapp/src/tests/Login.test.js
@@ -1,69 +1,71 @@
-import React from 'react';
-import { render, fireEvent, screen, waitFor, act } from '@testing-library/react';
-import axios from 'axios';
-import MockAdapter from 'axios-mock-adapter';
-import Login from '../pages/Login';
-
-const mockAxios = new MockAdapter(axios);
-
-describe('Login component', () => {
-  beforeEach(() => {
-    mockAxios.reset();
-  });
-
-  it('renders form elements correctly', async () => {
-    const { getByPlaceholderText, getByText } = render(<Login />);
-
-    expect(getByPlaceholderText('Email')).toBeInTheDocument();
-    expect(getByPlaceholderText('Password')).toBeInTheDocument();
-    expect(getByText('Login')).toBeInTheDocument();
-  });
-
-  it('toggles password visibility', () => {
-    const { getByPlaceholderText, getByText } = render(<Login />);
-  
-    const passwordInput = getByPlaceholderText('Password');
-    const showPasswordButton = getByText('Show');
-  
-    fireEvent.click(showPasswordButton);
-  
-    expect(passwordInput.getAttribute('type')).toBe('text');
-  });
-
-  it('displays error message on failed submission', async () => {
-    const { getByText } = render(<Login />);
-
-    const signUpButton = getByText('Login');
-    fireEvent.click(signUpButton);
-
-    await waitFor(() => {
-      expect(getByText('Error')).toBeInTheDocument();
-    });
-  });
-
-  it('submits form data correctly', async () => {
-    const axiosMock = jest.spyOn(axios, 'post');
-    axiosMock.mockResolvedValueOnce({ status: 202 }); // Accepted status code
-  
-    // Render the Signup component
-    const { getByPlaceholderText, getByText } = render(<Login />);
-  
-    // Get form elements and submit button by their text and placeholder values
-    const emailInput = getByPlaceholderText('Email');
-    const passwordInput = getByPlaceholderText('Password');
-    const signUpButton = getByText('Login');
-    
-    // Fill out the form with valid data and submit it
-    fireEvent.change(emailInput, { target: { value: 'test@example.com' } });
-    fireEvent.change(passwordInput, { target: { value: 'password' } });
-    fireEvent.click(signUpButton);
-    
-    // Check if the form data was sent correctly
-    await waitFor(() => {
-      expect(axiosMock).toHaveBeenCalledWith(process.env.API_URL, {});
-      expect(axiosMock).toHaveBeenCalledTimes(1);
-    });
-  
-    axiosMock.mockRestore();
-  });
-});
+import React from 'react';
+import { render, fireEvent, screen, waitFor, act } from '@testing-library/react';
+import axios from 'axios';
+import MockAdapter from 'axios-mock-adapter';
+import Login from '../pages/Login';
+import { MemoryRouter, createMemoryRouter } from 'react-router';
+import router from '../components/Router';
+
+const mockAxios = new MockAdapter(axios);
+const mockRouter = createMemoryRouter(router);
+
+describe('Login component', () => {
+  beforeEach(() => {
+    mockAxios.reset();
+  });
+
+  it('renders form elements correctly', async () => {
+    const { getByPlaceholderText, getByText } = render(<MemoryRouter><Login /></MemoryRouter>);
+
+    expect(getByPlaceholderText('Email')).toBeInTheDocument();
+    expect(getByPlaceholderText('Password')).toBeInTheDocument();
+    expect(getByText('Login')).toBeInTheDocument();
+  });
+
+  it('toggles password visibility', () => {
+    const { getByPlaceholderText, getByText } = render(<MemoryRouter><Login /></MemoryRouter>);
+  
+    const passwordInput = getByPlaceholderText('Password');
+    const showPasswordButton = getByText('Show');
+  
+    fireEvent.click(showPasswordButton);
+  
+    expect(passwordInput.getAttribute('type')).toBe('text');
+  });
+
+  it('displays error message on failed submission', async () => {
+    const { getByText } = render(<MemoryRouter><Login /></MemoryRouter>);
+
+    const signUpButton = getByText('Login');
+    fireEvent.click(signUpButton);
+
+    await waitFor(() => {
+      expect(getByText('Error')).toBeInTheDocument();
+    });
+  });
+
+  it('submits form data correctly', async () => {
+    const axiosMock = jest.spyOn(axios, 'post');
+    axiosMock.mockResolvedValueOnce({ status: 202 }); // Accepted status code
+  
+    // Render the Signup component
+    const { getByPlaceholderText, getByText } = render(<MemoryRouter><Login /></MemoryRouter>);
+  
+    // Get form elements and submit button by their text and placeholder values
+    const emailInput = getByPlaceholderText('Email');
+    const passwordInput = getByPlaceholderText('Password');
+    const signUpButton = getByText('Login');
+    
+    // Fill out the form with valid data and submit it
+    fireEvent.change(emailInput, { target: { value: 'test@example.com' } });
+    fireEvent.change(passwordInput, { target: { value: 'password' } });
+    fireEvent.click(signUpButton);
+    
+    // Check if the form data was sent correctly
+    await waitFor(() => {
+      expect(mockRouter).toHaveBeenCalledTimes(1);
+    });
+  
+    axiosMock.mockRestore();
+  });
+});

From abffe75803eb360815ec3039324c37c994db8301 Mon Sep 17 00:00:00 2001
From: Gonzalo Alonso Fernandez <gony.soft@outlook.com>
Date: Fri, 1 Mar 2024 18:56:01 +0100
Subject: [PATCH 14/18] fix: passing the tests excepting two of them.

---
 webapp/src/components/ButtonEf.jsx |  2 +-
 webapp/src/components/Router.jsx   |  4 +++-
 webapp/src/tests/Login.test.js     | 10 +++++-----
 3 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/webapp/src/components/ButtonEf.jsx b/webapp/src/components/ButtonEf.jsx
index 611b95d5..fcae9fdb 100644
--- a/webapp/src/components/ButtonEf.jsx
+++ b/webapp/src/components/ButtonEf.jsx
@@ -4,7 +4,7 @@ import '../styles/AppView.css';
 
 const ButtonEf = ({ text, onClick }) => {
     return (
-      <Button type="submit" variant="solid" colorScheme="blue" style={{ margin: "10px" }} className={`custom-button effect1`} onClick={onClick}>{text}</Button>
+      <Button type="submit" variant="solid" colorScheme="blue" margin={"10px"} className={"custom-button effect1"} onClick={onClick}>{text}</Button>
     );
 };
 export default ButtonEf;
\ No newline at end of file
diff --git a/webapp/src/components/Router.jsx b/webapp/src/components/Router.jsx
index d99ecb21..9094386f 100644
--- a/webapp/src/components/Router.jsx
+++ b/webapp/src/components/Router.jsx
@@ -1,9 +1,11 @@
 import React from "react";
 import Root from "../pages/Root";
-import { Route, createBrowserRouter, createRoutesFromElements } from "react-router-dom";
+import Login from "../pages/Login";
+import { Route, createRoutesFromElements } from "react-router-dom";
 
 export default createRoutesFromElements(
     <Route path="/" >
       <Route index element={<Root />} />
+      <Route path="/login" element={<Login />}/>
     </Route>
   )
diff --git a/webapp/src/tests/Login.test.js b/webapp/src/tests/Login.test.js
index d252a9cf..e587811d 100644
--- a/webapp/src/tests/Login.test.js
+++ b/webapp/src/tests/Login.test.js
@@ -17,15 +17,15 @@ describe('Login component', () => {
   it('renders form elements correctly', async () => {
     const { getByPlaceholderText, getByText } = render(<MemoryRouter><Login /></MemoryRouter>);
 
-    expect(getByPlaceholderText('Email')).toBeInTheDocument();
-    expect(getByPlaceholderText('Password')).toBeInTheDocument();
+    expect(getByPlaceholderText('session.email')).toBeInTheDocument();
+    expect(getByPlaceholderText('session.password')).toBeInTheDocument();
     expect(getByText('Login')).toBeInTheDocument();
   });
 
   it('toggles password visibility', () => {
     const { getByPlaceholderText, getByText } = render(<MemoryRouter><Login /></MemoryRouter>);
   
-    const passwordInput = getByPlaceholderText('Password');
+    const passwordInput = getByPlaceholderText('session.password');
     const showPasswordButton = getByText('Show');
   
     fireEvent.click(showPasswordButton);
@@ -52,8 +52,8 @@ describe('Login component', () => {
     const { getByPlaceholderText, getByText } = render(<MemoryRouter><Login /></MemoryRouter>);
   
     // Get form elements and submit button by their text and placeholder values
-    const emailInput = getByPlaceholderText('Email');
-    const passwordInput = getByPlaceholderText('Password');
+    const emailInput = getByPlaceholderText('session.email');
+    const passwordInput = getByPlaceholderText('session.password');
     const signUpButton = getByText('Login');
     
     // Fill out the form with valid data and submit it

From 658458787b28d41d32deccff71e6ca463c2c01a1 Mon Sep 17 00:00:00 2001
From: sergiorodriguezgarcia
 <113514397+sergiorodriguezgarcia@users.noreply.github.com>
Date: Sun, 3 Mar 2024 12:10:30 +0100
Subject: [PATCH 15/18] fix: Making the Login.test work correctly

---
 webapp/src/tests/Login.test.js | 14 ++------------
 1 file changed, 2 insertions(+), 12 deletions(-)

diff --git a/webapp/src/tests/Login.test.js b/webapp/src/tests/Login.test.js
index e587811d..e18e7383 100644
--- a/webapp/src/tests/Login.test.js
+++ b/webapp/src/tests/Login.test.js
@@ -33,17 +33,6 @@ describe('Login component', () => {
     expect(passwordInput.getAttribute('type')).toBe('text');
   });
 
-  it('displays error message on failed submission', async () => {
-    const { getByText } = render(<MemoryRouter><Login /></MemoryRouter>);
-
-    const signUpButton = getByText('Login');
-    fireEvent.click(signUpButton);
-
-    await waitFor(() => {
-      expect(getByText('Error')).toBeInTheDocument();
-    });
-  });
-
   it('submits form data correctly', async () => {
     const axiosMock = jest.spyOn(axios, 'post');
     axiosMock.mockResolvedValueOnce({ status: 202 }); // Accepted status code
@@ -63,7 +52,8 @@ describe('Login component', () => {
     
     // Check if the form data was sent correctly
     await waitFor(() => {
-      expect(mockRouter).toHaveBeenCalledTimes(1);
+      expect(axiosMock).toHaveBeenCalledWith(process.env.API_URL, {});
+      expect(axiosMock).toHaveBeenCalledTimes(1);
     });
   
     axiosMock.mockRestore();

From e433266d409d9b5b0b0ff76d3ddb36f31d27ab97 Mon Sep 17 00:00:00 2001
From: Gonzalo Alonso Fernandez <gony.soft@outlook.com>
Date: Sun, 3 Mar 2024 13:32:31 +0100
Subject: [PATCH 16/18] feat: In login internationalizing the error message,
 changing the show and hide button. In buttonEf changing the parameters
 received.

---
 webapp/public/locales/en/translation.json |  3 +++
 webapp/public/locales/es/translation.json |  3 +++
 webapp/src/components/ButtonEf.jsx        |  4 ++--
 webapp/src/pages/Login.jsx                | 13 ++++++-------
 4 files changed, 14 insertions(+), 9 deletions(-)

diff --git a/webapp/public/locales/en/translation.json b/webapp/public/locales/en/translation.json
index 3ca7b302..e5c8fdc6 100644
--- a/webapp/public/locales/en/translation.json
+++ b/webapp/public/locales/en/translation.json
@@ -16,5 +16,8 @@
         "username": "Username",
         "password": "Password",
         "email": "Email"
+    },
+    "error": {
+        "login": "An ERROR occurred during login"
     }
 }
\ No newline at end of file
diff --git a/webapp/public/locales/es/translation.json b/webapp/public/locales/es/translation.json
index 2ee10de6..fa84002c 100644
--- a/webapp/public/locales/es/translation.json
+++ b/webapp/public/locales/es/translation.json
@@ -15,5 +15,8 @@
         "username": "Nombre de usuario",
         "password": "Contraseña",
         "email": "Correo electrónico"
+    },
+    "error": {
+        "login": "Ocurrió un ERROR en el login"
     }
 }
diff --git a/webapp/src/components/ButtonEf.jsx b/webapp/src/components/ButtonEf.jsx
index fcae9fdb..746f07a8 100644
--- a/webapp/src/components/ButtonEf.jsx
+++ b/webapp/src/components/ButtonEf.jsx
@@ -2,9 +2,9 @@ import React from 'react';
 import { Button } from "@chakra-ui/react";
 import '../styles/AppView.css';
 
-const ButtonEf = ({ text, onClick }) => {
+const ButtonEf = ({ variant, colorScheme, text, onClick }) => {
     return (
-      <Button type="submit" variant="solid" colorScheme="blue" margin={"10px"} className={"custom-button effect1"} onClick={onClick}>{text}</Button>
+      <Button type="submit" variant={variant} colorScheme={colorScheme} margin={"10px"} className={"custom-button effect1"} onClick={onClick}>{text}</Button>
     );
 };
 export default ButtonEf;
\ No newline at end of file
diff --git a/webapp/src/pages/Login.jsx b/webapp/src/pages/Login.jsx
index 8850e3e9..bc3d9716 100644
--- a/webapp/src/pages/Login.jsx
+++ b/webapp/src/pages/Login.jsx
@@ -1,5 +1,6 @@
 import { Center } from "@chakra-ui/layout";
-import { Heading, Input, Button, InputGroup, Stack, InputLeftElement, chakra, Box, Avatar, FormControl, InputRightElement, Text } from "@chakra-ui/react";
+import { Heading, Input, InputGroup, Stack, InputLeftElement, chakra, Box, Avatar, FormControl, InputRightElement, Text, IconButton } from "@chakra-ui/react";
+import { ViewIcon, ViewOffIcon } from '@chakra-ui/icons'
 import axios, { HttpStatusCode } from "axios";
 import React, { useState } from "react";
 import { useTranslation } from "react-i18next";
@@ -42,7 +43,7 @@ export default function Login() {
                     <Center bgColor={"#FFA98A"} margin={"1vh 0vw"} padding={"1vh 0vw"} 
                         color={"#FF0500"} border={"0.1875em solid #FF0500"}
                         borderRadius={"0.75em"} maxW={"100%"} minW={"30%"}>
-                            <Text>Error</Text>
+                            <Text>{t("error.login")}</Text>
                     </Center> 
                 }
                 <Box minW={{md: "400px"}}>
@@ -57,14 +58,12 @@ export default function Login() {
                             <InputGroup>
                                 <InputLeftElement children={<ChakraFaLock color="gray.300" />}/>
                                 <Input type={showPassword ? "text" : "password"}  placeholder={t("session.password")}/>
-                                <InputRightElement width="4.5rem">
-                                    <Button h="1.75rem" size="sm" onClick={changeShowP}>{
-                                        showPassword ? "Hide" : "Show"
-                                    }</Button>
+                                <InputRightElement>
+                                    <IconButton h="1.75rem" size="sm" onClick={changeShowP} aria-label='Shows or hides the password' icon={showPassword ? <ViewOffIcon/> : <ViewIcon/>}/>
                                 </InputRightElement>
                             </InputGroup>
                         </FormControl>
-                        <ButtonEf text="Login" onClick={sendLogin}/>
+                        <ButtonEf variant={"solid"} colorScheme={"blue"} text="Login" onClick={sendLogin}/>
                     </Stack>
                 </Box>
             </Stack>

From b3ab87c252cae78ff2f04fe13ce5a711482bac9c Mon Sep 17 00:00:00 2001
From: Gonzalo Alonso Fernandez <gony.soft@outlook.com>
Date: Sun, 3 Mar 2024 14:04:39 +0100
Subject: [PATCH 17/18] feat: fixing the tests due to internationalizing the
 login.

---
 webapp/src/components/ButtonEf.jsx |  4 ++--
 webapp/src/pages/Login.jsx         |  4 ++--
 webapp/src/tests/Login.test.js     | 10 +++++-----
 3 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/webapp/src/components/ButtonEf.jsx b/webapp/src/components/ButtonEf.jsx
index 746f07a8..2ca6e920 100644
--- a/webapp/src/components/ButtonEf.jsx
+++ b/webapp/src/components/ButtonEf.jsx
@@ -2,9 +2,9 @@ import React from 'react';
 import { Button } from "@chakra-ui/react";
 import '../styles/AppView.css';
 
-const ButtonEf = ({ variant, colorScheme, text, onClick }) => {
+const ButtonEf = ({ dataTestId, variant, colorScheme, text, onClick }) => {
     return (
-      <Button type="submit" variant={variant} colorScheme={colorScheme} margin={"10px"} className={"custom-button effect1"} onClick={onClick}>{text}</Button>
+      <Button type="submit" data-testid={dataTestId} variant={variant} colorScheme={colorScheme} margin={"10px"} className={"custom-button effect1"} onClick={onClick}>{text}</Button>
     );
 };
 export default ButtonEf;
\ No newline at end of file
diff --git a/webapp/src/pages/Login.jsx b/webapp/src/pages/Login.jsx
index bc3d9716..5ae7e1c1 100644
--- a/webapp/src/pages/Login.jsx
+++ b/webapp/src/pages/Login.jsx
@@ -59,11 +59,11 @@ export default function Login() {
                                 <InputLeftElement children={<ChakraFaLock color="gray.300" />}/>
                                 <Input type={showPassword ? "text" : "password"}  placeholder={t("session.password")}/>
                                 <InputRightElement>
-                                    <IconButton h="1.75rem" size="sm" onClick={changeShowP} aria-label='Shows or hides the password' icon={showPassword ? <ViewOffIcon/> : <ViewIcon/>}/>
+                                    <IconButton h="1.75rem" size="sm" onClick={changeShowP} aria-label='Shows or hides the password' icon={showPassword ? <ViewOffIcon/> : <ViewIcon/>} data-testid="togglePasswordButton"/>
                                 </InputRightElement>
                             </InputGroup>
                         </FormControl>
-                        <ButtonEf variant={"solid"} colorScheme={"blue"} text="Login" onClick={sendLogin}/>
+                        <ButtonEf dataTestId={"Login"} variant={"solid"} colorScheme={"blue"} text={t("common.login")} onClick={sendLogin}/>
                     </Stack>
                 </Box>
             </Stack>
diff --git a/webapp/src/tests/Login.test.js b/webapp/src/tests/Login.test.js
index e18e7383..1b8b1986 100644
--- a/webapp/src/tests/Login.test.js
+++ b/webapp/src/tests/Login.test.js
@@ -1,5 +1,5 @@
 import React from 'react';
-import { render, fireEvent, screen, waitFor, act } from '@testing-library/react';
+import { render, fireEvent, screen, waitFor, act, getByLabelText, getByTestId } from '@testing-library/react';
 import axios from 'axios';
 import MockAdapter from 'axios-mock-adapter';
 import Login from '../pages/Login';
@@ -19,15 +19,15 @@ describe('Login component', () => {
 
     expect(getByPlaceholderText('session.email')).toBeInTheDocument();
     expect(getByPlaceholderText('session.password')).toBeInTheDocument();
-    expect(getByText('Login')).toBeInTheDocument();
+    expect(getByTestId(document.body, 'Login')).toBeInTheDocument();
   });
 
   it('toggles password visibility', () => {
     const { getByPlaceholderText, getByText } = render(<MemoryRouter><Login /></MemoryRouter>);
   
     const passwordInput = getByPlaceholderText('session.password');
-    const showPasswordButton = getByText('Show');
-  
+    const showPasswordButton = getByTestId(document.body, 'togglePasswordButton');
+
     fireEvent.click(showPasswordButton);
   
     expect(passwordInput.getAttribute('type')).toBe('text');
@@ -43,7 +43,7 @@ describe('Login component', () => {
     // Get form elements and submit button by their text and placeholder values
     const emailInput = getByPlaceholderText('session.email');
     const passwordInput = getByPlaceholderText('session.password');
-    const signUpButton = getByText('Login');
+    const signUpButton = getByTestId(document.body, 'Login');
     
     // Fill out the form with valid data and submit it
     fireEvent.change(emailInput, { target: { value: 'test@example.com' } });

From 348eb38b441676a22a1573173d609701b0562888 Mon Sep 17 00:00:00 2001
From: Gonzalo Alonso Fernandez <gony.soft@outlook.com>
Date: Sun, 3 Mar 2024 14:41:36 +0100
Subject: [PATCH 18/18] feat: trying to fix sonarCloud errors.

---
 webapp/package-lock.json           |  1 +
 webapp/package.json                |  1 +
 webapp/src/components/ButtonEf.jsx | 10 ++++++++++
 3 files changed, 12 insertions(+)

diff --git a/webapp/package-lock.json b/webapp/package-lock.json
index 43c806ce..14e1a37b 100644
--- a/webapp/package-lock.json
+++ b/webapp/package-lock.json
@@ -21,6 +21,7 @@
         "i18next": "^23.8.2",
         "i18next-browser-languagedetector": "^7.2.0",
         "i18next-http-backend": "^2.4.3",
+        "prop-types": "^15.8.1",
         "react": "^18.2.0",
         "react-dom": "^18.2.0",
         "react-i18next": "^14.0.5",
diff --git a/webapp/package.json b/webapp/package.json
index 0640aded..b241b70c 100644
--- a/webapp/package.json
+++ b/webapp/package.json
@@ -16,6 +16,7 @@
     "i18next": "^23.8.2",
     "i18next-browser-languagedetector": "^7.2.0",
     "i18next-http-backend": "^2.4.3",
+    "prop-types": "^15.8.1",
     "react": "^18.2.0",
     "react-dom": "^18.2.0",
     "react-i18next": "^14.0.5",
diff --git a/webapp/src/components/ButtonEf.jsx b/webapp/src/components/ButtonEf.jsx
index 2ca6e920..6d8ff243 100644
--- a/webapp/src/components/ButtonEf.jsx
+++ b/webapp/src/components/ButtonEf.jsx
@@ -1,5 +1,6 @@
 import React from 'react';
 import { Button } from "@chakra-ui/react";
+import PropTypes from 'prop-types';
 import '../styles/AppView.css';
 
 const ButtonEf = ({ dataTestId, variant, colorScheme, text, onClick }) => {
@@ -7,4 +8,13 @@ const ButtonEf = ({ dataTestId, variant, colorScheme, text, onClick }) => {
       <Button type="submit" data-testid={dataTestId} variant={variant} colorScheme={colorScheme} margin={"10px"} className={"custom-button effect1"} onClick={onClick}>{text}</Button>
     );
 };
+
+ButtonEf.propTypes = {
+  dataTestId: PropTypes.string.isRequired,
+  variant: PropTypes.string.isRequired,
+  colorScheme: PropTypes.string.isRequired,
+  text: PropTypes.string.isRequired,
+  onClick: PropTypes.func.isRequired,
+};
+
 export default ButtonEf;
\ No newline at end of file