forked from cruip/tailwind-landing-page-template
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
3ae6e00
commit 25e5550
Showing
5 changed files
with
154 additions
and
195 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
import Image from "next/image"; | ||
import React, {ChangeEvent, useState} from "react"; | ||
import {toast, ToastContainer} from "react-toastify"; | ||
import 'react-toastify/dist/ReactToastify.css'; | ||
|
||
const MultipleUploadForm = () => { | ||
const [file, setFile] = useState<File | null>(null); | ||
const [previewUrls, setPreviewUrls] = useState<string[]>([]); | ||
|
||
const onFilesUploadChange = async (e: ChangeEvent<HTMLInputElement>) => { | ||
const fileInput = e.target; | ||
|
||
if (!fileInput.files) { | ||
toast.error("No file was chosen"); | ||
return; | ||
} | ||
|
||
if (!fileInput.files || fileInput.files.length === 0) { | ||
toast.error("Files list is empty"); | ||
return; | ||
} | ||
|
||
/** Files validation */ | ||
const validFiles: File[] = []; | ||
for (let i = 0; i < fileInput.files.length; i++) { | ||
const file = fileInput.files[i]; | ||
|
||
if (!file.type.startsWith("image")) { | ||
toast.error(`File ${i + 1} is invalid`); | ||
continue; | ||
} | ||
|
||
validFiles.push(file); | ||
} | ||
|
||
if (!validFiles.length) { | ||
toast.error('No valid files were chosen'); | ||
return; | ||
} | ||
|
||
/** Uploading files to the server */ | ||
try { | ||
const formData = new FormData(); | ||
validFiles.forEach(file => formData.append("media", file)); | ||
|
||
const resUpload = await fetch("/admin/api/upload", { | ||
method: "POST", | ||
body: formData, | ||
}); | ||
|
||
const { | ||
data, | ||
error, | ||
}: { | ||
data: { | ||
urls: {}; | ||
} | null; | ||
error: string | null; | ||
} = await resUpload.json(); | ||
|
||
if (error || !data) { | ||
toast.error(error || "Sorry! something went wrong."); | ||
return; | ||
} | ||
|
||
setPreviewUrls( | ||
validFiles.map(validFile => URL.createObjectURL(validFile)) | ||
); // we will use this to show the preview of the images | ||
|
||
/** Reset file input */ | ||
fileInput.type = "text"; | ||
fileInput.type = "file"; | ||
|
||
console.log("Files were uploaded successfully:", data); | ||
} catch (error) { | ||
console.error(error); | ||
toast.error("Sorry! something went wrong."); | ||
} | ||
}; | ||
|
||
return ( | ||
<> | ||
<form | ||
className="w-full p-3 border border-gray-500 border-dashed" | ||
onSubmit={(e) => e.preventDefault()} | ||
> | ||
{previewUrls.length > 0 ? ( | ||
<> | ||
<button | ||
onClick={() => setPreviewUrls([])} | ||
className="mb-3 text-sm font-medium text-gray-500 transition-colors duration-300 hover:text-gray-900" | ||
> | ||
Clear Previews | ||
</button> | ||
|
||
<div className="flex flex-wrap justify-start"> | ||
{previewUrls.map((previewUrl, idx) => ( | ||
<div key={idx} className="w-full p-1.5 md:w-1/2"> | ||
<Image | ||
alt="file uploader preview" | ||
objectFit="cover" | ||
src={previewUrl} | ||
width={320} | ||
height={218} | ||
layout="responsive" | ||
/> | ||
</div> | ||
))} | ||
</div> | ||
</> | ||
) : ( | ||
<label | ||
className="flex flex-col items-center justify-center h-full py-8 transition-colors duration-150 cursor-pointer hover:text-gray-600"> | ||
<svg | ||
xmlns="http://www.w3.org/2000/svg" | ||
className="w-14 h-14" | ||
fill="none" | ||
viewBox="0 0 24 24" | ||
stroke="currentColor" | ||
strokeWidth={2} | ||
> | ||
<path | ||
strokeLinecap="round" | ||
strokeLinejoin="round" | ||
d="M3 15a4 4 0 004 4h9a5 5 0 10-.1-9.999 5.002 5.002 0 10-9.78 2.096A4.001 4.001 0 003 15z" | ||
/> | ||
</svg> | ||
<strong className="text-sm font-medium">Select images</strong> | ||
<input | ||
className="block w-0 h-0" | ||
name="file" | ||
type="file" | ||
onChange={onFilesUploadChange} | ||
multiple | ||
/> | ||
</label> | ||
)} | ||
</form> | ||
<ToastContainer/> | ||
</> | ||
); | ||
}; | ||
|
||
export default MultipleUploadForm; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.