Header.tsx 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448
  1. import React, { useState, useEffect, useRef } from 'react';
  2. import { useNavigate, useLocation, Link } from 'react-router-dom';
  3. const Header: React.FC = () => {
  4. const navigate = useNavigate();
  5. const location = useLocation();
  6. const [isMenuOpen, setIsMenuOpen] = useState(false);
  7. const [isBuySimExpanded, setIsBuySimExpanded] = useState(false);
  8. const [isGuideExpanded, setIsGuideExpanded] = useState(false);
  9. const [isBuySimMegaVisible, setIsBuySimMegaVisible] = useState(false);
  10. const [isGuideMegaVisible, setIsGuideMegaVisible] = useState(false);
  11. const [isLangMenuOpen, setIsLangMenuOpen] = useState(false);
  12. const [selectedLang, setSelectedLang] = useState<'en' | 'vi'>('en');
  13. const [activeDesktopTab, setActiveDesktopTab] = useState<'popular' | 'region'>('popular');
  14. const [isScrolled, setIsScrolled] = useState(false);
  15. const langMenuRef = useRef<HTMLDivElement>(null);
  16. const countries = [
  17. { name: 'China', flag: 'cn' },
  18. { name: 'Hong Kong', flag: 'hk' },
  19. { name: 'Japan', flag: 'jp' },
  20. { name: 'Singapore', flag: 'sg' },
  21. { name: 'South Korea', flag: 'kr' },
  22. { name: 'Taiwan', flag: 'tw' },
  23. { name: 'Thailand', flag: 'th' },
  24. { name: 'United States', flag: 'us' },
  25. ];
  26. const regionList = [
  27. "Americas", "Asia", "Asia 11 countries", "Asialink 7 countries",
  28. "Australia & New Zealand", "EU 33 countries", "EU 40 countries", "Eurolink",
  29. "Europe", "Europe 33 countries", "Hong Kong & Macau", "Middle East and Africa",
  30. "North America & Canada", "North America A", "Oceania", "Singapore & Malaysia"
  31. ];
  32. const guideItems = [
  33. { label: "What is eSIM", path: "/support" },
  34. { label: "Installation instructions", path: "/support" },
  35. { label: "Support", path: "/support" },
  36. { label: "Order Tracking Search", path: "/support" }
  37. ];
  38. const languages = [
  39. { code: 'en', label: 'English', flag: 'us' },
  40. { code: 'vi', label: 'Tiếng Việt', flag: 'vn' }
  41. ];
  42. useEffect(() => {
  43. const handleScroll = () => {
  44. setIsScrolled(window.scrollY > 300);
  45. };
  46. window.addEventListener('scroll', handleScroll);
  47. return () => window.removeEventListener('scroll', handleScroll);
  48. }, []);
  49. const handleCountryClick = (c: { name: string; flag: string }) => {
  50. navigate(`/product/${c.name.toLowerCase()}`, { state: { country: c.name, flag: c.flag } });
  51. setIsBuySimMegaVisible(false);
  52. setIsMenuOpen(false);
  53. };
  54. const handleRegionClick = (region: string) => {
  55. navigate(`/product/${region.toLowerCase()}`, { state: { country: region, flag: 'un' } });
  56. setIsBuySimMegaVisible(false);
  57. setIsMenuOpen(false);
  58. };
  59. useEffect(() => {
  60. const handleClickOutside = (event: MouseEvent) => {
  61. if (langMenuRef.current && !langMenuRef.current.contains(event.target as Node)) {
  62. setIsLangMenuOpen(false);
  63. }
  64. };
  65. document.addEventListener('mousedown', handleClickOutside);
  66. return () => document.removeEventListener('mousedown', handleClickOutside);
  67. }, []);
  68. useEffect(() => {
  69. const handleResize = () => {
  70. if (window.innerWidth >= 1024) setIsMenuOpen(false);
  71. };
  72. window.addEventListener('resize', handleResize);
  73. return () => window.removeEventListener('resize', handleResize);
  74. }, []);
  75. const currentLangObj = languages.find(l => l.code === selectedLang) || languages[0];
  76. const isActive = (path: string) => location.pathname === path;
  77. return (
  78. <>
  79. <header className="sticky top-0 z-[60] w-full bg-white border-b border-slate-100 shadow-sm transition-all duration-300">
  80. <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
  81. <div className="flex justify-between items-center h-20">
  82. {/* Logo */}
  83. <Link to="/" className="flex-shrink-0 flex items-center">
  84. <div className="flex items-center space-x-1">
  85. <svg className="w-8 h-8 text-[#EE0434]" viewBox="0 0 24 24" fill="currentColor">
  86. <path d="M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5" />
  87. </svg>
  88. <span className="text-2xl font-bold tracking-tighter">
  89. <span className="text-[#EE0434]">Infi</span>
  90. <span className="text-[#333]">Gate</span>
  91. </span>
  92. </div>
  93. </Link>
  94. {/* Desktop Search on Scroll */}
  95. <div className={`hidden lg:flex items-center transition-all duration-500 overflow-hidden ${isScrolled ? 'flex-1 max-w-md mx-8 opacity-100' : 'max-w-0 opacity-0 pointer-events-none'}`}>
  96. <div className="relative w-full">
  97. <input
  98. type="text"
  99. placeholder="Search country..."
  100. className="w-full bg-slate-50 border border-slate-200 rounded-full py-2.5 px-6 pl-12 text-sm focus:outline-none focus:ring-2 focus:ring-red-100 focus:border-[#EE0434] transition-all"
  101. />
  102. <svg className="absolute left-4 top-1/2 -translate-y-1/2 w-4 h-4 text-slate-400" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2.5} d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"/></svg>
  103. </div>
  104. </div>
  105. {/* Desktop Nav */}
  106. <nav className={`hidden lg:flex items-center h-full transition-all duration-300 ${isScrolled ? 'space-x-4' : 'space-x-8'}`}>
  107. <Link to="/" className={`text-[17px] font-bold ${isActive('/') ? 'text-[#EE0434]' : 'text-slate-700 hover:text-[#EE0434]'}`}>Home</Link>
  108. <div
  109. className="relative h-full flex items-center"
  110. onMouseEnter={() => setIsBuySimMegaVisible(true)}
  111. onMouseLeave={() => setIsBuySimMegaVisible(false)}
  112. >
  113. <Link
  114. to="/buy-sim"
  115. className={`flex items-center text-[17px] font-bold transition-colors ${isActive('/buy-sim') ? 'text-[#EE0434]' : 'text-slate-700 hover:text-[#EE0434]'}`}
  116. >
  117. Buy SIM <svg className={`ml-1 w-4 h-4 transition-transform ${isBuySimMegaVisible ? 'rotate-180' : ''}`} fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 9l-7 7-7-7" /></svg>
  118. </Link>
  119. {isBuySimMegaVisible && (
  120. <div className="absolute top-full left-1/2 -translate-x-1/2 w-[950px] bg-white rounded-[32px] shadow-[0_30px_60px_-15px_rgba(0,0,0,0.15)] border border-slate-100 mt-0 overflow-hidden flex animate-in fade-in slide-in-from-top-2 duration-300">
  121. <div className="w-[280px] bg-red-50 p-10 flex flex-col">
  122. <h3 className="text-4xl font-black text-slate-900 mb-4">Buy SIM</h3>
  123. <button
  124. onClick={() => {
  125. navigate('/buy-sim');
  126. setIsBuySimMegaVisible(false);
  127. }}
  128. className="text-[#EE0434] font-bold text-xl flex items-center group mb-8"
  129. >
  130. View all <svg className="ml-2 w-5 h-5 transition-transform group-hover:translate-x-1" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={3} d="M9 5l7 7-7 7" /></svg>
  131. </button>
  132. </div>
  133. <div className="flex-1 p-10">
  134. <div className="flex space-x-4 mb-10">
  135. <button
  136. onClick={() => setActiveDesktopTab('popular')}
  137. className={`px-8 py-3 rounded-full text-base font-bold transition-all ${activeDesktopTab === 'popular' ? 'bg-[#EE0434] text-white shadow-lg shadow-red-100' : 'bg-slate-50 text-slate-900 hover:bg-slate-100'}`}
  138. >
  139. Most Popular
  140. </button>
  141. <button
  142. onClick={() => setActiveDesktopTab('region')}
  143. className={`px-8 py-3 rounded-full text-base font-bold transition-all ${activeDesktopTab === 'region' ? 'bg-[#EE0434] text-white shadow-lg shadow-red-100' : 'bg-slate-50 text-slate-900 hover:bg-slate-100'}`}
  144. >
  145. Region
  146. </button>
  147. </div>
  148. {activeDesktopTab === 'popular' ? (
  149. <div className="grid grid-cols-4 gap-y-8 gap-x-4">
  150. {countries.map((c) => (
  151. <div key={c.name} onClick={() => handleCountryClick(c)} className="flex items-center space-x-3 group cursor-pointer hover:bg-slate-50 p-2 rounded-xl transition-colors">
  152. <div className="w-7 h-7 rounded-full overflow-hidden border border-slate-200 shadow-sm shrink-0">
  153. <img src={`https://flagcdn.com/w40/${c.flag}.png`} alt={c.name} className="w-full h-full object-cover" />
  154. </div>
  155. <span className="text-[16px] font-bold text-slate-700 group-hover:text-[#EE0434] transition-colors">{c.name}</span>
  156. </div>
  157. ))}
  158. </div>
  159. ) : (
  160. <div className="grid grid-cols-4 gap-y-6 gap-x-2">
  161. {regionList.map((region) => (
  162. <div
  163. key={region}
  164. onClick={() => handleRegionClick(region)}
  165. className="flex items-center space-x-3 group cursor-pointer hover:bg-slate-50 p-2 rounded-xl transition-colors min-w-0"
  166. >
  167. <div className="w-7 h-7 rounded-full bg-red-50 flex items-center justify-center shrink-0 border border-red-100/50">
  168. <svg className="w-4 h-4 text-red-300" fill="currentColor" viewBox="0 0 24 24">
  169. <path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-1 17.93c-3.95-.49-7.01-3.55-7.5-7.5H7v-1H3.5c.49-3.95 3.55-7.01 7.5-7.5v3.5h1V3.5c3.95.49 7.01 3.55 7.5 7.5H17v1h3.5c-.49 3.95-3.55-7.01-7.5 7.5v-3.5h-1v3.5z"/>
  170. </svg>
  171. </div>
  172. <span className="text-[16px] font-bold text-slate-700 group-hover:text-[#EE0434] transition-colors truncate">
  173. {region}
  174. </span>
  175. </div>
  176. ))}
  177. </div>
  178. )}
  179. </div>
  180. </div>
  181. )}
  182. </div>
  183. <div
  184. className="relative h-full flex items-center"
  185. onMouseEnter={() => setIsGuideMegaVisible(true)}
  186. onMouseLeave={() => setIsGuideMegaVisible(false)}
  187. >
  188. <Link
  189. to="/support"
  190. className={`flex items-center text-[17px] font-bold transition-colors ${isActive('/support') ? 'text-[#EE0434]' : 'text-slate-700 hover:text-[#EE0434]'}`}
  191. >
  192. Guide <svg className={`ml-1 w-4 h-4 transition-transform ${isGuideMegaVisible ? 'rotate-180' : ''}`} fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 9l-7 7-7-7" /></svg>
  193. </Link>
  194. {isGuideMegaVisible && (
  195. <div className="absolute top-full left-0 w-[600px] bg-white rounded-[32px] shadow-2xl border border-slate-100 mt-0 overflow-hidden flex animate-in fade-in slide-in-from-top-2 duration-300">
  196. <div className="flex-1 py-10 px-6 flex flex-col">
  197. {guideItems.map((item, idx) => (
  198. <button
  199. key={item.label}
  200. onClick={() => {
  201. navigate(item.path);
  202. setIsGuideMegaVisible(false);
  203. }}
  204. className={`w-full text-left px-6 py-4 rounded-2xl text-base font-medium transition-all text-slate-600 hover:bg-slate-50 hover:text-[#EE0434]`}
  205. >
  206. {item.label}
  207. </button>
  208. ))}
  209. </div>
  210. </div>
  211. )}
  212. </div>
  213. <Link
  214. to="/news"
  215. className={`text-[17px] font-bold transition-colors ${isActive('/news') ? 'text-[#EE0434]' : 'text-slate-700 hover:text-[#EE0434]'}`}
  216. >
  217. News
  218. </Link>
  219. <Link
  220. to="/contact"
  221. className={`text-[17px] font-bold transition-colors ${isActive('/contact') ? 'text-[#EE0434]' : 'text-slate-700 hover:text-[#EE0434]'}`}
  222. >
  223. Contact
  224. </Link>
  225. </nav>
  226. {/* Icons */}
  227. <div className="flex items-center space-x-5">
  228. <Link
  229. to="/login"
  230. className="p-2 text-slate-700 hover:text-[#EE0434] transition-colors"
  231. >
  232. <svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z" /></svg>
  233. </Link>
  234. <button className="hidden sm:flex p-2 text-slate-700 hover:text-[#EE0434] relative">
  235. <svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M3 3h2l.4 2M7 13h10l4-8H5.4M7 13L5.4 5M7 13l-2.293 2.293c-.63.63-.184 1.707.707 1.707H17m0 0a2 2 0 100 4 2 2 0 000-4zm-8 2a2 2 0 11-4 0 2 2 0 014 0z" /></svg>
  236. <span className="absolute top-1 right-1 w-4 h-4 bg-[#EE0434] text-white text-[10px] flex items-center justify-center rounded-full font-black">0</span>
  237. </button>
  238. <div className="relative" ref={langMenuRef}>
  239. <button
  240. onClick={() => setIsLangMenuOpen(!isLangMenuOpen)}
  241. className="bg-white p-1 rounded-2xl border border-slate-100 shadow-sm hover:shadow-md transition-all flex items-center justify-center"
  242. >
  243. <div className="w-8 h-8 rounded-full overflow-hidden border border-slate-50">
  244. <img
  245. src={`https://flagcdn.com/w80/${currentLangObj.flag}.png`}
  246. alt={currentLangObj.label}
  247. className="w-full h-full object-cover"
  248. />
  249. </div>
  250. </button>
  251. {isLangMenuOpen && (
  252. <div className="absolute top-full right-0 mt-3 w-48 bg-white rounded-[24px] shadow-[0_20px_40px_rgba(0,0,0,0.1)] border border-slate-50 overflow-hidden animate-in fade-in slide-in-from-top-2 duration-200">
  253. <div className="flex flex-col">
  254. {languages.map((lang) => (
  255. <button
  256. key={lang.code}
  257. onClick={() => {
  258. setSelectedLang(lang.code as 'en' | 'vi');
  259. setIsLangMenuOpen(false);
  260. }}
  261. className={`flex items-center space-x-3 px-5 py-4 w-full text-left transition-colors ${
  262. selectedLang === lang.code ? 'bg-slate-50' : 'hover:bg-slate-50/50'
  263. }`}
  264. >
  265. <div className="w-7 h-7 rounded-full overflow-hidden border border-slate-100 shadow-sm">
  266. <img
  267. src={`https://flagcdn.com/w80/${lang.flag}.png`}
  268. alt={lang.label}
  269. className="w-full h-full object-cover"
  270. />
  271. </div>
  272. <span className={`text-[15px] font-bold ${selectedLang === lang.code ? 'text-slate-900' : 'text-slate-500'}`}>
  273. {lang.label}
  274. </span>
  275. </button>
  276. ))}
  277. </div>
  278. </div>
  279. )}
  280. </div>
  281. <button onClick={() => setIsMenuOpen(true)} className="lg:hidden p-2 text-slate-900">
  282. <svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2.5} d="M4 6h16M4 12h16m-7 6h7" /></svg>
  283. </button>
  284. </div>
  285. </div>
  286. </div>
  287. </header>
  288. {/* Full-Screen Mobile Menu with Slide-Right Transition */}
  289. <div className={`fixed inset-0 z-[100] lg:hidden transition-all duration-500 ease-in-out ${isMenuOpen ? 'opacity-100 pointer-events-auto' : 'opacity-0 pointer-events-none'}`}>
  290. <div className={`absolute inset-0 bg-white flex flex-col transform transition-transform duration-500 ease-out ${isMenuOpen ? 'translate-x-0' : '-translate-x-full'}`}>
  291. {/* Mobile Menu Header */}
  292. <div className="flex justify-between items-center p-6 border-b border-slate-50">
  293. <Link to="/" onClick={() => setIsMenuOpen(false)} className="flex items-center space-x-1">
  294. <svg className="w-7 h-7 text-[#EE0434]" viewBox="0 0 24 24" fill="currentColor">
  295. <path d="M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5" />
  296. </svg>
  297. <span className="text-xl font-black tracking-tighter">
  298. <span className="text-[#EE0434]">Infi</span>
  299. <span className="text-[#333]">Gate</span>
  300. </span>
  301. </Link>
  302. <button onClick={() => setIsMenuOpen(false)} className="p-2 text-slate-400 hover:text-[#EE0434] transition-colors rounded-full hover:bg-slate-100">
  303. <svg className="w-8 h-8" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" /></svg>
  304. </button>
  305. </div>
  306. <div className="flex-1 overflow-y-auto px-6 py-8 space-y-6">
  307. <div className="flex flex-col items-center space-y-4">
  308. <Link
  309. to="/"
  310. onClick={() => setIsMenuOpen(false)}
  311. className={`w-full text-center py-5 px-6 rounded-3xl text-2xl font-black transition-all ${isActive('/') ? 'bg-red-50 text-[#EE0434]' : 'text-slate-800 hover:bg-slate-50'}`}
  312. >
  313. Home
  314. </Link>
  315. <div className="w-full">
  316. <button
  317. onClick={() => setIsBuySimExpanded(!isBuySimExpanded)}
  318. className={`w-full flex items-center justify-center space-x-3 py-5 px-6 rounded-3xl text-2xl font-black transition-all ${isActive('/buy-sim') ? 'bg-red-50 text-[#EE0434]' : 'text-slate-800 hover:bg-slate-50'}`}
  319. >
  320. <span>Buy SIM</span>
  321. <svg className={`w-6 h-6 transition-transform duration-300 ${isBuySimExpanded ? 'rotate-180' : ''}`} fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2.5} d="M19 9l-7 7-7-7" /></svg>
  322. </button>
  323. <div className={`overflow-hidden transition-all duration-300 ease-in-out ${isBuySimExpanded ? 'max-h-[1000px] opacity-100 mt-4' : 'max-h-0 opacity-0'}`}>
  324. <div className="grid grid-cols-2 gap-3 px-2">
  325. <button
  326. onClick={() => { navigate('/buy-sim'); setIsMenuOpen(false); }}
  327. className="col-span-2 text-center py-4 bg-slate-50 rounded-2xl text-[#EE0434] font-black text-sm uppercase tracking-wider shadow-sm"
  328. >
  329. View All Destinations →
  330. </button>
  331. {countries.map(c => (
  332. <button
  333. key={c.name}
  334. onClick={() => handleCountryClick(c)}
  335. className="flex flex-col items-center justify-center space-y-2 py-5 rounded-2xl bg-white border border-slate-100 shadow-sm active:bg-slate-50"
  336. >
  337. <img src={`https://flagcdn.com/w80/${c.flag}.png`} alt={c.name} className="w-10 h-10 rounded-full object-cover border-2 border-slate-50" />
  338. <span className="text-sm font-bold text-slate-700">{c.name}</span>
  339. </button>
  340. ))}
  341. </div>
  342. </div>
  343. </div>
  344. <div className="w-full">
  345. <button
  346. onClick={() => setIsGuideExpanded(!isGuideExpanded)}
  347. className={`w-full flex items-center justify-center space-x-3 py-5 px-6 rounded-3xl text-2xl font-black transition-all ${isActive('/support') ? 'bg-red-50 text-[#EE0434]' : 'text-slate-800 hover:bg-slate-50'}`}
  348. >
  349. <span>Guide</span>
  350. <svg className={`w-6 h-6 transition-transform duration-300 ${isGuideExpanded ? 'rotate-180' : ''}`} fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2.5} d="M19 9l-7 7-7-7" /></svg>
  351. </button>
  352. <div className={`overflow-hidden transition-all duration-300 ease-in-out ${isGuideExpanded ? 'max-h-[400px] opacity-100 mt-4' : 'max-h-0 opacity-0'}`}>
  353. <div className="flex flex-col space-y-2 px-2">
  354. {guideItems.map(item => (
  355. <button
  356. key={item.label}
  357. onClick={() => { navigate(item.path); setIsMenuOpen(false); }}
  358. className="w-full text-center py-4 rounded-2xl bg-slate-50 text-slate-600 font-bold hover:text-[#EE0434] active:bg-red-50"
  359. >
  360. {item.label}
  361. </button>
  362. ))}
  363. </div>
  364. </div>
  365. </div>
  366. <Link
  367. to="/news"
  368. onClick={() => setIsMenuOpen(false)}
  369. className={`w-full text-center py-5 px-6 rounded-3xl text-2xl font-black transition-all ${isActive('/news') ? 'bg-red-50 text-[#EE0434]' : 'text-slate-800 hover:bg-slate-50'}`}
  370. >
  371. News
  372. </Link>
  373. <Link
  374. to="/contact"
  375. onClick={() => setIsMenuOpen(false)}
  376. className={`w-full text-center py-5 px-6 rounded-3xl text-2xl font-black transition-all ${isActive('/contact') ? 'bg-red-50 text-[#EE0434]' : 'text-slate-800 hover:bg-slate-50'}`}
  377. >
  378. Contact
  379. </Link>
  380. <div className="w-full pt-4">
  381. <p className="text-center text-slate-400 font-bold text-xs uppercase tracking-widest mb-4">Select Language</p>
  382. <div className="flex justify-center space-x-4">
  383. {languages.map(lang => (
  384. <button
  385. key={lang.code}
  386. onClick={() => setSelectedLang(lang.code as 'en' | 'vi')}
  387. className={`flex items-center space-x-2 px-4 py-2 rounded-2xl transition-all border ${selectedLang === lang.code ? 'bg-red-50 border-[#EE0434] text-[#EE0434]' : 'bg-white border-slate-100 text-slate-500'}`}
  388. >
  389. <img src={`https://flagcdn.com/w40/${lang.flag}.png`} alt={lang.label} className="w-6 h-6 rounded-full object-cover border border-slate-100" />
  390. <span className="font-bold">{lang.label}</span>
  391. </button>
  392. ))}
  393. </div>
  394. </div>
  395. </div>
  396. </div>
  397. <div className="p-8 border-t border-slate-50 bg-slate-50/50">
  398. <Link
  399. to="/login"
  400. onClick={() => setIsMenuOpen(false)}
  401. className="w-full bg-gradient-to-r from-[#E21c34] to-[#500B28] text-white py-5 rounded-[40px] font-black text-2xl shadow-xl active:scale-[0.98] transition-all flex justify-center"
  402. >
  403. Login / Register
  404. </Link>
  405. </div>
  406. </div>
  407. </div>
  408. </>
  409. );
  410. };
  411. export default Header;