From 3b7f9309676d54a0b86976a51c4dd92a8f78e4cb Mon Sep 17 00:00:00 2001 From: zysim Date: Mon, 9 Dec 2024 18:17:25 +0800 Subject: [PATCH 01/24] Scaffolding --- src/components/Leaderboard.vue | 185 +++++++++++++++++++++++++++++++++ src/main.ts | 6 ++ 2 files changed, 191 insertions(+) create mode 100644 src/components/Leaderboard.vue diff --git a/src/components/Leaderboard.vue b/src/components/Leaderboard.vue new file mode 100644 index 0000000..cc7873d --- /dev/null +++ b/src/components/Leaderboard.vue @@ -0,0 +1,185 @@ + + + + + diff --git a/src/main.ts b/src/main.ts index bfa4ea3..ebf2790 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,6 +1,7 @@ import { createApp } from 'vue' import { createRouter, createWebHistory } from 'vue-router' import App from './App.vue' +import Leaderboard from './components/Leaderboard.vue' import Leaderboards from './components/Leaderboards.vue' import Main from './components/Main.vue' import './style.css' @@ -11,6 +12,11 @@ const routes = [ name: 'home', component: Main, }, + { + path: '/leaderboard/:id', + name: 'leaderboard', + component: Leaderboard, + }, { path: '/leaderboards', name: 'leaderboardsList', From 5b2a67ffc1b8dd443b712f72ecf042a13faf7ab7 Mon Sep 17 00:00:00 2001 From: Ted Wollman <25165500+TheTedder@users.noreply.github.com> Date: Mon, 9 Dec 2024 15:22:53 -0500 Subject: [PATCH 02/24] Pass LB id as prop. --- src/components/Leaderboard.vue | 41 +++++----------------------------- src/main.ts | 37 +++++++++++++++--------------- 2 files changed, 24 insertions(+), 54 deletions(-) diff --git a/src/components/Leaderboard.vue b/src/components/Leaderboard.vue index cc7873d..57e2fab 100644 --- a/src/components/Leaderboard.vue +++ b/src/components/Leaderboard.vue @@ -5,37 +5,17 @@ import { useRoute, useRouter } from 'vue-router' import { Leaderboards } from '../lib/api/Leaderboards' const router = useRouter() -const route = useRoute() +const props = defineProps<{ + id: number +}>() const leaderboards = new Leaderboards({ baseUrl: import.meta.env.VITE_BACKEND_URL }) -const id = computed(() => { - const { id } = route.params - - if (Array.isArray(id)) { - return null - } - - const parsed = parseInt(id, 10) - - if (isNaN(parsed)) { - return null - } - - return parsed -}) - const {state: board, error, isLoading, execute} = useAsyncState(async () => { - if (id.value === null) { - // TODO: Handle appropriately - throw new Error('Leaderboard does not exist') - } - // TODO: Add param in BE that allows also fetching deleted boards - const resp = await leaderboards.getLeaderboard(id.value) - + const resp = await leaderboards.getLeaderboard(props.id) return resp.data }, null) @@ -52,24 +32,15 @@ const { } = useConfirmDialog() async function confirmDeleteBoard() { - if (id.value === null) { - return - } // TODO: Error-handling - await leaderboards.deleteLeaderboard(id.value) - + await leaderboards.deleteLeaderboard(props.id) router.go(0) } async function confirmRestoreBoard() { - if (id.value === null) { - return - } - // TODO: Error-handling - await leaderboards.restoreLeaderboard(id.value) - + await leaderboards.restoreLeaderboard(props.id) router.go(0) } diff --git a/src/main.ts b/src/main.ts index ebf2790..9b174b5 100644 --- a/src/main.ts +++ b/src/main.ts @@ -6,27 +6,26 @@ import Leaderboards from './components/Leaderboards.vue' import Main from './components/Main.vue' import './style.css' -const routes = [ - { - path: '/', - name: 'home', - component: Main, - }, - { - path: '/leaderboard/:id', - name: 'leaderboard', - component: Leaderboard, - }, - { - path: '/leaderboards', - name: 'leaderboardsList', - component: Leaderboards, - }, -] - const router = createRouter({ history: createWebHistory(), - routes, + routes: [ + { + path: '/', + name: '/home', + component: Main, + }, + { + path: '/leaderboard/:id(\\d+)', + name: 'leaderboard', + component: Leaderboard, + props: (route) => ({ id: Number.parseInt(route.params.id.toString()) }), + }, + { + path: '/leaderboards', + name: 'leaderboardsList', + component: Leaderboards, + }, + ], }) createApp(App).use(router).mount('#app') From a45ebf11ddebeec77ad3387a570ec559a4d84162 Mon Sep 17 00:00:00 2001 From: Ted Wollman <25165500+TheTedder@users.noreply.github.com> Date: Mon, 9 Dec 2024 15:24:38 -0500 Subject: [PATCH 03/24] Refetch LB instead of refreshing page. --- src/components/Leaderboard.vue | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/components/Leaderboard.vue b/src/components/Leaderboard.vue index 57e2fab..707e4cd 100644 --- a/src/components/Leaderboard.vue +++ b/src/components/Leaderboard.vue @@ -1,10 +1,7 @@ From ddd39b8637b65d7f135d45992052692c698db88f Mon Sep 17 00:00:00 2001 From: Ted Wollman <25165500+TheTedder@users.noreply.github.com> Date: Mon, 9 Dec 2024 15:24:51 -0500 Subject: [PATCH 04/24] Assert type of id route param. --- src/main.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.ts b/src/main.ts index 9b174b5..8a27b77 100644 --- a/src/main.ts +++ b/src/main.ts @@ -18,7 +18,7 @@ const router = createRouter({ path: '/leaderboard/:id(\\d+)', name: 'leaderboard', component: Leaderboard, - props: (route) => ({ id: Number.parseInt(route.params.id.toString()) }), + props: (route) => ({ id: Number.parseInt(route.params.id as string) }), }, { path: '/leaderboards', From 4bfd6b36753b3289f3ebf849a650d8dffe6e1522 Mon Sep 17 00:00:00 2001 From: Ted Wollman <25165500+TheTedder@users.noreply.github.com> Date: Mon, 9 Dec 2024 15:29:06 -0500 Subject: [PATCH 05/24] Use auth for deleting and restoring LB. --- src/components/Leaderboard.vue | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/components/Leaderboard.vue b/src/components/Leaderboard.vue index 707e4cd..8e118ec 100644 --- a/src/components/Leaderboard.vue +++ b/src/components/Leaderboard.vue @@ -1,11 +1,15 @@ From 0a9cbc6f5955d535449f211497ba9b0c06096d46 Mon Sep 17 00:00:00 2001 From: Ted Wollman <25165500+TheTedder@users.noreply.github.com> Date: Mon, 9 Dec 2024 18:28:26 -0500 Subject: [PATCH 06/24] Use global state for user details. --- src/App.vue | 28 +++++++++++++++----- src/components/Login.vue | 2 +- src/components/Navbar.vue | 2 +- src/composables/useUserDetails.ts | 44 +++++++++++++++++++------------ 4 files changed, 51 insertions(+), 25 deletions(-) diff --git a/src/App.vue b/src/App.vue index 29786b0..a079803 100644 --- a/src/App.vue +++ b/src/App.vue @@ -4,17 +4,24 @@ import Login from './components/Login.vue' import Navbar from './components/Navbar.vue' import { useUserDetails } from './composables/useUserDetails' -const user = useUserDetails() -const loggedIn = computed(() => user.value?.role === 'Administrator') +const { state, isLoading, isReady } = useUserDetails() +const loggedIn = computed( + () => state.value?.role === 'Administrator' +) @@ -22,4 +29,13 @@ const loggedIn = computed(() => user.value?.role === 'Administrator') .root { width: 100%; } + +.loader { + position: fixed; + z-index: 999; + top: 45%; + left: 50%; + padding: 1rem; + background-color: black; +} diff --git a/src/components/Login.vue b/src/components/Login.vue index 01cb402..02265db 100644 --- a/src/components/Login.vue +++ b/src/components/Login.vue @@ -11,7 +11,7 @@ const password = ref('') const loginError = ref(false) const submitted = ref(false) const token = useSessionToken() -const user = useUserDetails() +const { state: user } = useUserDetails() const loginFailed = computed( () => loginError.value || diff --git a/src/components/Navbar.vue b/src/components/Navbar.vue index 56c3181..eceac57 100644 --- a/src/components/Navbar.vue +++ b/src/components/Navbar.vue @@ -11,7 +11,7 @@ function logoutClicked() { token.value = '' } -const user = useUserDetails() +const { state: user } = useUserDetails()