This repository has been archived on 2026-04-03. You can view files and clone it, but cannot push or open issues or pull requests.
nyx/src/router.ts
Nico 42c6079755 Multi-tenant build system with K8s namespace separation
Build-time tenant config via VITE_TENANT env var (--mode loop42/dev).
Content pages moved to tenants/{name}/pages/ with dynamic imports and
loop42 fallback. Feature-gated routing (viewer/devTools per tenant).
Dockerfile parameterized with TENANT build arg. Deployed to separate
K8s namespaces: loop42.de → ns/loop42, loop42.dev → ns/dev.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-01 17:09:22 +02:00

47 lines
2.1 KiB
TypeScript

import { createRouter, createWebHistory, type RouteRecordRaw } from 'vue-router';
import LoginView from './views/LoginView.vue';
import { THEME_NAMES, useTheme } from './composables/useTheme';
import tenant from './tenant';
import { HomePage, ImpressumPage, DatenschutzPage } from './tenantPages';
const routes: RouteRecordRaw[] = [
{ path: '/', name: 'home', component: HomePage, meta: { suffix: '' } },
{ path: '/impressum', name: 'impressum', component: ImpressumPage, meta: { suffix: 'Impressum' } },
{ path: '/datenschutz', name: 'datenschutz', component: DatenschutzPage, meta: { suffix: 'Datenschutz' } },
{ path: '/login', name: 'login', component: LoginView, meta: { suffix: 'Login' } },
{ path: '/nyx', name: 'nyx', component: () => import('./views/AgentsView.vue'), meta: { suffix: 'nyx', requiresAuth: true } },
{ path: '/agents', redirect: '/nyx' },
{ path: '/chat', redirect: '/nyx' },
];
if (tenant.features.viewer) {
routes.push({ path: '/viewer', name: 'viewer', component: () => import('./views/ViewerView.vue'), meta: { suffix: 'Viewer', requiresAuth: true } });
}
routes.push({ path: '/:pathMatch(.*)*', redirect: '/' });
const router = createRouter({
history: createWebHistory(),
routes,
});
// Auth guard — redirect to /login for protected routes
router.beforeEach((to) => {
if (to.meta?.requiresAuth) {
const token = localStorage.getItem('nyx_session');
if (!token) {
sessionStorage.setItem('auth_return_path', to.fullPath);
return { name: 'login' };
}
}
});
router.afterEach((to) => {
const { theme } = useTheme();
const brand = THEME_NAMES[theme.value] || 'loop42';
const suffix = (to.meta?.suffix as string) || '';
document.title = suffix ? `${brand} - ${suffix}` : brand;
});
export default router;