feat(SPA): "<page> · RenewCMS" as pages titles, instead of being stuck on whatever lands on first loading
This commit is contained in:
1 parent
fe254112a2
commit
0632bf53cb
12 files changed
+702
-194
No files matched your search
+157
-148
@@ -1,128 +1,128 @@
|
||||
import {
|
||||
createRouter,
|
||||
createWebHistory,
|
||||
type RouterHistory,
|
||||
type RouteLocationNormalized,
|
||||
type RouteLocationRaw,
|
||||
type RouteRecordRaw,
|
||||
} from 'vue-router'
|
||||
import { useSessionStore } from '@/stores/session'
|
||||
import { installDocumentTitle } from '@/composables/documentTitle'
|
||||
|
||||
export type AuthRequirement = 'public' | 'session' | 'verified' | 'any'
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHistory(import.meta.env.BASE_URL),
|
||||
routes: [
|
||||
{
|
||||
path: '/',
|
||||
component: () => import('@/views/RootView.vue'),
|
||||
meta: { auth: 'any' },
|
||||
},
|
||||
{
|
||||
path: '/login',
|
||||
component: () => import('@/views/LoginView.vue'),
|
||||
meta: { auth: 'public' },
|
||||
},
|
||||
{
|
||||
path: '/register',
|
||||
component: () => import('@/views/RegisterView.vue'),
|
||||
meta: { auth: 'public' },
|
||||
},
|
||||
{
|
||||
path: '/register/pending',
|
||||
component: () => import('@/views/PendingView.vue'),
|
||||
meta: { auth: 'session' },
|
||||
},
|
||||
{
|
||||
path: '/register/validate',
|
||||
component: () => import('@/views/VerifyView.vue'),
|
||||
meta: { auth: 'public' },
|
||||
},
|
||||
{
|
||||
path: '/register/reset/request',
|
||||
component: () => import('@/views/ResetRequestView.vue'),
|
||||
meta: { auth: 'public' },
|
||||
},
|
||||
{
|
||||
path: '/register/reset/validate',
|
||||
component: () => import('@/views/ResetConfirmView.vue'),
|
||||
meta: { auth: 'public' },
|
||||
},
|
||||
{
|
||||
path: '/invite/accept',
|
||||
component: () => import('@/views/AcceptInviteView.vue'),
|
||||
meta: { auth: 'public' },
|
||||
},
|
||||
{
|
||||
path: '/home',
|
||||
component: () => import('@/views/HomeView.vue'),
|
||||
meta: { auth: 'verified', title: 'Home' },
|
||||
},
|
||||
{
|
||||
path: '/article',
|
||||
component: () => import('@/views/ArticleView.vue'),
|
||||
meta: { auth: 'verified', title: 'Articles' },
|
||||
},
|
||||
{
|
||||
path: '/article/new',
|
||||
component: () => import('@/views/ArticleView.vue'),
|
||||
meta: { auth: 'verified', title: 'Articles' },
|
||||
},
|
||||
{
|
||||
path: '/article/:id/edit',
|
||||
component: () => import('@/views/EditorView.vue'),
|
||||
meta: { auth: 'verified', title: 'Editor' },
|
||||
},
|
||||
{
|
||||
path: '/media',
|
||||
component: () => import('@/views/MediaView.vue'),
|
||||
meta: { auth: 'verified', title: 'Media' },
|
||||
},
|
||||
{
|
||||
path: '/users',
|
||||
component: () => import('@/views/UsersView.vue'),
|
||||
meta: { auth: 'verified', title: 'Users' },
|
||||
},
|
||||
{
|
||||
path: '/activity',
|
||||
component: () => import('@/views/ActivityView.vue'),
|
||||
meta: { auth: 'verified', title: 'Activity' },
|
||||
},
|
||||
{
|
||||
path: '/profile',
|
||||
component: () => import('@/views/ProfileView.vue'),
|
||||
meta: { auth: 'verified', title: 'Profile' },
|
||||
},
|
||||
{
|
||||
path: '/integration',
|
||||
component: () => import('@/views/IntegrationView.vue'),
|
||||
meta: { auth: 'verified', title: 'Integration' },
|
||||
},
|
||||
{
|
||||
path: '/integration/api-keys',
|
||||
component: () => import('@/views/ApiKeysView.vue'),
|
||||
meta: { auth: 'verified', title: 'Integration' },
|
||||
},
|
||||
{
|
||||
path: '/settings',
|
||||
component: () => import('@/views/SettingsView.vue'),
|
||||
meta: { auth: 'verified', title: 'Settings' },
|
||||
},
|
||||
{
|
||||
path: '/settings/media/variants',
|
||||
component: () => import('@/views/VariantsPage.vue'),
|
||||
meta: { auth: 'verified', title: 'Settings' },
|
||||
},
|
||||
{
|
||||
path: '/settings/media/cache',
|
||||
component: () => import('@/views/CachePage.vue'),
|
||||
meta: { auth: 'verified', title: 'Settings' },
|
||||
},
|
||||
{
|
||||
path: '/:pathMatch(.*)*',
|
||||
component: () => import('@/views/NotFoundView.vue'),
|
||||
meta: { auth: 'any' },
|
||||
},
|
||||
],
|
||||
})
|
||||
const routes: RouteRecordRaw[] = [
|
||||
{
|
||||
path: '/',
|
||||
component: () => import('@/views/RootView.vue'),
|
||||
meta: { auth: 'any' },
|
||||
},
|
||||
{
|
||||
path: '/login',
|
||||
component: () => import('@/views/LoginView.vue'),
|
||||
meta: { auth: 'public' },
|
||||
},
|
||||
{
|
||||
path: '/register',
|
||||
component: () => import('@/views/RegisterView.vue'),
|
||||
meta: { auth: 'public' },
|
||||
},
|
||||
{
|
||||
path: '/register/pending',
|
||||
component: () => import('@/views/PendingView.vue'),
|
||||
meta: { auth: 'session' },
|
||||
},
|
||||
{
|
||||
path: '/register/validate',
|
||||
component: () => import('@/views/VerifyView.vue'),
|
||||
meta: { auth: 'public' },
|
||||
},
|
||||
{
|
||||
path: '/register/reset/request',
|
||||
component: () => import('@/views/ResetRequestView.vue'),
|
||||
meta: { auth: 'public' },
|
||||
},
|
||||
{
|
||||
path: '/register/reset/validate',
|
||||
component: () => import('@/views/ResetConfirmView.vue'),
|
||||
meta: { auth: 'public' },
|
||||
},
|
||||
{
|
||||
path: '/invite/accept',
|
||||
component: () => import('@/views/AcceptInviteView.vue'),
|
||||
meta: { auth: 'public' },
|
||||
},
|
||||
{
|
||||
path: '/home',
|
||||
component: () => import('@/views/HomeView.vue'),
|
||||
meta: { auth: 'verified', title: 'Home' },
|
||||
},
|
||||
{
|
||||
path: '/article',
|
||||
component: () => import('@/views/ArticleView.vue'),
|
||||
meta: { auth: 'verified', title: 'Articles' },
|
||||
},
|
||||
{
|
||||
path: '/article/new',
|
||||
component: () => import('@/views/ArticleView.vue'),
|
||||
meta: { auth: 'verified', title: 'Articles' },
|
||||
},
|
||||
{
|
||||
path: '/article/:id/edit',
|
||||
component: () => import('@/views/EditorView.vue'),
|
||||
meta: { auth: 'verified', title: 'Editor' },
|
||||
},
|
||||
{
|
||||
path: '/media',
|
||||
component: () => import('@/views/MediaView.vue'),
|
||||
meta: { auth: 'verified', title: 'Media' },
|
||||
},
|
||||
{
|
||||
path: '/users',
|
||||
component: () => import('@/views/UsersView.vue'),
|
||||
meta: { auth: 'verified', title: 'Users' },
|
||||
},
|
||||
{
|
||||
path: '/activity',
|
||||
component: () => import('@/views/ActivityView.vue'),
|
||||
meta: { auth: 'verified', title: 'Activity' },
|
||||
},
|
||||
{
|
||||
path: '/profile',
|
||||
component: () => import('@/views/ProfileView.vue'),
|
||||
meta: { auth: 'verified', title: 'Profile' },
|
||||
},
|
||||
{
|
||||
path: '/integration',
|
||||
component: () => import('@/views/IntegrationView.vue'),
|
||||
meta: { auth: 'verified', title: 'Integration' },
|
||||
},
|
||||
{
|
||||
path: '/integration/api-keys',
|
||||
component: () => import('@/views/ApiKeysView.vue'),
|
||||
meta: { auth: 'verified', title: 'Integration' },
|
||||
},
|
||||
{
|
||||
path: '/settings',
|
||||
component: () => import('@/views/SettingsView.vue'),
|
||||
meta: { auth: 'verified', title: 'Settings' },
|
||||
},
|
||||
{
|
||||
path: '/settings/media/variants',
|
||||
component: () => import('@/views/VariantsPage.vue'),
|
||||
meta: { auth: 'verified', title: 'Settings' },
|
||||
},
|
||||
{
|
||||
path: '/settings/media/cache',
|
||||
component: () => import('@/views/CachePage.vue'),
|
||||
meta: { auth: 'verified', title: 'Settings' },
|
||||
},
|
||||
{
|
||||
path: '/:pathMatch(.*)*',
|
||||
component: () => import('@/views/NotFoundView.vue'),
|
||||
meta: { auth: 'public', documentTitle: '404' },
|
||||
},
|
||||
]
|
||||
|
||||
export function resolveAuthRedirect(
|
||||
to: RouteLocationNormalized,
|
||||
@@ -163,41 +163,50 @@ export function resolveAuthRedirect(
|
||||
return true
|
||||
}
|
||||
|
||||
router.beforeEach((to) => {
|
||||
if (to.meta.auth === 'public') {
|
||||
return true
|
||||
}
|
||||
export function createAppRouter(history: RouterHistory) {
|
||||
const router = createRouter({ history, routes })
|
||||
installDocumentTitle(router)
|
||||
|
||||
const session = useSessionStore()
|
||||
|
||||
if (session.status === 'idle') {
|
||||
session.check()
|
||||
return true
|
||||
}
|
||||
if (session.status === 'checking') {
|
||||
return true
|
||||
}
|
||||
|
||||
return resolveAuthRedirect(to, session)
|
||||
})
|
||||
|
||||
router.afterEach((to) => {
|
||||
if (to.meta.auth === 'public') {
|
||||
return
|
||||
}
|
||||
|
||||
const session = useSessionStore()
|
||||
const settled =
|
||||
session.status === 'idle' || session.status === 'checking'
|
||||
? session.check()
|
||||
: Promise.resolve()
|
||||
|
||||
settled.then(() => {
|
||||
const destination = resolveAuthRedirect(router.currentRoute.value, session)
|
||||
if (destination !== true) {
|
||||
router.replace(destination)
|
||||
router.beforeEach((to) => {
|
||||
if (to.meta.auth === 'public') {
|
||||
return true
|
||||
}
|
||||
|
||||
const session = useSessionStore()
|
||||
|
||||
if (session.status === 'idle') {
|
||||
session.check()
|
||||
return true
|
||||
}
|
||||
if (session.status === 'checking') {
|
||||
return true
|
||||
}
|
||||
|
||||
return resolveAuthRedirect(to, session)
|
||||
})
|
||||
})
|
||||
|
||||
router.afterEach((to) => {
|
||||
if (to.meta.auth === 'public') {
|
||||
return
|
||||
}
|
||||
|
||||
const session = useSessionStore()
|
||||
const settled =
|
||||
session.status === 'idle' || session.status === 'checking'
|
||||
? session.check()
|
||||
: Promise.resolve()
|
||||
|
||||
settled.then(() => {
|
||||
const destination = resolveAuthRedirect(router.currentRoute.value, session)
|
||||
if (destination !== true) {
|
||||
router.replace(destination)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
return router
|
||||
}
|
||||
|
||||
const router = createAppRouter(createWebHistory(import.meta.env.BASE_URL))
|
||||
|
||||
export default router
|
||||
Reference in new issue
Block a user