Saas-Teamspace/components/file-upload.tsx
2024-11-25 01:24:37 -05:00

84 lines
2.5 KiB
TypeScript

import * as React from "react"
import { useDropzone } from "react-dropzone"
import { Cloud, File, X } from "lucide-react"
import { Button } from "@/components/ui/button"
import { cn } from "@/lib/utils"
interface FileUploadProps {
onUpload: (files: File[]) => void
value?: File[]
onChange?: (files: File[]) => void
className?: string
}
export function FileUpload({ onUpload, value = [], onChange, className }: FileUploadProps) {
const [files, setFiles] = React.useState<File[]>(value)
const onDrop = React.useCallback((acceptedFiles: File[]) => {
setFiles(prev => [...prev, ...acceptedFiles])
onChange?.(acceptedFiles)
onUpload(acceptedFiles)
}, [onChange, onUpload])
const { getRootProps, getInputProps, isDragActive } = useDropzone({
onDrop,
accept: {
'image/*': [],
'application/pdf': [],
'application/msword': [],
'application/vnd.openxmlformats-officedocument.wordprocessingml.document': [],
}
})
const removeFile = (fileToRemove: File) => {
const newFiles = files.filter(file => file !== fileToRemove)
setFiles(newFiles)
onChange?.(newFiles)
}
return (
<div className={className}>
<div
{...getRootProps()}
className={cn(
"border-2 border-dashed rounded-lg p-8 text-center hover:border-primary/50 transition-colors",
isDragActive && "border-primary",
className
)}
>
<input {...getInputProps()} />
<div className="flex flex-col items-center gap-2">
<Cloud className="h-10 w-10 text-muted-foreground" />
<p className="text-sm text-muted-foreground">
Drag & drop files here, or click to select files
</p>
<Button variant="secondary" size="sm">
Select Files
</Button>
</div>
</div>
{files.length > 0 && (
<div className="mt-4 space-y-2">
{files.map((file, index) => (
<div
key={index}
className="flex items-center gap-2 rounded-md border p-2"
>
<File className="h-4 w-4 text-muted-foreground" />
<span className="text-sm flex-1 truncate">{file.name}</span>
<Button
variant="ghost"
size="icon"
className="h-8 w-8"
onClick={() => removeFile(file)}
>
<X className="h-4 w-4" />
</Button>
</div>
))}
</div>
)}
</div>
)
}