diff --git a/README.md b/README.md index 3d262ac9..6007b6cc 100644 --- a/README.md +++ b/README.md @@ -4,24 +4,32 @@ [![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=Arquisoft_wiq_en1b&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=Arquisoft_wiq_en1b) [![Coverage](https://sonarcloud.io/api/project_badges/measure?project=Arquisoft_wiq_en1b&metric=coverage)](https://sonarcloud.io/summary/new_code?id=Arquisoft_wiq_en1b) -This is a base repo for the [Software Architecture course](http://arquisoft.github.io/) in [2023/2024 edition](https://arquisoft.github.io/course2324.html). +To access the game simply follow the link [here](http://wiqen1b.serveminecraft.net:3000)
+The documentation of the system can be found [here](https://arquisoft.github.io/wiq_en1b/)
+And the API documentation can be seen [here](http://wiqen1b.serveminecraft.net:8000/api-doc/)
+![wiq-icon-improved](https://github.com/Arquisoft/wiq_en1b/assets/124193979/cfa27b39-d039-4502-9299-da424cd04151) -This repo is a basic application composed of several components. +## Application components + +This repo is an application made from several components. - **Gateway service**. Express service that is exposed to the public and serves as a proxy to the two previous ones. - **User service**. Express service that handles the insertion of new users in the system. - **Auth service**. Express service that handles the authentication of users. -- **Webapp**. React web application that uses the gateway service to allow basic login and new user features. +- **Record service**. Express service that handles the game results of all the users and shows a ranking. +- **Webapp**. React web application that uses the gateway service to allow users to play the game, in addition to registering, logging in, view the ranking and much more. +- **Question generator**. Java application that generates questions from Wikidata which are later used in the game. +- **Question service**. Express service that handles the database (MongoDB) and retrieves the previously generated question to be used in the game. -Both the user and auth service share a Mongo database that is accessed with mongoose. +Both the User service and Auth service share a Mongo database that is accessed with mongoose. The Question generator and Question service also share a MongoDB connection. ## Quick start guide In order to deployed it locally you can check out the docker configuration below: ### Using docker -The fastest way for launching this sample project is using docker. Just clone the project: +If you want to try it out by yourself, the fastest way for launching this project is using docker. Just clone the project: ```sh git clone https://github.com/Arquisoft/wiq_en1b.git @@ -33,9 +41,9 @@ and launch it with docker compose: docker compose --profile dev up --build ``` -### Deployed in Cloud -In order to view the application deploy in the cloud click [here](http://wiqen1b.serveminecraft.net:3000) -### Members +## Members + +The members of the great team that made this incredible application. - Lucía Ruiz Núñez uo289267@uniovi.es - Mario Junquera Rojas uo287557@uniovi.es diff --git a/docs/src/04_solution_strategy.adoc b/docs/src/04_solution_strategy.adoc index c6bdb431..8d84e92d 100644 --- a/docs/src/04_solution_strategy.adoc +++ b/docs/src/04_solution_strategy.adoc @@ -33,25 +33,29 @@ See https://docs.arc42.org/section-4/[Solution Strategy] in the arc42 documentat === Technology decisions The technologies chosen for developing the WIQ web app are :: +* **Java** : Java is a high-level, object-oriented programming language developed by Sun Microsystems. It is known for its portability, security features, and wide range of applications, from mobile to enterprise systems. + +* **Nodejs** : Node.js is an open-source, cross-platform JavaScript runtime environment that executes JavaScript code outside of a web browser, allowing developers to build scalable network applications. + * **ReactJS** : A JavaScript library that facilitates the creation of interactive grafical interfaces. -* **Sass** : A scripting language that is compiled into CSS. It extends CSS by providing several mechanisms such as variables, nested rules, mixins, functions, and inheritance. (Not used) -* **TypeScript** : A superset of JavaScript that adds various features that can resolve code errors before running the actual code. (Not used) -* **SpringBoot** : An extension of the Spring framework for creating Java applications. SpringBoot offers many preconfigurations that accelerate the code production process. (Not used) + * **Wikidata Toolkit** : Wikidata Toolkit is a Java library for accessing Wikidata and other Wikibase installations. It can be used to create bots, to perform data extraction tasks (e.g., convert all data in Wikidata to a new format), and to do large-scale analyses that are too complex for using a simple SPARQL query service. -* **Docker** : Docker provides tools and a runtime environment to manage these containers efficiently, allowing developers to build, ship, and run applications consistently across different environments. -* **MySql** : MySQL is an open-source relational database management system that uses SQL for managing and manipulating data. (Not used) -* **Mongo DB** : MongoDB is a popular open-source NoSQL database management system that stores data flexible, JSON-like documents with dynamic schemas. * **Express** : Express is a minimal and flexible Node.js web application framework that provides a robust set of features for building web and mobile applications. -* **Nodejs** : Node.js is an open-source, cross-platform JavaScript runtime environment that executes JavaScript code outside of a web browser, allowing developers to build scalable network applications. +* **Mongo DB** : MongoDB is a popular open-source NoSQL database management system that stores data flexible, JSON-like documents with dynamic schemas. + +* **Docker** : Docker provides tools and a runtime environment to manage these containers efficiently, allowing developers to build, ship, and run applications consistently across different environments. -* **Java** : Java is a high-level, object-oriented programming language developed by Sun Microsystems. It is known for its portability, security features, and wide range of applications, from mobile to enterprise systems. -* **TO BE ORGANIZED** +This decisions were eventually discarded :: +* **Sass** : A scripting language that is compiled into CSS. It extends CSS by providing several mechanisms such as variables, nested rules, mixins, functions, and inheritance. +* **TypeScript** : A superset of JavaScript that adds various features that can resolve code errors before running the actual code. +* **SpringBoot** : An extension of the Spring framework for creating Java applications. SpringBoot offers many preconfigurations that accelerate the code production process. +* **MySql** : MySQL is an open-source relational database management system that uses SQL for managing and manipulating data. === Top-level Decomposition diff --git a/docs/src/10_quality_requirements.adoc b/docs/src/10_quality_requirements.adoc index 8f9ace78..adc04fda 100644 --- a/docs/src/10_quality_requirements.adoc +++ b/docs/src/10_quality_requirements.adoc @@ -62,7 +62,7 @@ In any case the tree should include links to the scenarios of the following sect | The personal information of a user will only be viewable by him/her and user data must be stored securely. | Performance -| The application must not have fast response times. +| The application must have fast response times. | Robustness | The application must answer as expected under all conditions. diff --git a/webapp/public/person1.jpg b/webapp/public/person1.jpg new file mode 100644 index 00000000..f7ca7f0c Binary files /dev/null and b/webapp/public/person1.jpg differ diff --git a/webapp/public/person2.jpg b/webapp/public/person2.jpg new file mode 100644 index 00000000..232d128b Binary files /dev/null and b/webapp/public/person2.jpg differ diff --git a/webapp/public/person3.jpg b/webapp/public/person3.jpg new file mode 100644 index 00000000..6e69fc74 Binary files /dev/null and b/webapp/public/person3.jpg differ diff --git a/webapp/public/person4.jpg b/webapp/public/person4.jpg new file mode 100644 index 00000000..0843092f Binary files /dev/null and b/webapp/public/person4.jpg differ diff --git a/webapp/public/person5.jpg b/webapp/public/person5.jpg new file mode 100644 index 00000000..b9b46aed Binary files /dev/null and b/webapp/public/person5.jpg differ diff --git a/webapp/public/person6.jpg b/webapp/public/person6.jpg new file mode 100644 index 00000000..6c60143c Binary files /dev/null and b/webapp/public/person6.jpg differ diff --git a/webapp/src/App.js b/webapp/src/App.js index 49989923..07b0c74e 100644 --- a/webapp/src/App.js +++ b/webapp/src/App.js @@ -2,6 +2,9 @@ import React,{ useEffect } from 'react'; import QuestionView from './components/questionView/QuestionView'; import GameMenu from './components/GameMenu/GameMenu'; import Navbar from './components/fragments/NavBar'; +import Footer from './components/fragments/Footer'; +import About from './components/fragments/About'; + import ErrorPage from './components/fragments/ErrorPage'; import Home from './components/Home/Home'; import Login from './components/loginAndRegistration/Login'; @@ -29,7 +32,8 @@ function App() {
- + + } /> : } /> @@ -41,11 +45,15 @@ function App() { : } /> : }/> : } /> + } /> } /> } /> +
+
); } diff --git a/webapp/src/components/fragments/About.js b/webapp/src/components/fragments/About.js new file mode 100644 index 00000000..90ecc141 --- /dev/null +++ b/webapp/src/components/fragments/About.js @@ -0,0 +1,26 @@ +import React from 'react'; +import { useTranslation } from "react-i18next"; +import '../../custom.css'; + +function About() { + const t = useTranslation("global").t; + + const imageNames = ["person1.jpg", "person2.jpg", "person3.jpg", "person4.jpg", "person5.jpg", "person6.jpg"]; + + return ( +
+

{t("about.hello")}

+

{t("about.team")}

+ +
+ ); +} + +export default About; diff --git a/webapp/src/components/fragments/About.test.js b/webapp/src/components/fragments/About.test.js new file mode 100644 index 00000000..b5766807 --- /dev/null +++ b/webapp/src/components/fragments/About.test.js @@ -0,0 +1,31 @@ +import React from 'react'; +import { render, screen } from '@testing-library/react'; +import { BrowserRouter as Router } from 'react-router-dom'; +import About from './About'; + + +// Mocking useTranslation hook +jest.mock('react-i18next', () => ({ + useTranslation: () => ({ t: key => key }), + })); + + describe('About', () => { + test('renders about page', () => { + render( + + + + ); + + expect(screen.getByText('about.hello')).toBeInTheDocument(); + + expect(screen.getByText('about.name1')).toBeInTheDocument(); + expect(screen.getByText('about.name2')).toBeInTheDocument(); + expect(screen.getByText('about.name3')).toBeInTheDocument(); + expect(screen.getByText('about.name4')).toBeInTheDocument(); + expect(screen.getByText('about.name5')).toBeInTheDocument(); + expect(screen.getByText('about.name6')).toBeInTheDocument(); + + + }); + }); diff --git a/webapp/src/components/fragments/BackButtonToGameMenu.test.js b/webapp/src/components/fragments/BackButtonToGameMenu.test.js index 586cf695..88926bbc 100644 --- a/webapp/src/components/fragments/BackButtonToGameMenu.test.js +++ b/webapp/src/components/fragments/BackButtonToGameMenu.test.js @@ -18,7 +18,7 @@ global.i18en = i18en; describe('BackButtonToGameMenu component', () => { it('renders option to go back to the game menu', () => { - render(); + render(); const text = screen.getByText((content, element) => { const regex = new RegExp(i18en.t("gameMenu.back")); return regex.test(content); diff --git a/webapp/src/components/fragments/Footer.js b/webapp/src/components/fragments/Footer.js new file mode 100644 index 00000000..3643cbe3 --- /dev/null +++ b/webapp/src/components/fragments/Footer.js @@ -0,0 +1,29 @@ +import React from 'react'; +import '../../custom.css'; +import { Link } from 'react-router-dom'; +import { useTranslation } from "react-i18next"; + +function Footer() { + const [t] = useTranslation("global"); + + return ( + + ); +} + +export default Footer; diff --git a/webapp/src/components/fragments/Footer.test.js b/webapp/src/components/fragments/Footer.test.js new file mode 100644 index 00000000..3e448be0 --- /dev/null +++ b/webapp/src/components/fragments/Footer.test.js @@ -0,0 +1,34 @@ +import { render , screen } from '@testing-library/react'; +import { initReactI18next } from 'react-i18next'; +import i18en from 'i18next'; + +import App from '../../App' + +i18en.use(initReactI18next).init({ + resources: {}, + lng: 'en', + interpolation:{ + escapeValue: false, + } +}); +global.i18en = i18en; + +describe('Footer fragment', () => { + + + + test('Footer renders correctly', async () => { + render( + + ); + expect(screen.getByText('footer.about')).toBeInTheDocument(); + expect(screen.getByText('footer.API')).toBeInTheDocument(); + expect(screen.getByText('footer.ARC')).toBeInTheDocument(); + + + + + + }); +}); + diff --git a/webapp/src/custom.css b/webapp/src/custom.css index a1944f52..5cc05a4d 100644 --- a/webapp/src/custom.css +++ b/webapp/src/custom.css @@ -20,7 +20,23 @@ overflow: hidden; height: 100vh; } +/* About.css */ +.person-list { + list-style: none; + padding: 0; +} + +.person-item { + display: flex; + align-items: center; + margin-bottom: 10px; +} +.person-image { + width: 50px; + height: auto; + margin-right: 10px; +} /*---------------------------Navbar---------------------------*/ @@ -36,6 +52,31 @@ left: 0; top: 0; } + +.footer-container { + display: flex; + justify-content: space-between; + align-items: center; + bottom: 0; + left: 0; + width: 100%; + background-color: #000; + color: white; + width: 100vw; + padding: 5px; + box-sizing: border-box; + position: fixed; + height: 30px; +} + + + +.about, .API, .ARC{ + color: white; +} + + + .left-nav{ display:flex; align-items: left; @@ -104,7 +145,8 @@ .form { display: flex; flex-direction: column; - gap: 20px; + gap: 10px; + padding-top: 0; padding-left: 2em; padding-right: 2em; padding-bottom: 0.4em; @@ -116,7 +158,7 @@ .card { background-image: linear-gradient(163deg, #00ff75 0%, #3700ff 100%); - border-radius: 22px; + border-radius: 15px; transition: all 0.3s; } @@ -139,7 +181,7 @@ display: flex; flex-direction: row; align-items: center; - margin-bottom: 20px; + margin-bottom: 10px; } .input-box p { diff --git a/webapp/src/translations/en/global.json b/webapp/src/translations/en/global.json index 0eaa957a..e3a25d89 100644 --- a/webapp/src/translations/en/global.json +++ b/webapp/src/translations/en/global.json @@ -140,7 +140,22 @@ "enter_email_button": "Send email", "send_code": "Send code", "enter_password_button":"Send password" - } + }, + "footer":{ + "about": "About us", + "API": "API-Doc", + "ARC": "Arc42-Doc" + }, + "about":{ + "hello": "Hello there!", + "team": "We're the awesome bunch from en01b! We hope you like our game.", + "name1": "Mario Junquera Rojas", + "name2": "Lucia Ruiz Núñez", + "name3": "Daniel Sinne Argüelles", + "name4": "Jorge Cano Martínez", + "name5": "Ahmet Erdem Yabaci", + "name6": "Laura Gómez Menéndez" + } } diff --git a/webapp/src/translations/es/global.json b/webapp/src/translations/es/global.json index bf32ca33..6ed87ab4 100644 --- a/webapp/src/translations/es/global.json +++ b/webapp/src/translations/es/global.json @@ -141,7 +141,23 @@ "enter_email_button": "Enviar Email", "send_code": "Enviar Código", "enter_password_button":"Enviar contraseña" - } + }, + "footer":{ + "about": "Sobre nosotros", + "API": "API-Doc", + "ARC": "Arc42-Doc" + }, + + "about":{ + "hello": "¡Hola!", + "team": "¡Somos el increíble grupo en01b! Esperamos que les guste nuestro juego.", + "name1": "Mario Junquera Rojas", + "name2": "Lucía Ruiz Núñez", + "name3": "Daniel Sinne Argüelles", + "name4": "Jorge Cano Martínez", + "name5": "Ahmet Erdem Yabacı", + "name6": "Laura Gómez Menéndez" +} } \ No newline at end of file diff --git a/webapp/src/translations/tk/global.json b/webapp/src/translations/tk/global.json index 4ecedf8b..66657d3a 100644 --- a/webapp/src/translations/tk/global.json +++ b/webapp/src/translations/tk/global.json @@ -140,3 +140,20 @@ "enter_password_button":"Şifre Gönder" } } +, + "footer":{ + "about": "Hakkımızda", + "API": "API Belgeleri", + "ARC": "Arc42 Belgeleri" +}, + "about":{ + "hello": "Merhaba!", + "team": "Biz, en01b'den harika bir ekipiz! Oyunumuzu beğenmenizi umuyoruz.", + "name1": "Mario Junquera Rojas", + "name2": "Lucía Ruiz Núñez", + "name3": "Daniel Sinne Argüelles", + "name4": "Jorge Cano Martínez", + "name5": "Ahmet Erdem Yabacı", + "name6": "Laura Gómez Menéndez" +} + } \ No newline at end of file