Move session management to sessionStore.
This commit is contained in:
parent
074fce7498
commit
6d2df5d44a
10 changed files with 105 additions and 73 deletions
|
|
@ -5,19 +5,19 @@ import { RouterView } from 'vue-router'
|
|||
import Footer from "@/components/Footer.vue";
|
||||
import Sidebar from "@/components/Sidebar.vue";
|
||||
import TopBar from "@/components/TopBar.vue";
|
||||
import { useUserStore } from "@/stores/userStore";
|
||||
import { useSessionStore } from "@/stores/sessionStore";
|
||||
|
||||
const userStore = useUserStore();
|
||||
const sessionStore = useSessionStore();
|
||||
|
||||
const sidebarSize = computed(() => {
|
||||
return userStore.isAnonymous ? '0' : '90px';
|
||||
return sessionStore.isAnonymous ? '0' : '90px';
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="act-layout">
|
||||
<TopBar class="act-header"></TopBar>
|
||||
<div class="act-sidebar" v-if="!userStore.isAnonymous">
|
||||
<div class="act-sidebar" v-if="!sessionStore.isAnonymous">
|
||||
<Sidebar></Sidebar>
|
||||
</div>
|
||||
<div class="act-content">
|
||||
|
|
|
|||
|
|
@ -6,15 +6,15 @@ import Avatar from 'primevue/avatar';
|
|||
import Menu from "primevue/menu";
|
||||
|
||||
import { userActions } from "@/stores/userActionsStore";
|
||||
import { useUserStore } from "@/stores/userStore";
|
||||
import { useSessionStore } from "@/stores/sessionStore";
|
||||
import Navigation from "@/components/Navigation.vue";
|
||||
|
||||
|
||||
const userStore = useUserStore();
|
||||
const sessionStore = useSessionStore();
|
||||
const router = useRouter();
|
||||
|
||||
const logout = () => {
|
||||
userStore.logout();
|
||||
sessionStore.logout();
|
||||
};
|
||||
const profile = () => {
|
||||
router.push({name: "profile"});
|
||||
|
|
@ -42,13 +42,13 @@ const toggle = (event) => { menu.value.toggle(event); };
|
|||
<Navigation></Navigation>
|
||||
<div class="mt-auto act-avatar">
|
||||
<a class="nav-item" @click="toggle">
|
||||
<div v-if="userStore.isAnonymous">
|
||||
<div v-if="sessionStore.isAnonymous">
|
||||
<Avatar icon="pi pi-user" size="large" shape="circle" />
|
||||
</div>
|
||||
<div v-else>
|
||||
<Avatar v-bind:label="userStore.initials" size="large" shape="circle" />
|
||||
<Avatar v-bind:label="sessionStore.initials" size="large" shape="circle" />
|
||||
</div>
|
||||
<span class="inline lg:hidden">{{ userStore.user.name }}</span>
|
||||
<span class="inline lg:hidden">{{ sessionStore.user.name }}</span>
|
||||
</a>
|
||||
<Menu ref="menu" id="overlay_menu" :model="items" :popup="true">
|
||||
<template #item="{ item, props }">
|
||||
|
|
@ -56,7 +56,7 @@ const toggle = (event) => { menu.value.toggle(event); };
|
|||
class="flex items-center"
|
||||
v-bind:class="{ 'act-useraction': item.needsAuth }"
|
||||
v-bind="props.action"
|
||||
v-if="!item.needsAuth || !userStore.isAnonymous">
|
||||
v-if="!item.needsAuth || !sessionStore.isAnonymous">
|
||||
<span v-bind:class="item.icon" />
|
||||
<span>{{ item.label }}</span>
|
||||
</a>
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import { ref, watch } from 'vue';
|
|||
import { useRouter } from "vue-router";
|
||||
import { useRoute } from 'vue-router';
|
||||
|
||||
import { useUserStore } from "@/stores/userStore";
|
||||
import { useSessionStore } from "@/stores/sessionStore";
|
||||
import { userActions } from "@/stores/userActionsStore";
|
||||
|
||||
import Button from 'primevue/button';
|
||||
|
|
@ -13,7 +13,7 @@ import Menu from "primevue/menu";
|
|||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
const page_title = ref();
|
||||
const userStore = useUserStore();
|
||||
const sessionStore = useSessionStore();
|
||||
|
||||
watch(() => route.meta, (newVal, oldVal) => {
|
||||
page_title.value = newVal.title;
|
||||
|
|
@ -23,7 +23,7 @@ const toggle = (event) => {
|
|||
menu.value.toggle(event);
|
||||
};
|
||||
const logout = () => {
|
||||
userStore.logout();
|
||||
sessionStore.logout();
|
||||
};
|
||||
const profile = () => {
|
||||
router.push({name: "profile"});
|
||||
|
|
@ -79,7 +79,7 @@ const items = ref(allActions);
|
|||
<Button
|
||||
as="router-link"
|
||||
:to="{name: 'login', query: {next: route.fullPath }}"
|
||||
v-if="userStore.isAnonymous">
|
||||
v-if="sessionStore.isAnonymous">
|
||||
<i class="pi pi-sign-in" />
|
||||
<span>Login</span>
|
||||
</Button>
|
||||
|
|
@ -108,7 +108,7 @@ const items = ref(allActions);
|
|||
class="flex items-center"
|
||||
v-bind:class="{ 'act-useraction': item.needsAuth }"
|
||||
v-bind="props.action"
|
||||
v-if="!item.needsAuth || !userStore.isAnonymous">
|
||||
v-if="!item.needsAuth || !sessionStore.isAnonymous">
|
||||
<span v-bind:class="item.icon" />
|
||||
<span>{{ item.label }}</span>
|
||||
</a>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { createRouter, createWebHistory } from 'vue-router'
|
||||
|
||||
import { useUserStore } from "@/stores/userStore";
|
||||
import { useSessionStore } from "@/stores/sessionStore";
|
||||
import AboutView from '../views/AboutView.vue'
|
||||
import HomeView from '../views/HomeView.vue'
|
||||
import LoginView from '../views/LoginView.vue'
|
||||
|
|
@ -73,18 +73,18 @@ const router = createRouter({
|
|||
})
|
||||
|
||||
router.beforeEach((to, from) => {
|
||||
const userStore= useUserStore();
|
||||
if (userStore.isAnonymous && to.name == 'home') {
|
||||
const sessionStore= useSessionStore();
|
||||
if (sessionStore.isAnonymous && to.name == 'home') {
|
||||
return {name: 'welcome'};
|
||||
} else if (!userStore.isAnonymous && to.name == 'welcome') {
|
||||
} else if (!sessionStore.isAnonymous && to.name == 'welcome') {
|
||||
return {name: 'home'};
|
||||
} else if (to.name == 'profile' && to.params.username == "") {
|
||||
if (userStore.isAnonymous) {
|
||||
if (sessionStore.isAnonymous) {
|
||||
return {name: 'home'};
|
||||
} else {
|
||||
// Send to "my" profile page.
|
||||
return {name: 'profile', params: {
|
||||
username: userStore.user.username,
|
||||
username: sessionStore.user.username,
|
||||
}};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
65
src/stores/sessionStore.ts
Normal file
65
src/stores/sessionStore.ts
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
import {acceptHMRUpdate, defineStore} from 'pinia'
|
||||
|
||||
|
||||
export interface User {
|
||||
name: string,
|
||||
sticker_ids: string[],
|
||||
username: string | null,
|
||||
};
|
||||
|
||||
const anonymous: User = {
|
||||
name: 'Anonymous',
|
||||
sticker_ids: [],
|
||||
username: null,
|
||||
};
|
||||
|
||||
export interface State {
|
||||
user: User,
|
||||
}
|
||||
|
||||
export const useSessionStore = defineStore('session', {
|
||||
actions: {
|
||||
async login(username: string, password: string) {
|
||||
const response = await fetch(
|
||||
`/api/login/${username}`, // TODO: Should not be in path.
|
||||
{
|
||||
method: 'POST',
|
||||
},
|
||||
);
|
||||
const json = await response.json();
|
||||
console.log('login', json);
|
||||
// this.user.name = json.name;
|
||||
this.user = {
|
||||
name: json.name,
|
||||
sticker_ids: json.sticker_ids,
|
||||
username: json.username,
|
||||
};
|
||||
},
|
||||
logout() {
|
||||
console.log('logout');
|
||||
// TODO: Tell server.
|
||||
this.user = anonymous;
|
||||
// this.hasChanged = true;
|
||||
// this.user.name = 'Anonymous';
|
||||
// this.$reset();
|
||||
// this.$patch({user: anonymous});
|
||||
},
|
||||
},
|
||||
getters: {
|
||||
initials: (state: State): string => {
|
||||
return state.user.name[0] || '';
|
||||
},
|
||||
isAnonymous: (state: State): boolean => {
|
||||
return state.user.name === 'Anonymous';
|
||||
},
|
||||
},
|
||||
state: (): State => {
|
||||
return {
|
||||
user: anonymous,
|
||||
};
|
||||
},
|
||||
})
|
||||
|
||||
if (import.meta.hot) {
|
||||
import.meta.hot.accept(acceptHMRUpdate(useSessionStore, import.meta.hot))
|
||||
}
|
||||
|
|
@ -45,7 +45,7 @@ export const useStickerStore = defineStore('sticker', {
|
|||
}
|
||||
this.put(this.sticker.uuid);
|
||||
const userStore= useUserStore();
|
||||
userStore.addSticker(this.sticker.uuid);
|
||||
userStore.addSticker(user.username, this.sticker.uuid);
|
||||
},
|
||||
},
|
||||
state: () => {
|
||||
|
|
|
|||
|
|
@ -9,21 +9,17 @@ export interface User {
|
|||
username: string | null,
|
||||
};
|
||||
|
||||
const anonymous: User = {
|
||||
name: 'Anonymous',
|
||||
sticker_ids: [],
|
||||
username: null,
|
||||
};
|
||||
|
||||
export interface State {
|
||||
user: User,
|
||||
users: User[],
|
||||
}
|
||||
|
||||
export const useUserStore = defineStore('user', {
|
||||
actions: {
|
||||
addSticker(uuid: string) {
|
||||
this.user.sticker_ids.push(uuid);
|
||||
addSticker(username: string, uuid: string) {
|
||||
let user = this.getUser(username);
|
||||
if (user) {
|
||||
user.sticker_ids.push(uuid);
|
||||
}
|
||||
},
|
||||
async fetch(username: string) {
|
||||
let user = this.getUser(username);
|
||||
|
|
@ -42,39 +38,8 @@ export const useUserStore = defineStore('user', {
|
|||
stickersStore.fetch(sticker_id);
|
||||
})
|
||||
},
|
||||
async login(username: string, password: string) {
|
||||
const response = await fetch(
|
||||
`/api/login/${username}`, // TODO: Should not be in path.
|
||||
{
|
||||
method: 'POST',
|
||||
},
|
||||
);
|
||||
const json = await response.json();
|
||||
console.log('login', json);
|
||||
// this.user.name = json.name;
|
||||
this.user = {
|
||||
name: json.name,
|
||||
sticker_ids: json.sticker_ids,
|
||||
username: json.username,
|
||||
};
|
||||
},
|
||||
logout() {
|
||||
console.log('logout');
|
||||
// TODO: Tell server.
|
||||
this.user = anonymous;
|
||||
// this.hasChanged = true;
|
||||
// this.user.name = 'Anonymous';
|
||||
// this.$reset();
|
||||
// this.$patch({user: anonymous});
|
||||
},
|
||||
},
|
||||
getters: {
|
||||
initials: (state: State): string => {
|
||||
return state.user.name[0] || '';
|
||||
},
|
||||
isAnonymous: (state: State): boolean => {
|
||||
return state.user.name === 'Anonymous';
|
||||
},
|
||||
getUser: (state: State) => {
|
||||
return (username: string): User | null => {
|
||||
return state.users.find((user: User) => user.username === username)
|
||||
|
|
@ -83,7 +48,6 @@ export const useUserStore = defineStore('user', {
|
|||
},
|
||||
state: (): State => {
|
||||
return {
|
||||
user: anonymous,
|
||||
users: [],
|
||||
};
|
||||
},
|
||||
|
|
|
|||
|
|
@ -8,9 +8,10 @@ import InputText from 'primevue/inputtext';
|
|||
import Message from 'primevue/message';
|
||||
import Toast from 'primevue/toast';
|
||||
|
||||
import { useUserStore } from "@/stores/userStore";
|
||||
import { useSessionStore } from "@/stores/sessionStore";
|
||||
|
||||
const userStore = useUserStore();
|
||||
|
||||
const sessionStore = useSessionStore();
|
||||
const username = ref();
|
||||
const password = ref();
|
||||
const router = useRouter();
|
||||
|
|
@ -22,7 +23,7 @@ function handleLogin({ valid }) {
|
|||
if (!valid) {
|
||||
return;
|
||||
}
|
||||
userStore.login(username.value, username.value).then(() => {
|
||||
sessionStore.login(username.value, username.value).then(() => {
|
||||
router.push(next);
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,10 +11,12 @@ import Panel from 'primevue/panel';
|
|||
import Timeline from 'primevue/timeline';
|
||||
|
||||
import Sticker from "@/components/Sticker.vue";
|
||||
import {useSessionStore} from "@/stores/sessionStore";
|
||||
import {type User, useUserStore} from "@/stores/userStore";
|
||||
import { useStickersStore } from "@/stores/stickersStore";
|
||||
|
||||
|
||||
const sessionStore = useSessionStore();
|
||||
const userStore = useUserStore();
|
||||
const { getUser } = userStore;
|
||||
const route = useRoute();
|
||||
|
|
@ -29,7 +31,7 @@ onMounted(async () => {
|
|||
});
|
||||
|
||||
const myPage = computed(() => {
|
||||
return !userStore.isAnonymous && userStore.user.username == user?.value.username;
|
||||
return !sessionStore.isAnonymous && sessionStore.user.username == user.value?.username;
|
||||
});
|
||||
|
||||
const meterValue = ref([
|
||||
|
|
|
|||
|
|
@ -4,11 +4,11 @@ import Button from 'primevue/button';
|
|||
import Panel from 'primevue/panel';
|
||||
import Sticker from "@/components/Sticker.vue";
|
||||
import { useRoute } from 'vue-router';
|
||||
import { useUserStore } from "@/stores/userStore";
|
||||
import { useSessionStore } from "@/stores/sessionStore";
|
||||
import { useStickerStore } from "@/stores/stickerStore";
|
||||
|
||||
const sessionStore = useSessionStore();
|
||||
const stickerStore = useStickerStore();
|
||||
const userStore = useUserStore();
|
||||
|
||||
const route = useRoute();
|
||||
const uuid = ref<string>(route.params.uuid as string);
|
||||
|
|
@ -28,7 +28,7 @@ const second = computed(() => {
|
|||
})
|
||||
|
||||
function claimSticker() {
|
||||
stickerStore.setOwner(userStore.user);
|
||||
stickerStore.setOwner(sessionStore.user);
|
||||
}
|
||||
|
||||
</script>
|
||||
|
|
@ -56,12 +56,12 @@ function claimSticker() {
|
|||
/>
|
||||
</div>
|
||||
<Button
|
||||
v-bind:disabled="userStore.isAnonymous"
|
||||
v-bind:disabled="sessionStore.isAnonymous"
|
||||
v-if="stickerStore.sticker?.owner == null"
|
||||
v-on:click="claimSticker">
|
||||
This is my sticker!
|
||||
</Button>
|
||||
<span v-if="userStore.isAnonymous">
|
||||
<span v-if="sessionStore.isAnonymous">
|
||||
Log in to claim your sticker.
|
||||
</span>
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Reference in a new issue