import React, { useState } from 'react'; import { FileText, Plus, Search, Edit, Trash2, CheckCircle, XCircle, X } from 'lucide-react'; import { ToastContainer, useToast } from '../../UI/Toast'; import Table, { Column } from '../../UI/Table'; import ActionButtons from '../../UI/ActionButtons'; import ButtonUI from '../../UI/ButtonUI'; import Pagination from '../../UI/Pagination'; import ToggleSwitch from '../../UI/ToggleSwitch'; import CustomInput from '../../UI/CustomInput'; interface DocumentType { id: string; name: string; description: string; status: 'Active' | 'Inactive'; createdAt: string; updatedAt?: string; } // Create/Edit Modal Component - Moved outside and manages its own state interface ModalProps { isOpen: boolean; onClose: () => void; onSave: (data: { name: string; description: string }) => void; title: string; initialData?: { name: string; description: string } | null; } const Modal = ({ isOpen, onClose, onSave, title, initialData }: ModalProps) => { const [formData, setFormData] = useState({ name: initialData?.name || '', description: initialData?.description || '', }); // Reset form when modal opens with new data useState(() => { if (isOpen) { setFormData({ name: initialData?.name || '', description: initialData?.description || '', }); } }); // Update form when initialData changes React.useEffect(() => { if (initialData) { setFormData({ name: initialData.name || '', description: initialData.description || '', }); } }, [initialData]); if (!isOpen) return null; const handleInputChange = (field: string, value: any) => { setFormData((prev) => ({ ...prev, [field]: value })); }; const handleSubmit = () => { if (!formData.name) { // You can add toast here if needed return; } onSave(formData); }; return ( <>

{title}

