mirror of
https://github.com/formbricks/formbricks.git
synced 2026-05-08 06:41:45 -05:00
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:
@@ -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,
|
||||
});
|
||||
}
|
||||
}}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user