2025-09-19 00:26:07 -03:00

366 lines
10 KiB
JavaScript

import React, { useState } from "react";
import FullCalendar 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 "../../assets/css/index.css";
function Calendar1() {
const [events, setEvents] = useState([]);
const [editingEvent, setEditingEvent] = useState(null);
const [showPopup, setShowPopup] = useState(false);
const [showActionModal, setShowActionModal] = useState(false);
const [step, setStep] = useState(1);
const [newEvent, setNewEvent] = useState({ title: "", time: "" });
const [selectedDate, setSelectedDate] = useState(null);
const [selectedEvent, setSelectedEvent] = useState(null);
const colorsByType = {
Rotina: "#4dabf7",
Cardiologia: "#f76c6c",
Otorrino: "#f7b84d",
Pediatria: "#6cf78b"
};
// Clicar em um dia -> abrir popup 3 etapas
const handleDateClick = (arg) => {
setSelectedDate(arg.dateStr);
setNewEvent({ title: "", time: "" });
setStep(1);
setEditingEvent(null);
setShowPopup(true);
};
// Adicionar nova consulta
const handleAddEvent = () => {
const eventToAdd = {
id: Date.now(), // number
title: newEvent.title,
time: newEvent.time,
date: selectedDate,
color: colorsByType[newEvent.type] || "#4dabf7"
};
setEvents((prev) => [...prev, eventToAdd]);
setShowPopup(false);
};
// Editar consulta existente
const handleEditEvent = () => {
setEvents((prevEvents) =>
prevEvents.map((ev) =>
ev.id.toString() === editingEvent.id.toString()
? {
...ev,
title: newEvent.title,
time: newEvent.time,
color: colorsByType[newEvent.type] || "#4dabf7"
}
: ev
)
);
setEditingEvent(null);
setShowPopup(false);
setShowActionModal(false);
};
// Próxima etapa no popup
const handleNextStep = () => {
if (step < 2) setStep(step + 1);
else editingEvent ? handleEditEvent() : handleAddEvent();
};
// Clicar em uma consulta -> abre modal de ação (Editar/Apagar)
const handleEventClick = (clickInfo) => {
setSelectedEvent(clickInfo.event);
setShowActionModal(true);
};
// Apagar consulta
const handleDeleteEvent = () => {
if (!selectedEvent) return;
setEvents((prevEvents) =>
prevEvents.filter(
(ev) => ev.id.toString() !== selectedEvent.id.toString()
)
);
setShowActionModal(false);
};
// Começar a editar
const handleStartEdit = () => {
if (!selectedEvent) return;
setEditingEvent(selectedEvent);
setNewEvent({
title: selectedEvent.title,
time: selectedEvent.extendedProps.time
});
setStep(1);
setShowActionModal(false);
setShowPopup(true);
};
// Aparência da consulta dentro do calendário
const renderEventContent = (eventInfo) => {
const bg =
eventInfo.event.backgroundColor ||
eventInfo.event.extendedProps?.color ||
"#4dabf7";
return (
<div
style={{
display: "flex",
alignItems: "center",
gap: 6,
fontSize: "0.72rem",
padding: "1px 6px",
lineHeight: 1.1,
borderRadius: 4,
backgroundColor: bg,
color: "#fff",
cursor: "pointer",
// Mantém o retângulo pequeno e evita estourar a célula:
maxWidth: "100%",
whiteSpace: "nowrap",
overflow: "hidden",
textOverflow: "ellipsis"
}}
title={`${eventInfo.event.title}${eventInfo.event.extendedProps.type}${eventInfo.event.extendedProps.time}`} // tooltip
>
<span style={{ minWidth: 0, overflow: "hidden", textOverflow: "ellipsis" }}>
{eventInfo.event.title}
</span>
<span></span>
<span>{eventInfo.event.extendedProps.time}</span>
</div>
);
};
return (
<div
className="calendar-container"
style={{
marginLeft: "250px",
paddingTop: 60, // empurra o calendário p/ baixo
display: "flex",
justifyContent: "center"
}}
>
<div style={{ width: "95%", maxWidth: "none" }}>
<FullCalendar
plugins={[dayGridPlugin, timeGridPlugin, interactionPlugin]}
initialView="dayGridMonth"
locale={ptBrLocale}
height="80vh"
dateClick={handleDateClick}
events={events.map((ev) => ({
id: ev.id,
title: ev.title,
date: ev.date,
color: ev.color, // para o FullCalendar
extendedProps: {
type: ev.type,
time: ev.time,
color: ev.color // para o nosso renderEventContent
}
}))}
eventContent={renderEventContent}
eventClick={handleEventClick}
dayCellClassNames="calendar-day-cell"
/>
</div>
{/* POPUP 3 etapas (Adicionar/Editar) */}
{showPopup && (
<div
style={{
position: "fixed",
inset: 0,
backgroundColor: "rgba(0,0,0,0.5)",
display: "flex",
justifyContent: "center",
alignItems: "center",
zIndex: 1000
}}
>
<div
style={{
backgroundColor: "#fff",
padding: 20,
borderRadius: 8,
width: 320
}}
>
{step === 1 && (
<>
<h3 style={{ marginBottom: 8 }}>Nome do paciente</h3>
<input
type="text"
value={newEvent.title}
onChange={(e) =>
setNewEvent({ ...newEvent, title: e.target.value })
}
placeholder="Digite o nome"
style={{
width: "100%",
marginBottom: 12,
padding: 8,
borderRadius: 6,
border: "1px solid #ddd"
}}
/>
<button
onClick={handleNextStep}
disabled={!newEvent.title}
style={{
width: "100%",
padding: 10,
borderRadius: 6,
border: "none",
background: newEvent.title ? "#4dabf7" : "#c7dbf8",
color: "#fff",
cursor: newEvent.title ? "pointer" : "not-allowed"
}}
>
Próximo
</button>
</>
)}
{step === 2 && (
<>
<h3 style={{ marginBottom: 8 }}>Horário</h3>
<input
type="time"
value={newEvent.time}
onChange={(e) =>
setNewEvent({ ...newEvent, time: e.target.value })
}
style={{
width: "100%",
marginBottom: 12,
padding: 8,
borderRadius: 6,
border: "1px solid #ddd"
}}
/>
<button
onClick={handleNextStep}
disabled={!newEvent.time}
style={{
width: "100%",
padding: 10,
borderRadius: 6,
border: "none",
background: newEvent.time ? "#4dabf7" : "#c7dbf8",
color: "#fff",
cursor: newEvent.time ? "pointer" : "not-allowed"
}}
>
{editingEvent ? "Salvar Alterações" : "Adicionar"}
</button>
</>
)}
<button
onClick={() => setShowPopup(false)}
style={{
marginTop: 10,
width: "100%",
padding: 10,
borderRadius: 6,
border: "none",
background: "#ccc",
color: "#222",
cursor: "pointer"
}}
>
Cancelar
</button>
</div>
</div>
)}
{/* MODAL de ação ao clicar em consulta */}
{showActionModal && selectedEvent && (
<div
style={{
position: "fixed",
inset: 0,
backgroundColor: "rgba(0,0,0,0.5)",
display: "flex",
justifyContent: "center",
alignItems: "center",
zIndex: 1100
}}
>
<div
style={{
backgroundColor: "#fff",
padding: 20,
borderRadius: 8,
width: 320,
textAlign: "center"
}}
>
<h3 style={{ marginBottom: 4 }}>Consulta de {selectedEvent.title}</h3>
<p style={{ margin: 0 }}>
{selectedEvent.extendedProps.type} às {selectedEvent.extendedProps.time}
</p>
<div style={{ display: "flex", gap: 10, marginTop: 16 }}>
<button
onClick={handleStartEdit}
style={{
flex: 1,
padding: 10,
borderRadius: 6,
border: "none",
backgroundColor: "#4dabf7",
color: "#fff",
cursor: "pointer"
}}
>
Editar
</button>
<button
onClick={handleDeleteEvent}
style={{
flex: 1,
padding: 10,
borderRadius: 6,
border: "none",
backgroundColor: "#f76c6c",
color: "#fff",
cursor: "pointer"
}}
>
Apagar
</button>
</div>
<button
onClick={() => setShowActionModal(false)}
style={{
marginTop: 10,
width: "100%",
padding: 10,
borderRadius: 6,
border: "none",
background: "#ccc",
color: "#222",
cursor: "pointer"
}}
>
Cancelar
</button>
</div>
</div>
)}
</div>
);
}
export default Calendar1;