diff --git a/.gitignore b/.gitignore index 7c417fc..12bc57e 100644 --- a/.gitignore +++ b/.gitignore @@ -21,6 +21,7 @@ coverage .vscode/* !.vscode/extensions.json !.vscode/settings.json +!.vscode/launch.json .idea *.suo *.ntvs* diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..b6694d1 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,18 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "pwa-chrome", + "request": "launch", + "name": "Launch Chrome against localhost", + "url": "http://localhost:3000", + "webRoot": "${workspaceFolder}/src", + "sourceMapPathOverrides": { + "webpack:///src/*": "${webRoot}/*" + } + } + ] +} \ No newline at end of file diff --git a/src/components/Header/HeaderComponent.vue b/src/components/Header/HeaderComponent.vue index 8b4eab9..7759c84 100644 --- a/src/components/Header/HeaderComponent.vue +++ b/src/components/Header/HeaderComponent.vue @@ -23,21 +23,20 @@ - + diff --git a/src/data/Guild.ts b/src/data/Guild.ts index ffe40c0..7110304 100644 --- a/src/data/Guild.ts +++ b/src/data/Guild.ts @@ -2,6 +2,7 @@ type Guild = { id: string; name: string; iconUrl: string; + canManage: boolean; }; -export { Guild }; +export type { Guild }; diff --git a/src/data/InviteLink.ts b/src/data/InviteLink.ts new file mode 100644 index 0000000..1caea0d --- /dev/null +++ b/src/data/InviteLink.ts @@ -0,0 +1,5 @@ +type InviteLink = { + link: string; +}; + +export type { InviteLink }; diff --git a/src/main.ts b/src/main.ts index 99aa462..83d7b36 100644 --- a/src/main.ts +++ b/src/main.ts @@ -5,9 +5,13 @@ import vuetify from "./plugins/vuetify"; import { loadFonts } from "./plugins/webfontloader"; import { createPinia } from "pinia"; import piniaPluginPersistedstate from "pinia-plugin-persistedstate"; +import axios from "axios"; loadFonts(); const pinia = createPinia(); pinia.use(piniaPluginPersistedstate); +axios.defaults.baseURL = import.meta.env.VITE_API_BASE_URL; +axios.defaults.headers.post["Content-Type"] = "application/json"; + createApp(App).use(router).use(vuetify).use(pinia).mount("#app"); diff --git a/src/router/index.ts b/src/router/index.ts index 5616515..3ffd2a1 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -1,4 +1,8 @@ +import { logout } from "@/services/authService"; +import { getMutualGuilds } from "@/services/guildService"; +import { useMutualGuildsStore } from "@/stores/mutualGuilds"; import { useUserStore } from "@/stores/user"; +import GuildHomeViewVue from "@/views/GuildHomeView.vue"; import OauthCallbackViewVue from "@/views/oauth/OauthCallbackView.vue"; import OauthRedirectViewVue from "@/views/oauth/OauthRedirectView.vue"; import { createRouter, createWebHistory } from "vue-router"; @@ -21,6 +25,14 @@ const router = createRouter({ requiresAuth: false, }, }, + { + path: "/guild/:guildId", + name: "guildHome", + component: GuildHomeViewVue, + meta: { + requiresAuth: true, + }, + }, { path: "/oauth2/callback", name: "oauth-callback", @@ -43,8 +55,23 @@ const router = createRouter({ router.beforeEach((to, from) => { const store = useUserStore(); if (to.meta.requiresAuth && !store.isLoggedIn) { - (window).location = import.meta.env.VITE_OAUTH_REDIRECT_URL; - return false; + return { name: "oauth-redirect" }; + } else { + const mutualGuildsStore = useMutualGuildsStore(); + if (store.isLoggedIn) { + getMutualGuilds() + .then((value) => { + mutualGuildsStore.guilds = value; + mutualGuildsStore.loaded = true; + }) + .catch((reason) => { + if (reason?.response.status == 401) { + console.log("401, Login expired, logout..."); + logout(true, false); + router.push({ name: "home" }); + } + }); + } } }); diff --git a/src/services/authService.ts b/src/services/authService.ts index 1fc62ee..c2da45c 100644 --- a/src/services/authService.ts +++ b/src/services/authService.ts @@ -48,8 +48,6 @@ async function login(code: string): Promise { function logout(expired: boolean, loginFail: boolean): void { const userStore = useUserStore(); - const router = useRouter(); - userStore.token = ""; userStore.userName = ""; userStore.discordId = ""; @@ -57,11 +55,25 @@ function logout(expired: boolean, loginFail: boolean): void { userStore.asExpired = expired; const eventQueuStore = useEventQueuStore(); - eventQueuStore.push({ - uuid: undefined, - type: "success", - text: "Disconnected", - }); + if (!expired && !loginFail) { + eventQueuStore.push({ + uuid: undefined, + type: "success", + text: "Disconnected", + }); + } else if (expired) { + eventQueuStore.push({ + uuid: undefined, + type: "warning", + text: "Sesion expired, please re-login", + }); + } else { + eventQueuStore.push({ + uuid: undefined, + type: "error", + text: "Login fail, please try again", + }); + } } export { login, logout }; diff --git a/src/services/guildService.ts b/src/services/guildService.ts new file mode 100644 index 0000000..28bf93a --- /dev/null +++ b/src/services/guildService.ts @@ -0,0 +1,57 @@ +import type { Guild } from "@/data/Guild"; +import type { InviteLink } from "@/data/InviteLink"; +import { useEventQueuStore } from "@/stores/eventQueu"; +import { useUserStore } from "@/stores/user"; +import axios from "axios"; + +function getMutualGuilds(): Promise { + return new Promise((resolve, reject) => { + const userStore = useUserStore(); + + axios + .get("/guild/mutual", { + headers: { + authorization: `Bearer ${userStore.token}`, + }, + }) + .then((value) => { + console.log(value); + resolve(value.data); + }) + .catch((reason) => { + console.error(`Fail to get mutal guilds !`); + console.log(reason); + reject(reason); + }); + }); +} + +function getInviteLink(): Promise { + return new Promise((resolve, reject) => { + const userStore = useUserStore(); + + axios + .get("/guild/inviteLink", { + headers: { + authorization: `Bearer ${userStore.token}`, + }, + }) + .then((value) => { + console.log(value); + resolve(value.data); + }) + .catch((reason) => { + console.error(`Fail to get Invite !`); + console.log(reason); + const eventQueuStore = useEventQueuStore(); + eventQueuStore.push({ + uuid: undefined, + type: "error", + text: "Fail to retrive invite link !", + }); + reject(reason); + }); + }); +} + +export { getMutualGuilds, getInviteLink }; diff --git a/src/stores/counter.ts b/src/stores/counter.ts deleted file mode 100644 index 252406e..0000000 --- a/src/stores/counter.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { defineStore } from "pinia"; - -export const useCounterStore = defineStore({ - id: "counter", - state: () => ({ - counter: 0, - }), - getters: { - doubleCount: (state) => state.counter * 2, - }, - actions: { - increment() { - this.counter++; - }, - }, -}); diff --git a/src/stores/inviteLink.ts b/src/stores/inviteLink.ts new file mode 100644 index 0000000..7a1da6f --- /dev/null +++ b/src/stores/inviteLink.ts @@ -0,0 +1,15 @@ +import { defineStore } from "pinia"; + +export const useInviteLinkStore = defineStore({ + id: "inviteLink", + state: () => ({ + inviteLink: "", + }), + getters: { + isPresent(): boolean { + return !!this.inviteLink; + }, + }, + actions: {}, + persist: true, +}); diff --git a/src/stores/mutualGuilds.ts b/src/stores/mutualGuilds.ts new file mode 100644 index 0000000..b543514 --- /dev/null +++ b/src/stores/mutualGuilds.ts @@ -0,0 +1,18 @@ +import type { Guild } from "@/data/Guild"; +import { defineStore } from "pinia"; + +export const useMutualGuildsStore = defineStore({ + id: "mutualGuilds", + state: () => ({ + guilds: [] as Array, + loaded: false, + lastGuildId: "", + }), + getters: {}, + actions: { + getGuild(id: string): Guild | undefined { + return this.guilds.find((elem) => elem.id == id); + }, + }, + persist: true, +}); diff --git a/src/views/GuildHomeView.vue b/src/views/GuildHomeView.vue new file mode 100644 index 0000000..49827dd --- /dev/null +++ b/src/views/GuildHomeView.vue @@ -0,0 +1,11 @@ + + + + + diff --git a/src/views/HomeView.vue b/src/views/HomeView.vue index 6ecb962..044edf7 100644 --- a/src/views/HomeView.vue +++ b/src/views/HomeView.vue @@ -9,10 +9,23 @@