diff --git a/components/schedule/schedule-form.tsx b/components/schedule/schedule-form.tsx index af89a24..89ffb05 100644 --- a/components/schedule/schedule-form.tsx +++ b/components/schedule/schedule-form.tsx @@ -14,8 +14,10 @@ import { Textarea } from "@/components/ui/textarea"; import { Calendar as CalendarShadcn } from "@/components/ui/calendar"; import { format, addDays } from "date-fns"; import { User, StickyNote, Calendar } from "lucide-react"; +import {smsService } from "@/services/Sms.mjs" import { toast } from "@/hooks/use-toast"; + export default function ScheduleForm() { // Estado do usuário e role const [role, setRole] = useState("paciente"); @@ -244,41 +246,56 @@ const handleSubmit = async (e: React.FormEvent) => { }.`, }); - // 📞 busca o telefone corretamente - let phoneNumber = "+5511999999999"; // fallback +let phoneNumber = "+5511999999999"; // fallback - try { - if (isSecretaryLike) { - // se for secretária/admin → usa paciente selecionado - const patient = patients.find((p: any) => p.id === patientId); - if (patient?.phone_number) phoneNumber = patient.phone_number; - } else { - // se for paciente → usa o service do próprio user - const me = await usersService.getMe(); - if (me?.profile?.phone) phoneNumber = me.profile.phone; - } +try { + if (isSecretaryLike) { + // Secretária/admin → telefone do paciente selecionado + const patient = patients.find((p: any) => p.id === patientId); + + // Pacientes criados no sistema podem ter phone ou phone_mobile + const rawPhone = patient?.phone || patient?.phone_mobile || null; + + if (rawPhone) phoneNumber = rawPhone; + } else { + // Paciente → telefone vem do perfil do próprio usuário logado + const me = await usersService.getMe(); + + +const rawPhone = + me?.profile?.phone || + (typeof me?.profile === "object" && "phone_mobile" in me.profile ? (me.profile as any).phone_mobile : null) || + (typeof me === "object" && "user_metadata" in me ? (me as any).user_metadata?.phone : null) || + null; + + if (rawPhone) phoneNumber = rawPhone; + } + + // 🔹 Normaliza para formato internacional (+55) + if (phoneNumber) { + phoneNumber = phoneNumber.replace(/\D/g, ""); + if (!phoneNumber.startsWith("55")) phoneNumber = `55${phoneNumber}`; + phoneNumber = `+${phoneNumber}`; + } + + console.log("📞 Telefone usado:", phoneNumber); +} catch (err) { + console.warn("⚠️ Não foi possível obter telefone do paciente:", err); +} - // padroniza número para formato internacional (+55) - if (phoneNumber) { - phoneNumber = phoneNumber.replace(/\D/g, ""); // remove caracteres não numéricos - if (!phoneNumber.startsWith("55")) phoneNumber = `55${phoneNumber}`; - phoneNumber = `+${phoneNumber}`; - } - } catch (err) { - console.warn("Não foi possível obter telefone do paciente:", err); - } // 💬 envia o SMS de confirmação // 💬 Envia o SMS de lembrete (sem mostrar nada ao paciente) +// 💬 Envia o SMS de lembrete (somente loga no console, não mostra no sistema) try { - const smsRes = await appointmentsService.send_sms({ + const smsRes = await smsService.sendSms({ phone_number: phoneNumber, message: `Lembrete: sua consulta é em ${dateFormatted} às ${selectedTime} na Clínica MediConnect.`, patient_id: patientId, }); if (smsRes?.success) { - console.log("✅ SMS enviado com sucesso:", smsRes.message_sid || smsRes.sid || "(sem SID retornado)"); + console.log("✅ SMS enviado com sucesso:", smsRes.message_sid); } else { console.warn("⚠️ Falha no envio do SMS:", smsRes); } @@ -287,6 +304,8 @@ try { } + + // 🧹 limpa os campos setSelectedDoctor(""); setSelectedDate(""); diff --git a/services/Sms.mjs b/services/Sms.mjs new file mode 100644 index 0000000..daf4984 --- /dev/null +++ b/services/Sms.mjs @@ -0,0 +1,58 @@ +/** + * Serviço de SMS via Supabase Edge Function (sem backend) + * Usa o token JWT salvo no localStorage (chave: "token") + */ + +const SUPABASE_FUNCTION_URL = + "https://yuanqfswhberkoevtmfr.supabase.co/functions/v1/send-sms"; + +export const smsService = { + /** + * Envia um SMS de lembrete via Twilio + * @param {Object} params + * @param {string} params.phone_number - Ex: +5511999999999 + * @param {string} params.message - Mensagem de texto + * @param {string} [params.patient_id] - ID opcional do paciente + */ + async sendSms({ phone_number, message, patient_id }) { + try { + // 🔹 Busca o token salvo pelo login + const token = localStorage.getItem("token"); + + if (!token) { + console.error("❌ Nenhum token JWT encontrado no localStorage (chave: 'token')."); + return { success: false, error: "Token JWT não encontrado." }; + } + + const body = JSON.stringify({ + phone_number, + message, + patient_id, + }); + + console.log("[smsService] Enviando SMS para:", phone_number); + + const response = await fetch(SUPABASE_FUNCTION_URL, { + method: "POST", + headers: { + "Content-Type": "application/json", + Authorization: `Bearer ${token}`, // 🔑 autenticação Supabase + }, + body, + }); + + const result = await response.json(); + + if (!response.ok) { + console.error("❌ Falha no envio do SMS:", result); + return { success: false, error: result }; + } + + console.log("✅ SMS enviado com sucesso:", result); + return result; + } catch (err) { + console.error("❌ Erro inesperado ao enviar SMS:", err); + return { success: false, error: err.message }; + } + }, +}; diff --git a/services/api.mjs b/services/api.mjs index 573c1ff..d06bde5 100644 --- a/services/api.mjs +++ b/services/api.mjs @@ -89,11 +89,20 @@ async function request(endpoint, options = {}) { // --- CORREÇÃO 1: PARA O SUBMIT DO AGENDAMENTO --- // Se a resposta for um sucesso de criação (201) ou sem conteúdo (204), não quebra. - if (response.status === 201 || response.status === 204) { - return null; + // --- CORREÇÃO: funções do Supabase retornam 200 ou 201, nunca queremos perder o body --- + if (response.status === 204) { + return null; + } + + const text = await response.text(); + try { + return JSON.parse(text); + } catch { + return text || null; } - return response.json(); + + } // Exportamos o objeto 'api' com os métodos que os componentes vão usar. diff --git a/services/appointmentsApi.mjs b/services/appointmentsApi.mjs index bebf986..f5a5f7b 100644 --- a/services/appointmentsApi.mjs +++ b/services/appointmentsApi.mjs @@ -46,6 +46,6 @@ export const appointmentsService = { */ delete: (id) => api.delete(`/rest/v1/appointments?id=eq.${id}`), - send_sms: (data) => api.post("/functions/v1/send-sms", data) + }; \ No newline at end of file