handleInputChange('name', value)} placeholder="Enter document type name" required icon={} /> handleInputChange('description', value)} placeholder="Enter description" rows={3} />
Cancel {initialData ? 'Update' : 'Create'}
); }; const DocumentType = () => { const toast = useToast(); const [searchTerm, setSearchTerm] = useState(''); const [currentPage, setCurrentPage] = useState(1); const [showEntries, setShowEntries] = useState(10); const [showCreateModal, setShowCreateModal] = useState(false); const [showEditModal, setShowEditModal] = useState(false); const [selectedType, setSelectedType] = useState(null); const [showDeleteModal, setShowDeleteModal] = useState(false); const [typeToDelete, setTypeToDelete] = useState(null); const [isDeleting, setIsDeleting] = useState(false); // Mock data for document types const [documentTypes, setDocumentTypes] = useState([ { id: '1', name: 'Aadhaar Card', description: 'Government issued identity proof', status: 'Active', createdAt: '2024-01-15', }, { id: '2', name: 'PAN Card', description: 'Permanent Account Number card', status: 'Active', createdAt: '2024-02-10', }, { id: '3', name: 'Passport', description: 'International travel document', status: 'Active', createdAt: '2024-03-05', }, { id: '4', name: 'Driving License', description: 'Government issued driving license', status: 'Inactive', createdAt: '2024-04-20', }, { id: '5', name: 'Voter ID', description: 'Government issued voter identification', status: 'Active', createdAt: '2024-05-15', }, ]); const handleAddType = () => { setSelectedType(null); setShowCreateModal(true); }; const handleEditType = (type: DocumentType) => { setSelectedType(type); setShowEditModal(true); }; const handleDeleteType = (type: DocumentType) => { setTypeToDelete(type); setShowDeleteModal(true); }; const handleConfirmDelete = () => { if (!typeToDelete) return; setIsDeleting(true); setTimeout(() => { setDocumentTypes(documentTypes.filter((d) => d.id !== typeToDelete.id)); setShowDeleteModal(false); setTypeToDelete(null); setIsDeleting(false); toast.success(`Document type "${typeToDelete.name}" deleted successfully!`); }, 1000); }; const handleSaveType = (formData: { name: string; description: string }) => { if (!formData.name) { toast.error('Please fill in all required fields'); return; } if (selectedType) { // Edit existing setDocumentTypes( documentTypes.map((d) => d.id === selectedType.id ? { ...d, name: formData.name, description: formData.description, updatedAt: new Date().toISOString().split('T')[0], } : d, ), ); toast.success('Document type updated successfully!'); setShowEditModal(false); setSelectedType(null); } else { // Add new const newType: DocumentType = { id: String(documentTypes.length + 1), name: formData.name, description: formData.description, status: 'Active', createdAt: new Date().toISOString().split('T')[0], }; setDocumentTypes([...documentTypes, newType]); toast.success('Document type created successfully!'); setShowCreateModal(false); } }; const handleToggleStatus = (id: string) => { setDocumentTypes(documentTypes.map((d) => (d.id === id ? { ...d, status: d.status === 'Active' ? 'Inactive' : 'Active' } : d))); const type = documentTypes.find((d) => d.id === id); toast.info(`Document type "${type?.name}" status changed to ${type?.status === 'Active' ? 'Inactive' : 'Active'}`); }; // Filter document types const filteredTypes = documentTypes.filter((type) => { const searchLower = searchTerm.toLowerCase(); return type.name.toLowerCase().includes(searchLower) || type.description.toLowerCase().includes(searchLower); }); // Pagination const totalPages = Math.ceil(filteredTypes.length / showEntries); const startIndex = (currentPage - 1) * showEntries; const currentTypes = filteredTypes.slice(startIndex, startIndex + showEntries); // Define columns const columns: Column[] = [ { key: 'sno', header: 'S.No', align: 'center', accessor: (_row: DocumentType, index: number) => { const page = currentPage || 1; const entries = showEntries || 10; const calculatedIndex = (page - 1) * entries + (index || 0) + 1; return {calculatedIndex}; }, }, { key: 'name', header: 'DOCUMENT TYPE', accessor: (row: DocumentType) => (
{row.name}
), }, { key: 'description', header: 'DESCRIPTION', accessor: (row: DocumentType) =>
{row.description || '—'}
, }, { key: 'status', header: 'STATUS', align: 'center', accessor: (row: DocumentType) => handleToggleStatus(row.id)} activeColor="bg-green-600" inactiveColor="bg-gray-300" />, }, { key: 'actions', header: 'ACTION', align: 'center', accessor: (row: DocumentType) => ( handleEditType(row)} onDelete={() => handleDeleteType(row)} showView={false} editTooltip="Edit Document Type" deleteTooltip="Delete Document Type" size="sm" /> ), }, ]; return ( <>
{/* Header */}

Document Types

Manage document types for HRM

} onClick={handleAddType}> Add Document Type
{/* Stats Cards */}

Total Types

{documentTypes.length}

Active

{documentTypes.filter((d) => d.status === 'Active').length}

Inactive

{documentTypes.filter((d) => d.status === 'Inactive').length}

{/* Filters */}
Show
setSearchTerm(e.target.value)} className="w-full pl-9 pr-4 py-2 border border-gray-200 rounded-lg text-sm focus:outline-none focus:border-primary focus:ring-2 focus:ring-primary/20" />
{/* Table */} {/* Pagination */} {filteredTypes.length > 0 && ( )} {/* Create Modal */} { setShowCreateModal(false); setSelectedType(null); }} onSave={handleSaveType} title="Add Document Type" initialData={null} /> {/* Edit Modal */} { setShowEditModal(false); setSelectedType(null); }} onSave={handleSaveType} title="Edit Document Type" initialData={ selectedType ? { name: selectedType.name, description: selectedType.description, } : null } /> {/* Delete Confirmation Modal */} {showDeleteModal && (

Delete Document Type

Are you sure you want to delete "{typeToDelete?.name}"? This action cannot be undone.

{ setShowDeleteModal(false); setTypeToDelete(null); }} > Cancel {isDeleting ? 'Deleting...' : 'Delete'}
)} ); }; export default DocumentType;