mirror of
https://github.com/utopia-os/utopia-ui.git
synced 2026-04-06 01:25:33 +00:00
Add GalleryForm (WIP)
This commit is contained in:
parent
e26dfc6e66
commit
6a68300cea
82
src/Components/Profile/Subcomponents/GalleryForm.tsx
Normal file
82
src/Components/Profile/Subcomponents/GalleryForm.tsx
Normal 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>
|
||||||
|
)
|
||||||
|
}
|
||||||
@ -1,8 +1,8 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
||||||
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
||||||
|
|
||||||
import { ContactInfoForm } from '#components/Profile/Subcomponents/ContactInfoForm'
|
import { ContactInfoForm } from '#components/Profile/Subcomponents/ContactInfoForm'
|
||||||
import { CrowdfundingForm } from '#components/Profile/Subcomponents/CrowdfundingForm'
|
import { CrowdfundingForm } from '#components/Profile/Subcomponents/CrowdfundingForm'
|
||||||
|
import { GalleryForm } from '#components/Profile/Subcomponents/GalleryForm'
|
||||||
import { GroupSubheaderForm } from '#components/Profile/Subcomponents/GroupSubheaderForm'
|
import { GroupSubheaderForm } from '#components/Profile/Subcomponents/GroupSubheaderForm'
|
||||||
import { ProfileStartEndForm } from '#components/Profile/Subcomponents/ProfileStartEndForm'
|
import { ProfileStartEndForm } from '#components/Profile/Subcomponents/ProfileStartEndForm'
|
||||||
import { ProfileTextForm } from '#components/Profile/Subcomponents/ProfileTextForm'
|
import { ProfileTextForm } from '#components/Profile/Subcomponents/ProfileTextForm'
|
||||||
@ -16,6 +16,7 @@ const componentMap = {
|
|||||||
contactInfos: ContactInfoForm,
|
contactInfos: ContactInfoForm,
|
||||||
startEnd: ProfileStartEndForm,
|
startEnd: ProfileStartEndForm,
|
||||||
crowdfundings: CrowdfundingForm,
|
crowdfundings: CrowdfundingForm,
|
||||||
|
gallery: GalleryForm,
|
||||||
// weitere Komponenten hier
|
// weitere Komponenten hier
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -25,7 +26,7 @@ export const FlexForm = ({
|
|||||||
setState,
|
setState,
|
||||||
}: {
|
}: {
|
||||||
state: FormState
|
state: FormState
|
||||||
setState: React.Dispatch<React.SetStateAction<any>>
|
setState: React.Dispatch<React.SetStateAction<FormState>>
|
||||||
item: Item
|
item: Item
|
||||||
}) => {
|
}) => {
|
||||||
return (
|
return (
|
||||||
|
|||||||
2
src/types/Item.d.ts
vendored
2
src/types/Item.d.ts
vendored
@ -9,7 +9,7 @@ type TagIds = { tags_id: string }[]
|
|||||||
|
|
||||||
interface GalleryItem {
|
interface GalleryItem {
|
||||||
directus_files_id: {
|
directus_files_id: {
|
||||||
id: number
|
id: string
|
||||||
width: number
|
width: number
|
||||||
height: number
|
height: number
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user