/* eslint-disable @typescript-eslint/no-explicit-any */ import React, { useState, useEffect, useRef } from 'react'; import { format } from 'date-fns'; interface SomedayList { id: string; title: string; tasks: any[]; } interface SearchModalProps { isOpen: boolean; onClose: () => void; tasks: any[]; events: any[]; somedayLists?: SomedayList[]; onSelectTask: (date: Date) => void; } export default function SearchModal({ isOpen, onClose, tasks, events, somedayLists = [], onSelectTask }: SearchModalProps) { const [query, setQuery] = useState(''); const [results, setResults] = useState<{ type: 'task' | 'event' | 'someday', item: any }[]>([]); const inputRef = useRef(null); const dialogRef = useRef(null); useEffect(() => { if (isOpen && inputRef.current) { inputRef.current.focus(); } }, [isOpen]); // Focus trap useEffect(() => { if (!isOpen) return; const handleKeyDown = (e: KeyboardEvent) => { if (e.key === 'Escape') { onClose(); return; } if (e.key !== 'Tab') return; const dialog = dialogRef.current; if (!dialog) return; const focusable = Array.from( dialog.querySelectorAll('button, input, a[href], [tabindex]:not([tabindex="-1"])') ).filter(el => !el.hasAttribute('disabled')); if (focusable.length === 0) return; const first = focusable[0]; const last = focusable[focusable.length - 1]; if (e.shiftKey) { if (document.activeElement === first) { e.preventDefault(); last.focus(); } } else { if (document.activeElement === last) { e.preventDefault(); first.focus(); } } }; document.addEventListener('keydown', handleKeyDown); return () => document.removeEventListener('keydown', handleKeyDown); }, [isOpen, onClose]); useEffect(() => { if (!query.trim()) { setResults([]); return; } const lowerQuery = query.toLowerCase(); const filteredTasks = tasks.filter(t => t.title.toLowerCase().includes(lowerQuery) && !t.somedayListId ).map(t => ({ type: 'task' as const, item: t })); // Include someday tasks from all someday lists const somedayTasks = somedayLists.flatMap(list => list.tasks .filter(t => t.title.toLowerCase().includes(lowerQuery)) .map(t => ({ type: 'someday' as const, item: { ...t, somedayListTitle: list.title } })) ); const filteredEvents = events.filter(e => e.title.toLowerCase().includes(lowerQuery) ).map(e => ({ type: 'event' as const, item: e })); setResults([...filteredTasks, ...somedayTasks, ...filteredEvents].slice(0, 15)); }, [query, tasks, events, somedayLists]); if (!isOpen) return null; return ( ); }