RM / src /app /(dashboard) /layout.tsx
trretretret's picture
Initial commit: Add research assistant application
b708f13
// src/app/(dashboard)/layout.tsx
import { redirect } from 'next/navigation';
import { cookies } from 'next/headers';
import Navigation from '@/components/organisms/Navigation'; // Client component for sidebar
import { API_BASE_URL } from '@/lib/constants/api';
export default async function DashboardLayout({
children,
}: {
children: React.ReactNode;
}) {
// 1. Securely retrieve the token exactly as the FastAPI backend issues it
const cookieStore = cookies();
const token = cookieStore.get('access_token')?.value;
// 2. Immediate rejection if no token is present
if (!token) {
redirect('/login');
}
// 3. Optional: Validate the token against the backend to prevent spoofing
// Matches standard FastAPI /users/me or /auth/me endpoints
try {
const response = await fetch(`${API_BASE_URL}/users/me`, {
headers: {
Authorization: `Bearer ${token}`,
},
// Cache settings depend on how strictly you want to check token validity per navigation
cache: 'no-store',
});
if (!response.ok) {
// If FastAPI returns 401 Unauthorized (e.g., token expired)
redirect('/login');
}
// Parse user data to pass to client components (like is_premium status)
const user = await response.json();
return (
<div className="flex h-screen overflow-hidden bg-slate-50">
{/* Navigation is likely a Client Component ("use client")
that handles active states, but we can pass server-fetched user data to it
*/}
<Navigation user={user} />
{/* Main Content Area for the 10 Research Phases */}
<main className="flex-1 overflow-y-auto overflow-x-hidden pt-16 md:pt-0">
<div className="mx-auto max-w-7xl px-4 py-8 sm:px-6 md:px-8">
{children}
</div>
</main>
</div>
);
} catch (error) {
// Failsafe: If the backend is unreachable, force re-auth or show error
console.error('Backend connection failed:', error);
redirect('/login');
}
}