pmtool / src /components /employees /EmployeeDocumentSelector.tsx
devarshia5's picture
Upload 487 files
d97b8f9 verified
Raw
History Blame Contribute Delete
8.25 kB
import React, { useState } from 'react';
import { Button } from "@/components/ui/button";
import { Label } from "@/components/ui/label";
import { Input } from "@/components/ui/input";
import { Card } from "@/components/ui/card";
import { Textarea } from "@/components/ui/textarea";
import {
FileUp,
Loader2,
Search,
HelpCircle,
File
} from "lucide-react";
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from "@/components/ui/tooltip";
import { cn } from "@/lib/utils";
import CustomDialog from "@/components/CustomDialog";
// Interface for document types
export interface DocumentType {
name: string;
description: string;
}
interface EmployeeDocumentSelectorProps {
isOpen: boolean;
onClose: () => void;
documentTypes: DocumentType[];
onSelectAndUpload: (documentType: DocumentType, file: File, description: string) => void;
isUploading: boolean;
}
const EmployeeDocumentSelector: React.FC<EmployeeDocumentSelectorProps> = ({
isOpen,
onClose,
documentTypes,
onSelectAndUpload,
isUploading
}) => {
const [searchQuery, setSearchQuery] = useState('');
const [selectedType, setSelectedType] = useState<DocumentType | null>(null);
const [selectedFile, setSelectedFile] = useState<File | null>(null);
const [description, setDescription] = useState('');
const [step, setStep] = useState<'select-type' | 'select-file'>('select-type');
// Filter document types based on search
const filteredDocTypes = documentTypes.filter(docType =>
docType.name.toLowerCase().includes(searchQuery.toLowerCase()) ||
docType.description.toLowerCase().includes(searchQuery.toLowerCase())
);
// Reset state when dialog closes
const handleClose = () => {
if (isUploading) return;
setSelectedType(null);
setSelectedFile(null);
setDescription('');
setStep('select-type');
setSearchQuery('');
onClose();
};
// Handle document type selection
const handleTypeSelect = (docType: DocumentType) => {
setSelectedType(docType);
setStep('select-file');
};
// Handle file selection
const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const files = e.target.files;
if (files && files.length > 0) {
setSelectedFile(files[0]);
}
};
// Handle description change
const handleDescriptionChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
setDescription(e.target.value);
};
// Handle upload action
const handleUpload = () => {
if (selectedType && selectedFile) {
onSelectAndUpload(selectedType, selectedFile, description);
}
};
// Go back to document type selection
const handleBack = () => {
setStep('select-type');
setSelectedFile(null);
setDescription('');
};
return (
<CustomDialog
isOpen={isOpen}
onClose={handleClose}
title={step === 'select-type' ? 'Select Document Type' : `Upload ${selectedType?.name}`}
description={step === 'select-type'
? 'Select the type of document you want to upload'
: 'Choose a file and add optional details for the selected document type'}
allowClose={!isUploading}
isPending={isUploading}
>
{step === 'select-type' ? (
<div className="space-y-4">
<div className="relative">
<Search className="absolute left-2 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" />
<Input
placeholder="Search document types..."
value={searchQuery}
onChange={(e) => setSearchQuery(e.target.value)}
className="pl-8"
/>
</div>
<div className="max-h-[60vh] overflow-y-auto pr-1 space-y-1">
{filteredDocTypes.length > 0 ? (
filteredDocTypes.map((docType) => (
<TooltipProvider key={docType.name} delayDuration={300}>
<Tooltip>
<TooltipTrigger asChild>
<Card
className={cn(
"p-3 cursor-pointer border hover:bg-accent transition-colors",
"flex items-center justify-between"
)}
onClick={() => handleTypeSelect(docType)}
>
<span className="font-medium">{docType.name}</span>
{docType.description && (
<HelpCircle className="h-4 w-4 text-muted-foreground" />
)}
</Card>
</TooltipTrigger>
{docType.description && (
<TooltipContent side="left" className="max-w-sm">
{docType.description}
</TooltipContent>
)}
</Tooltip>
</TooltipProvider>
))
) : (
<div className="text-center py-8 text-muted-foreground">
No matching document types found
</div>
)}
</div>
</div>
) : (
<div className="space-y-4">
<div className="bg-muted/50 p-3 rounded-md">
<p className="text-sm font-medium">Selected Document Type:</p>
<p className="text-muted-foreground">{selectedType?.name}</p>
{selectedType?.description && (
<p className="text-xs text-muted-foreground mt-1">{selectedType.description}</p>
)}
</div>
<div className="space-y-2">
<Label htmlFor="file-upload">Select File</Label>
<div className="flex items-center gap-2">
<Input
id="file-upload"
type="file"
onChange={handleFileChange}
className="flex-1"
disabled={isUploading}
/>
</div>
{selectedFile && (
<div className="flex items-center gap-2 text-sm bg-accent/50 p-2 rounded-md">
<File className="h-4 w-4" />
<span>{selectedFile.name}</span>
<span className="text-muted-foreground ml-auto">
{(selectedFile.size / 1024).toFixed(1)} KB
</span>
</div>
)}
</div>
<div className="space-y-2">
<Label htmlFor="document-description">Description (Optional)</Label>
<Textarea
id="document-description"
placeholder="Add additional details about this document..."
value={description}
onChange={handleDescriptionChange}
className="resize-none h-24"
disabled={isUploading}
/>
<p className="text-xs text-muted-foreground">
Add any relevant information about this document such as issue date, reference numbers, etc.
</p>
</div>
</div>
)}
<div className="flex justify-between pt-4 mt-4">
{step === 'select-type' ? (
<Button variant="outline" onClick={handleClose} disabled={isUploading}>
Cancel
</Button>
) : (
<Button variant="outline" onClick={handleBack} disabled={isUploading}>
Back
</Button>
)}
{step === 'select-file' && (
<Button
onClick={handleUpload}
disabled={!selectedFile || isUploading}
>
{isUploading ? (
<>
<Loader2 className="h-4 w-4 animate-spin mr-2" />
Uploading...
</>
) : (
<>
<FileUp className="h-4 w-4 mr-2" />
Upload
</>
)}
</Button>
)}
</div>
</CustomDialog>
);
};
export default EmployeeDocumentSelector;