'use client';
import { useState, useRef, useEffect } from 'react';
import {
BiMenu,
BiChevronDown,
BiGlobe,
BiLogOut,
BiUserCircle,
BiLock,
BiX,
} from 'react-icons/bi';
import { cn } from '@/components/lib/utils';
import NotificationDropdown from './NotificationDropdown';
import {
Dialog,
DialogContent,
DialogHeader,
DialogTitle,
DialogTrigger,
DialogClose,
} from '@/components/ui/dialog';
import Image from 'next/image';
import Link from 'next/link';
import ChangePasswordModal from './ChangePasswordModal';
import LogoutModal from './LogoutModal';
import { useStudentLogout } from '@/lib/api/student';
import { useRouter } from 'next/navigation';
import { useSelector } from 'react-redux';
import { RootState } from '@/components/store';
import { useLanguage } from '@/components/hooks/useLanguage';
import { useTranslate } from '@/components/hooks/useTranslate';
import { useGetSchoolSettings } from '@/lib/api/student/queryHooks';
interface StudentHeaderProps {
onMenuClick: () => void;
isMobile?: boolean;
}
export default function StudentHeader({
onMenuClick,
isMobile = false,
}: StudentHeaderProps) {
const [selectedLanguage, setSelectedLanguage] = useState('English');
const [isLanguageModalOpen, setIsLanguageModalOpen] = useState(false);
// Change password modal state
const [isChangePasswordModalOpen, setIsChangePasswordModalOpen] =
useState(false);
// Logout modal state
const [isLogoutModalOpen, setIsLogoutModalOpen] = useState(false);
// User profile dropdown state
const [isProfileOpen, setIsProfileOpen] = useState(false);
const [isProfileVisible, setIsProfileVisible] = useState(false);
const profileDropdownRef = useRef<HTMLDivElement>(null);
const profileTriggerRef = useRef<HTMLDivElement>(null);
const hoverTimeoutRef = useRef<NodeJS.Timeout | null>(null);
// Logout hook and router for handling logout
const { logout } = useStudentLogout();
const router = useRouter();
// Get user data from Redux store
const user = useSelector((state: RootState) => state.studentAuth.user);
// Get language state and translate function from Redux
const { changeLanguage, currentLanguageName, languages } = useLanguage();
const translate = useTranslate();
// Load school settings once so we can swap the logo whenever backend updates it
const { data: schoolSettings, isLoading: isLoadingLogo } =
useGetSchoolSettings();
const fallbackLogo = '/assets/images/common/logo.png';
const dynamicLogo = schoolSettings?.data?.settings?.horizontal_logo;
const resolvedLogo =
typeof dynamicLogo === 'string' && dynamicLogo.trim().length > 0
? dynamicLogo.trim()
: fallbackLogo;
// Initialize selected language from Redux store
useEffect(() => {
setSelectedLanguage(currentLanguageName);
}, [currentLanguageName]);
// Handle language selection - update Redux store and close modal
const handleLanguageSelect = (languageName: string) => {
// Find the language code from the language name
const selectedLang = languages.find((lang) => lang.name === languageName);
if (selectedLang) {
// Update language in Redux store
changeLanguage(selectedLang.code);
setSelectedLanguage(languageName);
}
setIsLanguageModalOpen(false); // Close modal after selection
};
// Handle logout - clears Redux state, query cache, and redirects to login
const handleLogout = () => {
// Call logout function to clear Redux state and query cache
logout();
// Close the logout modal
setIsLogoutModalOpen(false);
// Redirect to student login page
router.push('/student/auth/login');
};
// Handle profile dropdown hover
const handleProfileMouseEnter = () => {
if (hoverTimeoutRef.current) {
clearTimeout(hoverTimeoutRef.current);
}
setIsProfileOpen(true);
setTimeout(() => setIsProfileVisible(true), 10);
};
const handleProfileMouseLeave = () => {
hoverTimeoutRef.current = setTimeout(() => {
setIsProfileVisible(false);
setTimeout(() => setIsProfileOpen(false), 150);
}, 150);
};
// Handle click outside to close profile dropdown
useEffect(() => {
const handleClickOutside = (event: MouseEvent) => {
if (
profileDropdownRef.current &&
!profileDropdownRef.current.contains(event.target as Node) &&
profileTriggerRef.current &&
!profileTriggerRef.current.contains(event.target as Node)
) {
setIsProfileVisible(false);
setTimeout(() => setIsProfileOpen(false), 150);
}
};
if (isProfileOpen) {
document.addEventListener('mousedown', handleClickOutside);
}
return () => {
document.removeEventListener('mousedown', handleClickOutside);
if (hoverTimeoutRef.current) {
clearTimeout(hoverTimeoutRef.current);
}
};
}, [isProfileOpen]);
return (
<div className="bg-white border-b border-gray-200 px-3 sm:px-4 lg:px-6 py-3 md:py-4 flex items-center justify-between sticky top-0 z-40">
{/* Left Section - Menu and Logo */}
{/* Using gap instead of space-x for RTL support */}
<div className="flex items-center gap-2 md:gap-3 lg:gap-4">
<button
onClick={onMenuClick}
className="p-1.5 md:p-2 hover:bg-gray-100 rounded-[4px] transition-colors border-[1px] border-[#EAEAEA]"
>
<BiMenu className="w-5 h-5 md:w-6 md:h-6 text-gray-600" />
</button>
{/* Mobile Logo - Show on mobile and tablet */}
{isMobile && (
<div className="flex items-center">
<div className="w-[90px] h-[32px] sm:w-[100px] sm:h-[35px]">
{isLoadingLogo ? (
// Loading skeleton for compact mobile logo
<div className="w-full h-full bg-gray-200 rounded animate-pulse" />
) : (
<Image
src={resolvedLogo}
alt="Logo"
width={0}
height={0}
className="w-full h-full object-contain"
priority
/>
)}
</div>
</div>
)}
</div>
{/* Right Section - User Info and Controls */}
{/* Using gap instead of space-x for RTL support */}
<div className="flex items-center gap-1.5 sm:gap-2 lg:gap-4">
{/* Language Selector Modal - Desktop and Tablet */}
<div className="hidden md:block">
<Dialog
open={isLanguageModalOpen}
onOpenChange={setIsLanguageModalOpen}
>
<DialogTrigger asChild>
<div className="flex items-center gap-1.5 lg:gap-2 cursor-pointer hover:bg-gray-50 px-2 lg:px-3 py-1.5 lg:py-2 rounded-lg transition-colors border border-gray-300 bg-white hover:border-gray-400">
<BiGlobe className="w-4 h-4 text-gray-600 flex-shrink-0" />
<span className="text-xs lg:text-sm font-medium text-gray-900 ">
{selectedLanguage}
</span>
{/* Show only icon on tablets, full text on large screens */}
<BiChevronDown className="w-3.5 h-3.5 lg:w-4 lg:h-4 text-gray-500 " />
</div>
</DialogTrigger>
<DialogContent className="sm:max-w-lg" showCloseButton={false}>
<DialogHeader className="flex flex-row items-center justify-between">
<DialogTitle className="text-left text-xl font-bold text-gray-900">
{translate('chooseYourLanguage')}
</DialogTitle>
<DialogClose asChild>
<button className="p-2 bg-gray-100 rounded transition-colors border-[1px] border-[#EAEAEA]">
<BiX className="w-5 h-5 text-gray-400" />
</button>
</DialogClose>
</DialogHeader>
<div className="space-y-2 mt-6">
{languages.map((language) => (
<button
key={language.code}
onClick={() => handleLanguageSelect(language.name)}
className={`w-full flex items-center gap-3 p-3 rounded-lg border transition-colors text-left ${
selectedLanguage === language.name
? 'border-gray-300 bg-gray-100'
: 'border-gray-200 hover:bg-gray-50 hover:border-gray-300'
}`}
>
<span className="text-lg">{language.flag}</span>
<span className="text-sm font-medium text-gray-900">
{language.name}
</span>
</button>
))}
</div>
</DialogContent>
</Dialog>
</div>
{/* Notifications */}
<NotificationDropdown />
{/* vertical divider - Hidden on mobile and tablet */}
<div className="hidden lg:block h-10 w-[1px] bg-[#EAEAEA]"></div>
{/* User Profile */}
<div className="relative">
{/* Trigger */}
<div
ref={profileTriggerRef}
onMouseEnter={handleProfileMouseEnter}
onMouseLeave={handleProfileMouseLeave}
className="flex items-center gap-1.5 sm:gap-2 lg:gap-3 cursor-pointer hover:bg-gray-50 rounded-[4px] transition-colors p-1 md:p-1.5 lg:p-2"
>
<div className="border-[2px] border-[#EAEAEA] rounded-full p-0.5 md:p-1">
<div className="w-6 h-6 md:w-7 md:h-7 lg:w-8 lg:h-8 rounded-full flex items-center justify-center overflow-hidden">
<Image
src={user?.image || resolvedLogo}
alt="Profile"
width={0}
height={0}
className="w-full h-full object-cover"
priority
/>
</div>
</div>
{/* User info - Show only on large screens (desktop) */}
<div className="hidden lg:flex flex-col">
<span className="text-sm font-medium text-gray-800 max-w-[150px] truncate">
{user?.first_name && user?.last_name
? `${user.first_name} ${user.last_name}`
: 'Student'}
</span>
<span className="text-sm font-normal text-gray-800 flex items-center">
{/* Class section with truncate - max width ~20 characters */}
<span className="max-w-[100px] truncate">
{user?.class_section?.full_name || 'N/A'}
</span>
{/* vertical divider */}
<span className="w-[1px] h-[15px] bg-gray-300 mx-2 flex items-center justify-center flex-shrink-0"></span>
<span className="whitespace-nowrap">
{translate('rollNo')}: {user?.roll_number || 'N/A'}
</span>
</span>
</div>
<BiChevronDown className="text-base md:text-lg lg:text-xl text-white bg-(--primary-color) rounded-full p-0.5 md:p-1 flex-shrink-0" />
</div>
{/* Dropdown Content */}
{isProfileOpen && (
<div
ref={profileDropdownRef}
onMouseEnter={() => {
if (hoverTimeoutRef.current) {
clearTimeout(hoverTimeoutRef.current);
}
}}
onMouseLeave={handleProfileMouseLeave}
className={cn(
'absolute top-full ltr:right-0 rtl:left-0 z-50 mt-1 w-56 overflow-hidden rounded-md border bg-white shadow-md',
'transition-all duration-200 ease-in-out',
isProfileVisible
? 'opacity-100 scale-100 translate-y-0'
: 'opacity-0 scale-95 -translate-y-1',
)}
>
<div className="text-sm font-normal py-3">
{/* <Link
href="/student/dashboard"
className="p-3 hover:bg-gray-100 cursor-pointer flex items-center"
>
<BiHomeAlt2 className="ltr:mr-2 rtl:ml-2 h-5 w-5" />
<span>{translate('goBackToWebsite')}</span>
</Link> */}
<div className="h-px bg-gray-50"></div>
<Link
href="/student/profile"
className="p-3 hover:bg-gray-100 cursor-pointer flex items-center"
>
<BiUserCircle className="ltr:mr-2 rtl:ml-2 h-5 w-5" />
<span>{translate('myProfile')}</span>
</Link>
<div className="h-px bg-gray-50"></div>
<button
onClick={() => setIsChangePasswordModalOpen(true)}
className="w-full p-3 hover:bg-gray-100 cursor-pointer flex items-center text-left"
>
<BiLock className="ltr:mr-2 rtl:ml-2 h-5 w-5" />
<span>{translate('changePassword')}</span>
</button>
<div className="h-px bg-gray-50"></div>
<button
onClick={() => setIsLogoutModalOpen(true)}
className="w-full p-3 hover:bg-gray-100 cursor-pointer flex items-center text-left"
>
<BiLogOut className="ltr:mr-2 rtl:ml-2 h-5 w-5" />
<span>{translate('logOut')}</span>
</button>
</div>
</div>
)}
</div>
</div>
{/* Change Password Modal */}
<ChangePasswordModal
open={isChangePasswordModalOpen}
onOpenChange={setIsChangePasswordModalOpen}
/>
{/* Logout Confirmation Modal */}
<LogoutModal
open={isLogoutModalOpen}
onOpenChange={setIsLogoutModalOpen}
onConfirm={handleLogout}
/>
</div>
);
}