Header.tsx 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. import { Phone, Menu, Globe } from 'lucide-react';
  2. import { useState } from 'react';
  3. import { useLanguage } from '../contexts/LanguageContext';
  4. import { useRouter } from '../contexts/RouterContext';
  5. import { Language, languages } from '../lib/i18n';
  6. import {
  7. DropdownMenu,
  8. DropdownMenuContent,
  9. DropdownMenuItem,
  10. DropdownMenuTrigger,
  11. } from './ui/dropdown-menu';
  12. export function Header() {
  13. const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
  14. const { language, setLanguage, t } = useLanguage();
  15. const { currentPage, navigateTo } = useRouter();
  16. const scrollToSection = (id: string) => {
  17. // Close mobile menu first for better UX
  18. console.log(currentPage, id,3333)
  19. setMobileMenuOpen(false);
  20. navigateTo('home', id);
  21. // if (currentPage !== 'home') {
  22. // navigateTo('home', id);
  23. // } else {
  24. // Small delay to ensure mobile menu is closed
  25. setTimeout(() => {
  26. const element = document.getElementById(id);
  27. if (element) {
  28. element.scrollIntoView({ behavior: 'smooth', block: 'start' });
  29. window.history.pushState(null, '', `#${id}`);
  30. }
  31. }, 50);
  32. // }
  33. };
  34. const handleNavigation = (page: 'faq' | 'contact') => {
  35. setMobileMenuOpen(false);
  36. console.log(page)
  37. navigateTo(page);
  38. };
  39. const scrollToTop = () => {
  40. setMobileMenuOpen(false);
  41. if (currentPage !== 'home') {
  42. navigateTo('home');
  43. } else {
  44. setTimeout(() => {
  45. window.scrollTo({ top: 0, behavior: 'smooth' });
  46. window.history.pushState(null, '', '');
  47. }, 50);
  48. }
  49. };
  50. return (
  51. <header className="sticky top-0 z-50 bg-white/95 backdrop-blur-sm border-b border-gray-200">
  52. <nav className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
  53. <div className="flex items-center justify-between h-14 sm:h-16">
  54. <button onClick={() => navigateTo('home')} className="flex items-center gap-2">
  55. <div className="w-9 h-9 sm:w-10 sm:h-10 bg-gray-900 rounded-lg sm:rounded-xl flex items-center justify-center">
  56. <Phone className="w-5 h-5 sm:w-6 sm:h-6 text-white" />
  57. </div>
  58. <span className="text-xl sm:text-2xl text-gray-900">Anycall</span>
  59. </button>
  60. {/* Desktop Navigation */}
  61. <div className="hidden md:flex items-center gap-8">
  62. <button
  63. onClick={scrollToTop}
  64. className="text-gray-600 hover:text-gray-900 transition-colors"
  65. >
  66. {t.home}
  67. </button>
  68. <button
  69. onClick={() => scrollToSection('features')}
  70. className="text-gray-600 hover:text-gray-900 transition-colors"
  71. >
  72. {t.features}
  73. </button>
  74. <button
  75. onClick={() => scrollToSection('faq')}
  76. className="text-gray-600 hover:text-gray-900 transition-colors"
  77. >
  78. {t.faq}
  79. </button>
  80. <button
  81. onClick={() => scrollToSection('contact')}
  82. className="text-gray-600 hover:text-gray-900 transition-colors"
  83. >
  84. {t.contact}
  85. </button>
  86. {/* Language Switcher */}
  87. <DropdownMenu>
  88. <DropdownMenuTrigger asChild>
  89. <button className="flex items-center gap-2 text-gray-600 hover:text-gray-900 transition-colors">
  90. <Globe className="w-4 h-4" />
  91. <span>{languages[language]}</span>
  92. </button>
  93. </DropdownMenuTrigger>
  94. <DropdownMenuContent align="end">
  95. {Object.entries(languages).map(([code, name]) => (
  96. <DropdownMenuItem
  97. key={code}
  98. onClick={() => setLanguage(code as Language)}
  99. className={language === code ? 'bg-gray-100 text-gray-900' : ''}
  100. >
  101. {name}
  102. </DropdownMenuItem>
  103. ))}
  104. </DropdownMenuContent>
  105. </DropdownMenu>
  106. </div>
  107. {/* Mobile menu button */}
  108. <button
  109. className="md:hidden p-2 hover:bg-gray-100 rounded-lg transition-colors"
  110. onClick={() => setMobileMenuOpen(!mobileMenuOpen)}
  111. aria-label="Toggle menu"
  112. >
  113. <Menu className="w-6 h-6 text-gray-900" />
  114. </button>
  115. </div>
  116. {/* Mobile Navigation */}
  117. {mobileMenuOpen && (
  118. <div className="md:hidden py-4 space-y-2 border-t border-gray-200">
  119. <button
  120. onClick={scrollToTop}
  121. className="block w-full text-left px-4 py-3 text-base text-gray-600 hover:text-gray-900 hover:bg-gray-50 rounded-lg transition-colors"
  122. >
  123. {t.home}
  124. </button>
  125. <button
  126. onClick={() => scrollToSection('features')}
  127. className="block w-full text-left px-4 py-3 text-base text-gray-600 hover:text-gray-900 hover:bg-gray-50 rounded-lg transition-colors"
  128. >
  129. {t.features}
  130. </button>
  131. <button
  132. onClick={() => handleNavigation('faq')}
  133. className="block w-full text-left px-4 py-3 text-base text-gray-600 hover:text-gray-900 hover:bg-gray-50 rounded-lg transition-colors"
  134. >
  135. {t.faq}
  136. </button>
  137. <button
  138. onClick={() => handleNavigation('contact')}
  139. className="block w-full text-left px-4 py-3 text-base text-gray-600 hover:text-gray-900 hover:bg-gray-50 rounded-lg transition-colors"
  140. >
  141. {t.contact}
  142. </button>
  143. {/* Mobile Language Switcher */}
  144. <div className="px-4 pt-4 pb-2 mt-2 border-t border-gray-200">
  145. <p className="text-sm text-gray-500 mb-3 flex items-center gap-2">
  146. <Globe className="w-4 h-4" />
  147. {t.contact.includes('Contact') ? 'Language' : '语言'}
  148. </p>
  149. <div className="grid grid-cols-2 gap-2">
  150. {Object.entries(languages).map(([code, name]) => (
  151. <button
  152. key={code}
  153. onClick={() => setLanguage(code as Language)}
  154. className={`px-3 py-2.5 rounded-lg text-sm transition-colors ${
  155. language === code
  156. ? 'bg-gray-900 text-white'
  157. : 'bg-gray-100 text-gray-600 hover:bg-gray-200'
  158. }`}
  159. >
  160. {name}
  161. </button>
  162. ))}
  163. </div>
  164. </div>
  165. </div>
  166. )}
  167. </nav>
  168. </header>
  169. );
  170. }