Header.tsx 3.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. "use client";
  2. import { Menu, Search, Bell, HelpCircle, X } from "lucide-react";
  3. import { ThemeToggle } from "@/components/ThemeToggle";
  4. import { useLayout } from "@/components/LayoutProvider";
  5. import { useState } from "react";
  6. import Image from "next/image";
  7. export default function Header() {
  8. const { setMobileMenuOpen } = useLayout();
  9. const [isSearchOpen, setIsSearchOpen] = useState(false);
  10. return (
  11. <header className="h-20 flex items-center justify-between px-6 lg:px-8 border-b border-outline-variant/30 z-10 bg-background/95 backdrop-blur-sm sticky top-0">
  12. <div className="flex items-center w-full max-w-xl">
  13. <button
  14. className="lg:hidden mr-4 shrink-0 text-secondary hover:text-on-surface transition-colors"
  15. onClick={() => setMobileMenuOpen(true)}
  16. >
  17. <Menu className="w-6 h-6" />
  18. </button>
  19. {/* Mobile Banner */}
  20. <div className="lg:hidden flex-1 flex items-center">
  21. <Image
  22. src="/banner.png"
  23. alt="SEEC Metrics Banner"
  24. width={120}
  25. height={30}
  26. className="object-contain"
  27. priority
  28. />
  29. </div>
  30. {/* Desktop Search (hidden on mobile) */}
  31. <div className="relative w-full hidden lg:block">
  32. <span className="absolute inset-y-0 left-0 flex items-center pl-3 pointer-events-none">
  33. <Search className="w-5 h-5 text-outline" />
  34. </span>
  35. <input
  36. className="w-full py-2.5 pl-10 pr-4 bg-surface-container-high border-none rounded-full focus:ring-1 focus:ring-primary text-sm placeholder-outline text-on-surface transition-all shadow-inner outline-none focus:outline-none"
  37. placeholder="搜索能力指标、学生名单..."
  38. type="text"
  39. />
  40. </div>
  41. {/* Mobile Search Button */}
  42. <button
  43. className="lg:hidden p-2 text-secondary hover:text-on-surface"
  44. onClick={() => setIsSearchOpen(true)}
  45. >
  46. <Search className="w-5 h-5" />
  47. </button>
  48. </div>
  49. {/* Mobile Expanded Search Overlay */}
  50. {isSearchOpen && (
  51. <div className="absolute inset-y-0 left-0 right-0 bg-background/95 backdrop-blur-sm z-20 flex items-center px-4 lg:hidden">
  52. <div className="relative w-full flex items-center">
  53. <span className="absolute left-3 flex items-center pointer-events-none">
  54. <Search className="w-5 h-5 text-outline" />
  55. </span>
  56. <input
  57. autoFocus
  58. className="w-full py-2 pl-10 pr-10 bg-surface-container-high border-none rounded-full focus:ring-1 focus:ring-primary text-sm placeholder-outline text-on-surface outline-none"
  59. placeholder="搜索能力指标、学生名单..."
  60. type="text"
  61. />
  62. <button
  63. className="absolute right-3 p-1 rounded-full hover:bg-surface-variant text-secondary"
  64. onClick={() => setIsSearchOpen(false)}
  65. >
  66. <X className="w-4 h-4" />
  67. </button>
  68. </div>
  69. </div>
  70. )}
  71. <div className="flex items-center space-x-3">
  72. <ThemeToggle />
  73. <button className="p-2 rounded-full hover:bg-surface-container-high text-secondary hover:text-on-surface transition-colors relative">
  74. <Bell className="w-6 h-6" />
  75. <span className="absolute top-2.5 right-2.5 h-2 w-2 bg-chart-2 rounded-full ring-2 ring-background"></span>
  76. </button>
  77. <button className="p-2 rounded-full hover:bg-surface-container-high text-secondary hover:text-on-surface transition-colors">
  78. <HelpCircle className="w-6 h-6" />
  79. </button>
  80. </div>
  81. </header>
  82. );
  83. }