import { useEffect, useState } from "react"; import { useCategories } from "../hooks/useCategories"; import { useCreateItem } from "../hooks/useItems"; import { CategoryPicker } from "./CategoryPicker"; import { ImageUpload } from "./ImageUpload"; interface ManualEntryFormProps { initialName?: string; onSuccess: (itemName: string) => void; } export function ManualEntryForm({ initialName, onSuccess, }: ManualEntryFormProps) { const { data: categories } = useCategories(); const createItem = useCreateItem(); const [name, setName] = useState(initialName ?? ""); const [categoryId, setCategoryId] = useState(null); const [weightGrams, setWeightGrams] = useState(""); const [priceDollars, setPriceDollars] = useState(""); const [purchasePrice, setPurchasePrice] = useState(""); const [notes, setNotes] = useState(""); const [productUrl, setProductUrl] = useState(""); const [imageFilename, setImageFilename] = useState(null); const [error, setError] = useState(null); // Pre-select first category when categories load useEffect(() => { if (categories && categories.length > 0 && categoryId === null) { setCategoryId(categories[0].id); } }, [categories, categoryId]); function handleSubmit(e: React.FormEvent) { e.preventDefault(); if (!name.trim()) { setError("Name is required"); return; } if (categoryId === null) { setError("Please select a category"); return; } setError(null); createItem.mutate( { name: name.trim(), categoryId, weightGrams: weightGrams ? Number(weightGrams) : undefined, priceCents: priceDollars ? Math.round(Number(priceDollars) * 100) : undefined, purchasePriceCents: purchasePrice ? Math.round(Number(purchasePrice) * 100) : undefined, notes: notes || undefined, productUrl: productUrl || undefined, imageFilename: imageFilename ?? undefined, }, { onSuccess: (item) => { onSuccess(item.name); }, onError: (err) => { setError(err instanceof Error ? err.message : "Failed to save"); }, }, ); } return (
{/* Image upload — hero position */}
setImageFilename(filename)} />
{/* Name */}
setName(e.target.value)} placeholder="Item name" required className="w-full px-3 py-2 border border-gray-200 rounded-lg text-sm text-gray-900 placeholder-gray-400 focus:outline-none focus:ring-2 focus:ring-gray-400 focus:border-transparent" />
{/* Category */}
setCategoryId(id)} />
{/* Weight and Price row */}
setWeightGrams(e.target.value)} placeholder="0" min="0" step="1" className="w-full px-3 py-2 border border-gray-200 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-gray-400 focus:border-transparent" />
setPriceDollars(e.target.value)} placeholder="0.00" min="0" step="0.01" className="w-full px-3 py-2 border border-gray-200 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-gray-400 focus:border-transparent" />
{/* Purchase Price */}
setPurchasePrice(e.target.value)} placeholder="0.00" min="0" step="0.01" className="w-full px-3 py-2 border border-gray-200 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-gray-400 focus:border-transparent" />
{/* Product URL */}
setProductUrl(e.target.value)} placeholder="https://..." className="w-full px-3 py-2 border border-gray-200 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-gray-400 focus:border-transparent" />
{/* Notes */}