fix: Display appropriate error message when uploading image (#1334)

Co-authored-by: pandeymangg <anshuman.pandey9999@gmail.com>
Co-authored-by: ShubhamPalriwala <spalriwalau@gmail.com>
This commit is contained in:
Olaleye Blessing
2023-10-23 07:34:43 +01:00
committed by GitHub
parent 1206b969e3
commit 2e53d3d039
+75 -26
View File
@@ -2,9 +2,11 @@
import { PhotoIcon, TrashIcon } from "@heroicons/react/24/outline";
import { ArrowUpTrayIcon } from "@heroicons/react/24/solid";
import { FileIcon } from "lucide-react";
import { useState } from "react";
import { useRef, useState } from "react";
import toast from "react-hot-toast";
import { uploadFile } from "./lib/fileUpload";
import { cn } from "@formbricks/lib/cn";
import { Button } from "../Button";
interface FileInputProps {
allowedFileExtensions: string[];
@@ -21,6 +23,8 @@ const FileInput: React.FC<FileInputProps> = ({
}) => {
const [selectedFile, setSelectedFile] = useState<File | null>(null);
const [isUploaded, setIsUploaded] = useState<boolean>(!!fileUrl);
const [isError, setIsError] = useState<boolean>(false);
const fileInputRef = useRef<HTMLInputElement>(null);
const handleDragOver = (e: React.DragEvent<HTMLLabelElement>) => {
e.preventDefault();
@@ -38,20 +42,44 @@ const FileInput: React.FC<FileInputProps> = ({
file.type &&
allowedFileExtensions.includes(file.type.substring(file.type.lastIndexOf("/") + 1))
) {
setIsUploaded(false);
setSelectedFile(file);
const response = await uploadFile(file, allowedFileExtensions, environmentId);
setIsUploaded(true);
onFileUpload(response.data.url);
await handleFileUpload({
file,
allowedFileExtensions,
environmentId,
});
} else {
toast.error("File not supported");
}
};
const handleFileUpload = async (params: {
file: File;
allowedFileExtensions: string[];
environmentId: string | undefined;
}) => {
setIsUploaded(false);
setIsError(false);
setSelectedFile(params.file);
try {
let response = await uploadFile(params.file, params.allowedFileExtensions, params.environmentId);
setIsUploaded(true);
onFileUpload(response.data.url);
} catch (error: any) {
setIsUploaded(false);
setSelectedFile(null);
setIsError(true);
toast.error("Something went wrong.");
}
};
return (
<label
htmlFor="selectedFile"
className="relative flex h-52 w-full cursor-pointer flex-col items-center justify-center rounded-lg border-2 border-dashed border-slate-300 bg-slate-50 hover:bg-slate-100 dark:border-slate-600 dark:bg-slate-700 dark:hover:border-slate-500 dark:hover:bg-slate-600 dark:hover:bg-slate-800"
className={cn(
"relative flex h-52 w-full cursor-pointer flex-col items-center justify-center rounded-lg border-2 border-dashed border-slate-300 bg-slate-50 hover:bg-slate-100 dark:border-slate-600 dark:bg-slate-700 dark:hover:border-slate-500 dark:hover:bg-slate-600 dark:hover:bg-slate-800",
isError && "border-red-500"
)}
onDragOver={(e) => handleDragOver(e)}
onDrop={(e) => handleDrop(e)}>
{isUploaded && fileUrl ? (
@@ -68,13 +96,13 @@ const FileInput: React.FC<FileInputProps> = ({
accept={allowedFileExtensions.map((ext) => `.${ext}`).join(",")}
className="hidden"
onChange={async (e) => {
const selectedFile = e.target?.files?.[0];
if (selectedFile) {
setIsUploaded(false);
setSelectedFile(selectedFile);
const response = await uploadFile(selectedFile, allowedFileExtensions, environmentId);
setIsUploaded(true);
onFileUpload(response.data.url);
const file = e.target?.files?.[0];
if (file) {
await handleFileUpload({
file,
allowedFileExtensions,
environmentId,
});
}
}}
/>
@@ -97,7 +125,7 @@ const FileInput: React.FC<FileInputProps> = ({
) : (
<div className="flex flex-col items-center justify-center pb-6 pt-5">
<FileIcon className="h-6 text-slate-500" />
<p className="dark.text-slate-400 mt-2 text-sm text-slate-500">
<p className="mt-2 text-sm text-slate-500">
<span className="font-semibold">{fileUrl.split("/").pop()}</span>
</p>
</div>
@@ -114,7 +142,7 @@ const FileInput: React.FC<FileInputProps> = ({
) : (
<div className="flex flex-col items-center justify-center pb-6 pt-5">
<FileIcon className="h-6 text-slate-500" />
<p className="dark.text-slate-400 mt-2 text-sm text-slate-500">
<p className="mt-2 text-sm text-slate-500">
<span className="font-semibold">{selectedFile.name}</span>
</p>
</div>
@@ -127,24 +155,45 @@ const FileInput: React.FC<FileInputProps> = ({
</>
) : (
<div className="flex flex-col items-center justify-center pb-6 pt-5">
<ArrowUpTrayIcon className="h-6 text-slate-500" />
<p className="dark.text-slate-400 mt-2 text-sm text-slate-500">
<span className="font-semibold">Click or drag to upload files.</span>
{!isError && <ArrowUpTrayIcon className="h-6 text-slate-500" />}
<p className={cn("mt-2 text-sm text-slate-500", isError && "text-red-500")}>
<span className="font-semibold">
{isError ? "Failed to upload file! Please try again." : "Click or drag to upload files."}
</span>
</p>
{isError && (
<Button
variant="warn"
className="mt-2"
onClick={() => {
setIsError(false);
setIsUploaded(false);
setSelectedFile(null);
if (fileInputRef.current) {
fileInputRef.current.value = "";
fileInputRef.current.click();
}
}}
type="button">
Retry
</Button>
)}
<input
type="file"
id="selectedFile"
ref={fileInputRef}
name="selectedFile"
accept={allowedFileExtensions.map((ext) => `.${ext}`).join(",")}
className="hidden"
onChange={async (e) => {
const selectedFile = e.target?.files?.[0];
if (selectedFile) {
setIsUploaded(false);
setSelectedFile(selectedFile);
const response = await uploadFile(selectedFile, allowedFileExtensions, environmentId);
setIsUploaded(true);
onFileUpload(response.data.url);
const file = e.target?.files?.[0];
if (file) {
await handleFileUpload({
file,
allowedFileExtensions,
environmentId,
});
}
}}
/>