From 4586b3bae5d8f8dd0732a2c9add55d785088d735 Mon Sep 17 00:00:00 2001 From: VPS 4 Builder Date: Tue, 9 Jun 2026 17:08:31 +0200 Subject: [PATCH] =?UTF-8?q?feat(equipe):=20conectar=20Google=20Agenda=20do?= =?UTF-8?q?=20funcion=C3=A1rio=20no=20painel=20de=20Equipe?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - botão Conectar (GoogleConnectButton, ownerId=userId do membro) no modal de edição do membro - status de conexão por membro via /api/auth/google/status - conexão 'na hora' (quem tem a senha do Gmail autoriza); sem auto-conexão na área do funcionário Co-Authored-By: Claude Opus 4.8 --- frontend/views/GestaoEquipeView.tsx | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/frontend/views/GestaoEquipeView.tsx b/frontend/views/GestaoEquipeView.tsx index aa718aa..d8cab0f 100644 --- a/frontend/views/GestaoEquipeView.tsx +++ b/frontend/views/GestaoEquipeView.tsx @@ -3,6 +3,7 @@ import { Users, Building, Briefcase, Plus, Trash2, Edit2, X, Check, UserPlus, Sh import { HybridBackend } from '../services/backend.ts'; import { useToast } from '../contexts/ToastContext.tsx'; import { PageHeader } from '../components/PageHeader.tsx'; +import { GoogleConnectButton } from '../components/GoogleConnectButton.tsx'; type Tab = 'usuarios' | 'setores' | 'funcoes'; @@ -149,6 +150,17 @@ const UsuariosTab: React.FC<{ clinicaId: string; isOwner: boolean; myNivel: numb useEffect(() => { load(); }, [load]); + // Status do Google da clínica (qual membro tem o calendário conectado). + const [googleAccounts, setGoogleAccounts] = useState([]); + const loadGoogleStatus = useCallback(async () => { + try { + const r = await fetch(`/api/auth/google/status?clinicaId=${clinicaId}`); + const d = await r.json(); + setGoogleAccounts(Array.isArray(d) ? d : []); + } catch { /* ignore */ } + }, [clinicaId]); + useEffect(() => { loadGoogleStatus(); }, [loadGoogleStatus]); + const handleAdd = async (e: React.FormEvent) => { e.preventDefault(); setSaving(true); @@ -376,6 +388,21 @@ const UsuariosTab: React.FC<{ clinicaId: string; isOwner: boolean; myNivel: numb {funcoes.filter(f => isOwner || (typeof f.nivel === 'number' ? f.nivel : 1) < myNivel).map(f => )} + + {/* Google Agenda do funcionário — conectado AQUI (quem tem a senha do Gmail autoriza na hora). */} +
+ +

+ Conecta o calendário do Gmail desta pessoa: os agendamentos viram cópia de backup e o paciente recebe convite + lembretes. Autorize com a conta dela (precisa da senha do Gmail). +

+ a.owner_id === editing.id)} + onStatusChange={loadGoogleStatus} + /> +
+