feat: stabilization + recipe edit/create UI
This commit is contained in:
62
frontend/src/pages/SearchPage.tsx
Normal file
62
frontend/src/pages/SearchPage.tsx
Normal file
@@ -0,0 +1,62 @@
|
||||
import { useState, useEffect, useRef } from 'react'
|
||||
import { useQuery } from '@tanstack/react-query'
|
||||
import { Search } from 'lucide-react'
|
||||
import { searchRecipes } from '../api/recipes'
|
||||
import { RecipeCardSmall } from '../components/recipe/RecipeCardSmall'
|
||||
import { EmptyState } from '../components/ui/EmptyState'
|
||||
|
||||
export function SearchPage() {
|
||||
const [query, setQuery] = useState('')
|
||||
const [debouncedQuery, setDebouncedQuery] = useState('')
|
||||
const inputRef = useRef<HTMLInputElement>(null)
|
||||
|
||||
useEffect(() => { inputRef.current?.focus() }, [])
|
||||
|
||||
useEffect(() => {
|
||||
const timer = setTimeout(() => setDebouncedQuery(query), 300)
|
||||
return () => clearTimeout(timer)
|
||||
}, [query])
|
||||
|
||||
const { data, isLoading } = useQuery({
|
||||
queryKey: ['search', debouncedQuery],
|
||||
queryFn: () => searchRecipes(debouncedQuery),
|
||||
enabled: debouncedQuery.length >= 2,
|
||||
})
|
||||
|
||||
const results = data?.data ?? (Array.isArray(data) ? data as any[] : [])
|
||||
|
||||
return (
|
||||
<div className="p-4">
|
||||
{/* Search Input */}
|
||||
<div className="relative mb-4">
|
||||
<Search size={18} className="absolute left-3 top-1/2 -translate-y-1/2 text-warm-grey" />
|
||||
<input
|
||||
ref={inputRef}
|
||||
type="text"
|
||||
value={query}
|
||||
onChange={(e) => setQuery(e.target.value)}
|
||||
placeholder="Rezept suchen..."
|
||||
className="w-full pl-10 pr-4 py-3 bg-surface rounded-xl border border-sand text-espresso text-sm focus:outline-none focus:border-primary"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Results */}
|
||||
{debouncedQuery.length < 2 ? (
|
||||
<EmptyState icon="🔍" title="Suche starten" description="Gib mindestens 2 Zeichen ein" />
|
||||
) : isLoading ? (
|
||||
<p className="text-warm-grey text-sm text-center py-8">Suche...</p>
|
||||
) : results.length === 0 ? (
|
||||
<EmptyState icon="😔" title="Nichts gefunden" description={`Keine Ergebnisse für "${debouncedQuery}"`} />
|
||||
) : (
|
||||
<>
|
||||
<p className="text-warm-grey text-xs mb-3">{results.length} Ergebnis{results.length !== 1 ? 'se' : ''}</p>
|
||||
<div className="space-y-3">
|
||||
{results.map((recipe: any) => (
|
||||
<RecipeCardSmall key={recipe.id} recipe={recipe} />
|
||||
))}
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user