import { useEffect, useRef, useState, type FormEvent } from "react"; import { useLocation, useSearch } from "wouter"; import { Search, SlidersHorizontal, X } from "lucide-react"; import { useMail } from "@/store/mail"; import { keyboard } from "@/lib/keyboard"; import { DateField } from "@/ui/datefield"; export function SearchBar() { const [location, navigate] = useLocation(); const search = useSearch(); const [q, setQ] = useState(""); const [adv, setAdv] = useState(false); const inputRef = useRef(null); const mailboxes = useMail((s) => s.mailboxes); const [advFields, setAdvFields] = useState({ from: "", to: "", subject: "", words: "", hasAttachment: false, unread: false, folder: "", after: "", before: "" }); // Sync from URL when on /search useEffect(() => { if (location.startsWith("/search")) { const params = new URLSearchParams(search); setQ(params.get("q") ?? ""); } else setQ(""); }, [location, search]); useEffect(() => keyboard.pushScope("search", [{ keys: "/", description: "Search mail", group: "Navigation", handler: () => inputRef.current?.focus() }]), []); const submit = (e?: FormEvent) => { e?.preventDefault(); const query = q.trim(); if (!query) return; setAdv(false); navigate(`/search?q=${encodeURIComponent(query)}`); inputRef.current?.blur(); }; const applyAdvanced = () => { const parts: string[] = []; const f = advFields; if (f.from) parts.push(`from:${quote(f.from)}`); if (f.to) parts.push(`to:${quote(f.to)}`); if (f.subject) parts.push(`subject:${quote(f.subject)}`); if (f.words) parts.push(f.words); if (f.hasAttachment) parts.push("has:attachment"); if (f.unread) parts.push("is:unread"); if (f.folder) parts.push(`in:${quote(f.folder)}`); if (f.after) parts.push(`after:${f.after}`); if (f.before) parts.push(`before:${f.before}`); const query = parts.join(" "); setQ(query); setAdv(false); if (query) navigate(`/search?q=${encodeURIComponent(query)}`); }; return (
setQ(e.target.value)} aria-label="Search mail" enterKeyHint="search" /> {q && ( )}
{adv && (
Date
setAdvFields({ ...advFields, after: v })} />to setAdvFields({ ...advFields, before: v })} />
)}
); } function quote(s: string): string { return /\s/.test(s) ? `"${s.replace(/"/g, "")}"` : s; }