Files
Website/resources/js/router/index.js
2023-02-27 16:08:41 +10:00

467 lines
13 KiB
JavaScript

import { useUserStore } from "@/store/UserStore";
import { createRouter, createWebHistory } from "vue-router";
import { api } from "../helpers/api";
import { useApplicationStore } from "../store/ApplicationStore";
import { useProgressStore } from "../store/ProgressStore";
export const routes = [
{
path: "/",
name: "home",
meta: {
title: "Home",
},
component: () => import("@/views/Home.vue"),
},
{
path: "/verify-email",
name: "verify-email",
meta: {
title: "Verify Email",
},
component: () => import("@/views/EmailVerify.vue"),
},
{
path: "/resend-verify-email",
name: "resend-verify-email",
meta: {
title: "Resend Verification Email",
},
component: () => import("@/views/ResendEmailVerify.vue"),
},
{
path: "/reset-password",
name: "reset-password",
meta: {
title: "Reset Password",
},
component: () => import("@/views/ResetPassword.vue"),
},
{
path: "/about",
name: "about",
meta: {
title: "About",
},
component: () => import("@/views/About.vue"),
},
{
path: "/privacy",
name: "privacy",
meta: {
title: "Privacy Policy",
},
component: () => import("@/views/Privacy.vue"),
},
{
path: "/rules",
name: "rules",
meta: {
title: "Rules",
},
component: () => import("@/views/Rules.vue"),
},
{
path: "/unsubscribe",
name: "unsubscribe",
meta: {
title: "Unsubscribe",
},
component: () => import("@/views/Unsubscribe.vue"),
},
{
path: "/terms",
name: "terms",
meta: {
title: "Terms and Conditions",
},
component: () => import("@/views/Terms.vue"),
},
{
path: "/minecraft",
name: "minecraft",
meta: {
title: "Minecraft",
},
component: () => import("@/views/Minecraft.vue"),
},
{
path: "/workshops",
children: [
{
path: "",
name: "workshop-list",
meta: {
title: "Workshops",
},
component: () => import("@/views/WorkshopList.vue"),
},
{
path: ":id",
name: "workshop-view",
component: () => import("@/views/WorkshopView.vue"),
},
],
},
{
path: "/login",
name: "login",
meta: {
title: "Login",
middleware: "guest",
},
component: () => import("@/views/Login.vue"),
},
{
path: "/logout",
name: "logout",
meta: {
title: "Logout",
},
component: () => import("@/views/Logout.vue"),
},
{
path: "/contact",
name: "contact",
meta: {
title: "Contact",
},
component: () => import("@/views/Contact.vue"),
},
{
path: "/register",
name: "register",
meta: {
title: "Register",
},
component: () => import("@/views/Register.vue"),
},
{
path: "/news",
children: [
{
path: "",
name: "news",
meta: {
title: "News",
},
component: () => import("@/views/NewsList.vue"),
},
{
path: ":slug",
name: "post-view",
component: () => import("@/views/NewsView.vue"),
},
],
},
{
path: "/dashboard",
children: [
{
path: "",
name: "dashboard",
meta: {
title: "Dashboard",
middleware: "authenticated",
},
component: () => import("@/views/dashboard/Dashboard.vue"),
},
{
path: "posts",
children: [
{
path: "",
name: "post-list",
meta: {
title: "Posts",
middleware: "authenticated",
},
component: () =>
import("@/views/dashboard/PostList.vue"),
},
{
path: "create",
name: "post-create",
meta: {
title: "Create Post",
middleware: "authenticated",
},
component: () =>
import("@/views/dashboard/PostEdit.vue"),
},
{
path: ":id",
name: "post-edit",
meta: {
title: "Edit Post",
middleware: "authenticated",
},
component: () =>
import("@/views/dashboard/PostEdit.vue"),
},
],
},
{
path: "events",
children: [
{
path: "",
name: "event-list",
meta: {
title: "Events",
middleware: "authenticated",
},
component: () =>
import("@/views/dashboard/EventList.vue"),
},
{
path: "create",
name: "event-create",
meta: {
title: "Create Event",
middleware: "authenticated",
},
component: () =>
import("@/views/dashboard/EventEdit.vue"),
},
{
path: ":id",
name: "event-edit",
meta: {
title: "Event Post",
middleware: "authenticated",
},
component: () =>
import("@/views/dashboard/EventEdit.vue"),
},
],
},
{
path: "details",
name: "account-details",
meta: {
title: "Account Details",
middleware: "authenticated",
},
component: () => import("@/views/dashboard/UserEdit.vue"),
},
{
path: "users",
children: [
{
path: "",
name: "user-list",
meta: {
title: "Users",
middleware: "authenticated",
},
component: () =>
import("@/views/dashboard/UserList.vue"),
},
{
path: ":id",
name: "user-edit",
meta: {
title: "Edit User",
middleware: "authenticated",
},
component: () =>
import("@/views/dashboard/UserEdit.vue"),
},
],
},
{
path: "media",
children: [
{
path: "",
name: "media",
meta: {
title: "Media",
middleware: "authenticated",
},
component: () =>
import("@/views/dashboard/MediaList.vue"),
},
{
path: "upload",
name: "media-upload",
meta: {
title: "Upload Media",
middleware: "authenticated",
},
component: () =>
import("@/views/dashboard/MediaEdit.vue"),
},
{
path: "edit/:id",
name: "media-edit",
meta: {
title: "Edit Media",
middleware: "authenticated",
},
component: () =>
import("@/views/dashboard/MediaEdit.vue"),
},
],
},
{
path: "discord-bot-logs",
name: "discord-bot-logs",
meta: {
title: "Discord Bot Logs",
middleware: "authenticated",
},
component: () => import("@/views/dashboard/DiscordBotLogs.vue"),
},
],
},
{
path: "/forgot-username",
name: "forgot-username",
meta: {
title: "Forgot Username",
},
component: () => import("@/views/ForgotUsername.vue"),
},
{
path: "/forgot-password",
name: "forgot-password",
meta: {
title: "Forgot Password",
},
component: () => import("@/views/ForgotPassword.vue"),
},
{
path: "/error/internal",
name: "error-internal",
meta: {
title: "Server error",
hideInEditor: true,
},
component: () => import("@/components/errors/Internal.vue"),
},
{
path: "/error/forbidden",
name: "forbidden",
meta: {
title: "Forbidden",
hideInEditor: true,
},
component: () => import("@/components/errors/Forbidden.vue"),
},
{
path: "/:catchAll(.*)",
name: "not-found",
meta: {
title: "Page not found",
hideInEditor: true,
},
component: () => import("@/components/errors/NotFound.vue"),
},
];
const router = createRouter({
history: createWebHistory(),
routes,
scrollBehavior(to, from, savedPosition) {
// always scroll to top
return { top: 0 };
},
});
// export let activeRoutes = [];
router.beforeEach(async (to, from, next) => {
const userStore = useUserStore();
const applicationStore = useApplicationStore();
const progressStore = useProgressStore();
progressStore.start();
applicationStore.clearDynamicTitle();
// Check Token
if (userStore.id) {
let redirect = false;
try {
let res = await api.get("/me");
userStore.setUserDetails(res.json.user);
} catch (err) {
if (err.status == 401) {
userStore.clearUser();
redirect = true;
}
}
if (
redirect &&
to.path.startsWith("/error/") === false &&
to.path.startsWith("/login") === false
) {
next({ name: "login", query: { redirect: to.fullPath } });
return;
}
}
// Document Title
const nearestWithTitle = to.matched
.slice()
.reverse()
.find((r) => r.meta && r.meta.title);
const previousNearestWithMeta = from.matched
.slice()
.reverse()
.find((r) => r.meta && r.meta.metaTags);
let title = "";
if (nearestWithTitle) {
title = nearestWithTitle.meta.title;
} else if (previousNearestWithMeta) {
title = previousNearestWithMeta.meta.title;
}
if (title != "") {
document.title = "STEMMechanics | " + title;
}
// Meta tags
const nearestWithMeta = to.matched
.slice()
.reverse()
.find((r) => r.meta && r.meta.metaTags);
Array.from(document.querySelectorAll("[data-vue-router-controlled]")).map(
(el) => el.parentNode.removeChild(el)
);
if (nearestWithMeta) {
nearestWithMeta.meta.metaTags
.map((tagDef) => {
const tag = document.createElement("meta");
Object.keys(tagDef).forEach((key) => {
tag.setAttribute(key, tagDef[key]);
});
tag.setAttribute("data-vue-router-controlled", "");
return tag;
})
.forEach((tag) => document.head.appendChild(tag));
}
if (to.meta.middleware == "authenticated" && !userStore.id) {
progressStore.finish();
next({ name: "login", query: { redirect: to.fullPath } });
} else {
next();
}
});
router.afterEach((to, from) => {
const progressStore = useProgressStore();
progressStore.finish();
});
export default router;