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>
51 lines
1.3 KiB
TypeScript
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>
|
|
);
|
|
}
|