"use client"; import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from "@/components/ui/card"; import { Button } from "@/components/ui/button"; import { Calendar, Clock, User, Trash2 } from "lucide-react"; import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, } from "@/components/ui/alert-dialog"; import Link from "next/link"; import { useEffect, useState } from "react"; import { toast } from "@/hooks/use-toast"; import { AvailabilityService } from "@/services/availabilityApi.mjs"; import { exceptionsService } from "@/services/exceptionApi.mjs"; import { doctorsService } from "@/services/doctorsApi.mjs"; import { usersService } from "@/services/usersApi.mjs"; import Sidebar from "@/components/Sidebar"; import WeeklyScheduleCard from "@/components/ui/WeeklyScheduleCard"; type Availability = { id: string; doctor_id: string; weekday: string; start_time: string; end_time: string; slot_minutes: number; appointment_type: string; active: boolean; created_at: string; updated_at: string; created_by: string; updated_by: string | null; }; type Schedule = { weekday: object; }; type Doctor = { id: string; user_id: string | null; crm: string; crm_uf: string; specialty: string; full_name: string; cpf: string; email: string; phone_mobile: string | null; phone2: string | null; cep: string | null; street: string | null; number: string | null; complement: string | null; neighborhood: string | null; city: string | null; state: string | null; birth_date: string | null; rg: string | null; active: boolean; created_at: string; updated_at: string; created_by: string; updated_by: string | null; max_days_in_advance: number; rating: number | null; }; interface UserPermissions { isAdmin: boolean; isManager: boolean; isDoctor: boolean; isSecretary: boolean; isAdminOrManager: boolean; } interface UserData { user: { id: string; email: string; email_confirmed_at: string | null; created_at: string | null; last_sign_in_at: string | null; }; profile: { id: string; full_name: string; email: string; phone: string; avatar_url: string | null; disabled: boolean; created_at: string | null; updated_at: string | null; }; roles: string[]; permissions: UserPermissions; } interface Exception { id: string; // id da exceção doctor_id: string; date: string; // formato YYYY-MM-DD start_time: string | null; // null = dia inteiro end_time: string | null; // null = dia inteiro kind: "bloqueio" | "disponibilidade"; // tipos conhecidos reason: string | null; // pode ser null created_at: string; // timestamp ISO created_by: string; } export default function PatientDashboard() { const [loggedDoctor, setLoggedDoctor] = useState(); const [userData, setUserData] = useState(); const [availability, setAvailability] = useState(null); const [exceptions, setExceptions] = useState([]); const [schedule, setSchedule] = useState< Record >({}); const formatTime = (time?: string | null) => time?.split(":")?.slice(0, 2).join(":") ?? ""; const [deleteDialogOpen, setDeleteDialogOpen] = useState(false); const [exceptionToDelete, setExceptionToDelete] = useState( null ); const [error, setError] = useState(null); // Mapa de tradução const weekdaysPT: Record = { sunday: "Domingo", monday: "Segunda", tuesday: "Terça", wednesday: "Quarta", thursday: "Quinta", friday: "Sexta", saturday: "Sábado", }; useEffect(() => { const fetchData = async () => { try { const doctorsList: Doctor[] = await doctorsService.list(); const doctor = doctorsList[0]; // Salva no estado setLoggedDoctor(doctor); // Busca disponibilidade const availabilityList = await AvailabilityService.list(); // Filtra já com a variável local const filteredAvail = availabilityList.filter( (disp: { doctor_id: string }) => disp.doctor_id === doctor?.id ); setAvailability(filteredAvail); // Busca exceções const exceptionsList = await exceptionsService.list(); const filteredExc = exceptionsList.filter((exc: { doctor_id: string }) => exc.doctor_id === doctor?.id); setExceptions(filteredExc); } catch (e: any) { alert(`${e?.error} ${e?.message}`); } }; fetchData(); }, []); // Função auxiliar para filtrar o id do doctor correspondente ao user logado function findDoctorById(id: string, doctors: Doctor[]) { return doctors.find((doctor) => doctor.user_id === id); } const openDeleteDialog = (exceptionId: string) => { setExceptionToDelete(exceptionId); setDeleteDialogOpen(true); }; const handleDeleteException = async (ExceptionId: string) => { try { alert(ExceptionId); const res = await exceptionsService.delete(ExceptionId); let message = "Exceção deletada com sucesso"; try { if (res) { throw new Error( `${res.error} ${res.message}` || "A API retornou erro" ); } else { console.log(message); } } catch {} toast({ title: "Sucesso", description: message, }); setExceptions((prev: Exception[]) => prev.filter((p) => String(p.id) !== String(ExceptionId)) ); } catch (e: any) { toast({ title: "Erro", description: e?.message || "Não foi possível deletar a exceção", }); } setDeleteDialogOpen(false); setExceptionToDelete(null); }; function formatAvailability(data: Availability[]) { // Agrupar os horários por dia da semana const schedule = data.reduce((acc: any, item) => { const { weekday, start_time, end_time } = item; // Se o dia ainda não existe, cria o array if (!acc[weekday]) { acc[weekday] = []; } // Adiciona o horário do dia acc[weekday].push({ start: start_time, end: end_time, }); return acc; }, {} as Record); return schedule; } useEffect(() => { if (availability) { const formatted = formatAvailability(availability); setSchedule(formatted); } }, [availability]); return (

Dashboard

Bem-vindo ao seu portal de consultas médicas

Próxima Consulta
02 out

Dr. Silva - 14:30

Consultas Este Mês
4

4 agendadas

Perfil
100%

Dados completos

Ações Rápidas Acesse rapidamente as principais funcionalidades Próximas Consultas Suas consultas agendadas

Dr. João Santos

Cardiologia

02 out

14:30

Horário Semanal Confira rapidamente a sua disponibilidade da semana {loggedDoctor && }
Exceções Bloqueios e liberações eventuais de agenda {exceptions && exceptions.length > 0 ? ( exceptions.map((ex: Exception) => { // Formata data e hora const date = new Date(ex.date).toLocaleDateString("pt-BR", { weekday: "long", day: "2-digit", month: "long", timeZone: "UTC", }); const startTime = formatTime(ex.start_time); const endTime = formatTime(ex.end_time); return (

{date}

{startTime && endTime ? `${startTime} - ${endTime}` : "Dia todo"}

{ex.kind === "bloqueio" ? "Bloqueio" : "Liberação"}

{ex.reason || "Sem motivo especificado"}

); }) ) : (

Nenhuma exceção registrada.

)}
Confirmar exclusão Tem certeza que deseja excluir esta exceção? Esta ação não pode ser desfeita. Cancelar exceptionToDelete && handleDeleteException(exceptionToDelete)} className="bg-red-600 hover:bg-red-700"> Excluir
); }