import React, { useState, useEffect, useRef } from 'react'; import { useNavigate } from 'react-router-dom'; import { useTranslation } from 'react-i18next'; import { usePPMs, usePPMMutations } from '../hooks/usePPM'; import { FaPlus, FaSearch, FaEdit, FaEye, FaTrash, FaCopy, FaEllipsisV, FaFileExport, FaCalendarCheck, FaBuilding } from 'react-icons/fa'; const PPMList: React.FC = () => { const { t } = useTranslation(); const navigate = useNavigate(); const [page, setPage] = useState(0); const [searchTerm, setSearchTerm] = useState(''); const [companyFilter, setCompanyFilter] = useState(''); const [deleteConfirmOpen, setDeleteConfirmOpen] = useState(null); const [actionMenuOpen, setActionMenuOpen] = useState(null); const dropdownRef = useRef(null); const limit = 20; const filters = companyFilter ? { company: companyFilter } : {}; const { ppms, totalCount, hasMore, loading, error, refetch } = usePPMs( filters, limit, page * limit, 'creation desc' ); const { deletePPM, loading: mutationLoading } = usePPMMutations(); useEffect(() => { const handleClickOutside = (event: MouseEvent) => { if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) { setActionMenuOpen(null); } }; if (actionMenuOpen) { document.addEventListener('mousedown', handleClickOutside); } return () => { document.removeEventListener('mousedown', handleClickOutside); }; }, [actionMenuOpen]); const handleCreateNew = () => { navigate('/ppm/new'); }; const handleView = (ppmName: string) => { navigate(`/ppm/${ppmName}`); }; const handleEdit = (ppmName: string) => { navigate(`/ppm/${ppmName}`); }; const handleDelete = async (ppmName: string) => { try { await deletePPM(ppmName); setDeleteConfirmOpen(null); refetch(); alert('PPM schedule deleted successfully!'); } catch (err) { alert(`Failed to delete: ${err instanceof Error ? err.message : 'Unknown error'}`); } }; const handleDuplicate = (ppmName: string) => { navigate(`/ppm/new?duplicate=${ppmName}`); }; const handleExport = (ppm: any) => { const dataStr = JSON.stringify(ppm, null, 2); const dataBlob = new Blob([dataStr], { type: 'application/json' }); const url = URL.createObjectURL(dataBlob); const link = document.createElement('a'); link.href = url; link.download = `ppm_${ppm.name}.json`; link.click(); URL.revokeObjectURL(url); }; const handleExportAll = () => { const headers = ['PPM ID', 'Company', 'Asset', 'Asset Type', 'Frequency', 'No. of PMs', 'Total Amount']; const csvContent = [ headers.join(','), ...ppms.map(ppm => [ ppm.name, ppm.company || '', ppm.asset_name || '', ppm.custom_asset_type || '', ppm.custom_frequency || '', ppm.custom_no_of_pms || '', ppm.custom_total_amount || '' ].join(',')) ].join('\n'); const dataBlob = new Blob([csvContent], { type: 'text/csv' }); const url = URL.createObjectURL(dataBlob); const link = document.createElement('a'); link.href = url; link.download = `ppm_schedules_${new Date().toISOString().split('T')[0]}.csv`; link.click(); URL.revokeObjectURL(url); }; if (loading && page === 0) { return (

{t('listPages.loading')}

); } if (error) { return (

⚠️ PPM API Not Available

The PPM API endpoint is not deployed yet.

Technical Error: {error}

); } const filteredPPMs = ppms.filter(ppm => ppm.name?.toLowerCase().includes(searchTerm.toLowerCase()) || ppm.asset_name?.toLowerCase().includes(searchTerm.toLowerCase()) || ppm.company?.toLowerCase().includes(searchTerm.toLowerCase()) || ppm.custom_asset_type?.toLowerCase().includes(searchTerm.toLowerCase()) ); return (
{/* Header */}

{t('ppm.title')}

Total: {totalCount} PPM schedule{totalCount !== 1 ? 's' : ''}

{/* Filters Bar */}
setSearchTerm(e.target.value)} className="flex-1 outline-none text-gray-700 dark:text-gray-200 bg-transparent" />
{ setCompanyFilter(e.target.value); setPage(0); }} className="w-full px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-700 dark:text-gray-200 focus:outline-none focus:ring-2 focus:ring-blue-500" />
{/* PPM Schedules Table */}
{filteredPPMs.length === 0 ? ( ) : ( filteredPPMs.map((ppm) => ( handleView(ppm.name)} > )) )}
PPM ID Company Asset Asset Type Frequency No. of PMs Total Amount Actions

No PPM schedules found

{ppm.name}
{ppm.company || '-'}
{ppm.asset_name || '-'}
{ppm.custom_asset_type || '-'}
{ppm.custom_frequency || '-'}
{ppm.custom_no_of_pms || '-'}
{ppm.custom_total_amount ? `$${ppm.custom_total_amount.toLocaleString()}` : '-'}
e.stopPropagation()}> {actionMenuOpen === ppm.name && (
)}
{/* Pagination */} {(hasMore || page > 0) && (
Showing {page * limit + 1} to {Math.min((page + 1) * limit, totalCount)} of {totalCount} results
)}
{/* Delete Confirmation Modal */} {deleteConfirmOpen && (

Confirm Delete

Are you sure you want to delete this PPM schedule? This action cannot be undone.

)}
); }; export default PPMList;