diff --git a/apps/app/src/pages-v2/dashboard.vue b/apps/app/src/pages-v2/dashboard.vue new file mode 100644 index 00000000..4a82305b --- /dev/null +++ b/apps/app/src/pages-v2/dashboard.vue @@ -0,0 +1,9 @@ + + + diff --git a/apps/app/typed-router.d.ts b/apps/app/typed-router.d.ts index 32b7549d..0126b155 100644 --- a/apps/app/typed-router.d.ts +++ b/apps/app/typed-router.d.ts @@ -63,6 +63,7 @@ declare module 'vue-router/auto-routes' { 'register-success': RouteRecordInfo<'register-success', '/register/success', Record, Record>, 'reset-password': RouteRecordInfo<'reset-password', '/reset-password', Record, Record>, 'select-organisation': RouteRecordInfo<'select-organisation', '/select-organisation', Record, Record>, + 'v2-dashboard': RouteRecordInfo<'v2-dashboard', '/v2/dashboard', Record, Record>, 'verify-email-change': RouteRecordInfo<'verify-email-change', '/verify-email-change', Record, Record>, } } diff --git a/apps/app/vite.config.ts b/apps/app/vite.config.ts index 26b954d6..9030c602 100644 --- a/apps/app/vite.config.ts +++ b/apps/app/vite.config.ts @@ -14,6 +14,7 @@ import MetaLayouts from 'vite-plugin-vue-meta-layouts' import vuetify from 'vite-plugin-vuetify' import tailwindcss from '@tailwindcss/vite' import svgLoader from 'vite-svg-loader' +import { v2RouteName } from './src/plugins/1.router/v2RouteName' // https://vitejs.dev/config/ export default defineConfig({ @@ -21,11 +22,42 @@ export default defineConfig({ // Docs: https://github.com/posva/unplugin-vue-router // ℹ️ This plugin should be placed before vue plugin VueRouter({ + // Parallel /v2/* tree (RFC-WS-GUI-REDESIGN AD-G1). The second + // routesFolder prefixes every v2 URL with /v2/; v2RouteName then + // prefixes the route NAME with `v2-` so file-name twins across + // pages/ and pages-v2/ cannot collide. Reverted at final cutover. + routesFolder: [ + { src: 'src/pages' }, + { src: 'src/pages-v2', path: 'v2/' }, + ], getRouteName: routeNode => { // Convert pascal case to kebab case - return getPascalCaseRouteName(routeNode) + const raw = getPascalCaseRouteName(routeNode) .replace(/([a-z\d])([A-Z])/g, '$1-$2') .toLowerCase() + + // Defensive path read: unplugin-vue-router 0.8.8 TreeNode exposes + // `.fullPath`; fall back to `.value.path` then '' so a future + // plugin bump can't silently drop the v2- prefix. Step 5 below + // empirically verifies the emitted name. + const nodePath + = (routeNode.fullPath + ?? routeNode.value?.path + ?? '') as string + + // getPascalCaseRouteName includes the 'v2' segment from the URL + // path prefix set by routesFolder (e.g. 'v2/dashboard' → 'v2-dashboard'). + // Strip that prefix before v2RouteName re-adds the canonical `v2-` + // so we get 'v2-dashboard' not 'v2-v2-dashboard'. + const isV2 + = nodePath === '/v2' + || nodePath === 'v2' + || nodePath.startsWith('/v2/') + || nodePath.startsWith('v2/') + + const base = isV2 && raw.startsWith('v2-') ? raw.slice(3) : raw + + return v2RouteName(base, nodePath) }, }), vue(),