- useIntakeStore: step tracking, photos (max 3), aiResult, editedName, error - submitIntake(): multipart FormData POST /api/intake with IntakeResponse type - DropZone: react-dropzone with camera capture, volt hover state, slot counter - PhotoPreview: thumbnail grid with X remove button per photo
34 lines
1 KiB
TypeScript
34 lines
1 KiB
TypeScript
import { X } from 'lucide-react'
|
|
import { Button } from '@/components/ui/button'
|
|
|
|
interface PhotoPreviewProps {
|
|
photos: File[]
|
|
onRemove: (index: number) => void
|
|
}
|
|
|
|
export function PhotoPreview({ photos, onRemove }: PhotoPreviewProps) {
|
|
if (photos.length === 0) return null
|
|
return (
|
|
<div className="flex gap-3 flex-wrap mt-4">
|
|
{photos.map((file, i) => {
|
|
const url = URL.createObjectURL(file)
|
|
return (
|
|
<div
|
|
key={i}
|
|
className="relative w-24 h-24 rounded-sharp overflow-hidden border border-charcoal/80 group"
|
|
>
|
|
<img src={url} alt={`Photo ${i + 1}`} className="w-full h-full object-cover" />
|
|
<Button
|
|
variant="destructive"
|
|
size="icon"
|
|
className="absolute top-1 right-1 h-5 w-5 opacity-0 group-hover:opacity-100 transition-opacity"
|
|
onClick={() => onRemove(i)}
|
|
>
|
|
<X className="w-3 h-3" />
|
|
</Button>
|
|
</div>
|
|
)
|
|
})}
|
|
</div>
|
|
)
|
|
}
|