/* ============================================================
KeS Metas — Agendamentos (reuniões + Google Agenda central)
============================================================ */
const { useState, useEffect } = React;
/* Banner da conta CENTRAL da KeS (uma agenda para toda a equipe). */
function GoogleBanner({ google, dispatch }) {
const K = window.KES;
const [busy, setBusy] = useState(false);
async function connect() {
setBusy(true);
// // AQUI: integrar com Google Calendar API — OAuth da conta central da KeS
const res = await K.GoogleCalendarService.connect();
setBusy(false);
dispatch({ type: "SET_GOOGLE", connected: res.connected });
dispatch({ type: "TOAST", msg: "Google Agenda da KeS conectado com sucesso." });
}
async function disconnect() {
setBusy(true);
await K.GoogleCalendarService.disconnect();
setBusy(false);
dispatch({ type: "SET_GOOGLE", connected: false });
}
return (
Google Agenda da KeS Assessoria
{google.connected
? Conectado
: Não conectado }
{google.connected
? <>Conta central {google.account} . Toda a equipe agenda nesta agenda — cada evento registra quem agendou.>
: <>Conecte a conta central {google.account} para sincronizar os agendamentos da equipe.>}
{google.connected
?
{busy ? "Desconectando…" : "Desconectar"}
:
{busy ? "Conectando…" : "Conectar agenda da KeS"}}
);
}
const MESES_ABREV = ["jan", "fev", "mar", "abr", "mai", "jun", "jul", "ago", "set", "out", "nov", "dez"];
function MeetingRow({ m, autor, onDelete }) {
const K = window.KES;
const d = K.parseISO(m.date);
return (
{String(d.getDate()).padStart(2, "0")}
{MESES_ABREV[d.getMonth()]}
{m.titulo}
{m.googleSynced
? Na agenda da KeS
: Pendente }
{m.hora} · {m.duracao} min
{m.participante}
{m.convidados && m.convidados.length > 0 && {m.convidados.length} convidado{m.convidados.length > 1 ? "s" : ""} }
{autor && (
Agendado por {autor.nome} · {autor.papel === "admin" ? "Administrador" : "Comercial"}
)}
{m.meetLink && (
e.stopPropagation()}>
{m.meetLink.replace("https://", "")}
)}
{m.observacoes ?
{m.observacoes}
: null}
{onDelete && (
)}
);
}
function AgendaScreen({ state, dispatch, viewer }) {
const K = window.KES;
const isAdmin = viewer.papel === "admin";
const usersById = {}; state.users.forEach((u) => { usersById[u.id] = u; });
const google = state.google;
// "autor" = quem está agendando. Admin pode agendar em nome de qualquer um.
const [autorId, setAutorId] = useState(viewer.id);
const autor = state.users.find((u) => u.id === autorId) || viewer;
const todayISO = K.iso(K.SIM_TODAY);
const newBlank = () => ({ titulo: "", date: todayISO, hora: "09:00", duracao: "30", participante: "", contexto: "", observacoes: "", meetLink: "", convidados: [], leadId: null });
const [form, setForm] = useState(newBlank);
const [guestInput, setGuestInput] = useState("");
const [syncing, setSyncing] = useState(false);
const [err, setErr] = useState("");
const set = (k, v) => setForm((f) => ({ ...f, [k]: v }));
// Pré-preenche a partir de um lead do CRM (ação "Agendar reunião").
useEffect(() => {
const lead = state.agendaPrefill;
if (!lead) return;
if (isAdmin && lead.responsavelId) setAutorId(lead.responsavelId);
const ctx = [
lead.empresa && `Empresa: ${lead.empresa}`,
lead.porte && `Porte: ${lead.porte}`,
lead.telefone && `Tel: ${lead.telefone}`,
lead.valor && `Oportunidade: ${K.fmtMoeda(lead.valor)}`,
].filter(Boolean).join(" · ");
setForm({
titulo: `Reunião — ${lead.empresa || lead.nome}`,
date: todayISO, hora: "09:00", duracao: "30",
participante: `${lead.nome}${lead.empresa ? " (" + lead.empresa + ")" : ""}`,
contexto: ctx,
observacoes: lead.observacoes || "",
meetLink: "",
convidados: lead.email ? [lead.email] : [],
leadId: lead.id,
});
dispatch({ type: "CLEAR_PREFILL" });
dispatch({ type: "TOAST", msg: `Agendando reunião com ${lead.nome}.` });
}, [state.agendaPrefill]);
function addGuest(v) {
const e = v.trim().toLowerCase();
if (!e) return;
if (!/^\S+@\S+\.\S+$/.test(e)) { setErr("E-mail de convidado inválido."); return; }
if (!form.convidados.includes(e)) set("convidados", [...form.convidados, e]);
setGuestInput(""); setErr("");
}
async function submit(e) {
e.preventDefault();
if (!form.titulo.trim()) { setErr("Informe o título da reunião."); return; }
if (!form.participante.trim()) { setErr("Informe o participante/contato."); return; }
setErr(""); setSyncing(true);
const meeting = {
id: "m" + Date.now(), userId: autor.id, autorNome: autor.nome, titulo: form.titulo.trim(),
date: form.date, hora: form.hora, duracao: parseInt(form.duracao, 10),
participante: form.participante.trim(), contexto: form.contexto.trim(), observacoes: form.observacoes.trim(),
meetLink: form.meetLink, convidados: form.convidados, leadId: form.leadId,
calendar: google.account, googleSynced: false, eventId: null,
};
// // AQUI: integrar com Google Calendar API — events.insert na agenda CENTRAL da KeS
// (descrição do evento inclui autor + contexto; attendees = convidados; conferenceData = Meet)
let synced = { synced: false, eventId: null, meetLink: form.meetLink };
if (google.connected) {
const res = await K.GoogleCalendarService.createEvent(autor, meeting);
synced = { synced: res.synced, eventId: res.eventId, meetLink: res.meetLink || form.meetLink };
}
meeting.googleSynced = synced.synced; meeting.eventId = synced.eventId; meeting.meetLink = synced.meetLink;
dispatch({ type: "ADD_MEETING", meeting });
setSyncing(false); setForm(newBlank()); setGuestInput("");
dispatch({ type: "TOAST", msg: google.connected ? "Reunião criada na agenda da KeS e convites enviados." : "Reunião criada (sincronização pendente — conecte a agenda da KeS)." });
}
// Exclui a reunião do sistema E do Google Agenda da KeS.
async function excluirReuniao(m) {
dispatch({ type: "DELETE_MEETING", id: m.id });
if (m.eventId && google.connected) {
const res = await K.GoogleCalendarService.deleteEvent(m.eventId);
dispatch({ type: "TOAST", msg: res.ok ? "Reunião excluída da agenda da KeS." : "Reunião removida aqui (não foi possível excluir do Google)." });
} else {
dispatch({ type: "TOAST", msg: "Reunião excluída." });
}
}
// Admin vê todas as próximas reuniões da equipe; comum vê só as suas.
const upcoming = state.meetings
.filter((m) => (isAdmin || m.userId === viewer.id) && m.date >= todayISO)
.sort((a, b) => (a.date + a.hora).localeCompare(b.date + b.hora));
return (
Agendamentos
Uma agenda central da KeS para toda a equipe. Cada reunião registra quem agendou e alimenta o indicador "Reuniões Agendadas".
{/* Lista */}
{isAdmin ? "Próximas reuniões da equipe" : "Suas próximas reuniões"}
{upcoming.length}
{upcoming.length === 0 ? (
Nenhuma reunião futura
Crie a primeira no formulário ao lado.
) : (
{upcoming.map((m) => excluirReuniao(m)} />)}
)}
{/* Form */}
);
}
window.AgendaScreen = AgendaScreen;