import React, { useState, useEffect, useRef } from 'react'; import axios from 'axios'; import { toast } from 'sonner'; import { useTranslation } from 'react-i18next'; import { Search as SearchIcon, Loader2 } from 'lucide-react'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Card, CardContent } from '@/components/ui/card'; import { Progress } from '@/components/ui/progress'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'; import { SearchResultCard } from '@/components/search/SearchResultCard'; const API_URL = '/api'; export default function Search() { const { t } = useTranslation(); const [query, setQuery] = useState(''); const [sites, setSites] = useState([]); const [selectedSiteId, setSelectedSiteId] = useState(null); const [isSearching, setIsSearching] = useState(false); const [progress, setProgress] = useState(null); const [results, setResults] = useState([]); const eventSourceRef = useRef(null); // Charger les sites au démarrage useEffect(() => { loadSites(); }, []); const loadSites = async () => { try { const response = await axios.get(`${API_URL}/search-sites`); const activeSites = response.data.filter(site => site.is_active); setSites(activeSites); // Sélectionner le premier site actif par défaut if (activeSites.length > 0 && !selectedSiteId) { setSelectedSiteId(activeSites[0].id.toString()); } } catch (error) { console.error('Error loading sites:', error); toast.error('Erreur lors du chargement des sites'); } }; const handleSearch = async (e) => { e.preventDefault(); if (!query.trim() || !selectedSiteId) { toast.error('Veuillez entrer une recherche et sélectionner un site'); return; } // Fermer l'EventSource précédent si existant if (eventSourceRef.current) { eventSourceRef.current.close(); } setIsSearching(true); setResults([]); setProgress({ status: 'searching', total: 1, completed: 0 }); // Construire l'URL avec les paramètres const params = new URLSearchParams({ q: query.trim(), sites: selectedSiteId, max_results: 20, }); // Créer l'EventSource pour SSE const eventSource = new EventSource(`${API_URL}/search?${params}`); eventSourceRef.current = eventSource; eventSource.addEventListener('progress', (event) => { try { const data = JSON.parse(event.data); setProgress(data); setResults(data.results || []); if (data.status === 'completed' || data.status === 'error') { setIsSearching(false); eventSource.close(); if (data.status === 'completed') { toast.success(`${data.results?.length || 0} produits trouvés`); } else if (data.message) { toast.error(data.message); } } } catch (error) { console.error('Error parsing SSE data:', error); } }); eventSource.onerror = () => { setIsSearching(false); eventSource.close(); toast.error('Erreur de connexion au serveur'); }; }; const handleAddToMonitoring = async (result) => { try { await axios.post(`${API_URL}/items`, { url: result.url, name: result.title, target_price: null, check_interval_minutes: 60, }); toast.success(`"${result.title}" ajouté au monitoring`); } catch (error) { console.error('Error adding item:', error); toast.error("Erreur lors de l'ajout au monitoring"); } }; const progressPercent = progress ? Math.round((progress.completed / Math.max(progress.total, 1)) * 100) : 0; const selectedSite = sites.find(s => s.id.toString() === selectedSiteId); return (
Recherchez des produits sur un site et ajoutez-les au monitoring
Essayez avec d'autres termes de recherche ou sélectionnez un autre site