This commit is contained in:
Iliyan Angelov
2025-12-09 00:14:21 +02:00
parent b818d645a9
commit e43a95eafb
43 changed files with 2070 additions and 772 deletions

View File

@@ -18,10 +18,12 @@ import {
} from 'lucide-react';
import { useClickOutside } from '../hooks/useClickOutside';
import { useCompanySettings } from '../contexts/CompanySettingsContext';
import { useTheme } from '../contexts/ThemeContext';
import { useAuthModal } from '../../features/auth/contexts/AuthModalContext';
import { normalizeImageUrl } from '../utils/imageUtils';
import InAppNotificationBell from '../../features/notifications/components/InAppNotificationBell';
import Navbar from './Navbar';
import { getThemeTextClasses } from '../utils/themeUtils';
interface HeaderProps {
isAuthenticated?: boolean;
@@ -40,12 +42,14 @@ const Header: React.FC<HeaderProps> = ({
onLogout
}) => {
const { settings } = useCompanySettings();
const { theme } = useTheme();
const { openModal } = useAuthModal();
const location = useLocation();
const textClasses = getThemeTextClasses(theme.theme_layout_mode);
const displayPhone = settings.company_phone || '+1 (234) 567-890';
const displayEmail = settings.company_email || 'info@luxuryhotel.com';
const displayPhone = settings.company_phone || null;
const displayEmail = settings.company_email || null;
const logoUrl = settings.company_logo_url
? (settings.company_logo_url.startsWith('http')
? settings.company_logo_url
@@ -110,12 +114,12 @@ const Header: React.FC<HeaderProps> = ({
onTouchStart={(e) => {
e.stopPropagation();
}}
className="flex items-center
space-x-2 px-4 py-3.5 text-white/95
className={`flex items-center
space-x-2 px-4 py-3.5 ${textClasses.primary}/95
hover:bg-[rgba(var(--luxury-gold-rgb),0.15)] hover:text-[var(--luxury-gold)]
rounded-md transition-all duration-300
border-l-2 border-transparent
hover:border-[var(--luxury-gold)] font-light tracking-wider text-sm w-full text-left group relative mx-2 cursor-pointer"
hover:border-[var(--luxury-gold)] font-light tracking-wider text-sm w-full text-left group relative mx-2 cursor-pointer`}
style={{ touchAction: 'manipulation' }}
>
<LogIn className="w-4 h-4" />
@@ -160,7 +164,7 @@ const Header: React.FC<HeaderProps> = ({
e.stopPropagation();
}}
className="flex items-center
space-x-2 px-4 py-3.5 text-white/95
space-x-2 px-4 py-3.5 ${textClasses.primary}/95
hover:bg-[rgba(var(--luxury-gold-rgb),0.15)] hover:text-[var(--luxury-gold)]
rounded-md transition-all duration-300
border-l-2 border-transparent
@@ -181,12 +185,12 @@ const Header: React.FC<HeaderProps> = ({
onTouchStart={(e) => {
e.stopPropagation();
}}
className="flex items-center
space-x-2 px-4 py-3 text-white/90
className={`flex items-center
space-x-2 px-4 py-3 ${textClasses.primary}/90
hover:bg-[rgba(var(--luxury-gold-rgb),0.1)] hover:text-[var(--luxury-gold)]
rounded-sm transition-all duration-300
border-l-2 border-transparent
hover:border-[var(--luxury-gold)] font-light tracking-wide"
hover:border-[var(--luxury-gold)] font-light tracking-wide`}
style={{ touchAction: 'manipulation' }}
>
<Calendar className="w-4 h-4" />
@@ -201,12 +205,12 @@ const Header: React.FC<HeaderProps> = ({
onTouchStart={(e) => {
e.stopPropagation();
}}
className="flex items-center
space-x-2 px-4 py-3 text-white/90
className={`flex items-center
space-x-2 px-4 py-3 ${textClasses.primary}/90
hover:bg-[rgba(var(--luxury-gold-rgb),0.1)] hover:text-[var(--luxury-gold)]
rounded-sm transition-all duration-300
border-l-2 border-transparent
hover:border-[var(--luxury-gold)] font-light tracking-wide"
hover:border-[var(--luxury-gold)] font-light tracking-wide`}
style={{ touchAction: 'manipulation' }}
>
<Heart className="w-4 h-4" />
@@ -221,12 +225,12 @@ const Header: React.FC<HeaderProps> = ({
onTouchStart={(e) => {
e.stopPropagation();
}}
className="flex items-center
space-x-2 px-4 py-3 text-white/90
className={`flex items-center
space-x-2 px-4 py-3 ${textClasses.primary}/90
hover:bg-[rgba(var(--luxury-gold-rgb),0.1)] hover:text-[var(--luxury-gold)]
rounded-sm transition-all duration-300
border-l-2 border-transparent
hover:border-[var(--luxury-gold)] font-light tracking-wide"
hover:border-[var(--luxury-gold)] font-light tracking-wide`}
style={{ touchAction: 'manipulation' }}
>
<Calendar className="w-4 h-4" />
@@ -241,12 +245,12 @@ const Header: React.FC<HeaderProps> = ({
onTouchStart={(e) => {
e.stopPropagation();
}}
className="flex items-center
space-x-2 px-4 py-3 text-white/90
className={`flex items-center
space-x-2 px-4 py-3 ${textClasses.primary}/90
hover:bg-[rgba(var(--luxury-gold-rgb),0.1)] hover:text-[var(--luxury-gold)]
rounded-sm transition-all duration-300
border-l-2 border-transparent
hover:border-[var(--luxury-gold)] font-light tracking-wide"
hover:border-[var(--luxury-gold)] font-light tracking-wide`}
style={{ touchAction: 'manipulation' }}
>
<Star className="w-4 h-4" />
@@ -261,12 +265,12 @@ const Header: React.FC<HeaderProps> = ({
onTouchStart={(e) => {
e.stopPropagation();
}}
className="flex items-center
space-x-2 px-4 py-3 text-white/90
className={`flex items-center
space-x-2 px-4 py-3 ${textClasses.primary}/90
hover:bg-[rgba(var(--luxury-gold-rgb),0.1)] hover:text-[var(--luxury-gold)]
rounded-sm transition-all duration-300
border-l-2 border-transparent
hover:border-[var(--luxury-gold)] font-light tracking-wide"
hover:border-[var(--luxury-gold)] font-light tracking-wide`}
style={{ touchAction: 'manipulation' }}
>
<Users className="w-4 h-4" />
@@ -281,12 +285,12 @@ const Header: React.FC<HeaderProps> = ({
onTouchStart={(e) => {
e.stopPropagation();
}}
className="flex items-center
space-x-2 px-4 py-3 text-white/90
className={`flex items-center
space-x-2 px-4 py-3 ${textClasses.primary}/90
hover:bg-[rgba(var(--luxury-gold-rgb),0.1)] hover:text-[var(--luxury-gold)]
rounded-sm transition-all duration-300
border-l-2 border-transparent
hover:border-[var(--luxury-gold)] font-light tracking-wide"
hover:border-[var(--luxury-gold)] font-light tracking-wide`}
style={{ touchAction: 'manipulation' }}
>
<AlertCircle className="w-4 h-4" />
@@ -301,12 +305,12 @@ const Header: React.FC<HeaderProps> = ({
onTouchStart={(e) => {
e.stopPropagation();
}}
className="flex items-center
space-x-2 px-4 py-3 text-white/90
className={`flex items-center
space-x-2 px-4 py-3 ${textClasses.primary}/90
hover:bg-[rgba(var(--luxury-gold-rgb),0.1)] hover:text-[var(--luxury-gold)]
rounded-sm transition-all duration-300
border-l-2 border-transparent
hover:border-[var(--luxury-gold)] font-light tracking-wide"
hover:border-[var(--luxury-gold)] font-light tracking-wide`}
style={{ touchAction: 'manipulation' }}
>
<Bell className="w-4 h-4" />
@@ -321,12 +325,12 @@ const Header: React.FC<HeaderProps> = ({
onTouchStart={(e) => {
e.stopPropagation();
}}
className="flex items-center
space-x-2 px-4 py-3 text-white/90
className={`flex items-center
space-x-2 px-4 py-3 ${textClasses.primary}/90
hover:bg-[rgba(var(--luxury-gold-rgb),0.1)] hover:text-[var(--luxury-gold)]
rounded-sm transition-all duration-300
border-l-2 border-transparent
hover:border-[var(--luxury-gold)] font-light tracking-wide"
hover:border-[var(--luxury-gold)] font-light tracking-wide`}
style={{ touchAction: 'manipulation' }}
>
<Shield className="w-4 h-4" />
@@ -344,12 +348,12 @@ const Header: React.FC<HeaderProps> = ({
onTouchStart={(e) => {
e.stopPropagation();
}}
className="flex items-center
space-x-2 px-4 py-3 text-white/90
className={`flex items-center
space-x-2 px-4 py-3 ${textClasses.primary}/90
hover:bg-[rgba(var(--luxury-gold-rgb),0.1)] hover:text-[var(--luxury-gold)]
rounded-sm transition-all duration-300
border-l-2 border-transparent
hover:border-[var(--luxury-gold)] font-light tracking-wide"
hover:border-[var(--luxury-gold)] font-light tracking-wide`}
style={{ touchAction: 'manipulation' }}
>
<User className="w-4 h-4" />
@@ -366,12 +370,12 @@ const Header: React.FC<HeaderProps> = ({
onTouchStart={(e) => {
e.stopPropagation();
}}
className="flex items-center
space-x-2 px-4 py-3 text-white/90
className={`flex items-center
space-x-2 px-4 py-3 ${textClasses.primary}/90
hover:bg-[rgba(var(--luxury-gold-rgb),0.1)] hover:text-[var(--luxury-gold)]
rounded-sm transition-all duration-300
border-l-2 border-transparent
hover:border-[var(--luxury-gold)] font-light tracking-wide"
hover:border-[var(--luxury-gold)] font-light tracking-wide`}
style={{ touchAction: 'manipulation' }}
>
<User className="w-4 h-4" />
@@ -388,12 +392,12 @@ const Header: React.FC<HeaderProps> = ({
onTouchStart={(e) => {
e.stopPropagation();
}}
className="flex items-center
space-x-2 px-4 py-3 text-white/90
className={`flex items-center
space-x-2 px-4 py-3 ${textClasses.primary}/90
hover:bg-[rgba(var(--luxury-gold-rgb),0.1)] hover:text-[var(--luxury-gold)]
rounded-sm transition-all duration-300
border-l-2 border-transparent
hover:border-[var(--luxury-gold)] font-light tracking-wide"
hover:border-[var(--luxury-gold)] font-light tracking-wide`}
style={{ touchAction: 'manipulation' }}
>
<User className="w-4 h-4" />
@@ -410,12 +414,12 @@ const Header: React.FC<HeaderProps> = ({
onTouchStart={(e) => {
e.stopPropagation();
}}
className="flex items-center
space-x-2 px-4 py-3 text-white/90
className={`flex items-center
space-x-2 px-4 py-3 ${textClasses.primary}/90
hover:bg-[rgba(var(--luxury-gold-rgb),0.1)] hover:text-[var(--luxury-gold)]
rounded-sm transition-all duration-300
border-l-2 border-transparent
hover:border-[var(--luxury-gold)] font-light tracking-wide"
hover:border-[var(--luxury-gold)] font-light tracking-wide`}
style={{ touchAction: 'manipulation' }}
>
<User className="w-4 h-4" />
@@ -446,9 +450,15 @@ const Header: React.FC<HeaderProps> = ({
return (
<header
className="bg-gradient-to-b from-[#0f0f0f] via-[#1a1a1a] to-[#0f0f0f] sticky top-0 z-50 border-b border-[rgba(var(--luxury-gold-rgb),0.15)] shadow-[0_8px_32px_rgba(0,0,0,0.4)] backdrop-blur-sm"
className={`sticky top-0 z-50 border-b backdrop-blur-sm ${
theme.theme_layout_mode === 'light'
? 'bg-gradient-to-b from-white via-gray-50 to-white border-gray-200 shadow-[0_8px_32px_rgba(0,0,0,0.1)]'
: 'bg-gradient-to-b from-[#0f0f0f] via-[#1a1a1a] to-[#0f0f0f] border-[rgba(var(--luxury-gold-rgb),0.15)] shadow-[0_8px_32px_rgba(0,0,0,0.4)]'
}`}
>
<div className="hidden lg:block bg-[#0a0a0a]/50 border-b border-[rgba(var(--luxury-gold-rgb),0.1)]">
<div className={`hidden lg:block ${theme.theme_layout_mode === 'light'
? 'bg-gray-50/80 border-gray-200'
: 'bg-[#0a0a0a]/50 border-[rgba(var(--luxury-gold-rgb),0.1)]'} border-b`}>
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-2">
<div className="flex items-center justify-end space-x-6 text-sm">
{displayPhone && (
@@ -492,7 +502,9 @@ const Header: React.FC<HeaderProps> = ({
</div>
)}
<div className="flex flex-col min-w-0">
<span className="text-sm sm:text-base md:text-lg lg:text-xl xl:text-2xl font-display font-semibold text-white tracking-tight leading-tight bg-gradient-to-r from-white to-white/90 bg-clip-text truncate">
<span className={`text-sm sm:text-base md:text-lg lg:text-xl xl:text-2xl font-display font-semibold ${textClasses.primary} tracking-tight leading-tight ${theme.theme_layout_mode === 'light'
? 'bg-gradient-to-r from-gray-900 to-gray-700 bg-clip-text'
: 'bg-gradient-to-r from-white to-white/90 bg-clip-text'} truncate`}>
{settings.company_name}
</span>
<span className="text-[8px] sm:text-[9px] md:text-[10px] text-[var(--luxury-gold)] tracking-[0.25em] uppercase font-light hidden sm:block">
@@ -530,10 +542,10 @@ const Header: React.FC<HeaderProps> = ({
<>
<button
onClick={() => openModal('login')}
className="flex items-center space-x-2
px-6 py-2.5 text-white/95
className={`flex items-center space-x-2
px-6 py-2.5 ${textClasses.primary}/95
hover:text-[var(--luxury-gold)] transition-all duration-300
font-light tracking-wider relative group overflow-hidden"
font-light tracking-wider relative group overflow-hidden`}
>
<span className="absolute inset-0 border border-[rgba(var(--luxury-gold-rgb),0.2)] rounded-md opacity-0 group-hover:opacity-100 transition-all duration-300 group-hover:border-[rgba(var(--luxury-gold-rgb),0.5)]"></span>
<span className="absolute inset-0 bg-gradient-to-r from-[rgba(var(--luxury-gold-rgb),0.05)] to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-300"></span>
@@ -590,22 +602,26 @@ const Header: React.FC<HeaderProps> = ({
</span>
</div>
)}
<span className="font-light text-white/95 tracking-wider text-sm">
<span className={`font-light ${textClasses.primary}/95 tracking-wider text-sm`}>
{userInfo?.name}
</span>
</button>
{isUserMenuOpen && (
<div className="absolute right-0 mt-3
w-56 bg-gradient-to-b from-[#0f0f0f] via-[#1a1a1a] to-[#0f0f0f]
rounded-lg shadow-[0_8px_32px_rgba(0,0,0,0.6)] py-3 border border-[rgba(var(--luxury-gold-rgb),0.2)]
z-[9999] backdrop-blur-xl animate-fade-in"
<div className={`absolute right-0 mt-3
w-56 ${theme.theme_layout_mode === 'light'
? 'bg-gradient-to-b from-white via-gray-50 to-white border-gray-200'
: 'bg-gradient-to-b from-[#0f0f0f] via-[#1a1a1a] to-[#0f0f0f] border-[rgba(var(--luxury-gold-rgb),0.2)]'}
rounded-lg ${theme.theme_layout_mode === 'light'
? 'shadow-[0_8px_32px_rgba(0,0,0,0.15)]'
: 'shadow-[0_8px_32px_rgba(0,0,0,0.6)]'} py-3 border
z-[9999] backdrop-blur-xl animate-fade-in`}
>
<Link
to="/profile"
onClick={() => setIsUserMenuOpen(false)}
className="flex items-center space-x-3
px-5 py-3 text-white/95
px-5 py-3 ${textClasses.primary}/95
hover:bg-[rgba(var(--luxury-gold-rgb),0.1)] hover:text-[var(--luxury-gold)]
transition-all duration-300 border-l-2 border-transparent
hover:border-[var(--luxury-gold)] rounded-md group relative"
@@ -620,7 +636,7 @@ const Header: React.FC<HeaderProps> = ({
to="/dashboard"
onClick={() => setIsUserMenuOpen(false)}
className="flex items-center space-x-3
px-5 py-3 text-white/95
px-5 py-3 ${textClasses.primary}/95
hover:bg-[rgba(var(--luxury-gold-rgb),0.1)] hover:text-[var(--luxury-gold)]
transition-all duration-300 border-l-2 border-transparent
hover:border-[var(--luxury-gold)] rounded-md group relative"
@@ -633,7 +649,7 @@ const Header: React.FC<HeaderProps> = ({
to="/favorites"
onClick={() => setIsUserMenuOpen(false)}
className="flex items-center space-x-3
px-5 py-3 text-white/95
px-5 py-3 ${textClasses.primary}/95
hover:bg-[rgba(var(--luxury-gold-rgb),0.1)] hover:text-[var(--luxury-gold)]
transition-all duration-300 border-l-2 border-transparent
hover:border-[var(--luxury-gold)] rounded-md group relative"
@@ -646,7 +662,7 @@ const Header: React.FC<HeaderProps> = ({
to="/bookings"
onClick={() => setIsUserMenuOpen(false)}
className="flex items-center space-x-3
px-5 py-3 text-white/95
px-5 py-3 ${textClasses.primary}/95
hover:bg-[rgba(var(--luxury-gold-rgb),0.1)] hover:text-[var(--luxury-gold)]
transition-all duration-300 border-l-2 border-transparent
hover:border-[var(--luxury-gold)] rounded-md group relative"
@@ -659,7 +675,7 @@ const Header: React.FC<HeaderProps> = ({
to="/loyalty"
onClick={() => setIsUserMenuOpen(false)}
className="flex items-center space-x-3
px-5 py-3 text-white/95
px-5 py-3 ${textClasses.primary}/95
hover:bg-[rgba(var(--luxury-gold-rgb),0.1)] hover:text-[var(--luxury-gold)]
transition-all duration-300 border-l-2 border-transparent
hover:border-[var(--luxury-gold)] rounded-md group relative"
@@ -672,7 +688,7 @@ const Header: React.FC<HeaderProps> = ({
to="/group-bookings"
onClick={() => setIsUserMenuOpen(false)}
className="flex items-center space-x-3
px-5 py-3 text-white/95
px-5 py-3 ${textClasses.primary}/95
hover:bg-[rgba(var(--luxury-gold-rgb),0.1)] hover:text-[var(--luxury-gold)]
transition-all duration-300 border-l-2 border-transparent
hover:border-[var(--luxury-gold)] rounded-md group relative"
@@ -685,7 +701,7 @@ const Header: React.FC<HeaderProps> = ({
to="/complaints"
onClick={() => setIsUserMenuOpen(false)}
className="flex items-center space-x-3
px-5 py-3 text-white/95
px-5 py-3 ${textClasses.primary}/95
hover:bg-[rgba(var(--luxury-gold-rgb),0.1)] hover:text-[var(--luxury-gold)]
transition-all duration-300 border-l-2 border-transparent
hover:border-[var(--luxury-gold)] rounded-md group relative"
@@ -698,7 +714,7 @@ const Header: React.FC<HeaderProps> = ({
to="/guest-requests"
onClick={() => setIsUserMenuOpen(false)}
className="flex items-center space-x-3
px-5 py-3 text-white/95
px-5 py-3 ${textClasses.primary}/95
hover:bg-[rgba(var(--luxury-gold-rgb),0.1)] hover:text-[var(--luxury-gold)]
transition-all duration-300 border-l-2 border-transparent
hover:border-[var(--luxury-gold)] rounded-md group relative"
@@ -711,7 +727,7 @@ const Header: React.FC<HeaderProps> = ({
to="/gdpr"
onClick={() => setIsUserMenuOpen(false)}
className="flex items-center space-x-3
px-5 py-3 text-white/95
px-5 py-3 ${textClasses.primary}/95
hover:bg-[rgba(var(--luxury-gold-rgb),0.1)] hover:text-[var(--luxury-gold)]
transition-all duration-300 border-l-2 border-transparent
hover:border-[var(--luxury-gold)] rounded-md group relative"
@@ -728,11 +744,11 @@ const Header: React.FC<HeaderProps> = ({
onClick={() =>
setIsUserMenuOpen(false)
}
className="flex items-center
space-x-3 px-5 py-3 text-white/95
className={`flex items-center
space-x-3 px-5 py-3 ${textClasses.primary}/95
hover:bg-[rgba(var(--luxury-gold-rgb),0.1)] hover:text-[var(--luxury-gold)]
transition-all duration-300 border-l-2 border-transparent
hover:border-[var(--luxury-gold)] rounded-md group relative"
hover:border-[var(--luxury-gold)] rounded-md group relative`}
>
<span className="absolute left-0 top-0 bottom-0 w-0 bg-gradient-to-r from-[rgba(var(--luxury-gold-rgb),0.1)] to-transparent group-hover:w-full transition-all duration-300 rounded-md"></span>
<User className="w-4 h-4 relative z-10 transition-transform duration-300 group-hover:scale-110" />
@@ -745,11 +761,11 @@ const Header: React.FC<HeaderProps> = ({
onClick={() =>
setIsUserMenuOpen(false)
}
className="flex items-center
space-x-3 px-5 py-3 text-white/95
className={`flex items-center
space-x-3 px-5 py-3 ${textClasses.primary}/95
hover:bg-[rgba(var(--luxury-gold-rgb),0.1)] hover:text-[var(--luxury-gold)]
transition-all duration-300 border-l-2 border-transparent
hover:border-[var(--luxury-gold)] rounded-md group relative"
hover:border-[var(--luxury-gold)] rounded-md group relative`}
>
<span className="absolute left-0 top-0 bottom-0 w-0 bg-gradient-to-r from-[rgba(var(--luxury-gold-rgb),0.1)] to-transparent group-hover:w-full transition-all duration-300 rounded-md"></span>
<User className="w-4 h-4 relative z-10 transition-transform duration-300 group-hover:scale-110" />
@@ -762,11 +778,11 @@ const Header: React.FC<HeaderProps> = ({
onClick={() =>
setIsUserMenuOpen(false)
}
className="flex items-center
space-x-3 px-5 py-3 text-white/95
className={`flex items-center
space-x-3 px-5 py-3 ${textClasses.primary}/95
hover:bg-[rgba(var(--luxury-gold-rgb),0.1)] hover:text-[var(--luxury-gold)]
transition-all duration-300 border-l-2 border-transparent
hover:border-[var(--luxury-gold)] rounded-md group relative"
hover:border-[var(--luxury-gold)] rounded-md group relative`}
>
<span className="absolute left-0 top-0 bottom-0 w-0 bg-gradient-to-r from-[rgba(var(--luxury-gold-rgb),0.1)] to-transparent group-hover:w-full transition-all duration-300 rounded-md"></span>
<User className="w-4 h-4 relative z-10 transition-transform duration-300 group-hover:scale-110" />
@@ -779,11 +795,11 @@ const Header: React.FC<HeaderProps> = ({
onClick={() =>
setIsUserMenuOpen(false)
}
className="flex items-center
space-x-3 px-5 py-3 text-white/95
className={`flex items-center
space-x-3 px-5 py-3 ${textClasses.primary}/95
hover:bg-[rgba(var(--luxury-gold-rgb),0.1)] hover:text-[var(--luxury-gold)]
transition-all duration-300 border-l-2 border-transparent
hover:border-[var(--luxury-gold)] rounded-md group relative"
hover:border-[var(--luxury-gold)] rounded-md group relative`}
>
<span className="absolute left-0 top-0 bottom-0 w-0 bg-gradient-to-r from-[rgba(var(--luxury-gold-rgb),0.1)] to-transparent group-hover:w-full transition-all duration-300 rounded-md"></span>
<User className="w-4 h-4 relative z-10 transition-transform duration-300 group-hover:scale-110" />