// Global search overlay — searches tenants (rentals) + equipment const { useState: useStateS, useMemo: useMemoS, useEffect: useEffectS, useRef: useRefS } = React; function SearchOverlay({ open, onClose, equipment = [], rentals = [], go }) { const t = useTheme(); const [q, setQ] = useStateS(''); const [visible, setVisible] = useStateS(open); const inputRef = useRefS(null); useEffectS(() => { if (open) { setVisible(true); return; } const id = setTimeout(() => setVisible(false), 340); return () => clearTimeout(id); }, [open]); useEffectS(() => { if (open) { setQ(''); setTimeout(() => inputRef.current && inputRef.current.focus(), 250); } }, [open]); const query = q.trim().toLowerCase(); // Unique tenants from rentals (Stammkunden) const tenants = useMemoS(() => { const map = {}; rentals.forEach(r => { const key = r.tenantName.toLowerCase(); if (!map[key]) map[key] = { name: r.tenantName, count: 0, last: '', phone: r.phone, email: r.email }; map[key].count += 1; if (r.start > map[key].last) map[key].last = r.start; }); return Object.values(map); }, [rentals]); const tenantHits = query ? tenants.filter(x => x.name.toLowerCase().includes(query) || (x.phone || '').toLowerCase().includes(query) || (x.email || '').toLowerCase().includes(query)) : []; const eqHits = query ? equipment.filter(e => e.name.toLowerCase().includes(query) || (e.cat || '').toLowerCase().includes(query) || (e.kind || '').toLowerCase().includes(query)) : []; const rentalHits = query ? rentals.filter(r => (r.purpose || '').toLowerCase().includes(query) || (r.equipmentName || '').toLowerCase().includes(query)) : []; const empty = query && tenantHits.length === 0 && eqHits.length === 0 && rentalHits.length === 0; const Section = ({ title, count }) => (
{title}
{count}
); const nav = (fn) => { onClose(); setTimeout(fn, 60); }; return (
{/* Search header */}
setQ(e.target.value)} placeholder="Mieter oder Equipment suchen" style={{ flex: 1, border: 'none', outline: 'none', background: 'transparent', fontSize: 15, color: t.text, fontFamily: 'inherit' }}/> {q && ( setQ('')} scale={0.85}>
)}
Fertig
{!query && (
🔎
Suche nach Mietern, Equipment oder Verwendungszweck.
)} {empty && (
Keine Treffer für „{q}“.
)} {/* Tenants */} {tenantHits.length > 0 &&
}
{tenantHits.map(x => { const rentalForTenant = rentals.find(r => r.tenantName === x.name); return ( nav(() => go('doc', { rentalId: rentalForTenant ? rentalForTenant.id : null }))} scale={0.98}>
{x.name.split(' ').map(w => w[0]).slice(0, 2).join('')}
{x.name}
{x.count} Miete{x.count > 1 ? 'n' : ''}{x.count > 1 ? ' · Stammkunde' : ''}
{x.count > 1 &&
}
); })}
{/* Equipment */} {eqHits.length > 0 &&
}
{eqHits.map(e => ( nav(() => go('detail', { id: e.id }))} scale={0.98}>
{e.name}
{e.cat} · {e.price} €/Tag
))}
{/* Rentals by purpose */} {rentalHits.length > 0 &&
}
{rentalHits.map(r => { const m = statusMeta(r.status); return ( nav(() => go('doc', { rentalId: r.id }))} scale={0.98}>
{r.purpose || '—'}
{r.tenantName} · {r.equipmentName}
● {m.label}
); })}
); } Object.assign(window, { SearchOverlay });