diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..9e26dfee --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/docs/images/businesscontext.png b/docs/images/businesscontext.png new file mode 100644 index 00000000..1609bb98 Binary files /dev/null and b/docs/images/businesscontext.png differ diff --git a/docs/images/technicalcontext.png b/docs/images/technicalcontext.png new file mode 100644 index 00000000..3f41aa63 Binary files /dev/null and b/docs/images/technicalcontext.png differ diff --git a/docs/src/01_introduction_and_goals.adoc b/docs/src/01_introduction_and_goals.adoc index 661c7c68..5c1f62d8 100644 --- a/docs/src/01_introduction_and_goals.adoc +++ b/docs/src/01_introduction_and_goals.adoc @@ -2,93 +2,77 @@ ifndef::imagesdir[:imagesdir: ../images] [[section-introduction-and-goals]] == Introduction and Goals -[role="arc42help"] -**** -Describes the relevant requirements and the driving forces that software architects and development team must consider. -These include - -* underlying business goals, -* essential features, -* essential functional requirements, -* quality goals for the architecture and -* relevant stakeholders and their expectations -**** -=== Requirements Overview +WIQ! is a project developed for the subject "Software Architecture" of the Computer Engineering degree of the School of Computer Engineering of the University of Oviedo. This project is based on the wiq project, made available to the students by the teachers of the subject. +WIQ! has been commissioned to the company HappySw by RTVE, with the aim of recreating its famous quiz show Saber y ganar in a web version accessible to everyone. This project will be carried out by the development team is formed by: -[role="arc42help"] -**** -.Contents -Short description of the functional requirements, driving forces, extract (or abstract) -of requirements. Link to (hopefully existing) requirements documents -(with version number and information where to find it). +* Martín Cancio Barrera, mailto:UO287561@uniovi.es[_UO287561_]. -.Motivation -From the point of view of the end users a system is created or modified to -improve support of a business activity and/or improve the quality. +* Iyán Fernández Riol, mailto:UO288231@uniovi.es[_UO288231_]. -.Form -Short textual description, probably in tabular use-case format. -If requirements documents exist this overview should refer to these documents. +* Rodrigo García Iglesias, mailto:UO276396@uniovi.es[_UO276396_]. -Keep these excerpts as short as possible. Balance readability of this document with potential redundancy w.r.t to requirements documents. +* Alfredo Jirout Cid, mailto:UO288443@uniovi.es[_UO288443_]. +WIQ! is a software by means of which users can emulate being the participants of the quiz show Saber y ganar, which has numerous functionalities: -.Further Information +* Play several of the game modes seen on the show. -See https://docs.arc42.org/section-1/[Introduction and Goals] in the arc42 documentation. +* Register to be able to keep track of their statistics in the game -**** +* Play with friends -=== Quality Goals +* Adjust the themes of the questions, the answer time, the number of questions... +*** + +=== Requirements Overview + +* The system will have at least one web frontend that will be deployed and accessed via the web. +* Users will be able to register in the system and consult the history of their participation in the system: number of games, number of correct/failed questions, times, etc. +* Questions will be automatically generated from Wikidata data. +* Questions must be answered within a given time limit. +* Each question will have one correct answer and several incorrect or distracting answers. Both correct and incorrect answers will be generated automatically. +* The system shall allow access to user information through an API. +* The system shall allow access to the information of the generated questions through an API. -[role="arc42help"] -**** -.Contents -The top three (max five) quality goals for the architecture whose fulfillment is of highest importance to the major stakeholders. -We really mean quality goals for the architecture. Don't confuse them with project goals. -They are not necessarily identical. +=== Quality Goals -Consider this overview of potential topics (based upon the ISO 25010 standard): +[options="header"] +|=== +| Priority | Quality Goal | Motivation -image::01_2_iso-25010-topics-EN.drawio.png["Categories of Quality Requirements"] +| *1* +| *_Usability_* +| The application should be intuitive for users, making it easy for them to interact with the application regardless of their skills. -.Motivation -You should know the quality goals of your most important stakeholders, since they will influence fundamental architectural decisions. -Make sure to be very concrete about these qualities, avoid buzzwords. -If you as an architect do not know how the quality of your work will be judged... +| *2* +| *_Mantainability_* +| The application must have a well-defined and structured design, so that it is easy to make modifications and/or extensions. -.Form -A table with quality goals and concrete scenarios, ordered by priorities -**** +| *3* +| *_Privacy_* +| The application must guarantee the privacy of its users' information, with mechanisms in place to prevent intrusions into the system. +|=== === Stakeholders -[role="arc42help"] -**** -.Contents -Explicit overview of stakeholders of the system, i.e. all person, roles or organizations that +[options="header"] +|=== +|Role/Name|Contact|Expectations -* should know the architecture -* have to be convinced of the architecture -* have to work with the architecture or with code -* need the documentation of the architecture for their work -* have to come up with decisions about the system or its development +| *_Students (HappySw)_* +| Martín Cancio Barrera, Iyán Fernández Riol, Rodrigo García Iglesias and Alfredo Jirout Cid +| The students are the developers of the application. They are in charge of the complete development, which will improve their programming and teamwork skills. -.Motivation -You should know all parties involved in development of the system or affected by the system. -Otherwise, you may get nasty surprises later in the development process. -These stakeholders determine the extent and the level of detail of your work and its results. +| *_Users_* +| Anyone who uses the application +| Users are the ones who will ultimately use the application, so it must be intuitive and easy to understand. -.Form -Table with role names, person names, and their expectations with respect to the architecture and its documentation. -**** +| *_Teachers_* +| José Emilio Labra Gayo, Pablo González González, Jorge Álvarez Fidalgo and Cristian Augusto Alonso. +| They are the supervisors of the project, and will help the students toensure that the project comes to fruition. -[options="header",cols="1,2,2"] -|=== -|Role/Name|Contact|Expectations -| Alfredo Jirout Cid | UO288443@uniovi.es | Aprobar (opcional) -| Rodrigo Gracía Iglesias | UO276396@uniovi.es | No tomar de ejemplo a Miguel -| Iyán Fernández Riol | UO288231@uniovi.es | Sacar matricula -| Martín Cancio Barrera | UO287561@uniovi.es | Ser feliz +| *_RTVE_* +| RTVE +| They are the main stakeholders in the application, as they are the ones who commissioned it, so that their viewers can use it. |=== diff --git a/docs/src/02_architecture_constraints.adoc b/docs/src/02_architecture_constraints.adoc index 226e501f..de6edc58 100644 --- a/docs/src/02_architecture_constraints.adoc +++ b/docs/src/02_architecture_constraints.adoc @@ -3,25 +3,23 @@ ifndef::imagesdir[:imagesdir: ../images] [[section-architecture-constraints]] == Architecture Constraints +|=== +| *_Architecture constraint_* | *_Description_* -[role="arc42help"] -**** -.Contents -Any requirement that constraints software architects in their freedom of design and implementation decisions or decision about the development process. These constraints sometimes go beyond individual systems and are valid for whole organizations and companies. +| *_Tecnología de Desarrollo_* | The application must be developed using web technologies compatible with RTVE's requirements and standards. -.Motivation -Architects should know exactly where they are free in their design decisions and where they must adhere to constraints. -Constraints must always be dealt with; they may be negotiable, though. +| *_Plataforma de Implementación_* | The application must be implemented on a web hosting platform that meets RTVE's performance, security and scalability requirements. -.Form -Simple tables of constraints with explanations. -If needed you can subdivide them into -technical constraints, organizational and political constraints and -conventions (e.g. programming or versioning guidelines, documentation or naming conventions) +| *_Cumplimiento de Normativas de Privacidad_* | The architecture must ensure compliance with data privacy regulations, such as GDPR, to protect users' information. +| *_Compatibilidad con Navegadores_* | The application should be compatible with a wide range of popular web browsers to ensure a consistent user experience. -.Further Information +| *_Seguridad de la Información_* | Strong security measures, such as user authentication, access control and data encryption, must be implemented to protect users' confidential information. -See https://docs.arc42.org/section-2/[Architecture Constraints] in the arc42 documentation. +| *_Escalabilidad_* | The architecture must be scalable to handle increased user traffic without compromising performance. -**** +| *_Mantenibilidad del Código_* | Software development practices that promote clean and well-documented code should be followed to facilitate future upgrades and maintenance. + +| *_Tiempo de Desarrollo_* | The application must be developed within a specific time frame, which may influence architectural decisions and technology selection. + +|=== diff --git a/docs/src/03_system_scope_and_context.adoc b/docs/src/03_system_scope_and_context.adoc index c528e907..af83295e 100644 --- a/docs/src/03_system_scope_and_context.adoc +++ b/docs/src/03_system_scope_and_context.adoc @@ -3,73 +3,8 @@ ifndef::imagesdir[:imagesdir: ../images] [[section-system-scope-and-context]] == System Scope and Context - -[role="arc42help"] -**** -.Contents -System scope and context - as the name suggests - delimits your system (i.e. your scope) from all its communication partners -(neighboring systems and users, i.e. the context of your system). It thereby specifies the external interfaces. - -If necessary, differentiate the business context (domain specific inputs and outputs) from the technical context (channels, protocols, hardware). - -.Motivation -The domain interfaces and technical interfaces to communication partners are among your system's most critical aspects. Make sure that you completely understand them. - -.Form -Various options: - -* Context diagrams -* Lists of communication partners and their interfaces. - - -.Further Information - -See https://docs.arc42.org/section-3/[Context and Scope] in the arc42 documentation. - -**** - - === Business Context - -[role="arc42help"] -**** -.Contents -Specification of *all* communication partners (users, IT-systems, ...) with explanations of domain specific inputs and outputs or interfaces. -Optionally you can add domain specific formats or communication protocols. - -.Motivation -All stakeholders should understand which data are exchanged with the environment of the system. - -.Form -All kinds of diagrams that show the system as a black box and specify the domain interfaces to communication partners. - -Alternatively (or additionally) you can use a table. -The title of the table is the name of your system, the three columns contain the name of the communication partner, the inputs, and the outputs. - -**** - -**** - -**** +image::businesscontext.png[Business context] === Technical Context - -[role="arc42help"] -**** -.Contents -Technical interfaces (channels and transmission media) linking your system to its environment. In addition a mapping of domain specific input/output to the channels, i.e. an explanation which I/O uses which channel. - -.Motivation -Many stakeholders make architectural decision based on the technical interfaces between the system and its context. Especially infrastructure or hardware designers decide these technical interfaces. - -.Form -E.g. UML deployment diagram describing channels to neighboring systems, -together with a mapping table showing the relationships between channels and input/output. - -**** - -**** - -**** - -**** +image::technicalcontext.png[Technical Context] diff --git a/docs/src/08_concepts.adoc b/docs/src/08_concepts.adoc index 591ccf1f..a3e657b5 100644 --- a/docs/src/08_concepts.adoc +++ b/docs/src/08_concepts.adoc @@ -56,18 +56,62 @@ See https://docs.arc42.org/section-8/[Concepts] in the arc42 documentation. **** -=== __ +=== __ -__ +__ +=== __ +__ -=== __ +=== __ + +__ + +=== __ + +__ + +=== __ + +__ + +=== __ + +_<- Build: This stage involves compiling, validating, and packaging the source code into executable or deployable artifacts. +- Test: This stage involves running various tests, such as unit tests, integration tests, and regression tests, to ensure the quality and functionality of the software. +- Deploy: This stage involves delivering or releasing the software to the target environment, such as a server, a cloud platform, or a user device. >_ + +=== __ + +__ + +=== __ + +__ + +=== __ + +__ + +=== __ + +__ + +=== __ + +__ + +=== __ + +__ + +=== __ + +__ -__ -... -=== __ +=== __ __ diff --git a/docs/src/10_quality_requirements.adoc b/docs/src/10_quality_requirements.adoc index 68475e80..e978d021 100644 --- a/docs/src/10_quality_requirements.adoc +++ b/docs/src/10_quality_requirements.adoc @@ -3,71 +3,52 @@ ifndef::imagesdir[:imagesdir: ../images] [[section-quality-scenarios]] == Quality Requirements +In our project, we have some quality goals or expectations that we want to be met. +These are: -[role="arc42help"] -**** +* Performance: ability of the software system to respond well to user interactions and perform tasks efficiently. -.Content -This section contains all quality requirements as quality tree with scenarios. The most important ones have already been described in section 1.2. (quality goals) +* Security: protection of the system from unauthorized access, data breaches, and malicious activities, ensuring safety of sensitive information. -Here you can also capture quality requirements with lesser priority, -which will not create high risks when they are not fully achieved. +* Usability: intuitiveness of the software interface, making it easy for users to interact with the system. -.Motivation -Since quality requirements will have a lot of influence on architectural -decisions you should know for every stakeholder what is really important to them, -concrete and measurable. +* Maintainability: how easily the software system can be modified, updated, and extended without significant effort or risk. -.Further Information - -See https://docs.arc42.org/section-10/[Quality Requirements] in the arc42 documentation. - -**** - === Quality Tree -[role="arc42help"] -**** -.Content -The quality tree (as defined in ATAM – Architecture Tradeoff Analysis Method) with quality/evaluation scenarios as leafs. - -.Motivation -The tree structure with priorities provides an overview for a sometimes large number of quality requirements. - -.Form -The quality tree is a high-level overview of the quality goals and requirements: +* Quality + - Performance + - Security + - Usability + - Maintainability -* tree-like refinement of the term "quality". Use "quality" or "usefulness" as a root -* a mind map with quality categories as main branches - -In any case the tree should include links to the scenarios of the following section. - - -**** +* Relationships + - Quality -> Performance + - Quality -> Security + - Quality -> Usability + - Quality -> Maintainability === Quality Scenarios -[role="arc42help"] -**** -.Contents -Concretization of (sometimes vague or implicit) quality requirements using (quality) scenarios. - -These scenarios describe what should happen when a stimulus arrives at the system. - -For architects, two kinds of scenarios are important: +### Usage Scenarios -* Usage scenarios (also called application scenarios or use case scenarios) describe the system’s runtime reaction to a certain stimulus. This also includes scenarios that describe the system’s efficiency or performance. Example: The system reacts to a user’s request within one second. -* Change scenarios describe a modification of the system or of its immediate environment. Example: Additional functionality is implemented or requirements for a quality attribute change. +[options="header"] +|=== +|Aspect|Source|Stimulus|Artefact|Environment|Response|Response Measurement +| Performance |User |While playing, a user selects a response to a question.|User Interface|Normal gameplay conditions.|The system updates its interface very fast and the user knows if they responded correctly, so they can keep playing.|Interface update time is less than 0.5 seconds. +|Security|User|A new user registers in the game by providing their username and password.|Encrypting system|User registration process.|The server encrypts the user's password before storing it in the MongoDB database, so it is safe from data leaks.|Passwords are encrypted using a strong hashing algorithm. +|Usability|User|A new user starts playing the game.|User Interface|Initial game setup.|The user interface displays available options and provides clear instructions on how to play, including a 'Help' button.|User can navigate through the interface without guidance. +|Performance|User|A user finishes playing a game and wants to start a new one.|System and User Interface|Post-game completion.|The system ends the current game, displays the user's score, resets all game elements, and offers the option to start a new game.|Score is saved accurately, and game restarts without errors. +|=== -.Motivation -Scenarios make quality requirements concrete and allow to -more easily measure or decide whether they are fulfilled. -Especially when you want to assess your architecture using methods like -ATAM you need to describe your quality goals (from section 1.2) -more precisely down to a level of scenarios that can be discussed and evaluated. +### Change Scenarios -.Form -Tabular or free form text. -**** +[options="header"] +|=== +| Aspect | Source | Stimulus | Artefact | Environment | Response | Response Measurement +| Security / Maintainability | Developers | We want to add the option of logging in with an e-mail instead of an username | Login system is well structured so it is easy to modify it or add new ways of logging in | Normal conditions | The development team implements the new login method easily, ensuring that neither the current data or the new credentials will be compromised | Successful integration of the new login method without compromising data +| Security | Developers | The decision is made to transition from MongoDB to another database system | User data migration to a new database system is secured | Database migration phase | The system initiates a secure data migration process, ensuring all user data, including usernames and passwords, is transferred to the new database system intact and encrypted | Successful transfer of user data without compromise +| Maintainability | Developers | Developers want to add a new game mode | The game's code is well-structured and documented | Development phase | Due to code being well-structured and documented, it is easy to add new functionality to our system without risking our already implemented functionality | Successful addition of new game mode +| Maintainability | Developers | An error is identified in the game that needs to be corrected. | The game's code is well-structured and documented | Error identification and resolution phase | Due to code being well-structured and documented, developers can easily locate the error and correct it | Successful identification and correction of the error \ No newline at end of file diff --git a/docs/src/12_glossary.adoc b/docs/src/12_glossary.adoc index 192b2353..810bb367 100644 --- a/docs/src/12_glossary.adoc +++ b/docs/src/12_glossary.adoc @@ -3,40 +3,49 @@ ifndef::imagesdir[:imagesdir: ../images] [[section-glossary]] == Glossary -[role="arc42help"] -**** -.Contents -The most important domain and technical terms that your stakeholders use when discussing the system. +[cols="e,2e" options="header"] +|=== +|Term |Definition -You can also see the glossary as source for translations if you work in multi-language teams. +|Quality Tree +| Structured representation of quality attributes and their relationships. -.Motivation -You should clearly define your terms, so that all stakeholders +|Quality Scenarios +| Specific instances or situations that show the behavior of a system under various quality attributes. -* have an identical understanding of these terms -* do not use synonyms and homonyms +|Change Scenarios +| Scenarios depicting how a system responds or adapts to changes, like fixes or addings. +|Usage Scenarios +| Instances demonstrating how users interact with a system in various contexts. -.Form +|User Interface +| The visual and interactive part of a computer program or system through which users interact. -A table with columns and . +|Query +| Request for information from a database. -Potentially more columns in case you need translations. +|Database +| Organized collection of structured information. +|Documentation +| Written information regarding a system's design, functionality, or usage. -.Further Information +|NodeJS +| Runtime environment that allows the execution of JavaScript code outside of a web browser. -See https://docs.arc42.org/section-12/[Glossary] in the arc42 documentation. +|ReactJS +| JavaScript library for building user interfaces, particularly single-page applications. -**** +|JavaScript +| High-level programming language primarily used for creating interactive web pages and applications. -[cols="e,2e" options="header"] -|=== -|Term |Definition +|MongoDB +| Popular NoSQL database program, known for its flexibility and scalability. -| -| +|CSS +| Cascading Style Sheets, used for styling and formatting web pages written in HTML. -| -| +|HTML +| Hypertext Markup Language, the standard markup language for creating web pages and web applications. |=== diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 00000000..1c5472ed --- /dev/null +++ b/package-lock.json @@ -0,0 +1,441 @@ +{ + "name": "wiq_es1a", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "dependencies": { + "react-auth-kit": "^3.0.2-alpha.19" + } + }, + "node_modules/@next/env": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@next/env/-/env-14.1.0.tgz", + "integrity": "sha512-Py8zIo+02ht82brwwhTg36iogzFqGLPXlRGKQw5s+qP/kMNc4MAyDeEwBKDijk6zTIbegEgu8Qy7C1LboslQAw==", + "peer": true + }, + "node_modules/@next/swc-darwin-arm64": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.1.0.tgz", + "integrity": "sha512-nUDn7TOGcIeyQni6lZHfzNoo9S0euXnu0jhsbMOmMJUBfgsnESdjN97kM7cBqQxZa8L/bM9om/S5/1dzCrW6wQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "peer": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-darwin-x64": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.1.0.tgz", + "integrity": "sha512-1jgudN5haWxiAl3O1ljUS2GfupPmcftu2RYJqZiMJmmbBT5M1XDffjUtRUzP4W3cBHsrvkfOFdQ71hAreNQP6g==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "peer": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-gnu": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.1.0.tgz", + "integrity": "sha512-RHo7Tcj+jllXUbK7xk2NyIDod3YcCPDZxj1WLIYxd709BQ7WuRYl3OWUNG+WUfqeQBds6kvZYlc42NJJTNi4tQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-musl": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.1.0.tgz", + "integrity": "sha512-v6kP8sHYxjO8RwHmWMJSq7VZP2nYCkRVQ0qolh2l6xroe9QjbgV8siTbduED4u0hlk0+tjS6/Tuy4n5XCp+l6g==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-gnu": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.1.0.tgz", + "integrity": "sha512-zJ2pnoFYB1F4vmEVlb/eSe+VH679zT1VdXlZKX+pE66grOgjmKJHKacf82g/sWE4MQ4Rk2FMBCRnX+l6/TVYzQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-musl": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.1.0.tgz", + "integrity": "sha512-rbaIYFt2X9YZBSbH/CwGAjbBG2/MrACCVu2X0+kSykHzHnYH5FjHxwXLkcoJ10cX0aWCEynpu+rP76x0914atg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-arm64-msvc": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.1.0.tgz", + "integrity": "sha512-o1N5TsYc8f/HpGt39OUQpQ9AKIGApd3QLueu7hXk//2xq5Z9OxmV6sQfNp8C7qYmiOlHYODOGqNNa0e9jvchGQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "peer": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-ia32-msvc": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.1.0.tgz", + "integrity": "sha512-XXIuB1DBRCFwNO6EEzCTMHT5pauwaSj4SWs7CYnME57eaReAKBXCnkUE80p/pAZcewm7hs+vGvNqDPacEXHVkw==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "peer": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-x64-msvc": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.1.0.tgz", + "integrity": "sha512-9WEbVRRAqJ3YFVqEZIxUqkiO8l1nool1LmNxygr5HWF8AcSYsEpneUDhmjUVJEzO2A04+oPtZdombzzPPkTtgg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "peer": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@swc/helpers": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.2.tgz", + "integrity": "sha512-E4KcWTpoLHqwPHLxidpOqQbcrZVgi0rsmmZXUle1jXmJfuIf/UWpczUJ7MZZ5tlxytgJXyp0w4PGkkeLiuIdZw==", + "peer": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/busboy": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", + "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", + "peer": true, + "dependencies": { + "streamsearch": "^1.1.0" + }, + "engines": { + "node": ">=10.16.0" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001583", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001583.tgz", + "integrity": "sha512-acWTYaha8xfhA/Du/z4sNZjHUWjkiuoAi2LM+T/aL+kemKQgPT1xBb/YKjlQ0Qo8gvbHsGNplrEJ+9G3gL7i4Q==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "peer": true + }, + "node_modules/client-only": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", + "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==", + "peer": true + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "peer": true + }, + "node_modules/js-cookie": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.5.tgz", + "integrity": "sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==", + "engines": { + "node": ">=14" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "peer": true + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "peer": true, + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "peer": true, + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/next": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/next/-/next-14.1.0.tgz", + "integrity": "sha512-wlzrsbfeSU48YQBjZhDzOwhWhGsy+uQycR8bHAOt1LY1bn3zZEcDyHQOEoN3aWzQ8LHCAJ1nqrWCc9XF2+O45Q==", + "peer": true, + "dependencies": { + "@next/env": "14.1.0", + "@swc/helpers": "0.5.2", + "busboy": "1.6.0", + "caniuse-lite": "^1.0.30001579", + "graceful-fs": "^4.2.11", + "postcss": "8.4.31", + "styled-jsx": "5.1.1" + }, + "bin": { + "next": "dist/bin/next" + }, + "engines": { + "node": ">=18.17.0" + }, + "optionalDependencies": { + "@next/swc-darwin-arm64": "14.1.0", + "@next/swc-darwin-x64": "14.1.0", + "@next/swc-linux-arm64-gnu": "14.1.0", + "@next/swc-linux-arm64-musl": "14.1.0", + "@next/swc-linux-x64-gnu": "14.1.0", + "@next/swc-linux-x64-musl": "14.1.0", + "@next/swc-win32-arm64-msvc": "14.1.0", + "@next/swc-win32-ia32-msvc": "14.1.0", + "@next/swc-win32-x64-msvc": "14.1.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.1.0", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "sass": "^1.3.0" + }, + "peerDependenciesMeta": { + "@opentelemetry/api": { + "optional": true + }, + "sass": { + "optional": true + } + } + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "peer": true + }, + "node_modules/postcss": { + "version": "8.4.31", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", + "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "peer": true, + "dependencies": { + "nanoid": "^3.3.6", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/react": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", + "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", + "peer": true, + "dependencies": { + "loose-envify": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-auth-kit": { + "version": "3.0.2-alpha.19", + "resolved": "https://registry.npmjs.org/react-auth-kit/-/react-auth-kit-3.0.2-alpha.19.tgz", + "integrity": "sha512-xZStv05wItit/AN2qgSErYCtpn9u8rr3cpgMxG8ZOkJMcYa4wvFPkYoAWT5rkOuP85fp9B0AqGb5tUen0B5yeg==", + "dependencies": { + "js-cookie": "^3.0.1", + "rxjs": "^7.8.1" + }, + "peerDependencies": { + "next": ">=13.0 || ^14.x", + "react": ">=16.8.0 || ^17.x || ^18.x", + "react-dom": ">=16.8.0 || ^17.x || ^18.x" + } + }, + "node_modules/react-dom": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", + "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==", + "peer": true, + "dependencies": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.0" + }, + "peerDependencies": { + "react": "^18.2.0" + } + }, + "node_modules/rxjs": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/scheduler": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", + "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==", + "peer": true, + "dependencies": { + "loose-envify": "^1.1.0" + } + }, + "node_modules/source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/streamsearch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", + "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", + "peer": true, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/styled-jsx": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.1.tgz", + "integrity": "sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw==", + "peer": true, + "dependencies": { + "client-only": "0.0.1" + }, + "engines": { + "node": ">= 12.0.0" + }, + "peerDependencies": { + "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "babel-plugin-macros": { + "optional": true + } + } + }, + "node_modules/tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 00000000..2d4da84c --- /dev/null +++ b/package.json @@ -0,0 +1,5 @@ +{ + "dependencies": { + "react-auth-kit": "^3.0.2-alpha.19" + } +} diff --git a/webapp/package-lock.json b/webapp/package-lock.json index 27466aee..d3aef19f 100644 --- a/webapp/package-lock.json +++ b/webapp/package-lock.json @@ -8,6 +8,7 @@ "name": "webapp", "version": "0.1.0", "dependencies": { + "@auth-kit/react-router": "^3.0.2-alpha.19", "@emotion/react": "^11.11.3", "@emotion/styled": "^11.11.0", "@mui/material": "^5.15.3", @@ -16,7 +17,9 @@ "@testing-library/user-event": "^14.5.2", "axios": "^1.6.5", "react": "^18.2.0", + "react-auth-kit": "^3.0.2-alpha.19", "react-dom": "^18.2.0", + "react-router-dom": "^6.22.0", "react-scripts": "5.0.1", "web-vitals": "^3.5.1" }, @@ -68,6 +71,18 @@ "node": ">=6.0.0" } }, + "node_modules/@auth-kit/react-router": { + "version": "3.0.2-alpha.19", + "resolved": "https://registry.npmjs.org/@auth-kit/react-router/-/react-router-3.0.2-alpha.19.tgz", + "integrity": "sha512-EK69EVVJd6y84VwE8GqNQtui+fQhMlkkSiaTleW8fHR8i+N7Ydwjgq2gTPiZokEfKzTk0X5lp7/0KEIChXS6EQ==", + "dependencies": { + "react-auth-kit": "^3.0.2-alpha.19" + }, + "peerDependencies": { + "react": ">=16.8.0 || ^17.x || ^18.x", + "react-router": ">=6.x" + } + }, "node_modules/@babel/code-frame": { "version": "7.23.5", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", @@ -4752,6 +4767,156 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" }, + "node_modules/@next/env": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@next/env/-/env-14.1.0.tgz", + "integrity": "sha512-Py8zIo+02ht82brwwhTg36iogzFqGLPXlRGKQw5s+qP/kMNc4MAyDeEwBKDijk6zTIbegEgu8Qy7C1LboslQAw==", + "peer": true + }, + "node_modules/@next/swc-darwin-arm64": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.1.0.tgz", + "integrity": "sha512-nUDn7TOGcIeyQni6lZHfzNoo9S0euXnu0jhsbMOmMJUBfgsnESdjN97kM7cBqQxZa8L/bM9om/S5/1dzCrW6wQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "peer": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-darwin-x64": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.1.0.tgz", + "integrity": "sha512-1jgudN5haWxiAl3O1ljUS2GfupPmcftu2RYJqZiMJmmbBT5M1XDffjUtRUzP4W3cBHsrvkfOFdQ71hAreNQP6g==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "peer": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-gnu": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.1.0.tgz", + "integrity": "sha512-RHo7Tcj+jllXUbK7xk2NyIDod3YcCPDZxj1WLIYxd709BQ7WuRYl3OWUNG+WUfqeQBds6kvZYlc42NJJTNi4tQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-musl": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.1.0.tgz", + "integrity": "sha512-v6kP8sHYxjO8RwHmWMJSq7VZP2nYCkRVQ0qolh2l6xroe9QjbgV8siTbduED4u0hlk0+tjS6/Tuy4n5XCp+l6g==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-gnu": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.1.0.tgz", + "integrity": "sha512-zJ2pnoFYB1F4vmEVlb/eSe+VH679zT1VdXlZKX+pE66grOgjmKJHKacf82g/sWE4MQ4Rk2FMBCRnX+l6/TVYzQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-musl": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.1.0.tgz", + "integrity": "sha512-rbaIYFt2X9YZBSbH/CwGAjbBG2/MrACCVu2X0+kSykHzHnYH5FjHxwXLkcoJ10cX0aWCEynpu+rP76x0914atg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-arm64-msvc": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.1.0.tgz", + "integrity": "sha512-o1N5TsYc8f/HpGt39OUQpQ9AKIGApd3QLueu7hXk//2xq5Z9OxmV6sQfNp8C7qYmiOlHYODOGqNNa0e9jvchGQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "peer": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-ia32-msvc": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.1.0.tgz", + "integrity": "sha512-XXIuB1DBRCFwNO6EEzCTMHT5pauwaSj4SWs7CYnME57eaReAKBXCnkUE80p/pAZcewm7hs+vGvNqDPacEXHVkw==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "peer": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-x64-msvc": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.1.0.tgz", + "integrity": "sha512-9WEbVRRAqJ3YFVqEZIxUqkiO8l1nool1LmNxygr5HWF8AcSYsEpneUDhmjUVJEzO2A04+oPtZdombzzPPkTtgg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "peer": true, + "engines": { + "node": ">= 10" + } + }, "node_modules/@nicolo-ribaudo/eslint-scope-5-internals": { "version": "5.1.1-v1", "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz", @@ -5005,6 +5170,14 @@ "node": ">=12" } }, + "node_modules/@remix-run/router": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.15.0.tgz", + "integrity": "sha512-HOil5aFtme37dVQTB6M34G95kPM3MMuqSmIRVCC52eKV+Y/tGSqw9P3rWhlAx6A+mz+MoX+XxsGsNJbaI5qCgQ==", + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@rollup/plugin-babel": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz", @@ -5354,6 +5527,15 @@ "url": "https://github.com/sponsors/gregberge" } }, + "node_modules/@swc/helpers": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.2.tgz", + "integrity": "sha512-E4KcWTpoLHqwPHLxidpOqQbcrZVgi0rsmmZXUle1jXmJfuIf/UWpczUJ7MZZ5tlxytgJXyp0w4PGkkeLiuIdZw==", + "peer": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, "node_modules/@testing-library/dom": { "version": "9.3.3", "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-9.3.3.tgz", @@ -7729,6 +7911,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/busboy": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", + "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", + "peer": true, + "dependencies": { + "streamsearch": "^1.1.0" + }, + "engines": { + "node": ">=10.16.0" + } + }, "node_modules/bytes": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", @@ -7818,9 +8012,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001576", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001576.tgz", - "integrity": "sha512-ff5BdakGe2P3SQsMsiqmt1Lc8221NR1VzHj5jXN5vBny9A6fpze94HiVV/n7XRosOlsShJcvMv5mdnpjOGCEgg==", + "version": "1.0.30001583", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001583.tgz", + "integrity": "sha512-acWTYaha8xfhA/Du/z4sNZjHUWjkiuoAi2LM+T/aL+kemKQgPT1xBb/YKjlQ0Qo8gvbHsGNplrEJ+9G3gL7i4Q==", "funding": [ { "type": "opencollective", @@ -8124,6 +8318,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/client-only": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", + "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==", + "peer": true + }, "node_modules/clipboardy": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/clipboardy/-/clipboardy-3.0.0.tgz", @@ -18233,6 +18433,14 @@ "@sideway/pinpoint": "^2.0.0" } }, + "node_modules/js-cookie": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.5.tgz", + "integrity": "sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==", + "engines": { + "node": ">=14" + } + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -19207,6 +19415,80 @@ "node": ">=12.22.0" } }, + "node_modules/next": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/next/-/next-14.1.0.tgz", + "integrity": "sha512-wlzrsbfeSU48YQBjZhDzOwhWhGsy+uQycR8bHAOt1LY1bn3zZEcDyHQOEoN3aWzQ8LHCAJ1nqrWCc9XF2+O45Q==", + "peer": true, + "dependencies": { + "@next/env": "14.1.0", + "@swc/helpers": "0.5.2", + "busboy": "1.6.0", + "caniuse-lite": "^1.0.30001579", + "graceful-fs": "^4.2.11", + "postcss": "8.4.31", + "styled-jsx": "5.1.1" + }, + "bin": { + "next": "dist/bin/next" + }, + "engines": { + "node": ">=18.17.0" + }, + "optionalDependencies": { + "@next/swc-darwin-arm64": "14.1.0", + "@next/swc-darwin-x64": "14.1.0", + "@next/swc-linux-arm64-gnu": "14.1.0", + "@next/swc-linux-arm64-musl": "14.1.0", + "@next/swc-linux-x64-gnu": "14.1.0", + "@next/swc-linux-x64-musl": "14.1.0", + "@next/swc-win32-arm64-msvc": "14.1.0", + "@next/swc-win32-ia32-msvc": "14.1.0", + "@next/swc-win32-x64-msvc": "14.1.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.1.0", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "sass": "^1.3.0" + }, + "peerDependenciesMeta": { + "@opentelemetry/api": { + "optional": true + }, + "sass": { + "optional": true + } + } + }, + "node_modules/next/node_modules/postcss": { + "version": "8.4.31", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", + "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "peer": true, + "dependencies": { + "nanoid": "^3.3.6", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, "node_modules/nice-try": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", @@ -21862,6 +22144,20 @@ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" }, + "node_modules/react-auth-kit": { + "version": "3.0.2-alpha.19", + "resolved": "https://registry.npmjs.org/react-auth-kit/-/react-auth-kit-3.0.2-alpha.19.tgz", + "integrity": "sha512-xZStv05wItit/AN2qgSErYCtpn9u8rr3cpgMxG8ZOkJMcYa4wvFPkYoAWT5rkOuP85fp9B0AqGb5tUen0B5yeg==", + "dependencies": { + "js-cookie": "^3.0.1", + "rxjs": "^7.8.1" + }, + "peerDependencies": { + "next": ">=13.0 || ^14.x", + "react": ">=16.8.0 || ^17.x || ^18.x", + "react-dom": ">=16.8.0 || ^17.x || ^18.x" + } + }, "node_modules/react-dev-utils": { "version": "12.0.1", "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-12.0.1.tgz", @@ -22009,6 +22305,36 @@ "node": ">=0.10.0" } }, + "node_modules/react-router": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.22.0.tgz", + "integrity": "sha512-q2yemJeg6gw/YixRlRnVx6IRJWZD6fonnfZhN1JIOhV2iJCPeRNSH3V1ISwHf+JWcESzLC3BOLD1T07tmO5dmg==", + "dependencies": { + "@remix-run/router": "1.15.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8" + } + }, + "node_modules/react-router-dom": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.22.0.tgz", + "integrity": "sha512-z2w+M4tH5wlcLmH3BMMOMdrtrJ9T3oJJNsAlBJbwk+8Syxd5WFJ7J5dxMEW0/GEXD1BBis4uXRrNIz3mORr0ag==", + "dependencies": { + "@remix-run/router": "1.15.0", + "react-router": "6.22.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8", + "react-dom": ">=16.8" + } + }, "node_modules/react-scripts": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-5.0.1.tgz", @@ -23755,7 +24081,6 @@ "version": "7.8.1", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", - "dev": true, "dependencies": { "tslib": "^2.1.0" } @@ -25246,6 +25571,15 @@ "duplexer": "~0.1.1" } }, + "node_modules/streamsearch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", + "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", + "peer": true, + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/streamx": { "version": "2.15.6", "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.15.6.tgz", @@ -25485,6 +25819,29 @@ "webpack": "^5.0.0" } }, + "node_modules/styled-jsx": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.1.tgz", + "integrity": "sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw==", + "peer": true, + "dependencies": { + "client-only": "0.0.1" + }, + "engines": { + "node": ">= 12.0.0" + }, + "peerDependencies": { + "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "babel-plugin-macros": { + "optional": true + } + } + }, "node_modules/stylehacks": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.1.1.tgz", diff --git a/webapp/package.json b/webapp/package.json index 74e31bee..44fe9415 100644 --- a/webapp/package.json +++ b/webapp/package.json @@ -3,6 +3,7 @@ "version": "0.1.0", "private": true, "dependencies": { + "@auth-kit/react-router": "^3.0.2-alpha.19", "@emotion/react": "^11.11.3", "@emotion/styled": "^11.11.0", "@mui/material": "^5.15.3", @@ -11,7 +12,9 @@ "@testing-library/user-event": "^14.5.2", "axios": "^1.6.5", "react": "^18.2.0", + "react-auth-kit": "^3.0.2-alpha.19", "react-dom": "^18.2.0", + "react-router-dom": "^6.22.0", "react-scripts": "5.0.1", "web-vitals": "^3.5.1" }, diff --git a/webapp/src/App.css b/webapp/src/App.css index 74b5e053..a3cbc06b 100644 --- a/webapp/src/App.css +++ b/webapp/src/App.css @@ -1,38 +1,40 @@ -.App { - text-align: center; -} - -.App-logo { - height: 40vmin; - pointer-events: none; -} - -@media (prefers-reduced-motion: no-preference) { - .App-logo { - animation: App-logo-spin infinite 20s linear; - } -} - -.App-header { - background-color: #282c34; - min-height: 100vh; +#root{ + height: 100vh; display: flex; flex-direction: column; align-items: center; - justify-content: center; - font-size: calc(10px + 2vmin); - color: white; + text-align: center; + justify-content: space-between; +} + +h1{ + text-align: center; } -.App-link { - color: #61dafb; +input, button, a{ + appearance: none; + background-color: transparent; + border: 0.13rem solid #0F0F0F; + border-radius: 15px; + box-sizing: border-box; + color: #0F0F0F; + padding: 1rem; + text-align: center; + text-decoration: none; + transition: all 300ms cubic-bezier(.23, 1, 0.32, 1); + user-select: none; + -webkit-user-select: none; + touch-action: manipulation; + width: 100%; + will-change: transform; + -webkit-box-shadow: 10px 10px 6px 0px rgba(0,255,192,1); + -moz-box-shadow: 10px 10px 6px 0px rgba(0,255,192,1); + box-shadow: 5px 5px 6px 0px rgba(0,255,192,1); + margin: 1rem; } -@keyframes App-logo-spin { - from { - transform: rotate(0deg); - } - to { - transform: rotate(360deg); - } +input:hover, button:hover, a:hover { + background-color: #00ffc0; + -webkit-box-shadow: 0 0 0 0 #000,0 0 0 2px #00ffc0; + box-shadow: 0 0 0 0 #000,0 0 0 2px #00ffc0 } diff --git a/webapp/src/App.js b/webapp/src/App.js index d932005b..c37a947f 100644 --- a/webapp/src/App.js +++ b/webapp/src/App.js @@ -1,38 +1,41 @@ import React, { useState } from 'react'; -import AddUser from './components/AddUser'; -import Login from './components/Login'; -import CssBaseline from '@mui/material/CssBaseline'; -import Container from '@mui/material/Container'; -import Typography from '@mui/material/Typography'; -import Link from '@mui/material/Link'; +import Authenticate from './pages/Authenticate/Authenticate.js'; +import Home from './pages/Home/Home.js'; +import Clasico from './pages/Clasico/Clasico.js'; +import WrongRoute from './pages/WrongRoute/WrongRoute.js'; +import './App.css'; -function App() { - const [showLogin, setShowLogin] = useState(true); +import {BrowserRouter, Routes, Route} from "react-router-dom"; +import AuthProvider from 'react-auth-kit'; +import AuthOutlet from '@auth-kit/react-router/AuthOutlet'; +import createStore from 'react-auth-kit/createStore'; - const handleToggleView = () => { - setShowLogin(!showLogin); - }; +const store = createStore({ + authName:'_auth', + authType:'cookie', + cookieDomain: window.location.hostname, + cookieSecure: window.location.protocol === 'https:' +}) + + const App = () => { + return ( + + + + {/** Rutas públicas */} + }/> + + {/** Rutas privadas */} + }> + } /> + } /> + - return ( - - - - Welcome to the 2024 edition of the Software Architecture course - - {showLogin ? : } - - {showLogin ? ( - - Don't have an account? Register here. - - ) : ( - - Already have an account? Login here. - - )} - - - ); -} + } /> + + + + ); + }; export default App; diff --git a/webapp/src/components/Footer/Footer.css b/webapp/src/components/Footer/Footer.css new file mode 100644 index 00000000..c422f99e --- /dev/null +++ b/webapp/src/components/Footer/Footer.css @@ -0,0 +1,3 @@ +footer{ + margin: 3rem; +} \ No newline at end of file diff --git a/webapp/src/components/Footer/Footer.js b/webapp/src/components/Footer/Footer.js new file mode 100644 index 00000000..7198079f --- /dev/null +++ b/webapp/src/components/Footer/Footer.js @@ -0,0 +1,14 @@ +import React from 'react'; +import { Link } from "react-router-dom"; +import './Footer.css'; + +const Footer = () => { + return( +
+

