quest-vorteq/src/app/(portal)/layout.tsx
Lorentz a67558de23 feat(F-008,F-009,F-010): complete Phase 1 foundation with middleware, navigation, and migrations
Implements authentication middleware with rate limiting, comprehensive permission
system, full portal navigation with sidebar and header, company selection flow,
and data migration tooling from SQL Server to PostgreSQL.

Key additions:
- Middleware: auth guards, rate limiting, session management
- Permissions: role-based access control with hierarchical permission rules
- Navigation: responsive sidebar with expandable sections, header with notifications
- Company selector: multi-company user support with session-based active company
- Data migration: comprehensive script for migrating auth and quest domain tables
- Schema: added auth_user_type_permission_group junction table

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-16 11:07:44 +00:00

51 lines
1.3 KiB
TypeScript

import { getQuestSession, getActiveCompany } from '@/lib/permissions';
import { PortalSidebar } from '@/components/layout/portal-sidebar';
import { PortalHeader } from '@/components/layout/portal-header';
import { Breadcrumb } from '@/components/layout/breadcrumb';
import { redirect } from 'next/navigation';
import { db } from '@/lib/db';
export default async function PortalLayout({
children,
}: {
children: React.ReactNode;
}) {
// Check authentication
const session = await getQuestSession();
if (!session) {
redirect('/login');
}
// Get active company
const activeCompany = await getActiveCompany();
// Get unread notifications count
const unreadNotifications = await db.quest_user_notification_alert_read.count(
{
where: {
auth_user_id: session.user.id,
},
}
);
const isAdmin =
session.userType === 'Admin' || session.userType === 'Super Admin';
return (
<div className="flex min-h-screen">
<PortalSidebar isAdmin={isAdmin} permissions={session.permissionRules} />
<div className="flex-1 pl-64">
<PortalHeader
companyName={activeCompany?.display_name}
isAdmin={isAdmin}
unreadNotifications={unreadNotifications}
/>
<main className="p-6">
<Breadcrumb />
{children}
</main>
</div>
</div>
);
}