feat: stabilization + recipe edit/create UI

This commit is contained in:
clawd
2026-02-18 09:55:39 +00:00
commit ee452efa6a
75 changed files with 15160 additions and 0 deletions

View 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>
)
}