ai / components /Header.tsx
Lianjx's picture
Upload 75 files
8fb4cca verified
import React from 'react';
import { Camera, Globe, PhoneCall, User, LogIn, Settings, Info, MessageSquarePlus } from 'lucide-react';
import { Language, UserAccount, AdminConfig } from '../types';
import { TRANSLATIONS } from '../constants/translations';
interface HeaderProps {
language: Language;
onLanguageChange: (lang: Language) => void;
onBookClick: () => void;
user?: UserAccount;
config?: AdminConfig; // NEW: Receive AdminConfig for logo
onOpenUserCenter?: () => void;
onLoginClick?: () => void;
onOpenAdmin?: () => void;
onOpenAbout?: () => void;
onOpenFeedback?: () => void;
}
export const Header: React.FC<HeaderProps> = ({ language, onLanguageChange, onBookClick, user, config, onOpenUserCenter, onLoginClick, onOpenAdmin, onOpenAbout, onOpenFeedback }) => {
const t = TRANSLATIONS[language];
const isStaffOrAdmin = user && (user.role === 'admin' || user.role === 'staff');
return (
<header className="w-full py-4 sm:py-6 px-4 sm:px-8 border-b border-rose-100 bg-white/80 backdrop-blur-md sticky top-0 z-50">
<div className="max-w-7xl mx-auto flex items-center justify-between">
<div className="flex items-center gap-3 cursor-pointer" onClick={() => window.location.reload()}>
{config?.logoUrl ? (
<div className="w-10 h-10 sm:w-12 sm:h-12 rounded-full overflow-hidden shadow-lg ring-2 ring-rose-100">
<img src={config.logoUrl} alt="Logo" className="w-full h-full object-cover" />
</div>
) : (
<div className="w-10 h-10 sm:w-12 sm:h-12 bg-gray-900 rounded-full flex items-center justify-center text-rose-300 shadow-lg ring-2 ring-rose-100">
<Camera className="w-6 h-6" />
</div>
)}
<div>
<h1 className="font-serif text-xl sm:text-2xl font-bold text-gray-900 tracking-tight leading-none">
{t.title}
</h1>
<p className="text-[10px] sm:text-xs text-rose-500 font-sans tracking-widest uppercase font-bold mt-1">
{t.subtitle}
</p>
</div>
</div>
<div className="flex items-center gap-3 sm:gap-4">
{/* About Us Button (Desktop) */}
<button
onClick={onOpenAbout}
className="hidden sm:flex items-center gap-1 text-xs font-bold text-gray-600 hover:text-rose-600 transition-colors mr-2"
>
<Info className="w-3.5 h-3.5" />
{t.aboutUsBtn}
</button>
{/* Feedback Button */}
<button
onClick={onOpenFeedback}
className="flex items-center justify-center w-8 h-8 rounded-full hover:bg-gray-100 text-gray-500 hover:text-rose-500 transition-colors"
title="Feedback"
>
<MessageSquarePlus className="w-5 h-5" />
</button>
{/* Admin Panel Button */}
{isStaffOrAdmin && (
<button
onClick={onOpenAdmin}
className="hidden sm:flex items-center gap-2 px-3 py-1.5 bg-gray-800 text-white rounded-full text-xs font-bold hover:bg-gray-700 transition-colors"
>
<Settings className="w-3.5 h-3.5" />
Admin Panel
</button>
)}
{/* Book Now Button (Mobile: Icon only, Desktop: Text) */}
<button
onClick={onBookClick}
className="flex items-center gap-2 bg-rose-600 hover:bg-rose-700 text-white px-4 py-2 rounded-full shadow-lg shadow-rose-200 transition-all hover:scale-105 active:scale-95"
>
<PhoneCall className="w-4 h-4" />
<span className="hidden sm:inline text-xs font-bold uppercase tracking-wide">{t.bookNow}</span>
</button>
{/* User Avatar / Points OR Login Button */}
{user ? (
<button
onClick={onOpenUserCenter}
className="flex items-center gap-2 bg-gray-50 hover:bg-rose-50 border border-gray-200 pl-2 pr-3 py-1.5 rounded-full transition-colors group"
>
<div className="w-6 h-6 rounded-full bg-gray-200 flex items-center justify-center overflow-hidden">
{user.avatar ? <img src={user.avatar} className="w-full h-full object-cover" /> : <User className="w-4 h-4 text-gray-500" />}
</div>
<div className="flex flex-col items-start leading-none">
<span className="text-[9px] text-gray-400 font-bold uppercase">{t.myPoints}</span>
<span className="text-xs font-bold text-amber-500 group-hover:text-amber-600">{user.points}</span>
</div>
</button>
) : (
<button
onClick={onLoginClick}
className="flex items-center gap-2 text-gray-600 hover:text-rose-600 font-bold text-xs"
>
<LogIn className="w-4 h-4" />
<span className="hidden sm:inline">{t.authLogin}</span>
</button>
)}
{/* Language Selector */}
<div className="relative group hidden sm:block">
<button className="flex items-center gap-2 px-3 py-1.5 rounded-full bg-white border border-gray-200 text-xs font-semibold text-gray-700 hover:bg-gray-50 transition-colors">
<Globe className="w-3.5 h-3.5" />
<span className="uppercase">{language}</span>
</button>
<div className="absolute right-0 mt-2 w-32 bg-white rounded-xl shadow-xl border border-gray-100 overflow-hidden hidden group-hover:block animate-fade-in z-50">
<div className="flex flex-col py-1">
{['en', 'zh', 'ja', 'ko', 'es', 'fr'].map((lang) => (
<button
key={lang}
onClick={() => onLanguageChange(lang as Language)}
className={`px-4 py-2 text-left text-xs hover:bg-rose-50 ${language === lang ? 'text-rose-600 font-bold bg-rose-50' : 'text-gray-700'}`}
>
{lang === 'en' ? 'English' :
lang === 'zh' ? '中文' :
lang === 'ja' ? '日本語' :
lang === 'ko' ? '한국어' :
lang === 'es' ? 'Español' : 'Français'}
</button>
))}
</div>
</div>
</div>
</div>
</div>
</header>
);
};