Files
studyos/client/src/hooks/useSearch.js
renato97 4ff4302a8c feat: implement 33 nice-to-have features + fix 37 code review bugs
5 SDD batches archived:
- Batch 1: UI Polish (10 features, 14 tasks)
- Batch 2: Study System (8 features, 23 tasks)
- Batch 3: Infrastructure (5 features, 22 tasks)
- Batch 4: AI Advanced (5 features, 30 tasks) — RAG with @xenova/transformers
- Batch 5: Core Features (5 features, 19 tasks)

37 bugs fixed from comprehensive code review (11 CRITICAL, 12 HIGH, 14 MEDIUM/LOW):
- SSE streaming now works (event.token check)
- API keys no longer exposed via GET /api/models
- FTS5 injection sanitized
- DB backup/restore with admin auth
- Buddy mode wired (buddy_meta column)
- Exam auto-submit stale closure fixed
- CSS variables aligned with design tokens
- Progress data corruption fixed
- WebSocket protocol auto-detection
- Tests infrastructure completed (vitest + node:test)
2026-06-08 18:18:47 -03:00

45 lines
1.1 KiB
JavaScript

import { useState, useEffect, useCallback, useRef } from 'react';
import { searchApi } from '../lib/api';
export default function useSearch() {
const [query, setQuery] = useState('');
const [results, setResults] = useState([]);
const [loading, setLoading] = useState(false);
const debounceRef = useRef(null);
const clear = useCallback(() => {
setQuery('');
setResults([]);
setLoading(false);
}, []);
useEffect(() => {
if (debounceRef.current) {
clearTimeout(debounceRef.current);
}
const trimmed = query.trim();
if (!trimmed) {
setResults([]);
setLoading(false);
return;
}
setLoading(true);
debounceRef.current = setTimeout(async () => {
try {
const data = await searchApi(trimmed);
setResults(data || []);
} catch (err) {
console.error('[useSearch] error:', err.message);
setResults([]);
} finally {
setLoading(false);
}
}, 300);
return () => {
if (debounceRef.current) clearTimeout(debounceRef.current);
};
}, [query]);
return { query, setQuery, results, loading, clear };
}