2026-01-11 21:30:57 +05:30
|
|
|
'use client';
|
|
|
|
|
|
2026-01-19 09:20:48 +05:30
|
|
|
import { useSession } from 'next-auth/react';
|
2026-01-19 10:30:28 +05:30
|
|
|
import { useRouter, usePathname } from 'next/navigation';
|
2026-03-10 09:28:19 +05:30
|
|
|
import { useEffect } from 'react';
|
2026-04-09 16:06:34 +05:30
|
|
|
import Image from 'next/image';
|
2026-01-19 09:20:48 +05:30
|
|
|
import { Footer } from '@/components/layout/Footer';
|
|
|
|
|
import { CommonHeader } from '@/components/layout/CommonHeader';
|
2026-02-21 22:11:42 +05:30
|
|
|
import { PresenceProvider } from '@/components/providers/presence-provider';
|
2026-01-11 21:30:57 +05:30
|
|
|
|
2026-01-29 00:02:59 +05:30
|
|
|
// Pages that don't require authentication
|
|
|
|
|
const publicPaths = [
|
|
|
|
|
'/user/dashboard',
|
|
|
|
|
'/user/profiles',
|
|
|
|
|
'/user/profile/', // Agent profile view (includes /user/profile/[id])
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
// Check if current path is public
|
|
|
|
|
const isPublicPath = (pathname: string) => {
|
|
|
|
|
return publicPaths.some(path => pathname === path || pathname.startsWith(path));
|
|
|
|
|
};
|
|
|
|
|
|
2026-01-11 21:21:34 +05:30
|
|
|
export default function UserLayout({
|
|
|
|
|
children,
|
|
|
|
|
}: {
|
|
|
|
|
children: React.ReactNode;
|
|
|
|
|
}) {
|
2026-01-11 21:30:57 +05:30
|
|
|
const { data: session, status } = useSession();
|
|
|
|
|
const router = useRouter();
|
2026-01-19 10:30:28 +05:30
|
|
|
const pathname = usePathname();
|
|
|
|
|
const isDashboard = pathname === '/user/dashboard';
|
2026-01-29 00:02:59 +05:30
|
|
|
const isPublic = isPublicPath(pathname);
|
2026-01-11 21:30:57 +05:30
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
if (status === 'loading') return;
|
|
|
|
|
|
2026-01-29 00:02:59 +05:30
|
|
|
// Allow public pages without authentication
|
|
|
|
|
if (isPublic) {
|
|
|
|
|
// If logged in as agent, redirect to agent dashboard only from user dashboard
|
|
|
|
|
if (session && pathname === '/user/dashboard') {
|
|
|
|
|
const userRole = (session.user as any)?.role;
|
|
|
|
|
if (userRole === 'AGENT') {
|
|
|
|
|
router.replace('/agent/dashboard');
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-10 09:28:19 +05:30
|
|
|
// Don't redirect to /login here for protected pages — the middleware handles that.
|
|
|
|
|
// Doing it here causes race conditions during logout (layout detects session loss
|
|
|
|
|
// and redirects to /login via client-side navigation, conflicting with server-side
|
|
|
|
|
// logout redirect).
|
|
|
|
|
if (!session) return;
|
2026-01-11 21:30:57 +05:30
|
|
|
|
2026-01-29 00:02:59 +05:30
|
|
|
// Redirect agents to agent dashboard for protected user pages
|
2026-01-11 21:30:57 +05:30
|
|
|
const userRole = (session.user as any)?.role;
|
|
|
|
|
if (userRole === 'AGENT') {
|
|
|
|
|
router.replace('/agent/dashboard');
|
|
|
|
|
}
|
2026-01-29 00:02:59 +05:30
|
|
|
}, [session, status, router, pathname, isPublic]);
|
|
|
|
|
|
2026-04-09 16:06:34 +05:30
|
|
|
const splashLoading = (
|
|
|
|
|
<div
|
|
|
|
|
className="min-h-screen flex flex-col items-center justify-center"
|
|
|
|
|
style={{ background: 'linear-gradient(to bottom, #c4d9d4, #f0f5fc)' }}
|
|
|
|
|
>
|
|
|
|
|
<Image src="/assets/images/splash-house.png" alt="" width={150} height={108} priority />
|
|
|
|
|
<div className="mt-[35px]">
|
|
|
|
|
<Image src="/assets/images/splash-logo.png" alt="RE-Quest" width={264} height={55} priority />
|
|
|
|
|
</div>
|
|
|
|
|
<div className="mt-8">
|
|
|
|
|
<div className="animate-spin rounded-full h-8 w-8 border-b-2 border-[#00293d]" />
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
|
2026-01-29 00:02:59 +05:30
|
|
|
// Show loading only for protected pages while checking auth
|
|
|
|
|
if (status === 'loading' && !isPublic) {
|
2026-04-09 16:06:34 +05:30
|
|
|
return splashLoading;
|
2026-01-29 00:02:59 +05:30
|
|
|
}
|
2026-01-11 21:30:57 +05:30
|
|
|
|
2026-01-29 00:02:59 +05:30
|
|
|
// Redirect protected pages if not logged in
|
|
|
|
|
if (!session && !isPublic) {
|
2026-04-09 16:06:34 +05:30
|
|
|
return splashLoading;
|
2026-01-11 21:30:57 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return (
|
2026-02-21 22:11:42 +05:30
|
|
|
<PresenceProvider>
|
|
|
|
|
<div className="min-h-screen flex flex-col">
|
|
|
|
|
{isDashboard ? (
|
|
|
|
|
<>
|
|
|
|
|
{/* Main Content with Header Overlay for Dashboard */}
|
|
|
|
|
<main className="flex-1 relative">
|
|
|
|
|
{/* Header overlaying the content */}
|
|
|
|
|
<div className="absolute top-0 left-0 right-0 z-50 px-4 py-3">
|
|
|
|
|
<div className="max-w-7xl mx-auto">
|
|
|
|
|
<CommonHeader />
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
{children}
|
|
|
|
|
</main>
|
|
|
|
|
</>
|
|
|
|
|
) : (
|
|
|
|
|
<>
|
|
|
|
|
{/* Regular Header for other pages */}
|
2026-03-28 20:08:59 +05:30
|
|
|
<div className="px-4 sm:px-6 lg:px-8 pt-3 pb-1 bg-white">
|
2026-01-19 10:30:28 +05:30
|
|
|
<div className="max-w-7xl mx-auto">
|
|
|
|
|
<CommonHeader />
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
2026-02-21 22:11:42 +05:30
|
|
|
{/* Main Content */}
|
|
|
|
|
<main className="flex-1">
|
|
|
|
|
{children}
|
|
|
|
|
</main>
|
|
|
|
|
</>
|
|
|
|
|
)}
|
2026-01-11 21:30:57 +05:30
|
|
|
|
2026-02-21 22:11:42 +05:30
|
|
|
{/* Footer */}
|
|
|
|
|
<Footer />
|
|
|
|
|
</div>
|
|
|
|
|
</PresenceProvider>
|
2026-01-11 21:30:57 +05:30
|
|
|
);
|
2026-01-11 21:21:34 +05:30
|
|
|
}
|