mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-27 04:46:58 -05:00
feat: Implement full Phase 3 API optimizations
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
import { useDebouncedValue } from '@/hooks/useDebouncedValue';
|
||||
import { useGlobalSearch } from '@/hooks/search/useGlobalSearch';
|
||||
import { Card, CardContent } from '@/components/ui/card';
|
||||
import { Badge } from '@/components/ui/badge';
|
||||
import { Button } from '@/components/ui/button';
|
||||
@@ -20,57 +22,20 @@ type SearchResult = {
|
||||
};
|
||||
|
||||
export function SearchResults({ query, onClose }: SearchResultsProps) {
|
||||
const [results, setResults] = useState<SearchResult[]>([]);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const navigate = useNavigate();
|
||||
|
||||
useEffect(() => {
|
||||
if (query.length >= 2) {
|
||||
searchContent();
|
||||
} else {
|
||||
setResults([]);
|
||||
}
|
||||
}, [query]);
|
||||
|
||||
const searchContent = async () => {
|
||||
setLoading(true);
|
||||
try {
|
||||
const searchTerm = `%${query.toLowerCase()}%`;
|
||||
|
||||
// Search parks
|
||||
const { data: parks } = await supabase
|
||||
.from('parks')
|
||||
.select(`*, location:locations(*)`)
|
||||
.or(`name.ilike.${searchTerm},description.ilike.${searchTerm}`)
|
||||
.limit(5);
|
||||
|
||||
// Search rides
|
||||
const { data: rides } = await supabase
|
||||
.from('rides')
|
||||
.select(`*, park:parks!inner(name, slug)`)
|
||||
.or(`name.ilike.${searchTerm},description.ilike.${searchTerm}`)
|
||||
.limit(5);
|
||||
|
||||
// Search companies
|
||||
const { data: companies } = await supabase
|
||||
.from('companies')
|
||||
.select('id, name, slug, description, company_type, logo_url, average_rating, review_count')
|
||||
.or(`name.ilike.${searchTerm},description.ilike.${searchTerm}`)
|
||||
.limit(3);
|
||||
|
||||
const allResults: SearchResult[] = [
|
||||
...(parks || []).map(park => ({ type: 'park' as const, data: park })),
|
||||
...(rides || []).map(ride => ({ type: 'ride' as const, data: ride })),
|
||||
...(companies || []).map(company => ({ type: 'company' as const, data: company }))
|
||||
];
|
||||
|
||||
setResults(allResults);
|
||||
} catch (error: unknown) {
|
||||
logger.error('Search failed', { error: getErrorMessage(error), query });
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
// Debounce search query
|
||||
const debouncedQuery = useDebouncedValue(query, 300);
|
||||
|
||||
// Use global search hook with caching
|
||||
const { data, isLoading: loading } = useGlobalSearch(debouncedQuery);
|
||||
|
||||
// Flatten results
|
||||
const results: SearchResult[] = [
|
||||
...(data?.parks || []).map(park => ({ type: 'park' as const, data: park })),
|
||||
...(data?.rides || []).map(ride => ({ type: 'ride' as const, data: ride })),
|
||||
...(data?.companies || []).map(company => ({ type: 'company' as const, data: company })),
|
||||
];
|
||||
|
||||
const handleResultClick = (result: SearchResult) => {
|
||||
onClose();
|
||||
|
||||
Reference in New Issue
Block a user