diff --git a/frontend/src/components/AppShell.vue b/frontend/src/components/AppShell.vue index c3b2087..52bc3d9 100644 --- a/frontend/src/components/AppShell.vue +++ b/frontend/src/components/AppShell.vue @@ -25,7 +25,7 @@ const navItems = [ ] const currentLabel = computed( - () => navItems.find((item) => item.to === route.path)?.label ?? 'Awards', + () => navItems.find((item) => route.path === item.to || route.path.startsWith(`${item.to}/`))?.label ?? 'Awards', ) const visibleNavItems = computed(() => @@ -103,7 +103,7 @@ async function login(role: 'viewer' | 'admin') { :key="item.to" :to="item.to" class="rounded-full px-4 py-2 transition hover:bg-violet-50 hover:text-violet-700" - :class="route.path === item.to ? 'bg-violet-100 text-violet-800' : ''" + :class="route.path === item.to || route.path.startsWith(`${item.to}/`) ? 'bg-violet-100 text-violet-800' : ''" > {{ item.label }} diff --git a/frontend/src/components/admin/AdminSeasonToolbar.vue b/frontend/src/components/admin/AdminSeasonToolbar.vue new file mode 100644 index 0000000..f3bc038 --- /dev/null +++ b/frontend/src/components/admin/AdminSeasonToolbar.vue @@ -0,0 +1,44 @@ + + + diff --git a/frontend/src/router.ts b/frontend/src/router.ts index 0f3a0fc..0f1ddec 100644 --- a/frontend/src/router.ts +++ b/frontend/src/router.ts @@ -1,7 +1,12 @@ import { createRouter, createWebHistory } from 'vue-router' import { useAuthStore } from './stores/auth' -import AdminView from './views/AdminView.vue' +import AdminCandidatesView from './views/admin/AdminCandidatesView.vue' +import AdminDashboardView from './views/admin/AdminDashboardView.vue' +import AdminLayoutView from './views/admin/AdminLayoutView.vue' +import AdminReviewsView from './views/admin/AdminReviewsView.vue' +import AdminRiskView from './views/admin/AdminRiskView.vue' +import AdminSeasonsView from './views/admin/AdminSeasonsView.vue' import HomeView from './views/HomeView.vue' import NominationsView from './views/NominationsView.vue' import VotingView from './views/VotingView.vue' @@ -41,11 +46,41 @@ const router = createRouter({ }, { path: '/admin', - name: 'admin', - component: AdminView, + component: AdminLayoutView, meta: { requiresAdmin: true, }, + children: [ + { + path: '', + redirect: { name: 'admin-dashboard' }, + }, + { + path: 'dashboard', + name: 'admin-dashboard', + component: AdminDashboardView, + }, + { + path: 'seasons', + name: 'admin-seasons', + component: AdminSeasonsView, + }, + { + path: 'candidates', + name: 'admin-candidates', + component: AdminCandidatesView, + }, + { + path: 'reviews', + name: 'admin-reviews', + component: AdminReviewsView, + }, + { + path: 'risk', + name: 'admin-risk', + component: AdminRiskView, + }, + ], }, ], }) diff --git a/frontend/src/stores/awards.ts b/frontend/src/stores/awards.ts index 5965c53..8bd9c76 100644 --- a/frontend/src/stores/awards.ts +++ b/frontend/src/stores/awards.ts @@ -208,6 +208,7 @@ export const useAwardsStore = defineStore('awards', { admin: fallbackAdmin as AdminDashboardResponse, adminSeasons: fallbackAdminSeasons as AdminSeasonListItem[], adminSeasonDetail: fallbackAdminSeasonDetail as AdminSeasonDetailResponse, + adminSelectedSeasonId: fallbackAdminSeasonDetail.id as number | null, loading: false, apiMode: 'fallback' as 'api' | 'fallback', }), @@ -237,22 +238,39 @@ export const useAwardsStore = defineStore('awards', { try { this.admin = await api.getAdminDashboard() this.adminSeasons = await api.getAdminSeasons() - this.adminSeasonDetail = await api.getAdminSeasonDetail(this.adminSeasons[0]?.id ?? 1) + if (!this.adminSelectedSeasonId || !this.adminSeasons.some((season) => season.id === this.adminSelectedSeasonId)) { + this.adminSelectedSeasonId = this.adminSeasons[0]?.id ?? null + } + + if (this.adminSelectedSeasonId) { + this.adminSeasonDetail = await api.getAdminSeasonDetail(this.adminSelectedSeasonId) + } this.apiMode = 'api' } catch { this.admin = emptyAdmin this.adminSeasons = emptyAdminSeasons this.adminSeasonDetail = emptyAdminSeasonDetail + this.adminSelectedSeasonId = null } }, async loadAdminSeasonDetail(seasonId: number) { try { + this.adminSelectedSeasonId = seasonId this.adminSeasonDetail = await api.getAdminSeasonDetail(seasonId) this.apiMode = 'api' } catch { this.adminSeasonDetail = emptyAdminSeasonDetail } }, + async initializeAdminWorkspace() { + await this.loadAdmin() + if (this.adminSelectedSeasonId && this.adminSeasonDetail.id !== this.adminSelectedSeasonId) { + await this.loadAdminSeasonDetail(this.adminSelectedSeasonId) + } + }, + setAdminSeason(seasonId: number) { + this.adminSelectedSeasonId = seasonId + }, submitNomination(payload: CreateNominationPayload) { return api.submitNomination(payload) }, diff --git a/frontend/src/views/AdminView.vue b/frontend/src/views/AdminView.vue deleted file mode 100644 index b8fa885..0000000 --- a/frontend/src/views/AdminView.vue +++ /dev/null @@ -1,654 +0,0 @@ - - -