envio de sms ao agendar consulta
This commit is contained in:
parent
0fcc7ae97b
commit
866e15df9e
@ -14,8 +14,10 @@ import { Textarea } from "@/components/ui/textarea";
|
|||||||
import { Calendar as CalendarShadcn } from "@/components/ui/calendar";
|
import { Calendar as CalendarShadcn } from "@/components/ui/calendar";
|
||||||
import { format, addDays } from "date-fns";
|
import { format, addDays } from "date-fns";
|
||||||
import { User, StickyNote, Calendar } from "lucide-react";
|
import { User, StickyNote, Calendar } from "lucide-react";
|
||||||
|
import {smsService } from "@/services/Sms.mjs"
|
||||||
import { toast } from "@/hooks/use-toast";
|
import { toast } from "@/hooks/use-toast";
|
||||||
|
|
||||||
|
|
||||||
export default function ScheduleForm() {
|
export default function ScheduleForm() {
|
||||||
// Estado do usuário e role
|
// Estado do usuário e role
|
||||||
const [role, setRole] = useState<string>("paciente");
|
const [role, setRole] = useState<string>("paciente");
|
||||||
@ -244,41 +246,56 @@ const handleSubmit = async (e: React.FormEvent) => {
|
|||||||
}.`,
|
}.`,
|
||||||
});
|
});
|
||||||
|
|
||||||
// 📞 busca o telefone corretamente
|
let phoneNumber = "+5511999999999"; // fallback
|
||||||
let phoneNumber = "+5511999999999"; // fallback
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (isSecretaryLike) {
|
if (isSecretaryLike) {
|
||||||
// se for secretária/admin → usa paciente selecionado
|
// Secretária/admin → telefone do paciente selecionado
|
||||||
const patient = patients.find((p: any) => p.id === patientId);
|
const patient = patients.find((p: any) => p.id === patientId);
|
||||||
if (patient?.phone_number) phoneNumber = patient.phone_number;
|
|
||||||
|
// Pacientes criados no sistema podem ter phone ou phone_mobile
|
||||||
|
const rawPhone = patient?.phone || patient?.phone_mobile || null;
|
||||||
|
|
||||||
|
if (rawPhone) phoneNumber = rawPhone;
|
||||||
} else {
|
} else {
|
||||||
// se for paciente → usa o service do próprio user
|
// Paciente → telefone vem do perfil do próprio usuário logado
|
||||||
const me = await usersService.getMe();
|
const me = await usersService.getMe();
|
||||||
if (me?.profile?.phone) phoneNumber = me.profile.phone;
|
|
||||||
|
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
// padroniza número para formato internacional (+55)
|
// 🔹 Normaliza para formato internacional (+55)
|
||||||
if (phoneNumber) {
|
if (phoneNumber) {
|
||||||
phoneNumber = phoneNumber.replace(/\D/g, ""); // remove caracteres não numéricos
|
phoneNumber = phoneNumber.replace(/\D/g, "");
|
||||||
if (!phoneNumber.startsWith("55")) phoneNumber = `55${phoneNumber}`;
|
if (!phoneNumber.startsWith("55")) phoneNumber = `55${phoneNumber}`;
|
||||||
phoneNumber = `+${phoneNumber}`;
|
phoneNumber = `+${phoneNumber}`;
|
||||||
}
|
}
|
||||||
} catch (err) {
|
|
||||||
console.warn("Não foi possível obter telefone do paciente:", err);
|
console.log("📞 Telefone usado:", 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 confirmação
|
||||||
// 💬 Envia o SMS de lembrete (sem mostrar nada ao paciente)
|
// 💬 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 {
|
try {
|
||||||
const smsRes = await appointmentsService.send_sms({
|
const smsRes = await smsService.sendSms({
|
||||||
phone_number: phoneNumber,
|
phone_number: phoneNumber,
|
||||||
message: `Lembrete: sua consulta é em ${dateFormatted} às ${selectedTime} na Clínica MediConnect.`,
|
message: `Lembrete: sua consulta é em ${dateFormatted} às ${selectedTime} na Clínica MediConnect.`,
|
||||||
patient_id: patientId,
|
patient_id: patientId,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (smsRes?.success) {
|
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 {
|
} else {
|
||||||
console.warn("⚠️ Falha no envio do SMS:", smsRes);
|
console.warn("⚠️ Falha no envio do SMS:", smsRes);
|
||||||
}
|
}
|
||||||
@ -287,6 +304,8 @@ try {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// 🧹 limpa os campos
|
// 🧹 limpa os campos
|
||||||
setSelectedDoctor("");
|
setSelectedDoctor("");
|
||||||
setSelectedDate("");
|
setSelectedDate("");
|
||||||
|
|||||||
58
services/Sms.mjs
Normal file
58
services/Sms.mjs
Normal file
@ -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 };
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
@ -89,11 +89,20 @@ async function request(endpoint, options = {}) {
|
|||||||
|
|
||||||
// --- CORREÇÃO 1: PARA O SUBMIT DO AGENDAMENTO ---
|
// --- 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.
|
// 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) {
|
// --- CORREÇÃO: funções do Supabase retornam 200 ou 201, nunca queremos perder o body ---
|
||||||
|
if (response.status === 204) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return response.json();
|
const text = await response.text();
|
||||||
|
try {
|
||||||
|
return JSON.parse(text);
|
||||||
|
} catch {
|
||||||
|
return text || null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Exportamos o objeto 'api' com os métodos que os componentes vão usar.
|
// Exportamos o objeto 'api' com os métodos que os componentes vão usar.
|
||||||
|
|||||||
@ -46,6 +46,6 @@ export const appointmentsService = {
|
|||||||
*/
|
*/
|
||||||
delete: (id) => api.delete(`/rest/v1/appointments?id=eq.${id}`),
|
delete: (id) => api.delete(`/rest/v1/appointments?id=eq.${id}`),
|
||||||
|
|
||||||
send_sms: (data) => api.post("/functions/v1/send-sms", data)
|
|
||||||
|
|
||||||
};
|
};
|
||||||
Loading…
x
Reference in New Issue
Block a user