From a17665ea302c442d997b802b9b36146c01f49bf8 Mon Sep 17 00:00:00 2001 From: JeanClement <jean-clement.gallardo@inrae.fr> Date: Fri, 14 Mar 2025 14:06:12 +0100 Subject: [PATCH] Add login logic --- LICENSE | 202 +++++++++++++++++++++ assets/main.css | 17 ++ components/usersUtilities/UserHomePage.vue | 50 ++++- components/usersUtilities/UserLogin.vue | 35 ++++ components/usersUtilities/UserNotLogin.vue | 32 ++++ components/utilities/HeaderBar.vue | 22 ++- components/utilities/Hero.vue | 1 - components/utilities/PageWithLeftBar.vue | 8 +- nuxt.config.ts | 1 + package-lock.json | 44 +++++ package.json | 2 + pages/users/index.vue | 5 +- stores/UserStore.ts | 18 ++ 13 files changed, 431 insertions(+), 6 deletions(-) create mode 100644 LICENSE create mode 100644 components/usersUtilities/UserLogin.vue create mode 100644 components/usersUtilities/UserNotLogin.vue create mode 100644 stores/UserStore.ts diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..a3761a1 --- /dev/null +++ b/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + https://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [2025] [INRAE] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/assets/main.css b/assets/main.css index 52e4054..40c850d 100644 --- a/assets/main.css +++ b/assets/main.css @@ -5,6 +5,23 @@ top: 0; } +.savgLoginMask { + position: fixed; + margin-left: auto; + z-index: 9999; + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0, 0.300); +} + +.savgLoginForm { + margin-top: 15%; + margin-left: auto; + margin-right: auto; + height: 350px; + width: 350px; +} + .savgUserPage { margin-top: 15px; margin-left: 270px; diff --git a/components/usersUtilities/UserHomePage.vue b/components/usersUtilities/UserHomePage.vue index 9589adc..cb10034 100644 --- a/components/usersUtilities/UserHomePage.vue +++ b/components/usersUtilities/UserHomePage.vue @@ -1,3 +1,51 @@ <template> - <h1 class="savgUserPage">Hello</h1> + <v-layout class="savgUserPage"> + <v-main :min-height="$vuetify.display.mdAndUp ? 800 : 550"> + <v-container class="h-100 d-flex align-top justify-center mb-4"> + <div class="w-50 text-left mt-16"> + <h1 class="text-h4 text-md-h2 font-weight-bold my-6"> + Welcome to your user profile + </h1> + + <div class="text-body-1 text-medium-emphasis mb-4"> + This page is dedicated to managing yours exports and collaborations that you have. <br> + If you want to start a new visualisation, go to the Graph visualisation page. <br> + If you want to see the community's creations, go to the Gallery page. + </div> + + <div class="mb-4 justify-center"> + <v-btn + class="text-none" + color="primary" + flat + rounded="lg" + text="Graph visualisation" + @click="navigateTo('/visualisation')" + /> + + <v-btn + append-icon="mdi-chevron-right" + class="text-none ml-2" + flat + rounded="lg" + text="Gallery" + @click="navigateTo('/gallery')" + /> + </div> + </div> + + <div class="w-50"> + <v-img + aspect-ratio="16/9" + cover + src="~/assets/images/recon2.BVytBvg-.jpeg" + /> + </div> + + <div class="v-bg position-absolute top-0 right-0 left-0 bottom-0"> + <div aria-hidden="true" class="overflow-hidden opacity-20 w-100 h-100" /> + </div> + </v-container> + </v-main> + </v-layout> </template> \ No newline at end of file diff --git a/components/usersUtilities/UserLogin.vue b/components/usersUtilities/UserLogin.vue new file mode 100644 index 0000000..56d14e1 --- /dev/null +++ b/components/usersUtilities/UserLogin.vue @@ -0,0 +1,35 @@ +<!-- + Copyright 2025 INRAE + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<!-- eslint-disable vue/multi-word-component-names --> +<template> + <div class="savgLoginMask"> + <v-card class="savgLoginForm" elevation="4"> + <v-card-title> + Login form + </v-card-title> + <v-btn @click="emit('login')">LOGIN</v-btn> + <v-btn @click="emit('cancel')">CANCEL</v-btn> + </v-card> + </div> +</template> + +<script setup lang="ts"> +const emit = defineEmits([ + 'login', + 'cancel' +]); +</script> diff --git a/components/usersUtilities/UserNotLogin.vue b/components/usersUtilities/UserNotLogin.vue new file mode 100644 index 0000000..02ae7fe --- /dev/null +++ b/components/usersUtilities/UserNotLogin.vue @@ -0,0 +1,32 @@ +<template> + <v-layout> + <v-main :min-height="$vuetify.display.mdAndUp ? 800 : 550"> + <v-container class="h-100 d-flex align-center justify-center mb-4 pb-16"> + <div class="w-100 text-center mt-16"> + <h1 class="text-h4 text-md-h2 font-weight-bold my-6"> + Access refused, you are not logged in. + </h1> + + <div class="text-body-1 text-medium-emphasis mb-4"> + To access the user page, please log in first. If you do no have an account, please go to <a target="_blank" href="http://147.100.181.110:8089/metexplore3/">MetExplore3</a> site to register. + </div> + + <div class="mb-4 justify-center align-center d-flex"> + <v-btn + class="text-none" + color="primary" + flat + rounded="lg" + text="Back home" + @click="navigateTo('/')" + /> + </div> + </div> + + <div class="v-bg position-absolute top-0 right-0 left-0 bottom-0"> + <div aria-hidden="true" class="overflow-hidden opacity-20 w-100 h-100" /> + </div> + </v-container> + </v-main> + </v-layout> +</template> \ No newline at end of file diff --git a/components/utilities/HeaderBar.vue b/components/utilities/HeaderBar.vue index 6a24518..8133c54 100644 --- a/components/utilities/HeaderBar.vue +++ b/components/utilities/HeaderBar.vue @@ -20,17 +20,26 @@ </div> <div class="d-flex flex-1-1-0 pe-3"> - <v-btn density="compact" append-icon="mdi-chevron-right" class="ms-auto text-none" slim text="Login" @click="navigateTo('/users')" /> + <v-btn v-if="!(useUserParams().getLoginState)" density="compact" append-icon="mdi-chevron-right" class="ms-auto text-none" slim text="Login" @click="properties.activeLogin = true" /> + <v-btn v-if="useUserParams().getLoginState" density="compact" append-icon="mdi-chevron-right" class="ms-auto text-none" slim text="User profile" @click="navigateTo('/users')" /> </div> </v-app-bar> </v-container> </div> + <UserLogin v-if="properties.activeLogin" @cancel="properties.activeLogin = false" @login="login" /> </template> <script setup lang="ts"> import { useRoute } from 'vue-router'; import { encodeBase64 } from '~/composables/useEncodeSvg'; +import { reactive } from 'vue'; +import UserLogin from '../usersUtilities/UserLogin.vue'; +import { useUserParams } from '~/stores/UserStore'; + +const properties = reactive({ + activeLogin: false +}); const route = useRoute(); @@ -41,5 +50,14 @@ const exportButton = computed(() => { } else { return false; } -}) +}); + +function login(): void { + useUserParams().userLogin(); + properties.activeLogin = false; + const path = route.fullPath; + if (path === "/") { + navigateTo('/users'); + } +} </script> \ No newline at end of file diff --git a/components/utilities/Hero.vue b/components/utilities/Hero.vue index afd49f2..d0a7fed 100644 --- a/components/utilities/Hero.vue +++ b/components/utilities/Hero.vue @@ -1,4 +1,3 @@ - <template> <v-layout> <v-main :min-height="$vuetify.display.mdAndUp ? 800 : 550"> diff --git a/components/utilities/PageWithLeftBar.vue b/components/utilities/PageWithLeftBar.vue index 51e57fa..87d0b84 100644 --- a/components/utilities/PageWithLeftBar.vue +++ b/components/utilities/PageWithLeftBar.vue @@ -4,7 +4,6 @@ <v-navigation-drawer> <v-list> <v-list-item - prepend-avatar="https://randomuser.me/api/portraits/women/85.jpg" subtitle="sandra_a88@gmailcom" title="Sandra Adams" ></v-list-item> @@ -16,6 +15,7 @@ <v-list-item prepend-icon="mdi-folder" title="My Exports" value="myExports"></v-list-item> <v-list-item prepend-icon="mdi-account-multiple" title="Shared with me" value="shared"></v-list-item> <v-list-item prepend-icon="mdi-star" title="Favorites" value="favorites"></v-list-item> + <v-list-item prepend-icon="mdi-logout" title="Logout" @click="logout"></v-list-item> </v-list> </v-navigation-drawer> <slot /> @@ -23,11 +23,17 @@ </template> <script setup lang="ts"> +import { useUserParams } from '~/stores/UserStore'; const userNav = reactive({itemActive: ''}); const emit = defineEmits([ 'changeUserPage' ]); +function logout(): void { + navigateTo('/'); + useUserParams().userLogout(); +} + watch(() => userNav.itemActive, (newActive) => { emit('changeUserPage', newActive[0]); }); diff --git a/nuxt.config.ts b/nuxt.config.ts index 4131b62..9a7fb86 100644 --- a/nuxt.config.ts +++ b/nuxt.config.ts @@ -6,6 +6,7 @@ export default defineNuxtConfig({ }, modules: [ + '@pinia/nuxt', (_options, nuxt) => { nuxt.hooks.hook('vite:extendConfig', (config) => { // @ts-expect-error diff --git a/package-lock.json b/package-lock.json index 52eb3c9..89763da 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,9 @@ "dependencies": { "@mdi/font": "^7.4.47", "@metabohub/mth-ui-viz": "^0.5.5", + "@pinia/nuxt": "^0.10.1", "nuxt": "^3.16.0", + "pinia": "^3.0.1", "vue": "^3.5.13", "vue-router": "^4.5.0" }, @@ -1928,6 +1930,20 @@ "url": "https://opencollective.com/parcel" } }, + "node_modules/@pinia/nuxt": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/@pinia/nuxt/-/nuxt-0.10.1.tgz", + "integrity": "sha512-xrpkKZHSmshPK6kQzboJ+TZiZ5zj73gBCI5SfiUaJkKKS9gx4B1hLEzJIjxZl0/HS5jRWrIvQ+u9ulvIRlNiow==", + "dependencies": { + "@nuxt/kit": "^3.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/posva" + }, + "peerDependencies": { + "pinia": "^3.0.1" + } + }, "node_modules/@pkgjs/parseargs": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", @@ -6930,6 +6946,34 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/pinia": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/pinia/-/pinia-3.0.1.tgz", + "integrity": "sha512-WXglsDzztOTH6IfcJ99ltYZin2mY8XZCXujkYWVIJlBjqsP6ST7zw+Aarh63E1cDVYeyUcPCxPHzJpEOmzB6Wg==", + "dependencies": { + "@vue/devtools-api": "^7.7.2" + }, + "funding": { + "url": "https://github.com/sponsors/posva" + }, + "peerDependencies": { + "typescript": ">=4.4.4", + "vue": "^2.7.0 || ^3.5.11" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/pinia/node_modules/@vue/devtools-api": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-7.7.2.tgz", + "integrity": "sha512-1syn558KhyN+chO5SjlZIwJ8bV/bQ1nOVTG66t2RbG66ZGekyiYNmRO7X9BJCXQqPsFHlnksqvPhce2qpzxFnA==", + "dependencies": { + "@vue/devtools-kit": "^7.7.2" + } + }, "node_modules/pkg-types": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-2.1.0.tgz", diff --git a/package.json b/package.json index 94869c4..2a884a4 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,9 @@ "dependencies": { "@mdi/font": "^7.4.47", "@metabohub/mth-ui-viz": "^0.5.5", + "@pinia/nuxt": "^0.10.1", "nuxt": "^3.16.0", + "pinia": "^3.0.1", "vue": "^3.5.13", "vue-router": "^4.5.0" }, diff --git a/pages/users/index.vue b/pages/users/index.vue index 9d52ebe..5a0c1cf 100644 --- a/pages/users/index.vue +++ b/pages/users/index.vue @@ -1,7 +1,10 @@ <template> - <UserPage /> + <UserPage v-if="useUserParams().getLoginState" /> + <UserNotLogin v-else /> </template> <script setup lang="ts"> import UserPage from '~/components/UserPage.vue'; +import UserNotLogin from '~/components/usersUtilities/UserNotLogin.vue'; +import { useUserParams } from '~/stores/UserStore'; </script> \ No newline at end of file diff --git a/stores/UserStore.ts b/stores/UserStore.ts new file mode 100644 index 0000000..7b63cfe --- /dev/null +++ b/stores/UserStore.ts @@ -0,0 +1,18 @@ +import { defineStore } from "pinia"; + +export const useUserParams = defineStore('userParams', { + state: () => ({ + login: false + }), + getters: { + getLoginState: (state) => state.login + }, + actions: { + userLogin() { + this.login = true; + }, + userLogout() { + this.login = false; + } + } +}); \ No newline at end of file -- GitLab