119 lines
3.5 KiB
TypeScript
119 lines
3.5 KiB
TypeScript
import { createRouter, createWebHistory, type RouteLocationNormalizedLoaded, type RouteLocationRaw } from "vue-router";
|
|
import Clock from "@/Clock.vue";
|
|
import Games from "@/Games.vue";
|
|
import Home from "@/Home.vue";
|
|
import Market from "@/Market.vue";
|
|
import Noita from "@/Noita.vue";
|
|
import OpusMagnum from "@/OpusMagnum.vue";
|
|
import Place from "@/Place.vue";
|
|
import PlaceEmbed from "@/PlaceEmbed.vue";
|
|
import Submissions from "@/Submissions.vue";
|
|
import SubmissionsSelect from "@/SubmissionsSelect.vue";
|
|
import { usePageHeaderStore } from "@/stores/pageHeader";
|
|
|
|
declare module "vue-router" {
|
|
interface RouteMeta {
|
|
// Static label for AppHeader's title bar. Pages whose title depends on
|
|
// fetched data (e.g. submissions) set one at runtime via
|
|
// usePageHeaderStore() instead and leave this out.
|
|
titleKey?: string;
|
|
getBackRoute?: (route: RouteLocationNormalizedLoaded) => RouteLocationRaw;
|
|
// Skips AppHeader/AppFooter (see App.vue) - for pages meant to be
|
|
// dropped into an <iframe> as-is, like place/embed.
|
|
embed?: boolean;
|
|
}
|
|
}
|
|
|
|
const eventHome = (route: RouteLocationNormalizedLoaded): RouteLocationRaw => ({
|
|
name: "home",
|
|
params: { eventPath: route.params.eventPath },
|
|
});
|
|
|
|
export const router = createRouter({
|
|
history: createWebHistory("/"),
|
|
routes: [
|
|
{
|
|
path: "/:eventPath/",
|
|
name: "home",
|
|
component: Home,
|
|
props: true,
|
|
},
|
|
{
|
|
path: "/:eventPath/games",
|
|
name: "games",
|
|
component: Games,
|
|
props: true,
|
|
meta: { titleKey: "games.header", getBackRoute: eventHome },
|
|
},
|
|
{
|
|
path: "/:eventPath/market",
|
|
name: "market",
|
|
component: Market,
|
|
props: true,
|
|
meta: { titleKey: "market.header", getBackRoute: eventHome },
|
|
},
|
|
{
|
|
path: "/:eventPath/opus-magnum",
|
|
name: "opus-magnum",
|
|
component: OpusMagnum,
|
|
props: true,
|
|
meta: { titleKey: "opusMagnum.header", getBackRoute: eventHome },
|
|
},
|
|
{
|
|
path: "/:eventPath/noita",
|
|
name: "noita",
|
|
component: Noita,
|
|
props: true,
|
|
meta: { titleKey: "noita.header", getBackRoute: eventHome },
|
|
},
|
|
{
|
|
path: "/:eventPath/clock",
|
|
name: "clock",
|
|
component: Clock,
|
|
props: true,
|
|
meta: { titleKey: "clock.header", getBackRoute: eventHome },
|
|
},
|
|
{
|
|
path: "/:eventPath/place",
|
|
name: "place",
|
|
component: Place,
|
|
props: true,
|
|
meta: { titleKey: "place.header", getBackRoute: eventHome },
|
|
},
|
|
{
|
|
path: "/:eventPath/place/embed",
|
|
name: "place-embed",
|
|
component: PlaceEmbed,
|
|
props: true,
|
|
meta: { embed: true },
|
|
},
|
|
{
|
|
path: "/:eventPath/submissions/:gamePath",
|
|
name: "submissions-select",
|
|
component: SubmissionsSelect,
|
|
props: true,
|
|
meta: { titleKey: "submissionsSelect.title", getBackRoute: eventHome },
|
|
},
|
|
{
|
|
path: "/:eventPath/submissions/:gamePath/:scopeId",
|
|
name: "submissions",
|
|
component: Submissions,
|
|
props: true,
|
|
meta: {
|
|
// No static titleKey: Submissions.vue sets a dynamic
|
|
// "{game} Submissions — {scope}" title once it has fetched both.
|
|
getBackRoute: (route) => ({
|
|
name: "submissions-select",
|
|
params: { eventPath: route.params.eventPath, gamePath: route.params.gamePath },
|
|
}),
|
|
},
|
|
},
|
|
],
|
|
});
|
|
|
|
// Every route change starts from a clean header title; pages that need a
|
|
// dynamic one (see submissions above) set it again once their data lands.
|
|
router.beforeEach(() => {
|
|
usePageHeaderStore().clear();
|
|
});
|