Add GalleryForm (WIP)

This commit is contained in:
Maximilian Harz 2025-06-04 23:44:50 +02:00
parent e26dfc6e66
commit 6a68300cea
3 changed files with 86 additions and 3 deletions

View File

@ -0,0 +1,82 @@
import { useDropzone } from 'react-dropzone'
import { useAppState } from '#components/AppShell/hooks/useAppState'
import type { FormState } from '#types/FormState'
interface Props {
state: FormState
setState: React.Dispatch<React.SetStateAction<FormState>>
}
export const GalleryForm = ({ state, setState }: Props) => {
const appState = useAppState()
const upload = async (acceptedFiles: File[]) => {
const assets = await Promise.all(
acceptedFiles.map(async (file) => {
return appState.assetsApi.upload(file, 'gallery')
}),
)
const newGalleryItems = assets.map((asset) => ({
directus_files_id: {
id: asset.id,
width: 600, // TODO determine
height: 400, // TODO determine
},
}))
setState((prevState) => ({
...prevState,
gallery: [...prevState.gallery, ...newGalleryItems],
}))
}
const { getRootProps, getInputProps } = useDropzone({
// eslint-disable-next-line @typescript-eslint/no-misused-promises
onDrop: upload,
})
const images = state.gallery.map((i, j) => ({
src: appState.assetsApi.url + `${i.directus_files_id.id}.jpg`,
width: i.directus_files_id.width,
height: i.directus_files_id.height,
index: j,
}))
const removeImage = (index: number) => {
setState((prevState) => ({
...prevState,
gallery: prevState.gallery.filter((_, i) => i !== index),
}))
}
return (
<div className='tw:h-full tw:flex tw:flex-col tw:mt-4'>
<div
{...getRootProps()}
className='tw:cursor-pointer tw:border tw:border-dashed tw:border-gray-300 tw:p-4 tw:rounded-lg'
>
<input {...getInputProps()} />
Drop here
</div>
{images.map((image, index) => (
<div key={index} className='tw:mb-2'>
<img
src={image.src}
alt={`Gallery image ${index + 1}`}
className='tw:w-full tw:h-auto tw:rounded-lg'
/>
<button
className='tw:mt-2 tw:bg-red-500 tw:text-white tw:px-4 tw:py-2 tw:rounded'
onClick={() => removeImage(index)}
>
Remove
</button>
</div>
))}
</div>
)
}

View File

@ -1,8 +1,8 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
import { ContactInfoForm } from '#components/Profile/Subcomponents/ContactInfoForm'
import { CrowdfundingForm } from '#components/Profile/Subcomponents/CrowdfundingForm'
import { GalleryForm } from '#components/Profile/Subcomponents/GalleryForm'
import { GroupSubheaderForm } from '#components/Profile/Subcomponents/GroupSubheaderForm'
import { ProfileStartEndForm } from '#components/Profile/Subcomponents/ProfileStartEndForm'
import { ProfileTextForm } from '#components/Profile/Subcomponents/ProfileTextForm'
@ -16,6 +16,7 @@ const componentMap = {
contactInfos: ContactInfoForm,
startEnd: ProfileStartEndForm,
crowdfundings: CrowdfundingForm,
gallery: GalleryForm,
// weitere Komponenten hier
}
@ -25,7 +26,7 @@ export const FlexForm = ({
setState,
}: {
state: FormState
setState: React.Dispatch<React.SetStateAction<any>>
setState: React.Dispatch<React.SetStateAction<FormState>>
item: Item
}) => {
return (

2
src/types/Item.d.ts vendored
View File

@ -9,7 +9,7 @@ type TagIds = { tags_id: string }[]
interface GalleryItem {
directus_files_id: {
id: number
id: string
width: number
height: number
}