fix(registro): guardar el telefono en el formato que usa WhatsApp
Revisión con IA / ai-review (pull_request) Successful in 2m12s
Revisión con IA / ai-review (pull_request) Successful in 2m12s
Un cliente registrado por la web no lo reconocia el bot: el formulario dejaba escribir el numero en cualquier formato (1141984844, 01157260394) mientras que Meta manda el wa_id 5491141984844, asi que la busqueda por telefonoNorm no encontraba nada, mandaba al alta y ahi chocaba contra el email ya registrado. Quedaba en un callejon sin salida. Ahora el campo muestra "+54 9" fijo y grisado y el cliente completa solo la caracteristica (sin el 0) y el abonado (sin el 15), 10 digitos. El backend valida ese formato y guarda telefonoNorm ya como lo espera el bot. Se rechaza tambien un telefono repetido, que antes reventaba con el indice unico. Se agrega scripts/chat-bot.ts, que es como se encontro esto: permite conversar con el bot desde la consola contra cualquier base, sin Meta ni credenciales. Corriendolo contra una copia de la base de produccion se ve el ciclo completo: alta por web -> el bot lo reconoce por telefono -> pide el email -> reserva. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { prisma } from "@/lib/prisma";
|
||||
import { aFormatoWhatsapp, esLocalArgentinoValido, normalizarTelefono } from "@/lib/telefono";
|
||||
import nodemailer from "nodemailer";
|
||||
|
||||
const transporter = nodemailer.createTransport({
|
||||
@@ -18,11 +19,29 @@ export async function POST(req: NextRequest) {
|
||||
if (!email || !nombre || !apellido || !telefono)
|
||||
return NextResponse.json({ error: "Todos los campos son requeridos" }, { status: 400 });
|
||||
|
||||
if (!esLocalArgentinoValido(telefono))
|
||||
return NextResponse.json(
|
||||
{ error: "El teléfono debe tener 10 dígitos, sin el 0 de la característica ni el 15" },
|
||||
{ status: 400 }
|
||||
);
|
||||
|
||||
const existe = await prisma.cliente.findUnique({ where: { email: email.toLowerCase() } });
|
||||
if (existe) return NextResponse.json({ error: "El email ya está registrado" }, { status: 409 });
|
||||
|
||||
// `telefonoNorm` queda igual al `wa_id` que manda Meta, que es como lo busca el bot.
|
||||
const telefonoNorm = aFormatoWhatsapp(telefono);
|
||||
const yaUsado = await prisma.cliente.findFirst({ where: { telefonoNorm } });
|
||||
if (yaUsado)
|
||||
return NextResponse.json({ error: "Ese teléfono ya está registrado" }, { status: 409 });
|
||||
|
||||
const cliente = await prisma.cliente.create({
|
||||
data: { email: email.toLowerCase().trim(), nombre, apellido, telefono },
|
||||
data: {
|
||||
email: email.toLowerCase().trim(),
|
||||
nombre,
|
||||
apellido,
|
||||
telefono: normalizarTelefono(telefono),
|
||||
telefonoNorm,
|
||||
},
|
||||
});
|
||||
|
||||
await transporter.sendMail({
|
||||
|
||||
@@ -5,19 +5,36 @@ import Link from "next/link";
|
||||
import Button from "@/components/ui/Button";
|
||||
import Input from "@/components/ui/Input";
|
||||
import Card from "@/components/ui/Card";
|
||||
import { esLocalArgentinoValido } from "@/lib/telefono";
|
||||
|
||||
export default function RegistroPage() {
|
||||
const router = useRouter();
|
||||
const [form, setForm] = useState({ email: "", nombre: "", apellido: "", telefono: "" });
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [error, setError] = useState("");
|
||||
const [telefonoError, setTelefonoError] = useState("");
|
||||
|
||||
function set(field: string) {
|
||||
return (e: React.ChangeEvent<HTMLInputElement>) => setForm((f) => ({ ...f, [field]: e.target.value }));
|
||||
}
|
||||
|
||||
// El teléfono se guarda como lo espera WhatsApp: solo característica + abonado,
|
||||
// sin el 0 ni el 15 (el +54 9 lo pone el prefijo fijo del campo).
|
||||
function handleTelefono(e: React.ChangeEvent<HTMLInputElement>) {
|
||||
const soloDigitos = e.target.value.replace(/\D/g, "").slice(0, 10);
|
||||
setForm((f) => ({ ...f, telefono: soloDigitos }));
|
||||
if (soloDigitos === "") setTelefonoError("");
|
||||
else if (soloDigitos.startsWith("0")) setTelefonoError("Sin el 0 de la característica");
|
||||
else if (soloDigitos.length < 10) setTelefonoError("Faltan dígitos (son 10 en total)");
|
||||
else setTelefonoError("");
|
||||
}
|
||||
|
||||
async function handleSubmit(e: React.FormEvent) {
|
||||
e.preventDefault();
|
||||
if (!esLocalArgentinoValido(form.telefono)) {
|
||||
setTelefonoError("Revisá el número: son 10 dígitos, sin el 0 y sin el 15");
|
||||
return;
|
||||
}
|
||||
setLoading(true);
|
||||
setError("");
|
||||
const res = await fetch("/api/cliente/registro", {
|
||||
@@ -47,7 +64,20 @@ export default function RegistroPage() {
|
||||
<Input id="nombre" label="Nombre" placeholder="Juan" value={form.nombre} onChange={set("nombre")} required />
|
||||
<Input id="apellido" label="Apellido" placeholder="Pérez" value={form.apellido} onChange={set("apellido")} required />
|
||||
<Input id="email" type="email" label="Email" placeholder="juan@email.com" value={form.email} onChange={set("email")} required />
|
||||
<Input id="telefono" type="tel" label="Teléfono" placeholder="11 1234-5678" value={form.telefono} onChange={set("telefono")} required />
|
||||
<Input
|
||||
id="telefono"
|
||||
type="tel"
|
||||
inputMode="numeric"
|
||||
label="Teléfono (celular)"
|
||||
prefijo="+54 9"
|
||||
placeholder="1141984844"
|
||||
maxLength={10}
|
||||
ayuda="Característica sin el 0 y número sin el 15. Es el celular con el que vas a poder sacar turnos por WhatsApp."
|
||||
error={telefonoError}
|
||||
value={form.telefono}
|
||||
onChange={handleTelefono}
|
||||
required
|
||||
/>
|
||||
{error && <p className="text-sm text-red-500 text-center">{error}</p>}
|
||||
<Button type="submit" loading={loading} className="w-full">
|
||||
Crear cuenta
|
||||
|
||||
Reference in New Issue
Block a user