import React, { useState, useCallback } from 'react'; import { Calendar } from '@fullcalendar/react'; import dayGridPlugin from '@fullcalendar/daygrid'; import timeGridPlugin from '@fullcalendar/timegrid'; import interactionPlugin from '@fullcalendar/interaction'; import ptBrLocale from '@fullcalendar/core/locales/pt-br'; import { format } from 'date-fns'; import { api } from '../services/api'; import { toast } from 'react-toastify'; interface Agendamento { id: string; data: string; observacoes?: string; status: string; cliente: { id: string; nome: string; }; } interface CalendarEvent { id: string; title: string; start: string; end: string; backgroundColor?: string; borderColor?: string; extendedProps: { agendamento: Agendamento; }; } interface AgendamentoCalendarioProps { onEventClick?: (event: any) => void; onDateSelect?: (selectInfo: any) => void; } export const AgendamentoCalendario: React.FC = ({ onEventClick, onDateSelect }) => { const [eventos, setEventos] = useState([]); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); const formatEventos = useCallback((agendamentos: Agendamento[]): CalendarEvent[] => { return agendamentos.map(ag => ({ id: ag.id, title: `${ag.cliente.nome} ${ag.observacoes ? `- ${ag.observacoes}` : ''}`, start: ag.data, end: ag.data, backgroundColor: ag.status === 'CANCELADO' ? '#FEE2E2' : '#E0F2FE', borderColor: ag.status === 'CANCELADO' ? '#EF4444' : '#0EA5E9', extendedProps: { agendamento: ag } })); }, []); const loadAgendamentos = useCallback(async ({ start, end }: { start: Date, end: Date }) => { try { setLoading(true); setError(null); const response = await api.get('/atendimentos/agendamentos', { params: { inicio: format(start, 'yyyy-MM-dd'), fim: format(end, 'yyyy-MM-dd') } }); setEventos(formatEventos(response.data)); } catch (err: any) { const mensagem = err.response?.data?.error || 'Erro ao carregar agendamentos'; setError(mensagem); toast.error(mensagem); } finally { setLoading(false); } }, [formatEventos]); return (
{loading && (
)} {error && (
{error}
)} loadAgendamentos({ start, end })} eventClick={({ event }) => onEventClick?.(event)} select={(selectInfo) => onDateSelect?.(selectInfo)} headerToolbar={{ left: 'prev,next today', center: 'title', right: 'dayGridMonth,timeGridWeek,timeGridDay' }} slotMinTime="08:00:00" slotMaxTime="18:00:00" />
); };