feat: add file preview functionality to dropzone

- Add filePreviews state to track base64 preview URLs
- Implement FileReader-based preview generation on file drop
- Add preview image display in DropzoneContent
- Update variant removal to clear associated previews
- Add preview cleanup in form reset and clear functions
- Enhance user experience with immediate visual feedback
This commit is contained in:
Thomas Camlong
2025-10-02 16:20:56 +02:00
parent c5949aab03
commit 758c4a5bbc

View File

@@ -80,6 +80,7 @@ export function AdvancedIconSubmissionForm() {
const [isExistingIcon, setIsExistingIcon] = useState(false) const [isExistingIcon, setIsExistingIcon] = useState(false)
const [activeVariants, setActiveVariants] = useState<string[]>(["base"]) const [activeVariants, setActiveVariants] = useState<string[]>(["base"])
const [files, setFiles] = useState<Record<string, File[]>>({}) const [files, setFiles] = useState<Record<string, File[]>>({})
const [filePreviews, setFilePreviews] = useState<Record<string, string>>({})
const [aliases, setAliases] = useState<string[]>([]) const [aliases, setAliases] = useState<string[]>([])
const [aliasInput, setAliasInput] = useState("") const [aliasInput, setAliasInput] = useState("")
const [categories, setCategories] = useState<string[]>([]) const [categories, setCategories] = useState<string[]>([])
@@ -96,8 +97,11 @@ export function AdvancedIconSubmissionForm() {
if (variantId !== "base") { if (variantId !== "base") {
setActiveVariants(activeVariants.filter((id) => id !== variantId)) setActiveVariants(activeVariants.filter((id) => id !== variantId))
const newFiles = { ...files } const newFiles = { ...files }
const newPreviews = { ...filePreviews }
delete newFiles[variantId] delete newFiles[variantId]
delete newPreviews[variantId]
setFiles(newFiles) setFiles(newFiles)
setFilePreviews(newPreviews)
} }
} }
@@ -106,6 +110,20 @@ export function AdvancedIconSubmissionForm() {
...files, ...files,
[variantId]: droppedFiles, [variantId]: droppedFiles,
}) })
// Generate preview for the first file
if (droppedFiles.length > 0) {
const reader = new FileReader()
reader.onload = (e) => {
if (typeof e.target?.result === 'string') {
setFilePreviews({
...filePreviews,
[variantId]: e.target.result,
})
}
}
reader.readAsDataURL(droppedFiles[0])
}
} }
const handleAddAlias = () => { const handleAddAlias = () => {
@@ -212,6 +230,7 @@ export function AdvancedIconSubmissionForm() {
// Reset form // Reset form
setIconName("") setIconName("")
setFiles({}) setFiles({})
setFilePreviews({})
setActiveVariants(["base"]) setActiveVariants(["base"])
setAliases([]) setAliases([])
setCategories([]) setCategories([])
@@ -312,7 +331,17 @@ export function AdvancedIconSubmissionForm() {
src={files[variantId]} src={files[variantId]}
> >
<DropzoneEmptyState /> <DropzoneEmptyState />
<DropzoneContent /> <DropzoneContent>
{filePreviews[variantId] && (
<div className="h-[102px] w-full">
<img
alt="Preview"
className="absolute top-0 left-0 h-full w-full object-cover"
src={filePreviews[variantId]}
/>
</div>
)}
</DropzoneContent>
</Dropzone> </Dropzone>
</div> </div>
) )
@@ -432,6 +461,7 @@ export function AdvancedIconSubmissionForm() {
onClick={() => { onClick={() => {
setIconName("") setIconName("")
setFiles({}) setFiles({})
setFilePreviews({})
setActiveVariants(["base"]) setActiveVariants(["base"])
setAliases([]) setAliases([])
setCategories([]) setCategories([])