erp-cicd/frontend/src/components/ui/file-upload.tsx
Ali af6fd7bcad
All checks were successful
Build & Deploy Frontend / build-push-deploy (push) Successful in 1m45s
added some
2025-08-30 11:57:49 +05:30

115 lines
3.4 KiB
TypeScript

import React, { useCallback, useState } from 'react';
import { useDropzone } from 'react-dropzone';
import { Upload, X, FileText } from 'lucide-react';
import { Button } from '@/components/ui/button';
import { cn } from '@/lib/utils';
interface FileUploadProps {
onFileSelect: (file: File) => void;
onFileRemove: () => void;
selectedFile?: File;
currentFileUrl?: string;
accept?: string;
maxSize?: number;
className?: string;
}
export function FileUpload({
onFileSelect,
onFileRemove,
selectedFile,
currentFileUrl,
accept = '.pdf,.jpg,.jpeg,.png',
maxSize = 5 * 1024 * 1024, // 5MB
className
}: FileUploadProps) {
const [error, setError] = useState<string>('');
const onDrop = useCallback((acceptedFiles: File[], rejectedFiles: any[]) => {
setError('');
if (rejectedFiles.length > 0) {
const rejection = rejectedFiles[0];
if (rejection.errors[0]?.code === 'file-too-large') {
setError('File is too large. Maximum size is 5MB.');
} else if (rejection.errors[0]?.code === 'file-invalid-type') {
setError('Invalid file type. Please upload PDF, JPG, or PNG files.');
} else {
setError('File upload failed. Please try again.');
}
return;
}
if (acceptedFiles.length > 0) {
onFileSelect(acceptedFiles[0]);
}
}, [onFileSelect]);
const { getRootProps, getInputProps, isDragActive } = useDropzone({
onDrop,
accept: {
'application/pdf': ['.pdf'],
'image/jpeg': ['.jpg', '.jpeg'],
'image/png': ['.png']
},
maxSize,
multiple: false
});
const hasFile = selectedFile || currentFileUrl;
return (
<div className={cn('space-y-2', className)}>
{!hasFile ? (
<div
{...getRootProps()}
className={cn(
'border-2 border-dashed rounded-lg p-6 text-center cursor-pointer transition-colors',
isDragActive
? 'border-primary bg-primary/5'
: 'border-muted-foreground/25 hover:border-primary hover:bg-primary/5'
)}
>
<input {...getInputProps()} />
<Upload className="mx-auto h-8 w-8 text-muted-foreground mb-2" />
<p className="text-sm text-muted-foreground">
{isDragActive ? (
'Drop the file here...'
) : (
<>
Drag & drop an invoice file here, or{' '}
<span className="text-primary font-medium">click to browse</span>
</>
)}
</p>
<p className="text-xs text-muted-foreground mt-1">
PDF, JPG, PNG up to 5MB
</p>
</div>
) : (
<div className="border rounded-lg p-4 bg-muted/50">
<div className="flex items-center justify-between">
<div className="flex items-center space-x-2">
<FileText className="h-4 w-4 text-muted-foreground" />
<span className="text-sm font-medium">
{selectedFile ? selectedFile.name : 'Current invoice file'}
</span>
</div>
<Button
type="button"
variant="ghost"
size="sm"
onClick={onFileRemove}
>
<X className="h-4 w-4" />
</Button>
</div>
</div>
)}
{error && (
<p className="text-sm text-red-600">{error}</p>
)}
</div>
);
}