Initial commit
This commit is contained in:
233
resources/js/router/index.js
vendored
Normal file
233
resources/js/router/index.js
vendored
Normal file
@@ -0,0 +1,233 @@
|
||||
import Vue from 'vue'
|
||||
import store from '~/store'
|
||||
import Meta from 'vue-meta'
|
||||
import routes from './routes'
|
||||
import Router from 'vue-router'
|
||||
import { sync } from 'vuex-router-sync'
|
||||
|
||||
Vue.use(Meta)
|
||||
Vue.use(Router)
|
||||
|
||||
// The middleware for every page of the application.
|
||||
const globalMiddleware = ['locale', 'check-auth', 'notion-connection']
|
||||
|
||||
// Load middleware modules dynamically.
|
||||
const routeMiddleware = resolveMiddleware(
|
||||
require.context('~/middleware', false, /.*\.js$/)
|
||||
)
|
||||
|
||||
const router = createRouter()
|
||||
|
||||
sync(store, router)
|
||||
|
||||
export default router
|
||||
|
||||
/**
|
||||
* Create a new router instance.
|
||||
*
|
||||
* @return {Router}
|
||||
*/
|
||||
function createRouter () {
|
||||
const router = new Router({
|
||||
scrollBehavior,
|
||||
mode: 'history',
|
||||
routes
|
||||
})
|
||||
|
||||
router.beforeEach(beforeEach)
|
||||
router.afterEach(afterEach)
|
||||
|
||||
return router
|
||||
}
|
||||
|
||||
/**
|
||||
* Global router guard.
|
||||
*
|
||||
* @param {Route} to
|
||||
* @param {Route} from
|
||||
* @param {Function} next
|
||||
*/
|
||||
async function beforeEach (to, from, next) {
|
||||
let components = []
|
||||
|
||||
// External redirect
|
||||
if (to.matched.some((record) => record.meta.externalUrl)) {
|
||||
const url = to.meta.externalUrl
|
||||
window.location.replace(url)
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
// Get the matched components and resolve them.
|
||||
components = await resolveComponents(
|
||||
router.getMatchedComponents({ ...to })
|
||||
)
|
||||
} catch (error) {
|
||||
if (/^Loading( CSS)? chunk (\d)+ failed\./.test(error.message)) {
|
||||
window.location.reload(true)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if (components.length === 0) {
|
||||
return next()
|
||||
}
|
||||
|
||||
// Start the loading bar.
|
||||
if (components[components.length - 1].loading !== false) {
|
||||
router.app.$nextTick(() => router.app.$loading.start())
|
||||
}
|
||||
|
||||
// Get the middleware for all the matched components.
|
||||
const middleware = getMiddleware(components)
|
||||
|
||||
// Call each middleware.
|
||||
callMiddleware(middleware, to, from, (...args) => {
|
||||
// Set the application layout only if "next()" was called with no args.
|
||||
if (args.length === 0) {
|
||||
router.app.setLayout(components[0].layout || '')
|
||||
}
|
||||
|
||||
next(...args)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Global after hook.
|
||||
*
|
||||
* @param {Route} to
|
||||
* @param {Route} from
|
||||
* @param {Function} next
|
||||
*/
|
||||
async function afterEach (to, from, next) {
|
||||
await router.app.$nextTick()
|
||||
|
||||
router.app.$loading.finish()
|
||||
}
|
||||
|
||||
/**
|
||||
* Call each middleware.
|
||||
*
|
||||
* @param {Array} middleware
|
||||
* @param {Route} to
|
||||
* @param {Route} from
|
||||
* @param {Function} next
|
||||
*/
|
||||
function callMiddleware (middleware, to, from, next) {
|
||||
const stack = middleware.reverse()
|
||||
|
||||
const _next = (...args) => {
|
||||
// Stop if "_next" was called with an argument or the stack is empty.
|
||||
if (args.length > 0 || stack.length === 0) {
|
||||
if (args.length > 0) {
|
||||
router.app.$loading.finish()
|
||||
}
|
||||
|
||||
return next(...args)
|
||||
}
|
||||
|
||||
const { middleware, params } = parseMiddleware(stack.pop())
|
||||
|
||||
if (typeof middleware === 'function') {
|
||||
middleware(to, from, _next, params)
|
||||
} else if (routeMiddleware[middleware]) {
|
||||
routeMiddleware[middleware](to, from, _next, params)
|
||||
} else {
|
||||
throw Error(`Undefined middleware [${middleware}]`)
|
||||
}
|
||||
}
|
||||
|
||||
_next()
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {String|Function} middleware
|
||||
* @return {Object}
|
||||
*/
|
||||
function parseMiddleware (middleware) {
|
||||
if (typeof middleware === 'function') {
|
||||
return { middleware }
|
||||
}
|
||||
|
||||
const [name, params] = middleware.split(':')
|
||||
|
||||
return { middleware: name, params }
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve async components.
|
||||
*
|
||||
* @param {Array} components
|
||||
* @return {Array}
|
||||
*/
|
||||
function resolveComponents (components) {
|
||||
return Promise.all(components.map(component => {
|
||||
return typeof component === 'function' ? component() : component
|
||||
}))
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge the the global middleware with the components middleware.
|
||||
*
|
||||
* @param {Array} components
|
||||
* @return {Array}
|
||||
*/
|
||||
function getMiddleware (components) {
|
||||
const middleware = [...globalMiddleware]
|
||||
|
||||
components.filter(c => c.middleware).forEach(component => {
|
||||
if (Array.isArray(component.middleware)) {
|
||||
middleware.push(...component.middleware)
|
||||
} else {
|
||||
middleware.push(component.middleware)
|
||||
}
|
||||
})
|
||||
|
||||
return middleware
|
||||
}
|
||||
|
||||
/**
|
||||
* Scroll Behavior
|
||||
*
|
||||
* @link https://router.vuejs.org/en/advanced/scroll-behavior.html
|
||||
*
|
||||
* @param {Route} to
|
||||
* @param {Route} from
|
||||
* @param {Object|undefined} savedPosition
|
||||
* @return {Object}
|
||||
*/
|
||||
function scrollBehavior (to, from, savedPosition) {
|
||||
if (savedPosition) {
|
||||
return savedPosition
|
||||
}
|
||||
|
||||
if (to.hash) {
|
||||
return { selector: to.hash }
|
||||
}
|
||||
|
||||
const [component] = router.getMatchedComponents({ ...to }).slice(-1)
|
||||
|
||||
if (component && component.scrollToTop === false) {
|
||||
return {}
|
||||
}
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
setTimeout(() => {
|
||||
resolve({ x: 0, y: 0 })
|
||||
}, 190)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Object} requireContext
|
||||
* @return {Object}
|
||||
*/
|
||||
function resolveMiddleware (requireContext) {
|
||||
return requireContext.keys()
|
||||
.map(file =>
|
||||
[file.replace(/(^.\/)|(\.js$)/g, ''), requireContext(file)]
|
||||
)
|
||||
.reduce((guards, [name, guard]) => (
|
||||
{ ...guards, [name]: guard.default }
|
||||
), {})
|
||||
}
|
||||
56
resources/js/router/routes.js
vendored
Normal file
56
resources/js/router/routes.js
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
function page (path) {
|
||||
return () => import(/* webpackChunkName: '' */ `~/pages/${path}`).then(m => m.default || m)
|
||||
}
|
||||
|
||||
export default [
|
||||
// Logged Users
|
||||
{ path: '/home', name: 'home', component: page('home.vue') },
|
||||
|
||||
// Forms
|
||||
{ path: '/forms/create', name: 'forms.create', component: page('forms/create.vue') },
|
||||
{ path: '/forms/:slug/show', name: 'forms.show', component: page('forms/show.vue') },
|
||||
{ path: '/forms/:slug/edit', name: 'forms.edit', component: page('forms/edit.vue') },
|
||||
|
||||
// Subscription
|
||||
{ path: '/subscriptions/success', name: 'subscriptions.success', component: page('subscriptions/success.vue') },
|
||||
{ path: '/subscriptions/error', name: 'subscriptions.error', component: page('subscriptions/error.vue') },
|
||||
|
||||
// Settings
|
||||
{
|
||||
path: '/settings',
|
||||
component: page('settings/index.vue'),
|
||||
children: [
|
||||
{ path: '', redirect: { name: 'settings.workspaces' } },
|
||||
{ path: 'workspaces', name: 'settings.workspaces', component: page('settings/workspace.vue') },
|
||||
{ path: 'billing', name: 'settings.billing', component: page('settings/billing.vue') },
|
||||
{ path: 'profile', name: 'settings.profile', component: page('settings/profile.vue') },
|
||||
{ path: 'account', name: 'settings.account', component: page('settings/account.vue') },
|
||||
{ path: 'password', name: 'settings.password', component: page('settings/password.vue') },
|
||||
{ path: 'admin', name: 'settings.admin', component: page('settings/admin.vue') }
|
||||
]
|
||||
},
|
||||
|
||||
// Auth Routes
|
||||
{ path: '/login', name: 'login', component: page('auth/login.vue') },
|
||||
{ path: '/register', name: 'register', component: page('auth/register.vue') },
|
||||
{ path: '/password/reset', name: 'password.request', component: page('auth/password/email.vue') },
|
||||
{ path: '/password/reset/:token', name: 'password.reset', component: page('auth/password/reset.vue') },
|
||||
{ path: '/email/verify/:id', name: 'verification.verify', component: page('auth/verification/verify.vue') },
|
||||
{ path: '/email/resend', name: 'verification.resend', component: page('auth/verification/resend.vue') },
|
||||
|
||||
// Public Content
|
||||
|
||||
// Legal Routes
|
||||
{ path: '/privacy-policy', name: 'privacy-policy', component: page('legal-help/privacy-policy.vue') },
|
||||
{ path: '/terms-conditions', name: 'terms-conditions', component: page('legal-help/terms-conditions.vue') },
|
||||
|
||||
// Community
|
||||
{ path: '/discount-students-academics-ngos', name: 'discount-community', component: page('community/students-academics-ngos.vue') },
|
||||
|
||||
// Guest Routes
|
||||
{ path: '/', name: 'welcome', component: page('welcome.vue') },
|
||||
{ path: '/integrations', name: 'integrations', component: page('integrations.vue') },
|
||||
{ path: '/forms/:slug', name: 'forms.show_public', component: page('forms/show-public.vue') },
|
||||
|
||||
{ path: '*', component: page('errors/404.vue') }
|
||||
]
|
||||
Reference in New Issue
Block a user