kattoolbox/src/components/Header.tsx

80 lines
3.1 KiB
TypeScript

"use client";
import { useState } from "react";
import Link from "next/link";
import { tools } from "@/lib/tools";
export default function Header() {
const [query, setQuery] = useState("");
const [showResults, setShowResults] = useState(false);
const filtered = query.trim()
? tools.filter(
(t) =>
t.name.toLowerCase().includes(query.toLowerCase()) ||
t.description.toLowerCase().includes(query.toLowerCase()) ||
t.category.toLowerCase().includes(query.toLowerCase())
)
: [];
return (
<header className="relative z-20 border-b border-[#141414] bg-black/90 backdrop-blur-md sticky top-0">
<div className="mx-auto max-w-7xl px-4 py-3 flex items-center justify-between gap-4">
{/* Corner Client-Side indicator linking home */}
<Link
href="/"
className="text-[10px] font-mono uppercase tracking-widest text-[#333] hover:text-[#555] transition-colors shrink-0 select-none"
title="Return to index"
>
client-side
</Link>
{/* Centered Search Bar */}
<div className="relative flex-1 max-w-lg mx-auto">
<svg
className="absolute left-3 top-1/2 -translate-y-1/2 h-3.5 w-3.5 text-[#444]"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path strokeLinecap="square" strokeLinejoin="miter" strokeWidth={2} d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
</svg>
<input
type="text"
placeholder={`Search ${tools.length} utilities...`}
value={query}
onChange={(e) => {
setQuery(e.target.value);
setShowResults(true);
}}
onFocus={() => setShowResults(true)}
onBlur={() => setTimeout(() => setShowResults(false), 200)}
className="w-full border border-[#1c1c1c] bg-[#070707] pl-9 pr-3 py-1.5 text-xs text-gray-200 placeholder-[#444] outline-none focus:border-[#333] transition-colors"
/>
{showResults && filtered.length > 0 && (
<div className="absolute left-0 right-0 top-full mt-1 max-h-80 overflow-y-auto border border-[#1f1f1f] bg-[#090909] shadow-2xl z-50 divide-y divide-[#141414]">
{filtered.map((tool) => (
<Link
key={tool.slug}
href={`/tools/${tool.slug}`}
className="flex items-center justify-between px-3.5 py-2 text-xs text-gray-300 hover:bg-[#121212] hover:text-blue-400 transition-colors"
onClick={() => {
setQuery("");
setShowResults(false);
}}
>
<span className="font-medium text-gray-200">{tool.name}</span>
<span className="text-[11px] text-[#555] truncate ml-3">{tool.description}</span>
</Link>
))}
</div>
)}
</div>
{/* Balancer spacing for desktop layout */}
<div className="w-[70px] hidden sm:block shrink-0" />
</div>
</header>
);
}