import { createRouter, createWebHistory } from "vue-router"; import Login from "@/views/Login.vue"; import { isAuthenticated } from "./authGuard"; import { loadAccountData } from "./accountGuard"; import { isSetup } from "./setupGuard"; import { abilityAndNavUpdate } from "./adminGuard"; import type { PermissionType, PermissionSection, PermissionModule } from "@/types/permissionTypes"; import { resetMemberStores, setMemberId } from "./memberGuard"; import { resetProtocolStores, setProtocolId } from "./protocolGuard"; import { resetNewsletterStores, setNewsletterId } from "./newsletterGuard"; import { config } from "../config"; import { setBackupPage } from "./backupGuard"; const router = createRouter({ history: createWebHistory(import.meta.env.BASE_URL), routes: [ { path: "/", redirect: { name: "admin" }, }, { path: "/login", name: "login", component: Login, }, { path: "/setup", name: "setup", component: () => import("@/views/RouterView.vue"), beforeEnter: [isSetup], children: [ { path: "", name: "setup-create", component: () => import("@/views/setup/Setup.vue"), }, { path: "verify", name: "setup-verify", component: () => import("@/views/setup/Verify.vue"), props: (route) => ({ mail: route.query.mail, token: route.query.token }), }, ], }, { path: "/reset", name: "reset", component: () => import("@/views/RouterView.vue"), children: [ { path: "", name: "reset-start", component: () => import("@/views/reset/Start.vue"), }, { path: "reset", name: "reset-reset", component: () => import("@/views/reset/Reset.vue"), props: (route) => ({ mail: route.query.mail, token: route.query.token }), }, ], }, { path: "/invite", name: "invite", component: () => import("@/views/RouterView.vue"), children: [ { path: "verify", name: "invite-verify", component: () => import("@/views/invite/Verify.vue"), props: (route) => ({ mail: route.query.mail, token: route.query.token }), }, ], }, { path: "/admin", name: "admin", component: () => import("@/views/admin/View.vue"), beforeEnter: [isAuthenticated], children: [ { path: "", name: "admin-default", component: () => import("@/views/admin/ViewSelect.vue"), }, { path: "club", name: "admin-club", component: () => import("@/views/RouterView.vue"), meta: { type: "read", section: "club" }, beforeEnter: [abilityAndNavUpdate], children: [ { path: "", name: "admin-club-default", component: () => import("@/views/admin/ViewSelect.vue"), meta: { type: "read", section: "club" }, beforeEnter: [abilityAndNavUpdate], }, { path: "members", name: "admin-club-member-route", component: () => import("@/views/RouterView.vue"), meta: { type: "read", section: "club", module: "member" }, beforeEnter: [abilityAndNavUpdate], children: [ { path: "", name: "admin-club-member", component: () => import("@/views/admin/club/members/Member.vue"), beforeEnter: [resetMemberStores], }, { path: ":memberId", name: "admin-club-member-routing", component: () => import("@/views/admin/club/members/MemberRouting.vue"), beforeEnter: [setMemberId], props: true, children: [ { path: "overview", name: "admin-club-member-overview", component: () => import("@/views/admin/club/members/MemberOverview.vue"), props: true, }, { path: "membership", name: "admin-club-member-membership", component: () => import("@/views/admin/club/members/Membership.vue"), props: true, }, { path: "communication", name: "admin-club-member-communication", component: () => import("@/views/admin/club/members/MemberCommunication.vue"), props: true, }, { path: "awards", name: "admin-club-member-awards", component: () => import("@/views/admin/club/members/MemberAwards.vue"), props: true, }, { path: "qualifications", name: "admin-club-member-qualifications", component: () => import("@/views/admin/club/members/MemberQualifications.vue"), props: true, }, { path: "positions", name: "admin-club-member-positions", component: () => import("@/views/admin/club/members/MemberExecutivePositions.vue"), props: true, }, { path: "edit", name: "admin-club-member-edit", component: () => import("@/views/admin/club/members/MemberEdit.vue"), meta: { type: "update", section: "club", module: "member" }, beforeEnter: [abilityAndNavUpdate], props: true, }, ], }, ], }, { path: "calendar", name: "admin-club-calendar", component: () => import("@/views/admin/club/calendar/Calendar.vue"), meta: { type: "read", section: "club", module: "calendar" }, beforeEnter: [abilityAndNavUpdate], }, { path: "newsletter", name: "admin-club-newsletter-route", component: () => import("@/views/RouterView.vue"), meta: { type: "read", section: "club", module: "newsletter" }, beforeEnter: [abilityAndNavUpdate], children: [ { path: "", name: "admin-club-newsletter", component: () => import("@/views/admin/club/newsletter/Newsletter.vue"), beforeEnter: [resetNewsletterStores], }, { path: ":newsletterId", name: "admin-club-newsletter-routing", component: () => import("@/views/admin/club/newsletter/NewsletterRouting.vue"), beforeEnter: [setNewsletterId], props: true, children: [ { path: "overview", name: "admin-club-newsletter-overview", component: () => import("@/views/admin/club/newsletter/NewsletterOverview.vue"), props: true, }, { path: "data", name: "admin-club-newsletter-data", component: () => import("@/views/admin/club/newsletter/NewsletterData.vue"), props: true, }, { path: "recipients", name: "admin-club-newsletter-recipients", component: () => import("@/views/admin/club/newsletter/NewsletterRecipients.vue"), props: true, }, { path: "dates", name: "admin-club-newsletter-dates", component: () => import("@/views/admin/club/newsletter/NewsletterDates.vue"), props: true, }, { path: "printout", name: "admin-club-newsletter-printout", component: () => import("@/views/admin/club/newsletter/NewsletterPrintout.vue"), props: true, }, ], }, ], }, { path: "protocol", name: "admin-club-protocol-route", component: () => import("@/views/RouterView.vue"), meta: { type: "read", section: "club", module: "protocol" }, beforeEnter: [abilityAndNavUpdate], children: [ { path: "", name: "admin-club-protocol", component: () => import("@/views/admin/club/protocol/Protocol.vue"), beforeEnter: [resetProtocolStores], }, { path: ":protocolId", name: "admin-club-protocol-routing", component: () => import("@/views/admin/club/protocol/ProtocolRouting.vue"), beforeEnter: [setProtocolId], props: true, children: [ { path: "overview", name: "admin-club-protocol-overview", component: () => import("@/views/admin/club/protocol/ProtocolOverview.vue"), props: true, }, { path: "presence", name: "admin-club-protocol-presence", component: () => import("@/views/admin/club/protocol/ProtocolPresence.vue"), props: true, }, { path: "voting", name: "admin-club-protocol-voting", component: () => import("@/views/admin/club/protocol/ProtocolVoting.vue"), props: true, }, { path: "decisions", name: "admin-club-protocol-decisions", component: () => import("@/views/admin/club/protocol/ProtocolDecisions.vue"), props: true, }, { path: "agenda", name: "admin-club-protocol-agenda", component: () => import("@/views/admin/club/protocol/ProtocolAgenda.vue"), props: true, }, { path: "printout", name: "admin-club-protocol-printout", component: () => import("@/views/admin/club/protocol/ProtocolPrintout.vue"), props: true, }, ], }, ], }, { path: "query-builder", name: "admin-club-query_builder", component: () => import("@/views/admin/club/query/Builder.vue"), meta: { type: "read", section: "club", module: "query" }, beforeEnter: [abilityAndNavUpdate], }, ], }, { path: "configuration", name: "admin-configuration", component: () => import("@/views/RouterView.vue"), meta: { type: "read", section: "configuration" }, beforeEnter: [abilityAndNavUpdate], children: [ { path: "", name: "admin-configuration-default", component: () => import("@/views/admin/ViewSelect.vue"), meta: { type: "read", section: "configuration" }, beforeEnter: [abilityAndNavUpdate], }, { path: "qualification", name: "admin-configuration-qualification-route", component: () => import("@/views/RouterView.vue"), meta: { type: "read", section: "configuration", module: "qualification" }, beforeEnter: [abilityAndNavUpdate], children: [ { path: "", name: "admin-configuration-qualification", component: () => import("@/views/admin/configuration/qualification/Qualification.vue"), }, { path: ":id/edit", name: "admin-configuration-qualification-edit", component: () => import("@/views/admin/configuration/qualification/QualificationEdit.vue"), meta: { type: "update", section: "configuration", module: "qualification" }, beforeEnter: [abilityAndNavUpdate], props: true, }, ], }, { path: "award", name: "admin-configuration-award-route", component: () => import("@/views/RouterView.vue"), meta: { type: "read", section: "configuration", module: "award" }, beforeEnter: [abilityAndNavUpdate], children: [ { path: "", name: "admin-configuration-award", component: () => import("@/views/admin/configuration/award/Award.vue"), }, { path: ":id/edit", name: "admin-configuration-award-edit", component: () => import("@/views/admin/configuration/award/AwardEdit.vue"), meta: { type: "update", section: "configuration", module: "award" }, beforeEnter: [abilityAndNavUpdate], props: true, }, ], }, { path: "executive-position", name: "admin-configuration-executive_position-route", component: () => import("@/views/RouterView.vue"), meta: { type: "read", section: "configuration", module: "executive_position" }, beforeEnter: [abilityAndNavUpdate], children: [ { path: "", name: "admin-configuration-executive_position", component: () => import("@/views/admin/configuration/executivePosition/ExecutivePosition.vue"), meta: { type: "read", section: "configuration", module: "executive_position" }, beforeEnter: [abilityAndNavUpdate], }, { path: ":id/edit", name: "admin-configuration-executive_position-edit", component: () => import("@/views/admin/configuration/executivePosition/ExecutivePositionEdit.vue"), meta: { type: "update", section: "configuration", module: "executive_position" }, beforeEnter: [abilityAndNavUpdate], props: true, }, ], }, { path: "communication-type", name: "admin-configuration-communication_type-route", component: () => import("@/views/RouterView.vue"), meta: { type: "read", section: "configuration", module: "communication_type" }, beforeEnter: [abilityAndNavUpdate], children: [ { path: "", name: "admin-configuration-communication_type", component: () => import("@/views/admin/configuration/communicationType/CommunicationType.vue"), }, { path: ":id/edit", name: "admin-configuration-communication_type-edit", component: () => import("@/views/admin/configuration/communicationType/CommunicationTypeEdit.vue"), meta: { type: "update", section: "configuration", module: "communication_type" }, beforeEnter: [abilityAndNavUpdate], props: true, }, ], }, { path: "status", name: "admin-configuration-membership_status-route", component: () => import("@/views/RouterView.vue"), meta: { type: "read", section: "configuration", module: "membership_status" }, beforeEnter: [abilityAndNavUpdate], children: [ { path: "", name: "admin-configuration-membership_status", component: () => import("@/views/admin/configuration/membershipStatus/MembershipStatus.vue"), }, { path: ":id/edit", name: "admin-configuration-membership_status-edit", component: () => import("@/views/admin/configuration/membershipStatus/MembershipStatusEdit.vue"), meta: { type: "update", section: "configuration", module: "membership_status" }, beforeEnter: [abilityAndNavUpdate], props: true, }, ], }, { path: "salutation", name: "admin-configuration-salutation-route", component: () => import("@/views/RouterView.vue"), meta: { type: "read", section: "configuration", module: "salutation" }, beforeEnter: [abilityAndNavUpdate], children: [ { path: "", name: "admin-configuration-salutation", component: () => import("@/views/admin/configuration/salutation/Salutation.vue"), }, { path: ":id/edit", name: "admin-configuration-salutation-edit", component: () => import("@/views/admin/configuration/salutation/SalutationEdit.vue"), meta: { type: "update", section: "configuration", module: "salutation" }, beforeEnter: [abilityAndNavUpdate], props: true, }, ], }, { path: "calendar-type", name: "admin-configuration-calendar_type-route", component: () => import("@/views/RouterView.vue"), meta: { type: "read", section: "configuration", module: "calendar_type" }, beforeEnter: [abilityAndNavUpdate], children: [ { path: "", name: "admin-configuration-calendar_type", component: () => import("@/views/admin/configuration/calendarType/CalendarType.vue"), }, { path: ":id/edit", name: "admin-configuration-calendar_type-edit", component: () => import("@/views/admin/configuration/calendarType/CalendarTypeEdit.vue"), meta: { type: "update", section: "configuration", module: "calendar_type" }, beforeEnter: [abilityAndNavUpdate], props: true, }, ], }, { path: "query-store", name: "admin-configuration-query_store", component: () => import("@/views/admin/configuration/queryStore/QueryStore.vue"), meta: { type: "read", section: "configuration", module: "query_store" }, beforeEnter: [abilityAndNavUpdate], }, { path: "template", name: "admin-configuration-template-route", component: () => import("@/views/RouterView.vue"), meta: { type: "read", section: "configuration", module: "template" }, beforeEnter: [abilityAndNavUpdate], children: [ { path: "", name: "admin-configuration-template", component: () => import("@/views/admin/configuration/template/Template.vue"), }, { path: "info", name: "admin-configuration-template-info", component: () => import("@/views/admin/configuration/template/UsageInfo.vue"), props: true, }, { path: ":id/edit", name: "admin-configuration-template-edit", component: () => import("@/views/admin/configuration/template/TemplateEdit.vue"), meta: { type: "update", section: "configuration", module: "template" }, beforeEnter: [abilityAndNavUpdate], props: true, }, ], }, { path: "template-usage", name: "admin-configuration-template_usage", component: () => import("@/views/admin/configuration/templateUsage/TemplateUsage.vue"), meta: { type: "read", section: "configuration", module: "template_usage" }, beforeEnter: [abilityAndNavUpdate], }, { path: "newsletter-config", name: "admin-configuration-newsletter_config", component: () => import("@/views/admin/configuration/newsletterConfig/NewsletterConfig.vue"), meta: { type: "read", section: "configuration", module: "newsletter_config" }, beforeEnter: [abilityAndNavUpdate], }, ], }, { path: "management", name: "admin-management", component: () => import("@/views/RouterView.vue"), meta: { type: "read", section: "management" }, beforeEnter: [abilityAndNavUpdate], children: [ { path: "", name: "admin-management-default", component: () => import("@/views/admin/ViewSelect.vue"), meta: { type: "read", section: "management" }, beforeEnter: [abilityAndNavUpdate], }, { path: "user", name: "admin-management-user-route", component: () => import("@/views/RouterView.vue"), meta: { type: "read", section: "management", module: "user" }, beforeEnter: [abilityAndNavUpdate], children: [ { path: "", name: "admin-management-user", component: () => import("@/views/admin/management/user/User.vue"), }, { path: "invites", name: "admin-management-user-invites", component: () => import("@/views/admin/management/user/Invite.vue"), }, { path: ":id/edit", name: "admin-management-user-edit", component: () => import("@/views/admin/management/user/UserEdit.vue"), meta: { type: "update", section: "management", module: "user" }, beforeEnter: [abilityAndNavUpdate], props: true, }, { path: ":id/permission", name: "admin-management-user-permission", component: () => import("@/views/admin/management/user/UserEditPermission.vue"), meta: { type: "update", section: "management", module: "user" }, beforeEnter: [abilityAndNavUpdate], props: true, }, { path: ":id/roles", name: "admin-management-user-roles", component: () => import("@/views/admin/management/user/UserEditRoles.vue"), meta: { type: "update", section: "management", module: "user" }, beforeEnter: [abilityAndNavUpdate], props: true, }, ], }, { path: "role", name: "admin-management-role-route", component: () => import("@/views/RouterView.vue"), meta: { type: "read", section: "management", module: "role" }, beforeEnter: [abilityAndNavUpdate], children: [ { path: "", name: "admin-management-role", component: () => import("@/views/admin/management/role/Role.vue"), }, { path: ":id/edit", name: "admin-management-role-edit", component: () => import("@/views/admin/management/role/RoleEdit.vue"), meta: { type: "update", section: "management", module: "role" }, beforeEnter: [abilityAndNavUpdate], props: true, }, { path: ":id/permission", name: "admin-management-role-permission", component: () => import("@/views/admin/management/role/RoleEditPermission.vue"), meta: { type: "update", section: "management", module: "role" }, beforeEnter: [abilityAndNavUpdate], props: true, }, ], }, { path: "webapi", name: "admin-management-webapi-route", component: () => import("@/views/RouterView.vue"), meta: { type: "read", section: "management", module: "webapi" }, beforeEnter: [abilityAndNavUpdate], children: [ { path: "", name: "admin-management-webapi", component: () => import("@/views/admin/management/webapi/Webapi.vue"), }, { path: ":id/edit", name: "admin-management-webapi-edit", component: () => import("@/views/admin/management/webapi/WebapiEdit.vue"), meta: { type: "update", section: "management", module: "webapi" }, beforeEnter: [abilityAndNavUpdate], props: true, }, { path: ":id/permission", name: "admin-management-webapi-permission", component: () => import("@/views/admin/management/webapi/WebapiEditPermission.vue"), meta: { type: "update", section: "management", module: "webapi" }, beforeEnter: [abilityAndNavUpdate], props: true, }, ], }, { path: "backup", name: "admin-management-backup-route", component: () => import("@/views/admin/management/backup/BackupRouting.vue"), meta: { type: "read", section: "management", module: "backup" }, beforeEnter: [abilityAndNavUpdate], children: [ { path: "", name: "admin-management-backup", redirect: { name: "admin-management-backup-generated" }, }, { path: "generated", name: "admin-management-backup-generated", component: () => import("@/views/admin/management/backup/GeneratedBackup.vue"), beforeEnter: [setBackupPage], }, { path: "uploads", name: "admin-management-backup-uploaded", component: () => import("@/views/admin/management/backup/UploadedBackup.vue"), beforeEnter: [setBackupPage], }, ], }, { path: "version", name: "admin-management-version", component: () => import("@/views/admin/management/version/VersionDisplay.vue"), meta: { admin: true }, beforeEnter: [abilityAndNavUpdate], }, ], }, { path: ":pathMatch(.*)*", name: "admin-404", component: () => import("@/views/notFound.vue"), }, ], }, { path: "/account", name: "account", component: () => import("@/views/account/View.vue"), beforeEnter: [isAuthenticated], children: [ { path: "", name: "account-default", component: () => import("@/views/account/ViewSelect.vue"), }, { path: "me", name: "account-me", component: () => import("@/views/account/Me.vue"), }, { path: "logindata", name: "account-logindata", component: () => import("@/views/account/LoginData.vue"), }, { path: "permission", name: "account-permission", component: () => import("@/views/account/Permission.vue"), }, { path: "administration", name: "account-administration", component: () => import("@/views/account/Administration.vue"), }, { path: ":pathMatch(.*)*", name: "account-404", component: () => import("@/views/notFound.vue"), }, ], }, { path: "/public", name: "public", component: () => import("@/views/public/View.vue"), children: [ { path: "", name: "public-default", component: () => import("@/views/notFound.vue"), }, { path: "calendar", name: "public-calendar", component: () => import("@/views/public/calendar/Calendar.vue"), }, { path: "calendar-explain", name: "public-calendar-explain", component: () => import("@/views/public/calendar/CalendarExplain.vue"), }, ], }, { path: "/docs", name: "docs", component: () => import("@/views/docs/View.vue"), beforeEnter: [isAuthenticated], props: true, children: [ { path: "", name: "docs-default", component: () => import("@/views/docs/ViewSelect.vue"), }, { path: ":page", name: "docs-page", component: () => import("@/views/docs/DocPage.vue"), props: true, }, ], }, { path: "/nopermissions", name: "nopermissions", component: () => import("@/views/NoPermission.vue"), }, { path: "/:pathMatch(.*)*", name: "404", component: () => import("@/views/notFound.vue"), }, ], }); router.afterEach((to, from) => { document.title = config.app_name_overwrite || "FF Admin"; }); export default router; declare module "vue-router" { interface RouteMeta { admin?: boolean; type?: PermissionType | "admin"; section?: PermissionSection; module?: PermissionModule; } }