diff --git a/apps/app/components/core/image-picker-popover.tsx b/apps/app/components/core/image-picker-popover.tsx index 9304f9ba6..b4398a7c4 100644 --- a/apps/app/components/core/image-picker-popover.tsx +++ b/apps/app/components/core/image-picker-popover.tsx @@ -1,8 +1,15 @@ -import React, { useEffect, useState, useRef } from "react"; +import React, { useEffect, useState, useRef, useCallback } from "react"; + +// next +import Image from "next/image"; +import { useRouter } from "next/router"; // swr import useSWR from "swr"; +// react-dropdown +import { useDropzone } from "react-dropzone"; + // headless ui import { Tab, Transition, Popover } from "@headlessui/react"; @@ -12,6 +19,7 @@ import fileService from "services/file.service"; // components import { Input, Spinner, PrimaryButton } from "components/ui"; // hooks +import useWorkspaceDetails from "hooks/use-workspace-details"; import useOutsideClickDetector from "hooks/use-outside-click-detector"; const unsplashEnabled = @@ -38,7 +46,13 @@ type Props = { export const ImagePickerPopover: React.FC = ({ label, value, onChange }) => { const ref = useRef(null); - const [isOpen, setIsOpen] = useState(false); + const router = useRouter(); + const { workspaceSlug } = router.query; + + const [image, setImage] = useState(null); + const [isImageUploading, setIsImageUploading] = useState(false); + + const [isOpen, setIsOpen] = useState(true); const [searchParams, setSearchParams] = useState(""); const [formData, setFormData] = useState({ search: "", @@ -48,10 +62,49 @@ export const ImagePickerPopover: React.FC = ({ label, value, onChange }) fileService.getUnsplashImages(1, searchParams) ); + const { workspaceDetails } = useWorkspaceDetails(); + useOutsideClickDetector(ref, () => { setIsOpen(false); }); + const onDrop = useCallback((acceptedFiles: File[]) => { + setImage(acceptedFiles[0]); + }, []); + + const { getRootProps, getInputProps, isDragActive } = useDropzone({ + onDrop, + }); + + const handleSubmit = async () => { + setIsImageUploading(true); + + if (!image || !workspaceSlug) return; + + const formData = new FormData(); + formData.append("asset", image); + formData.append("attributes", JSON.stringify({})); + + fileService + .uploadFile(workspaceSlug.toString(), formData) + .then((res) => { + const oldValue = value; + const isUnsplashImage = oldValue?.split("/")[2] === "images.unsplash.com"; + + const imageUrl = res.asset; + onChange(imageUrl); + setIsImageUploading(false); + setImage(null); + + if (isUnsplashImage) return; + + if (oldValue && workspaceDetails) fileService.deleteFile(workspaceDetails.id, oldValue); + }) + .catch((err) => { + console.log(err); + }); + }; + useEffect(() => { if (!images || value !== null) return; onChange(images[0].urls.regular); @@ -77,22 +130,24 @@ export const ImagePickerPopover: React.FC = ({ label, value, onChange }) leaveTo="transform opacity-0 scale-95" > -
+
- - {tabOptions.map((tab) => ( - - `rounded py-1 px-4 text-center text-sm outline-none transition-colors ${ - selected ? "bg-custom-primary text-white" : "text-custom-text-100" - }` - } - > - {tab.title} - - ))} - +
+ + {tabOptions.map((tab) => ( + + `rounded py-1 px-4 text-center text-sm outline-none transition-colors ${ + selected ? "bg-custom-primary text-white" : "text-custom-text-100" + }` + } + > + {tab.title} + + ))} + +
@@ -133,8 +188,57 @@ export const ImagePickerPopover: React.FC = ({ label, value, onChange })
)}
- -

Coming Soon...

+ +
+
+
+ + {image !== null || (value && value !== "") ? ( + <> + image + + ) : ( +
+ + {isDragActive + ? "Drop image here to upload" + : "Drag & drop image here"} + +
+ )} + + +
+
+ +
+ + {isImageUploading ? "Uploading..." : "Upload & Save"} + +
+