diff --git a/.vscode/extensions.json b/.vscode/extensions.json
index c0a6e5a..f6adb4b 100644
--- a/.vscode/extensions.json
+++ b/.vscode/extensions.json
@@ -1,3 +1,7 @@
{
- "recommendations": ["Vue.volar", "Vue.vscode-typescript-vue-plugin"]
-}
+ "recommendations": [
+ "Vue.volar",
+ "dbaeumer.vscode-eslint",
+ "vuetifyjs.vuetify-vscode"
+ ]
+}
\ No newline at end of file
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 63b9302..b305cf1 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -1,6 +1,7 @@
{
"editor.codeActionsOnSave": {
- "source.fixAll.eslint": "explicit"
+ "source.fixAll": "always",
+ "source.organizeImports": "always"
},
"eslint.validate": [
"javascript"
diff --git a/README.md b/README.md
index 7b23d92..4b1c5d4 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# Hutopia
-This template should help get you started developing with Vue 3 in Vite.
+Hutopia frontEnd. Using vue3 and vuetify3.
## Recommended IDE Setup
diff --git a/src/components/HelloWorld.vue b/src/components/HelloWorld.vue
deleted file mode 100644
index 5fb372c..0000000
--- a/src/components/HelloWorld.vue
+++ /dev/null
@@ -1,44 +0,0 @@
-
-
-
-
-
{{ msg }}
-
- You’ve successfully created a project with
- Vite +
- Vue 3.
-
-
-
-
-
diff --git a/src/components/TheWelcome.vue b/src/components/TheWelcome.vue
deleted file mode 100644
index dab9536..0000000
--- a/src/components/TheWelcome.vue
+++ /dev/null
@@ -1,88 +0,0 @@
-
-
-
-
-
-
-
- Documentation
-
- Vue’s
- official documentation
- provides you with all information you need to get started.
-
-
-
-
-
-
- Tooling
-
- This project is served and bundled with
- Vite. The
- recommended IDE setup is
- VSCode +
- Volar. If
- you need to test your components and web pages, check out
- Cypress and
- Cypress Component Testing.
-
-
-
- More instructions are available in README.md.
-
-
-
-
-
-
- Ecosystem
-
- Get official tools and libraries for your project:
- Pinia,
- Vue Router,
- Vue Test Utils, and
- Vue Dev Tools. If
- you need more resources, we suggest paying
- Awesome Vue
- a visit.
-
-
-
-
-
-
- Community
-
- Got stuck? Ask your question on
- Vue Land, our official
- Discord server, or
- StackOverflow. You should also subscribe to
- our mailing list and follow
- the official
- @vuejs
- twitter account for latest news in the Vue world.
-
-
-
-
-
-
- Support Vue
-
- As an independent project, Vue relies on community backing for its sustainability. You can help
- us by
- becoming a sponsor.
-
-
diff --git a/src/components/WelcomeItem.vue b/src/components/WelcomeItem.vue
deleted file mode 100644
index ac366d0..0000000
--- a/src/components/WelcomeItem.vue
+++ /dev/null
@@ -1,86 +0,0 @@
-
-
-
-
-
diff --git a/src/layouts/DefaultLayout.vue b/src/layouts/DefaultLayout.vue
index f66ede9..067885e 100644
--- a/src/layouts/DefaultLayout.vue
+++ b/src/layouts/DefaultLayout.vue
@@ -91,6 +91,10 @@
+
+ Hello, {{ user.email }}
+
+ Logout
@@ -112,14 +116,21 @@
+
+
\ No newline at end of file
diff --git a/src/main.js b/src/main.js
index 98db279..e55acf4 100644
--- a/src/main.js
+++ b/src/main.js
@@ -3,24 +3,25 @@ import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'
import router from './router'
-import axios from 'axios'
import '@mdi/font/css/materialdesignicons.css'
import 'vuetify/styles'
import { createVuetify } from 'vuetify'
import * as components from 'vuetify/components'
import * as directives from 'vuetify/directives'
+import clientPlugin from './plugins/clientPlugin'
const vuetify = createVuetify({
components,
directives
});
-axios.defaults.baseURL = 'http://127.0.0.1:8000';
-
const app = createApp(App);
+// Create an axios client preconfigured to the Hutopy API.
+app.use(clientPlugin);
+
app.use(createPinia());
app.use(vuetify);
-app.use(router, axios);
+app.use(router);
app.mount('#app')
diff --git a/src/plugins/clientPlugin.js b/src/plugins/clientPlugin.js
new file mode 100644
index 0000000..c5faed0
--- /dev/null
+++ b/src/plugins/clientPlugin.js
@@ -0,0 +1,34 @@
+import axios from "axios";
+import { inject } from 'vue';
+
+const clientKey = Symbol('client');
+
+export default {
+ //todo: Need to have the baseURL in the config for later ( dev and prod env. )
+ install: (app) => {
+ const axiosInstance = axios.create({
+ baseURL: 'https://localhost:5001/',
+ timeout: 2000,
+ });
+
+ axiosInstance.interceptors.request.use((config) => {
+ const token = localStorage.getItem('jwt');
+ if (token) {
+ config.headers.Authorization = `Bearer ${token}`;
+ }
+ return config;
+ }, (error) => {
+ return Promise.reject(error);
+ });
+
+ app.provide(clientKey, axiosInstance);
+ }
+};
+
+export function useClient() {
+ const client = inject(clientKey);
+ if (!client) {
+ throw new Error('Axios instance is not provided');
+ }
+ return client;
+}
\ No newline at end of file
diff --git a/src/plugins/store/authStore.js b/src/plugins/store/authStore.js
new file mode 100644
index 0000000..cf0fef0
--- /dev/null
+++ b/src/plugins/store/authStore.js
@@ -0,0 +1,55 @@
+import { defineStore } from 'pinia';
+
+const baseUrl = '/api/Users';
+
+export const useAuthStore = defineStore({
+ id: 'auth',
+ state: () => ({
+ user: null,
+ refreshTokenTimeout: null
+ }),
+ actions: {
+ async login(client, email, password) {
+ const requestBody = {
+ email: email,
+ password: password
+ };
+ try {
+ const response = await client.post(`${baseUrl}/login`, requestBody)
+ this.user = {
+ accessToken: response.data.accessToken,
+ refreshToken: response.data.refreshToken,
+ email: email
+ }
+ localStorage.setItem('jwt', this.user.accessToken);
+ this.startRefreshTokenTimer();
+ } catch (error) {
+ throw new Error('Login failed.')
+ }
+
+
+
+ },
+ logout() {
+ localStorage.setItem('jwt', '');
+ this.stopRefreshTokenTimer();
+ this.user = null;
+
+ },
+ async refreshToken(client) {
+ const response = await client.post(`${baseUrl}/refresh`, {});
+ this.user.accessToken = response.accessToken;
+ localStorage.setItem('jwt', this.user.accessToken);
+
+
+ this.startRefreshTokenTimer();
+ },
+ startRefreshTokenTimer() {
+ const timeout = 50 * 1000;
+ this.refreshTokenTimeout = setTimeout(this.refreshToken, timeout);
+ },
+ stopRefreshTokenTimer() {
+ clearTimeout(this.refreshTokenTimeout);
+ }
+ }
+});
\ No newline at end of file
diff --git a/src/views/LoginView.vue b/src/views/LoginView.vue
index 698e5cb..e2217a7 100644
--- a/src/views/LoginView.vue
+++ b/src/views/LoginView.vue
@@ -1,47 +1,66 @@
-
-
-
-
Log in
+
+
+
+
+
+ Login
+
+
+
+
+
+
+
+ Email ou mot de passe invalide.
+
+
+ Fermer
+
+
+
+
+
+
+ Login
+
+
+ Continuer sans se connecter
- Lorem Ipsum is simply dummy text of the printing and typesetting industry.
- Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer
- took a galley of type and scrambled it to make a type specimen book. It has survived not only five
- centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was
- popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more
- recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
+
+
+
+
+
-
Don't have an account ? Click
- here to create one!
-
-
+
\ No newline at end of file
diff --git a/src/views/main/HomeView.vue b/src/views/main/HomeView.vue
index e8972f9..3c5885a 100644
--- a/src/views/main/HomeView.vue
+++ b/src/views/main/HomeView.vue
@@ -340,35 +340,74 @@
+
+ Get items
+
-
-
+
+ Vous n'etes pas connecter !
+
+
+ Fermer
+
+
+ Se connecter
+
+
+
+
+
+
+
+
+
-
+let itemList = ref([]);
+let errorNoAccessSnackBar = ref(false);
-