import { useState, useEffect, useCallback, useMemo } from 'react'; import toast from 'react-hot-toast'; import { AxiosError } from 'axios'; import { getAccreditationsApi, createAccreditationApi, updateAccreditationApi, deleteAccreditationApi, Accreditation, } from '@/api/accreditation'; import AccreditationModal from '@/components/AccreditationModal/AccreditationModal'; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; import { Button } from '@/components/ui/button'; import { Badge } from '@/components/ui/badge'; import { Switch } from '@/components/ui/switch'; import { Input } from '@/components/ui/input'; import { Loader2, RefreshCw, Plus, Pencil, Trash2, Award } from 'lucide-react'; export default function AccreditationPage() { const [items, setItems] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(''); const [modalOpen, setModalOpen] = useState(false); const [editingItem, setEditingItem] = useState(null); const [searchText, setSearchText] = useState(''); const [categoryFilter, setCategoryFilter] = useState(''); const [form, setForm] = useState>({ title: '', type: 'ACCREDITATION', logo: '', image: '', description: '', sortOrder: 1000, isActive: true, }); const fetchData = useCallback(async () => { setLoading(true); setError(''); try { const res = await getAccreditationsApi(); setItems(res.data || []); } catch (err) { if (err instanceof AxiosError) { setError(err.response?.data?.message || 'Failed to fetch accreditation records'); } else { setError('Something went wrong'); } } finally { setLoading(false); } }, []); useEffect(() => { fetchData(); }, [fetchData]); const filteredItems = useMemo(() => { return items.filter((item) => { const matchesSearch = item.title.toLowerCase().includes(searchText.toLowerCase()); const matchesCategory = categoryFilter ? item.type === categoryFilter : true; return matchesSearch && matchesCategory; }); }, [items, searchText, categoryFilter]); const handleToggleStatus = async (item: Accreditation) => { if (!item.id) return; try { await updateAccreditationApi(item.id, { isActive: !item.isActive, }); toast.success('Status updated'); fetchData(); } catch (err) { console.error(err); toast.error('Failed to update status'); } }; const handleDelete = async (id: number) => { const confirmDelete = window.confirm('Delete this accreditation permanently?'); if (!confirmDelete) return; try { await deleteAccreditationApi(id); fetchData(); } catch (err) { console.error(err); } }; const openAdd = () => { setEditingItem(null); setForm({ title: '', type: 'ACCREDITATION', logo: '', image: '', description: '', sortOrder: 1000, isActive: true, }); setModalOpen(true); }; const openEdit = (item: Accreditation) => { setEditingItem(item); setForm({ ...item, }); setModalOpen(true); }; const saveItem = async () => { if (!form.title?.trim()) { return toast.error('Title is required'); } if (!form.type) { return toast.error('Category is required'); } try { if (editingItem?.id) { const changedFields: Record = {}; Object.keys(form).forEach((key) => { const k = key as keyof Accreditation; if (JSON.stringify(form[k]) !== JSON.stringify(editingItem[k])) { changedFields[k] = form[k]; } }); delete changedFields.id; delete changedFields.createdAt; delete changedFields.updatedAt; if (Object.keys(changedFields).length === 0) { setModalOpen(false); return; } await updateAccreditationApi(editingItem.id, changedFields); } else { await createAccreditationApi(form); } setModalOpen(false); fetchData(); } catch (err) { console.error(err); toast.error('Failed to save accreditation'); } }; return (
{/* Header */}

Accreditations & Certifications

setSearchText(e.target.value)} className="w-[250px]" />
{error &&
{error}
} Accreditation Directory
Order Logo Details Category Status Actions {loading ? ( ) : filteredItems.length === 0 ? ( No accreditation records found. ) : ( filteredItems.map((item) => ( {item.sortOrder}
{item.logo ? ( {item.title} ) : ( )}
{item.title}
{item.description || 'No description provided'}
{item.image && ( )}
{item.type}
handleToggleStatus(item)} /> {item.isActive ? 'Active' : 'Hidden'}
)) )}
); }