218 lines
13 KiB
TypeScript
218 lines
13 KiB
TypeScript
'use client';
|
||
import { FC, useState, useEffect } from "react";
|
||
import { HeaderProps } from "@/validations/mutual/dashboard/props";
|
||
import { langGetKey } from "@/lib/langGet";
|
||
import { LanguageTypes } from "@/validations/mutual/language/validations";
|
||
import LanguageSelectionComponent from "@/components/mutual/languageSelection/component";
|
||
|
||
const translations = {
|
||
en: {
|
||
selectedPage: "selectedPage",
|
||
page: "page",
|
||
search: "Search...",
|
||
notifications: "Notifications",
|
||
messages: "Messages",
|
||
profile: "Profile",
|
||
settings: "Settings",
|
||
logout: "Log Out"
|
||
},
|
||
tr: {
|
||
selectedPage: "seçiliSayfa",
|
||
page: "sayfa",
|
||
search: "Ara...",
|
||
notifications: "Bildirimler",
|
||
messages: "Mesajlar",
|
||
profile: "Profil",
|
||
settings: "Ayarlar",
|
||
logout: "Çıkış"
|
||
}
|
||
}
|
||
|
||
const HeaderComponent: FC<HeaderProps> = ({
|
||
activePageUrl, searchParams,
|
||
onlineData, onlineLoading, onlineError, refreshOnline, updateOnline,
|
||
userData, userLoading, userError, refreshUser, updateUser
|
||
}) => {
|
||
const lang = onlineData?.lang as LanguageTypes || 'en';
|
||
const [activeTab, setActiveTab] = useState('notifications');
|
||
const [isFullscreen, setIsFullscreen] = useState(false);
|
||
|
||
useEffect(() => {
|
||
const handleFullscreenChange = () => {
|
||
setIsFullscreen(!!document.fullscreenElement);
|
||
};
|
||
|
||
document.addEventListener('fullscreenchange', handleFullscreenChange);
|
||
return () => {
|
||
document.removeEventListener('fullscreenchange', handleFullscreenChange);
|
||
};
|
||
}, []);
|
||
|
||
const toggleFullscreen = () => {
|
||
if (document.fullscreenElement) {
|
||
document.exitFullscreen();
|
||
} else {
|
||
document.documentElement.requestFullscreen().catch(err => {
|
||
console.error(`Error attempting to enable fullscreen: ${err.message}`);
|
||
});
|
||
}
|
||
};
|
||
|
||
return (
|
||
<div className="py-2 px-6 bg-[#f8f4f3] flex items-center shadow-md shadow-black/5 sticky top-0 left-0 z-30">
|
||
<button type="button" className="text-lg text-gray-900 font-semibold sidebar-toggle">
|
||
<i className="ri-menu-line"></i>
|
||
</button>
|
||
|
||
<div className="ml-4">
|
||
<p className="text-lg font-semibold">{activePageUrl || langGetKey(translations[lang], 'page')}</p>
|
||
</div>
|
||
|
||
<ul className="ml-auto flex items-center">
|
||
<li className="mr-1 dropdown relative group">
|
||
<button type="button" className="dropdown-toggle text-gray-400 mr-4 w-8 h-8 rounded flex items-center justify-center hover:text-gray-600">
|
||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" className="hover:bg-gray-100 rounded-full" viewBox="0 0 24 24" style={{ fill: 'gray' }}>
|
||
<path d="M19.023 16.977a35.13 35.13 0 0 1-1.367-1.384c-.372-.378-.596-.653-.596-.653l-2.8-1.337A6.962 6.962 0 0 0 16 9c0-3.859-3.14-7-7-7S2 5.141 2 9s3.14 7 7 7c1.763 0 3.37-.66 4.603-1.739l1.337 2.8s.275.224.653.596c.387.363.896.854 1.384 1.367l1.358 1.392.604.646 2.121-2.121-.646-.604c-.379-.372-.885-.866-1.391-1.36zM9 14c-2.757 0-5-2.243-5-5s2.243-5 5-5 5 2.243 5 5-2.243 5-5 5z"></path>
|
||
</svg>
|
||
</button>
|
||
<div className="dropdown-menu shadow-md shadow-black/5 z-30 hidden group-hover:block absolute right-0 top-full max-w-xs w-60 bg-white rounded-md border border-gray-100">
|
||
<form action="" className="p-4 border-b border-b-gray-100">
|
||
<div className="relative w-full">
|
||
<input type="text" className="py-2 pr-4 pl-10 bg-gray-50 w-full outline-none border border-gray-100 rounded-md text-sm focus:border-blue-500" placeholder={langGetKey(translations[lang], 'search')} />
|
||
<i className="ri-search-line absolute top-1/2 left-4 -translate-y-1/2 text-gray-900"></i>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
</li>
|
||
|
||
<li className="dropdown relative group">
|
||
<button type="button" className="dropdown-toggle text-gray-400 mr-4 w-8 h-8 rounded flex items-center justify-center hover:text-gray-600">
|
||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" className="hover:bg-gray-100 rounded-full" viewBox="0 0 24 24" style={{ fill: 'gray' }}>
|
||
<path d="M19 13.586V10c0-3.217-2.185-5.927-5.145-6.742C13.562 2.52 12.846 2 12 2s-1.562.52-1.855 1.258C7.185 4.074 5 6.783 5 10v3.586l-1.707 1.707A.996.996 0 0 0 3 16v2a1 1 0 0 0 1 1h16a1 1 0 0 0 1-1v-2a.996.996 0 0 0-.293-.707L19 13.586zM19 17H5v-.586l1.707-1.707A.996.996 0 0 0 7 14v-4c0-2.757 2.243-5 5-5s5 2.243 5 5v4c0 .266.105.52.293.707L19 16.414V17zm-7 5a2.98 2.98 0 0 0 2.818-2H9.182A2.98 2.98 0 0 0 12 22z"></path>
|
||
</svg>
|
||
</button>
|
||
<div className="dropdown-menu shadow-md shadow-black/5 z-30 hidden group-hover:block absolute right-0 top-full max-w-xs w-80 bg-white rounded-md border border-gray-100">
|
||
<div className="flex items-center px-4 pt-4 border-b border-b-gray-100 notification-tab">
|
||
<button
|
||
type="button"
|
||
onClick={() => setActiveTab('notifications')}
|
||
className={`text-gray-400 font-medium text-[13px] hover:text-gray-600 border-b-2 ${activeTab === 'notifications' ? 'border-b-blue-500 text-blue-500' : 'border-b-transparent'} mr-4 pb-1`}
|
||
>
|
||
{langGetKey(translations[lang], 'notifications')}
|
||
</button>
|
||
<button
|
||
type="button"
|
||
onClick={() => setActiveTab('messages')}
|
||
className={`text-gray-400 font-medium text-[13px] hover:text-gray-600 border-b-2 ${activeTab === 'messages' ? 'border-b-blue-500 text-blue-500' : 'border-b-transparent'} mr-4 pb-1`}
|
||
>
|
||
{langGetKey(translations[lang], 'messages')}
|
||
</button>
|
||
</div>
|
||
<div className="my-2">
|
||
<ul className={`max-h-64 overflow-y-auto ${activeTab === 'notifications' ? 'block' : 'hidden'}`}>
|
||
{/* Notification items would go here */}
|
||
<li>
|
||
<a href="#" className="py-2 px-4 flex items-center hover:bg-gray-50 group">
|
||
<div className="w-8 h-8 rounded bg-blue-100 flex items-center justify-center mr-2">
|
||
<i className="ri-notification-2-line text-blue-500"></i>
|
||
</div>
|
||
<div className="ml-2">
|
||
<div className="text-[13px] text-gray-600 font-medium truncate group-hover:text-blue-500">System Notification</div>
|
||
<div className="text-[11px] text-gray-400">Just now</div>
|
||
</div>
|
||
</a>
|
||
</li>
|
||
</ul>
|
||
<ul className={`max-h-64 overflow-y-auto ${activeTab === 'messages' ? 'block' : 'hidden'}`}>
|
||
{/* Message items would go here */}
|
||
<li>
|
||
<a href="#" className="py-2 px-4 flex items-center hover:bg-gray-50 group">
|
||
<div className="w-8 h-8 rounded-full bg-gray-100 flex items-center justify-center mr-2">
|
||
<i className="ri-user-line text-gray-500"></i>
|
||
</div>
|
||
<div className="ml-2">
|
||
<div className="text-[13px] text-gray-600 font-medium truncate group-hover:text-blue-500">Support Team</div>
|
||
<div className="text-[11px] text-gray-400">Hello there!</div>
|
||
</div>
|
||
</a>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
</li>
|
||
|
||
<button onClick={toggleFullscreen} className="text-gray-400 mr-4 w-8 h-8 rounded flex items-center justify-center hover:text-gray-600">
|
||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" className="hover:bg-gray-100 rounded-full" viewBox="0 0 24 24" style={{ fill: 'gray' }}>
|
||
<path d="M5 5h5V3H3v7h2zm5 14H5v-5H3v7h7zm11-5h-2v5h-5v2h7zm-2-4h2V3h-7v2h5z"></path>
|
||
</svg>
|
||
</button>
|
||
|
||
<li className="dropdown ml-3 relative group">
|
||
<button type="button" className="dropdown-toggle flex items-center">
|
||
<div className="flex-shrink-0 w-10 h-10 relative">
|
||
<div className="p-1 bg-white rounded-full focus:outline-none focus:ring">
|
||
{userData?.avatar ? (
|
||
<img className="w-8 h-8 rounded-full" src={userData.avatar} alt="User Avatar" />
|
||
) : (
|
||
<div className="w-8 h-8 rounded-full bg-gray-200 flex items-center justify-center">
|
||
<i className="ri-user-line text-gray-500"></i>
|
||
</div>
|
||
)}
|
||
{!onlineLoading && onlineData && onlineData.status === 'online' && (
|
||
<>
|
||
<div className="top-0 left-7 absolute w-3 h-3 bg-lime-400 border-2 border-white rounded-full animate-ping"></div>
|
||
<div className="top-0 left-7 absolute w-3 h-3 bg-lime-500 border-2 border-white rounded-full"></div>
|
||
</>
|
||
)}
|
||
</div>
|
||
</div>
|
||
<div className="p-2 md:block text-left">
|
||
<h2 className="text-sm font-semibold text-gray-800">{userData?.name || 'User'}</h2>
|
||
<p className="text-xs text-gray-500">{onlineData?.userType || 'Guest'}</p>
|
||
</div>
|
||
</button>
|
||
<ul className="dropdown-menu shadow-md shadow-black/5 z-30 hidden group-hover:block absolute right-0 top-full py-1.5 rounded-md bg-white border border-gray-100 w-full max-w-[140px]">
|
||
<li>
|
||
<a href="#" className="flex items-center text-[13px] py-1.5 px-4 text-gray-600 hover:text-[#f84525] hover:bg-gray-50">
|
||
{langGetKey(translations[lang], 'profile')}
|
||
</a>
|
||
</li>
|
||
<li>
|
||
<a href="#" className="flex items-center text-[13px] py-1.5 px-4 text-gray-600 hover:text-[#f84525] hover:bg-gray-50">
|
||
{langGetKey(translations[lang], 'settings')}
|
||
</a>
|
||
</li>
|
||
<li>
|
||
<form method="POST" action="">
|
||
<a
|
||
role="menuitem"
|
||
className="flex items-center text-[13px] py-1.5 px-4 text-gray-600 hover:text-[#f84525] hover:bg-gray-50 cursor-pointer"
|
||
onClick={(e) => {
|
||
e.preventDefault();
|
||
// Handle logout logic here
|
||
}}
|
||
>
|
||
{langGetKey(translations[lang], 'logout')}
|
||
</a>
|
||
</form>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
|
||
<div className="ml-3">
|
||
<LanguageSelectionComponent
|
||
activePage={activePageUrl}
|
||
onlineData={onlineData}
|
||
onlineLoading={onlineLoading}
|
||
onlineError={onlineError}
|
||
refreshOnline={refreshOnline}
|
||
updateOnline={updateOnline}
|
||
/>
|
||
</div>
|
||
</ul>
|
||
</div>
|
||
);
|
||
};
|
||
|
||
export default HeaderComponent;
|