'use client' import { useState, useEffect } from 'react' import { useRouter } from 'next/navigation' import { Newspaper, Plus, Search, Filter, Loader2, Eye, EyeOff, Calendar, Building2, FileText, Clock, AlertTriangle, ChevronDown, ChevronUp, Trash2, RefreshCw, Bell, } from 'lucide-react' interface Processo { id: string numeroProcesso: string tribunal: string vara: string | null comarca: string | null parteAutora: string | null parteRe: string | null status: 'ATIVO' | 'ARQUIVADO' | 'SUSPENSO' publicacoesNaoLidas: number ultimaPublicacao: Publicacao | null } interface Publicacao { id: string processoId: string dataPublicacao: string diario: string conteudo: string tipo: 'INTIMACAO' | 'CITACAO' | 'SENTENCA' | 'DESPACHO' | 'ACORDAO' | 'OUTROS' prazoCalculado: string | null prazoTipo: string | null visualizado: boolean processo?: { numeroProcesso: string tribunal: string parteAutora: string | null parteRe: string | null } } const tipoConfig = { INTIMACAO: { label: 'Intimação', bg: 'bg-blue-500/15 border-blue-500/30', color: 'text-blue-400' }, CITACAO: { label: 'Citação', bg: 'bg-purple-500/15 border-purple-500/30', color: 'text-purple-400' }, SENTENCA: { label: 'Sentença', bg: 'bg-red-500/15 border-red-500/30', color: 'text-red-400' }, DESPACHO: { label: 'Despacho', bg: 'bg-yellow-500/15 border-yellow-500/30', color: 'text-yellow-400' }, ACORDAO: { label: 'Acórdão', bg: 'bg-orange-500/15 border-orange-500/30', color: 'text-orange-400' }, OUTROS: { label: 'Outros', bg: 'bg-zinc-500/15 border-zinc-500/30', color: 'text-zinc-400' }, } export default function PublicacoesPage() { const router = useRouter() const [processos, setProcessos] = useState([]) const [publicacoes, setPublicacoes] = useState([]) const [loading, setLoading] = useState(true) const [buscando, setBuscando] = useState(false) const [expandedId, setExpandedId] = useState(null) // Filtros const [filterTipo, setFilterTipo] = useState('') const [filterVisualizado, setFilterVisualizado] = useState('') const [filterProcesso, setFilterProcesso] = useState('') useEffect(() => { fetchData() }, [filterTipo, filterVisualizado, filterProcesso]) async function fetchData() { setLoading(true) try { // Busca processos e publicações em paralelo const [processosRes, publicacoesRes] = await Promise.all([ fetch('/api/processos'), fetchPublicacoes(), ]) if (processosRes.ok) { const data = await processosRes.json() setProcessos(data.processos || []) } } catch (e) { console.error('Failed to load data:', e) } finally { setLoading(false) } } async function fetchPublicacoes() { const params = new URLSearchParams() if (filterTipo) params.set('tipo', filterTipo) if (filterVisualizado) params.set('visualizado', filterVisualizado) if (filterProcesso) params.set('processoId', filterProcesso) const res = await fetch(`/api/publicacoes?${params}`) if (res.ok) { const data = await res.json() setPublicacoes(data.publicacoes || []) } return res } async function buscarNovasPublicacoes() { setBuscando(true) try { const res = await fetch('/api/publicacoes/buscar', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({}), }) if (res.ok) { await fetchData() } } catch (e) { console.error('Failed to search:', e) } finally { setBuscando(false) } } async function marcarComoLida(id: string) { try { await fetch(`/api/publicacoes/${id}/visualizar`, { method: 'PATCH' }) setPublicacoes(pubs => pubs.map(p => p.id === id ? { ...p, visualizado: true } : p)) } catch (e) { console.error('Failed to mark as read:', e) } } async function deleteProcesso(id: string) { if (!confirm('Tem certeza que deseja remover este processo do monitoramento?')) return try { await fetch(`/api/processos/${id}`, { method: 'DELETE' }) fetchData() } catch (e) { console.error('Failed to delete:', e) } } function formatDate(dateStr: string) { return new Date(dateStr).toLocaleDateString('pt-BR', { day: '2-digit', month: '2-digit', year: 'numeric' }) } function getDaysUntilPrazo(prazoStr: string | null) { if (!prazoStr) return null const now = new Date() now.setHours(0, 0, 0, 0) const prazo = new Date(prazoStr) prazo.setHours(0, 0, 0, 0) return Math.ceil((prazo.getTime() - now.getTime()) / (1000 * 60 * 60 * 24)) } // Stats const totalProcessos = processos.length const totalNaoLidas = publicacoes.filter(p => !p.visualizado).length const prazosProximos = publicacoes.filter(p => { const days = getDaysUntilPrazo(p.prazoCalculado) return days !== null && days >= 0 && days <= 5 }).length return (
{/* Header */}

Monitoramento de Publicações

Acompanhe publicações dos Diários Oficiais

{/* Stats Cards */}

Processos Monitorados

{totalProcessos}

Publicações Não Lidas

{totalNaoLidas}

Prazos Próximos (5 dias)

{prazosProximos}

{/* Filters */}
{processos.length > 0 && ( )}
{/* Content */} {loading ? (
) : processos.length === 0 ? (

Nenhum processo sendo monitorado

) : publicacoes.length === 0 ? (

Nenhuma publicação encontrada

) : (
{publicacoes.map(pub => { const config = tipoConfig[pub.tipo] const daysUntilPrazo = getDaysUntilPrazo(pub.prazoCalculado) const isUrgent = daysUntilPrazo !== null && daysUntilPrazo >= 0 && daysUntilPrazo <= 3 const isOverdue = daysUntilPrazo !== null && daysUntilPrazo < 0 const isExpanded = expandedId === pub.id return (
{/* Indicator */} {!pub.visualizado && (
)}
{config.label} {pub.diario} {formatDate(pub.dataPublicacao)}
{pub.processo && (

{pub.processo.numeroProcesso} ({pub.processo.tribunal})

)}
{!pub.visualizado && ( )}
{/* Preview / Full content */}

{pub.conteudo}

{/* Prazo */} {pub.prazoCalculado && (
Prazo: {formatDate(pub.prazoCalculado)} {pub.prazoTipo && ` (${pub.prazoTipo})`} {daysUntilPrazo !== null && ( {isOverdue ? `• Vencido há ${Math.abs(daysUntilPrazo)} dia(s)` : daysUntilPrazo === 0 ? '• Vence HOJE!' : daysUntilPrazo === 1 ? '• Vence AMANHÃ' : `• ${daysUntilPrazo} dias restantes` } )}
)}
) })}
)} {/* Processos monitorados section */} {processos.length > 0 && (

Processos Monitorados

{processos.map(p => (

{p.numeroProcesso}

{p.tribunal}

{(p.parteAutora || p.parteRe) && (

{p.parteAutora && `Autor: ${p.parteAutora}`} {p.parteAutora && p.parteRe && ' • '} {p.parteRe && `Réu: ${p.parteRe}`}

)}
{p.publicacoesNaoLidas > 0 && ( {p.publicacoesNaoLidas} )}
))}
)}
) }