1
0
Fork 0

Move session management to sessionStore.

This commit is contained in:
Brian D 2024-12-01 20:54:21 -05:00
parent 074fce7498
commit 6d2df5d44a
10 changed files with 105 additions and 73 deletions

View file

@ -5,19 +5,19 @@ import { RouterView } from 'vue-router'
import Footer from "@/components/Footer.vue"; import Footer from "@/components/Footer.vue";
import Sidebar from "@/components/Sidebar.vue"; import Sidebar from "@/components/Sidebar.vue";
import TopBar from "@/components/TopBar.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(() => { const sidebarSize = computed(() => {
return userStore.isAnonymous ? '0' : '90px'; return sessionStore.isAnonymous ? '0' : '90px';
}); });
</script> </script>
<template> <template>
<div class="act-layout"> <div class="act-layout">
<TopBar class="act-header"></TopBar> <TopBar class="act-header"></TopBar>
<div class="act-sidebar" v-if="!userStore.isAnonymous"> <div class="act-sidebar" v-if="!sessionStore.isAnonymous">
<Sidebar></Sidebar> <Sidebar></Sidebar>
</div> </div>
<div class="act-content"> <div class="act-content">

View file

@ -6,15 +6,15 @@ import Avatar from 'primevue/avatar';
import Menu from "primevue/menu"; import Menu from "primevue/menu";
import { userActions } from "@/stores/userActionsStore"; import { userActions } from "@/stores/userActionsStore";
import { useUserStore } from "@/stores/userStore"; import { useSessionStore } from "@/stores/sessionStore";
import Navigation from "@/components/Navigation.vue"; import Navigation from "@/components/Navigation.vue";
const userStore = useUserStore(); const sessionStore = useSessionStore();
const router = useRouter(); const router = useRouter();
const logout = () => { const logout = () => {
userStore.logout(); sessionStore.logout();
}; };
const profile = () => { const profile = () => {
router.push({name: "profile"}); router.push({name: "profile"});
@ -42,13 +42,13 @@ const toggle = (event) => { menu.value.toggle(event); };
<Navigation></Navigation> <Navigation></Navigation>
<div class="mt-auto act-avatar"> <div class="mt-auto act-avatar">
<a class="nav-item" @click="toggle"> <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" /> <Avatar icon="pi pi-user" size="large" shape="circle" />
</div> </div>
<div v-else> <div v-else>
<Avatar v-bind:label="userStore.initials" size="large" shape="circle" /> <Avatar v-bind:label="sessionStore.initials" size="large" shape="circle" />
</div> </div>
<span class="inline lg:hidden">{{ userStore.user.name }}</span> <span class="inline lg:hidden">{{ sessionStore.user.name }}</span>
</a> </a>
<Menu ref="menu" id="overlay_menu" :model="items" :popup="true"> <Menu ref="menu" id="overlay_menu" :model="items" :popup="true">
<template #item="{ item, props }"> <template #item="{ item, props }">
@ -56,7 +56,7 @@ const toggle = (event) => { menu.value.toggle(event); };
class="flex items-center" class="flex items-center"
v-bind:class="{ 'act-useraction': item.needsAuth }" v-bind:class="{ 'act-useraction': item.needsAuth }"
v-bind="props.action" v-bind="props.action"
v-if="!item.needsAuth || !userStore.isAnonymous"> v-if="!item.needsAuth || !sessionStore.isAnonymous">
<span v-bind:class="item.icon" /> <span v-bind:class="item.icon" />
<span>{{ item.label }}</span> <span>{{ item.label }}</span>
</a> </a>

View file

@ -3,7 +3,7 @@ import { ref, watch } from 'vue';
import { useRouter } from "vue-router"; import { useRouter } from "vue-router";
import { useRoute } from 'vue-router'; import { useRoute } from 'vue-router';
import { useUserStore } from "@/stores/userStore"; import { useSessionStore } from "@/stores/sessionStore";
import { userActions } from "@/stores/userActionsStore"; import { userActions } from "@/stores/userActionsStore";
import Button from 'primevue/button'; import Button from 'primevue/button';
@ -13,7 +13,7 @@ import Menu from "primevue/menu";
const route = useRoute(); const route = useRoute();
const router = useRouter(); const router = useRouter();
const page_title = ref(); const page_title = ref();
const userStore = useUserStore(); const sessionStore = useSessionStore();
watch(() => route.meta, (newVal, oldVal) => { watch(() => route.meta, (newVal, oldVal) => {
page_title.value = newVal.title; page_title.value = newVal.title;
@ -23,7 +23,7 @@ const toggle = (event) => {
menu.value.toggle(event); menu.value.toggle(event);
}; };
const logout = () => { const logout = () => {
userStore.logout(); sessionStore.logout();
}; };
const profile = () => { const profile = () => {
router.push({name: "profile"}); router.push({name: "profile"});
@ -79,7 +79,7 @@ const items = ref(allActions);
<Button <Button
as="router-link" as="router-link"
:to="{name: 'login', query: {next: route.fullPath }}" :to="{name: 'login', query: {next: route.fullPath }}"
v-if="userStore.isAnonymous"> v-if="sessionStore.isAnonymous">
<i class="pi pi-sign-in" /> <i class="pi pi-sign-in" />
<span>Login</span> <span>Login</span>
</Button> </Button>
@ -108,7 +108,7 @@ const items = ref(allActions);
class="flex items-center" class="flex items-center"
v-bind:class="{ 'act-useraction': item.needsAuth }" v-bind:class="{ 'act-useraction': item.needsAuth }"
v-bind="props.action" v-bind="props.action"
v-if="!item.needsAuth || !userStore.isAnonymous"> v-if="!item.needsAuth || !sessionStore.isAnonymous">
<span v-bind:class="item.icon" /> <span v-bind:class="item.icon" />
<span>{{ item.label }}</span> <span>{{ item.label }}</span>
</a> </a>

View file

@ -1,6 +1,6 @@
import { createRouter, createWebHistory } from 'vue-router' import { createRouter, createWebHistory } from 'vue-router'
import { useUserStore } from "@/stores/userStore"; import { useSessionStore } from "@/stores/sessionStore";
import AboutView from '../views/AboutView.vue' import AboutView from '../views/AboutView.vue'
import HomeView from '../views/HomeView.vue' import HomeView from '../views/HomeView.vue'
import LoginView from '../views/LoginView.vue' import LoginView from '../views/LoginView.vue'
@ -73,18 +73,18 @@ const router = createRouter({
}) })
router.beforeEach((to, from) => { router.beforeEach((to, from) => {
const userStore= useUserStore(); const sessionStore= useSessionStore();
if (userStore.isAnonymous && to.name == 'home') { if (sessionStore.isAnonymous && to.name == 'home') {
return {name: 'welcome'}; return {name: 'welcome'};
} else if (!userStore.isAnonymous && to.name == 'welcome') { } else if (!sessionStore.isAnonymous && to.name == 'welcome') {
return {name: 'home'}; return {name: 'home'};
} else if (to.name == 'profile' && to.params.username == "") { } else if (to.name == 'profile' && to.params.username == "") {
if (userStore.isAnonymous) { if (sessionStore.isAnonymous) {
return {name: 'home'}; return {name: 'home'};
} else { } else {
// Send to "my" profile page. // Send to "my" profile page.
return {name: 'profile', params: { return {name: 'profile', params: {
username: userStore.user.username, username: sessionStore.user.username,
}}; }};
} }
} }

View 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))
}

View file

@ -45,7 +45,7 @@ export const useStickerStore = defineStore('sticker', {
} }
this.put(this.sticker.uuid); this.put(this.sticker.uuid);
const userStore= useUserStore(); const userStore= useUserStore();
userStore.addSticker(this.sticker.uuid); userStore.addSticker(user.username, this.sticker.uuid);
}, },
}, },
state: () => { state: () => {

View file

@ -9,21 +9,17 @@ export interface User {
username: string | null, username: string | null,
}; };
const anonymous: User = {
name: 'Anonymous',
sticker_ids: [],
username: null,
};
export interface State { export interface State {
user: User,
users: User[], users: User[],
} }
export const useUserStore = defineStore('user', { export const useUserStore = defineStore('user', {
actions: { actions: {
addSticker(uuid: string) { addSticker(username: string, uuid: string) {
this.user.sticker_ids.push(uuid); let user = this.getUser(username);
if (user) {
user.sticker_ids.push(uuid);
}
}, },
async fetch(username: string) { async fetch(username: string) {
let user = this.getUser(username); let user = this.getUser(username);
@ -42,39 +38,8 @@ export const useUserStore = defineStore('user', {
stickersStore.fetch(sticker_id); 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: { getters: {
initials: (state: State): string => {
return state.user.name[0] || '';
},
isAnonymous: (state: State): boolean => {
return state.user.name === 'Anonymous';
},
getUser: (state: State) => { getUser: (state: State) => {
return (username: string): User | null => { return (username: string): User | null => {
return state.users.find((user: User) => user.username === username) return state.users.find((user: User) => user.username === username)
@ -83,7 +48,6 @@ export const useUserStore = defineStore('user', {
}, },
state: (): State => { state: (): State => {
return { return {
user: anonymous,
users: [], users: [],
}; };
}, },

View file

@ -8,9 +8,10 @@ import InputText from 'primevue/inputtext';
import Message from 'primevue/message'; import Message from 'primevue/message';
import Toast from 'primevue/toast'; 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 username = ref();
const password = ref(); const password = ref();
const router = useRouter(); const router = useRouter();
@ -22,7 +23,7 @@ function handleLogin({ valid }) {
if (!valid) { if (!valid) {
return; return;
} }
userStore.login(username.value, username.value).then(() => { sessionStore.login(username.value, username.value).then(() => {
router.push(next); router.push(next);
}); });
} }

View file

@ -11,10 +11,12 @@ import Panel from 'primevue/panel';
import Timeline from 'primevue/timeline'; import Timeline from 'primevue/timeline';
import Sticker from "@/components/Sticker.vue"; import Sticker from "@/components/Sticker.vue";
import {useSessionStore} from "@/stores/sessionStore";
import {type User, useUserStore} from "@/stores/userStore"; import {type User, useUserStore} from "@/stores/userStore";
import { useStickersStore } from "@/stores/stickersStore"; import { useStickersStore } from "@/stores/stickersStore";
const sessionStore = useSessionStore();
const userStore = useUserStore(); const userStore = useUserStore();
const { getUser } = userStore; const { getUser } = userStore;
const route = useRoute(); const route = useRoute();
@ -29,7 +31,7 @@ onMounted(async () => {
}); });
const myPage = computed(() => { const myPage = computed(() => {
return !userStore.isAnonymous && userStore.user.username == user?.value.username; return !sessionStore.isAnonymous && sessionStore.user.username == user.value?.username;
}); });
const meterValue = ref([ const meterValue = ref([

View file

@ -4,11 +4,11 @@ import Button from 'primevue/button';
import Panel from 'primevue/panel'; import Panel from 'primevue/panel';
import Sticker from "@/components/Sticker.vue"; import Sticker from "@/components/Sticker.vue";
import { useRoute } from 'vue-router'; import { useRoute } from 'vue-router';
import { useUserStore } from "@/stores/userStore"; import { useSessionStore } from "@/stores/sessionStore";
import { useStickerStore } from "@/stores/stickerStore"; import { useStickerStore } from "@/stores/stickerStore";
const sessionStore = useSessionStore();
const stickerStore = useStickerStore(); const stickerStore = useStickerStore();
const userStore = useUserStore();
const route = useRoute(); const route = useRoute();
const uuid = ref<string>(route.params.uuid as string); const uuid = ref<string>(route.params.uuid as string);
@ -28,7 +28,7 @@ const second = computed(() => {
}) })
function claimSticker() { function claimSticker() {
stickerStore.setOwner(userStore.user); stickerStore.setOwner(sessionStore.user);
} }
</script> </script>
@ -56,12 +56,12 @@ function claimSticker() {
/> />
</div> </div>
<Button <Button
v-bind:disabled="userStore.isAnonymous" v-bind:disabled="sessionStore.isAnonymous"
v-if="stickerStore.sticker?.owner == null" v-if="stickerStore.sticker?.owner == null"
v-on:click="claimSticker"> v-on:click="claimSticker">
This is my sticker! This is my sticker!
</Button> </Button>
<span v-if="userStore.isAnonymous"> <span v-if="sessionStore.isAnonymous">
Log in to claim your sticker. Log in to claim your sticker.
</span> </span>
</div> </div>