import { headers } from "next/headers"; import { auth } from "@/lib/auth"; import { prisma } from "@/lib/prisma"; import { redirect } from "next/navigation"; import Link from "next/link"; import { LogoutButton } from "@/components/layout/logout-button"; import { getSetting } from "@/lib/settings"; import { StopImpersonateBanner } from "@/components/admin/stop-impersonate-banner"; export default async function StudentLayout({ children }: { children: React.ReactNode }) { const session = await auth.api.getSession({ headers: await headers() }); if (!session) redirect("/login"); const isImpersonating = !!(session.session as { impersonatedBy?: string }).impersonatedBy; // Force password change for auto-provisioned buyers (temp password). // Skip while an admin is impersonating — they only view the client's cabinet; // the client sets their own password on a real first login. const dbUser = await prisma.user.findUnique({ where: { id: session.user.id }, select: { mustChangePassword: true }, }); if (dbUser?.mustChangePassword && !isImpersonating) redirect("/change-password"); // Maintenance mode: non-admin users see the maintenance page if (session.user.role !== "admin") { const maintenance = await getSetting("maintenanceMode"); if (maintenance === "true") redirect("/maintenance"); } const [schoolName, logoUrl, showLogo, socialYoutube, socialVk, socialTelegram, orgRequisites] = await Promise.all([ getSetting("schoolName"), getSetting("logoUrl"), getSetting("showLogo"), getSetting("socialYoutube"), getSetting("socialVk"), getSetting("socialTelegram"), getSetting("orgRequisites"), ]); return (
{isImpersonating && }
{logoUrl && showLogo === "true" && ( // eslint-disable-next-line @next/next/no-img-element {schoolName} )} {schoolName}
Wrapped {process.env.TOOLBOX_VISIBLE === "true" && ( Инструменты )} Вопросы {session.user.name}
{children}
{(socialYoutube || socialVk || socialTelegram || orgRequisites) && ( )}
); }