import { useState, useEffect, useCallback } from 'react' import type { NextPage } from 'next' import Head from 'next/head' import AdminLayout from '../../components/AdminLayout' import { ShieldExclamationIcon, FunnelIcon, MagnifyingGlassIcon, CheckCircleIcon, XCircleIcon, EyeIcon, ExclamationTriangleIcon } from '@heroicons/react/24/outline' interface Source { id: number url: string domain: string title?: string type: string status: string risk_level: number created_at: string } const SourcesManagement: NextPage = () => { const [sources, setSources] = useState([]) const [loading, setLoading] = useState(true) const [filter, setFilter] = useState('pending') const [searchTerm, setSearchTerm] = useState('') const fetchSources = useCallback(async () => { try { const response = await fetch(`/api/admin/sources?status=${filter}&search=${searchTerm}`) if (response.ok) { const data = await response.json() setSources(data) } } catch (error) { console.error('Failed to fetch sources:', error) } finally { setLoading(false) } }, [filter, searchTerm]) useEffect(() => { fetchSources() }, [fetchSources]) const updateSource = async (id: number, status: string, riskLevel: number) => { try { const response = await fetch(`/api/admin/sources/${id}`, { method: 'PATCH', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ status, risk_level: riskLevel, }), }) if (response.ok) { fetchSources() } } catch (error) { console.error('Failed to update source:', error) } } const getRiskBadge = (level: number) => { if (level >= 4) return 'bg-red-100 text-red-800' if (level >= 3) return 'bg-yellow-100 text-yellow-800' if (level >= 2) return 'bg-orange-100 text-orange-800' return 'bg-green-100 text-green-800' } const getStatusBadge = (status: string) => { switch (status) { case 'verified': return 'bg-green-100 text-green-800' case 'rejected': return 'bg-red-100 text-red-800' case 'pending': return 'bg-yellow-100 text-yellow-800' default: return 'bg-gray-100 text-gray-800' } } const getStatusIcon = (status: string) => { switch (status) { case 'verified': return case 'rejected': return case 'pending': return default: return } } return ( Správa zdrojov - Hliadka.sk Admin
{/* Filters and Search */}
setSearchTerm(e.target.value)} className="input pl-10" />
{/* Sources Table */}

Zdroje ({sources.length})

{loading ? (
) : (
{sources.map((source) => ( ))} {sources.length === 0 && ( )}
Doména Typ Riziko Status Dátum Akcie
{source.domain} {source.title && (
{source.title}
)}
{source.type} Úroveň {source.risk_level}
{getStatusIcon(source.status)} {source.status}
{new Date(source.created_at).toLocaleString('sk-SK')} {source.status === 'pending' && (
)} {source.status !== 'pending' && ( )}

Žiadne zdroje pre vybrané kritériá

)}
{/* Quick Actions */}
Bulk akcie
Export
Štatistiky
Čakajúce: {sources.filter(s => s.status === 'pending').length}
Vysoké riziko: {sources.filter(s => s.risk_level >= 4).length}
) } export default SourcesManagement