WIQ!

+

Copyright 2024 ® Grupo 1A de Arquitectura del Software

+
+ ); +} + +export default Footer; \ No newline at end of file diff --git a/webapp/src/components/Login/Login.css b/webapp/src/components/Login/Login.css new file mode 100644 index 00000000..c73fe721 --- /dev/null +++ b/webapp/src/components/Login/Login.css @@ -0,0 +1,13 @@ +.login-container { + display: grid; + grid-template-columns: 1fr; + gap: 1rem; +} + +.login-container h1{ + text-align: center; +} + +a{ + box-shadow: none; +} \ No newline at end of file diff --git a/webapp/src/components/Login.js b/webapp/src/components/Login/Login.js similarity index 54% rename from webapp/src/components/Login.js rename to webapp/src/components/Login/Login.js index 0ad6268e..e6a85166 100644 --- a/webapp/src/components/Login.js +++ b/webapp/src/components/Login/Login.js @@ -2,30 +2,48 @@ import React, { useState } from 'react'; import axios from 'axios'; import { Container, Typography, TextField, Button, Snackbar } from '@mui/material'; +import { useNavigate } from "react-router-dom"; +import useSignIn from 'react-auth-kit/hooks/useSignIn'; +import './Login.css'; const Login = () => { + const signIn = useSignIn(); const [username, setUsername] = useState(''); const [password, setPassword] = useState(''); + const [token, setToken] = useState(''); const [error, setError] = useState(''); const [loginSuccess, setLoginSuccess] = useState(false); const [createdAt, setCreatedAt] = useState(''); const [openSnackbar, setOpenSnackbar] = useState(false); + const navigate = useNavigate(); + const apiEndpoint = process.env.REACT_APP_API_ENDPOINT || 'http://localhost:8000'; const loginUser = async () => { try { const response = await axios.post(`${apiEndpoint}/login`, { username, password }); - + console.log(response); // Extract data from the response const { createdAt: userCreatedAt } = response.data; + setToken(response.data.token); + + signIn({ + auth: { + token: token + }, + userState: {name: username} + }) setCreatedAt(userCreatedAt); setLoginSuccess(true); setOpenSnackbar(true); + + navigate('/home') } catch (error) { - setError(error.response.data.error); + //console.log(error); + //setError(error.response.data.error); } }; @@ -34,47 +52,50 @@ const Login = () => { }; return ( - +
{loginSuccess ? (
- +

Hello {username}! - - +

+

Your account was created on {new Date(createdAt).toLocaleDateString()}. - +

) : ( -
- - Login - - +

Login

+ setUsername(e.target.value)} /> - setPassword(e.target.value)} /> - - + + {openSnackbar && ( +
+ Login successful +
+ )} {error && ( - setError('')} message={`Error: ${error}`} /> +
+ Error: {error} +
)} -
+ )} - - ); -}; +
+ ) +} export default Login; diff --git a/webapp/src/components/Login.test.js b/webapp/src/components/Login/Login.test.js similarity index 100% rename from webapp/src/components/Login.test.js rename to webapp/src/components/Login/Login.test.js diff --git a/webapp/src/components/Nav/Nav.css b/webapp/src/components/Nav/Nav.css new file mode 100644 index 00000000..cbb4329b --- /dev/null +++ b/webapp/src/components/Nav/Nav.css @@ -0,0 +1,33 @@ +.logo{ + font-family: oswald,sans-serif; + width: 100%; + font-size: 5rem; + font-weight: 700; + margin: 0; + text-shadow: 4px 4px 0 #00ffc0; +} + +nav{ + width: 80vw; + display: flex; + flex-wrap: wrap; + border: 3px solid #0F0F0F; + border-radius: 1rem; + padding: 1rem; + margin: 1rem; + justify-content: center; + -webkit-box-shadow: 10px 10px 6px 0px rgba(0,255,192,1); + -moz-box-shadow: 10px 10px 6px 0px rgba(0,255,192,1); + box-shadow: 10px 10px 5px 0px rgba(0,255,192,1); +} + +nav ul{ + display: flex; + justify-content: center; + flex-direction: row; +} + +nav li{ + display: flex; + flex-direction: row; +} \ No newline at end of file diff --git a/webapp/src/components/Nav/Nav.js b/webapp/src/components/Nav/Nav.js new file mode 100644 index 00000000..95d8f951 --- /dev/null +++ b/webapp/src/components/Nav/Nav.js @@ -0,0 +1,17 @@ +import React from 'react'; +import { Link } from "react-router-dom"; +import './Nav.css'; + +const Nav = () => { + return( + + ); +} + +export default Nav; \ No newline at end of file diff --git a/webapp/src/components/Preguntas.js b/webapp/src/components/Preguntas.js new file mode 100644 index 00000000..3083f529 --- /dev/null +++ b/webapp/src/components/Preguntas.js @@ -0,0 +1,56 @@ +const Preguntas = [ + { + pregunta: "¿Cuál es la capital de Francia?", + respuestas: ["Londres", "París", "Madrid", "Roma"], + respuestaCorrecta: "París" + }, + { + pregunta: "¿Cuál es el río más largo del mundo?", + respuestas: ["Amazonas", "Nilo", "Misisipi", "Yangtsé"], + respuestaCorrecta: "Amazonas" + } + //, + // { + // pregunta: "¿Cuál es el océano más grande?", + // respuestas: ["Pacífico", "Atlántico", "Índico", "Ártico"], + // respuestaCorrecta: "Pacífico" + // }, + // { + // pregunta: "¿Quién escribió 'Don Quijote de la Mancha'?", + // respuestas: ["Miguel de Cervantes", "Gabriel García Márquez", "William Shakespeare", "Leo Tolstoy"], + // respuestaCorrecta: "Miguel de Cervantes" + // }, + // { + // pregunta: "¿Cuál es el elemento más abundante en la Tierra?", + // respuestas: ["Hierro", "Oxígeno", "Hidrógeno", "Silicio"], + // respuestaCorrecta: "Oxígeno" + // }, + // { + // pregunta: "¿Cuál es el país más poblado del mundo?", + // respuestas: ["India", "China", "Estados Unidos", "Brasil"], + // respuestaCorrecta: "China" + // }, + // { + // pregunta: "¿Quién pintó la 'Mona Lisa'?", + // respuestas: ["Leonardo da Vinci", "Pablo Picasso", "Vincent van Gogh", "Rembrandt"], + // respuestaCorrecta: "Leonardo da Vinci" + // }, + // { + // pregunta: "¿Cuál es el hueso más largo del cuerpo humano?", + // respuestas: ["Fémur", "Tibia", "Húmero", "Radio"], + // respuestaCorrecta: "Fémur" + // }, + // { + // pregunta: "¿Quién fue el primer presidente de Estados Unidos?", + // respuestas: ["George Washington", "Thomas Jefferson", "Abraham Lincoln", "John Adams"], + // respuestaCorrecta: "George Washington" + // }, + // { + // pregunta: "¿Cuál es la montaña más alta del mundo?", + // respuestas: ["Monte Everest", "Monte Kilimanjaro", "Monte McKinley", "Monte Aconcagua"], + // respuestaCorrecta: "Monte Everest" + // } +]; + +export default Preguntas; + \ No newline at end of file diff --git a/webapp/src/components/AddUser.js b/webapp/src/components/Register/Register.js similarity index 100% rename from webapp/src/components/AddUser.js rename to webapp/src/components/Register/Register.js diff --git a/webapp/src/components/AddUser.test.js b/webapp/src/components/Register/Register.test.js similarity index 100% rename from webapp/src/components/AddUser.test.js rename to webapp/src/components/Register/Register.test.js diff --git a/webapp/src/pages/Authenticate/Authenticate.js b/webapp/src/pages/Authenticate/Authenticate.js new file mode 100644 index 00000000..5ebf98de --- /dev/null +++ b/webapp/src/pages/Authenticate/Authenticate.js @@ -0,0 +1,43 @@ +import React, { useState } from 'react'; +import AddUser from '../../components/Register/Register'; +import Login from '../../components/Login/Login'; +import CssBaseline from '@mui/material/CssBaseline'; +import Container from '@mui/material/Container'; +import Typography from '@mui/material/Typography'; +import Link from '@mui/material/Link'; +import Footer from '../../components/Footer/Footer.js'; + +import { BrowserRouter as Router, Route, Redirect } from 'react-router-dom'; +import { PrivateRoute, useAuth } from 'react-auth-kit'; + +function Authenticate() { + const [showLogin, setShowLogin] = useState(true); + + const handleToggleView = () => { + setShowLogin(!showLogin); + }; + + return ( + + + + Bienvenido a WIQ + + {showLogin ? : } + + {showLogin ? ( + + ¿No tienes cuenta? Regístrate. + + ) : ( + + Ya tienes cuenta? Inicia sesión. + + )} + +