2026-02-12 15:24:32 -03:00
|
|
|
import { useState, useEffect } from "react";
|
|
|
|
|
import { ProfileService } from "../services/profile.service";
|
|
|
|
|
import { useAuth } from "../context/AuthContext";
|
|
|
|
|
import { AuthService } from "../services/auth.service";
|
2026-03-12 13:52:33 -03:00
|
|
|
import {
|
|
|
|
|
NotificationPreferencesService,
|
|
|
|
|
type NotificationPreferences,
|
|
|
|
|
} from "../services/notification-preferences.service";
|
2026-01-29 13:43:44 -03:00
|
|
|
|
|
|
|
|
export default function PerfilPage() {
|
|
|
|
|
const { user, refreshSession } = useAuth();
|
|
|
|
|
const [loading, setLoading] = useState(true);
|
|
|
|
|
const [saving, setSaving] = useState(false);
|
|
|
|
|
|
2026-02-12 15:24:32 -03:00
|
|
|
const [showEmailModal, setShowEmailModal] = useState(false);
|
|
|
|
|
const [newEmail, setNewEmail] = useState("");
|
|
|
|
|
const [authCode, setAuthCode] = useState(""); // Código Google Authenticator
|
|
|
|
|
const [loadingEmail, setLoadingEmail] = useState(false);
|
|
|
|
|
|
2026-01-29 13:43:44 -03:00
|
|
|
const [formData, setFormData] = useState({
|
2026-02-12 15:24:32 -03:00
|
|
|
firstName: "",
|
|
|
|
|
lastName: "",
|
|
|
|
|
phoneNumber: "",
|
2026-01-29 13:43:44 -03:00
|
|
|
});
|
|
|
|
|
|
2026-03-12 13:52:33 -03:00
|
|
|
// Estado de preferencias de notificación
|
|
|
|
|
const [notifPrefs, setNotifPrefs] = useState<NotificationPreferences>({
|
|
|
|
|
sistema: true,
|
|
|
|
|
marketing: true,
|
|
|
|
|
rendimiento: true,
|
|
|
|
|
mensajes: true,
|
|
|
|
|
});
|
|
|
|
|
const [savingPrefs, setSavingPrefs] = useState(false);
|
|
|
|
|
const [prefsSaved, setPrefsSaved] = useState(false);
|
|
|
|
|
const [loadingPrefs, setLoadingPrefs] = useState(true);
|
|
|
|
|
|
2026-01-29 13:43:44 -03:00
|
|
|
useEffect(() => {
|
|
|
|
|
loadProfile();
|
2026-03-12 13:52:33 -03:00
|
|
|
loadNotifPrefs();
|
2026-01-29 13:43:44 -03:00
|
|
|
}, []);
|
|
|
|
|
|
2026-03-12 13:52:33 -03:00
|
|
|
const loadNotifPrefs = async () => {
|
|
|
|
|
try {
|
|
|
|
|
const data = await NotificationPreferencesService.getPreferences();
|
|
|
|
|
setNotifPrefs(data);
|
|
|
|
|
} catch (err) {
|
|
|
|
|
console.error("Error cargando preferencias de notificación", err);
|
|
|
|
|
} finally {
|
|
|
|
|
setLoadingPrefs(false);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const handleSaveNotifPrefs = async () => {
|
|
|
|
|
setSavingPrefs(true);
|
|
|
|
|
try {
|
|
|
|
|
await NotificationPreferencesService.updatePreferences(notifPrefs);
|
|
|
|
|
setPrefsSaved(true);
|
|
|
|
|
setTimeout(() => setPrefsSaved(false), 3000);
|
|
|
|
|
} catch (err) {
|
|
|
|
|
alert("Error al guardar las preferencias de notificación.");
|
|
|
|
|
} finally {
|
|
|
|
|
setSavingPrefs(false);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2026-01-29 13:43:44 -03:00
|
|
|
const loadProfile = async () => {
|
|
|
|
|
try {
|
|
|
|
|
const data = await ProfileService.getProfile();
|
|
|
|
|
setFormData({
|
2026-02-12 15:24:32 -03:00
|
|
|
firstName: data.firstName || "",
|
|
|
|
|
lastName: data.lastName || "",
|
|
|
|
|
phoneNumber: data.phoneNumber || "",
|
2026-01-29 13:43:44 -03:00
|
|
|
});
|
|
|
|
|
} catch (err) {
|
|
|
|
|
console.error("Error loading profile", err);
|
|
|
|
|
} finally {
|
|
|
|
|
setLoading(false);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const handleSubmit = async (e: React.FormEvent) => {
|
|
|
|
|
e.preventDefault();
|
|
|
|
|
setSaving(true);
|
|
|
|
|
try {
|
|
|
|
|
await ProfileService.updateProfile(formData);
|
2026-02-12 15:24:32 -03:00
|
|
|
alert("Perfil actualizado con éxito");
|
2026-01-29 13:43:44 -03:00
|
|
|
if (refreshSession) refreshSession();
|
|
|
|
|
} catch (err) {
|
2026-02-12 15:24:32 -03:00
|
|
|
alert("Error al actualizar el perfil");
|
2026-01-29 13:43:44 -03:00
|
|
|
} finally {
|
|
|
|
|
setSaving(false);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
if (loading) {
|
|
|
|
|
return (
|
|
|
|
|
<div className="flex justify-center p-40">
|
|
|
|
|
<div className="animate-spin rounded-full h-12 w-12 border-b-2 border-blue-500"></div>
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<div className="container mx-auto px-6 py-12 max-w-4xl">
|
|
|
|
|
<div className="mb-12">
|
2026-02-12 15:24:32 -03:00
|
|
|
<h1 className="text-5xl font-black tracking-tighter uppercase mb-2">
|
|
|
|
|
Mi <span className="text-blue-500">Perfil</span>
|
|
|
|
|
</h1>
|
|
|
|
|
<p className="text-gray-500 font-bold tracking-widest uppercase text-xs">
|
|
|
|
|
Gestiona tu información personal
|
|
|
|
|
</p>
|
2026-01-29 13:43:44 -03:00
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div className="grid grid-cols-1 lg:grid-cols-3 gap-8">
|
|
|
|
|
{/* Sidebar Info */}
|
|
|
|
|
<div className="lg:col-span-1 space-y-6">
|
|
|
|
|
<div className="glass p-8 rounded-[2rem] border border-white/5 text-center">
|
|
|
|
|
<div className="w-24 h-24 bg-blue-600/20 rounded-full flex items-center justify-center text-4xl text-blue-400 font-bold mx-auto mb-4 border border-blue-500/20 shadow-lg shadow-blue-500/10">
|
|
|
|
|
{user?.username?.[0].toUpperCase()}
|
|
|
|
|
</div>
|
2026-02-12 15:24:32 -03:00
|
|
|
<h2 className="text-xl font-black text-white uppercase tracking-tight">
|
|
|
|
|
{user?.username}
|
|
|
|
|
</h2>
|
|
|
|
|
<p className="text-xs text-gray-500 font-medium mb-6">
|
|
|
|
|
{user?.email}
|
|
|
|
|
</p>
|
2026-01-29 13:43:44 -03:00
|
|
|
|
|
|
|
|
<div className="flex flex-col gap-2">
|
2026-02-12 15:24:32 -03:00
|
|
|
<span
|
|
|
|
|
className={`px-4 py-1.5 rounded-full text-[10px] font-black uppercase tracking-widest ${user?.userType === 3 ? "bg-amber-500/10 text-amber-500 border border-amber-500/20" : "bg-blue-600/10 text-blue-400 border border-blue-600/20"}`}
|
|
|
|
|
>
|
|
|
|
|
{user?.userType === 3
|
|
|
|
|
? "🛡️ Administrador"
|
|
|
|
|
: "👤 Usuario Particular"}
|
2026-01-29 13:43:44 -03:00
|
|
|
</span>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
2026-03-12 13:52:33 -03:00
|
|
|
{/* Formulario de datos personales */}
|
2026-01-29 13:43:44 -03:00
|
|
|
<div className="lg:col-span-2">
|
2026-02-12 15:24:32 -03:00
|
|
|
<form
|
|
|
|
|
onSubmit={handleSubmit}
|
|
|
|
|
className="glass p-8 rounded-[2.5rem] border border-white/5 space-y-8"
|
|
|
|
|
>
|
2026-01-29 13:43:44 -03:00
|
|
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
|
|
|
|
<div className="space-y-2">
|
2026-02-12 15:24:32 -03:00
|
|
|
<label className="text-[10px] font-black uppercase tracking-widest text-gray-500 ml-1">
|
|
|
|
|
Nombre
|
|
|
|
|
</label>
|
2026-01-29 13:43:44 -03:00
|
|
|
<input
|
|
|
|
|
type="text"
|
|
|
|
|
value={formData.firstName}
|
2026-02-12 15:24:32 -03:00
|
|
|
onChange={(e) =>
|
|
|
|
|
setFormData({ ...formData, firstName: e.target.value })
|
|
|
|
|
}
|
2026-01-29 13:43:44 -03:00
|
|
|
className="w-full bg-white/5 border border-white/10 rounded-2xl px-5 py-4 text-sm text-white outline-none focus:border-blue-500 transition-all font-medium"
|
|
|
|
|
placeholder="Tu nombre"
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div className="space-y-2">
|
2026-02-12 15:24:32 -03:00
|
|
|
<label className="text-[10px] font-black uppercase tracking-widest text-gray-500 ml-1">
|
|
|
|
|
Apellido
|
|
|
|
|
</label>
|
2026-01-29 13:43:44 -03:00
|
|
|
<input
|
|
|
|
|
type="text"
|
|
|
|
|
value={formData.lastName}
|
2026-02-12 15:24:32 -03:00
|
|
|
onChange={(e) =>
|
|
|
|
|
setFormData({ ...formData, lastName: e.target.value })
|
|
|
|
|
}
|
2026-01-29 13:43:44 -03:00
|
|
|
className="w-full bg-white/5 border border-white/10 rounded-2xl px-5 py-4 text-sm text-white outline-none focus:border-blue-500 transition-all font-medium"
|
|
|
|
|
placeholder="Tu apellido"
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div className="space-y-2 md:col-span-2">
|
2026-02-12 15:24:32 -03:00
|
|
|
<label className="text-[10px] font-black uppercase tracking-widest text-gray-500 ml-1">
|
|
|
|
|
Teléfono de Contacto
|
|
|
|
|
</label>
|
2026-01-29 13:43:44 -03:00
|
|
|
<input
|
|
|
|
|
type="text"
|
|
|
|
|
value={formData.phoneNumber}
|
2026-02-12 15:24:32 -03:00
|
|
|
onChange={(e) =>
|
|
|
|
|
setFormData({ ...formData, phoneNumber: e.target.value })
|
|
|
|
|
}
|
2026-01-29 13:43:44 -03:00
|
|
|
className="w-full bg-white/5 border border-white/10 rounded-2xl px-5 py-4 text-sm text-white outline-none focus:border-blue-500 transition-all font-medium"
|
|
|
|
|
placeholder="Ej: +54 9 11 1234 5678"
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div className="space-y-2 md:col-span-2">
|
2026-02-12 15:24:32 -03:00
|
|
|
<label className="text-[10px] font-black uppercase tracking-widest text-gray-500 ml-1">
|
|
|
|
|
Email
|
|
|
|
|
</label>
|
|
|
|
|
<div className="flex gap-2">
|
|
|
|
|
<input
|
|
|
|
|
type="email"
|
|
|
|
|
value={user?.email}
|
|
|
|
|
disabled
|
|
|
|
|
className="flex-1 bg-white/5 border border-white/10 rounded-2xl px-5 py-4 text-sm text-gray-500 outline-none cursor-not-allowed font-medium"
|
|
|
|
|
/>
|
|
|
|
|
<button
|
|
|
|
|
type="button"
|
|
|
|
|
onClick={() => {
|
|
|
|
|
if (!user?.isMFAEnabled) {
|
|
|
|
|
alert(
|
|
|
|
|
"⚠️ Acción restringida.\n\nPara cambiar tu email, primero debes activar la Autenticación de Dos Factores (2FA) en la sección de Seguridad.",
|
|
|
|
|
);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
setShowEmailModal(true);
|
|
|
|
|
}}
|
|
|
|
|
className="bg-white/5 hover:bg-blue-600 hover:text-white border border-white/10 text-gray-300 px-6 rounded-2xl text-[10px] font-black uppercase tracking-widest transition-all"
|
|
|
|
|
>
|
|
|
|
|
Cambiar
|
|
|
|
|
</button>
|
|
|
|
|
</div>
|
2026-01-29 13:43:44 -03:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div className="pt-6 border-t border-white/5">
|
|
|
|
|
<button
|
|
|
|
|
type="submit"
|
|
|
|
|
disabled={saving}
|
|
|
|
|
className="w-full md:w-auto bg-blue-600 hover:bg-blue-500 text-white py-4 px-12 rounded-2xl text-[10px] font-black uppercase tracking-widest transition-all shadow-lg shadow-blue-600/20 active:scale-95 disabled:opacity-50"
|
|
|
|
|
>
|
2026-02-12 15:24:32 -03:00
|
|
|
{saving ? "Guardando..." : "Guardar Cambios"}
|
2026-01-29 13:43:44 -03:00
|
|
|
</button>
|
|
|
|
|
</div>
|
|
|
|
|
</form>
|
2026-03-12 13:52:33 -03:00
|
|
|
|
|
|
|
|
{/* ─── Preferencias de Notificación ─── */}
|
|
|
|
|
<div className="mt-8 glass p-8 rounded-[2.5rem] border border-white/5">
|
|
|
|
|
<div className="flex items-center gap-3 mb-6">
|
|
|
|
|
<div className="w-10 h-10 bg-blue-600/15 rounded-2xl flex items-center justify-center text-xl border border-blue-500/20">
|
|
|
|
|
🔔
|
|
|
|
|
</div>
|
|
|
|
|
<div>
|
|
|
|
|
<h3 className="text-sm font-black uppercase tracking-widest text-white">
|
|
|
|
|
Preferencias de Notificación
|
|
|
|
|
</h3>
|
|
|
|
|
<p className="text-[10px] text-gray-500 font-medium mt-0.5">
|
|
|
|
|
Elegir qué correos querés recibir
|
|
|
|
|
</p>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{loadingPrefs ? (
|
|
|
|
|
<div className="flex items-center gap-3 py-4 text-gray-500 text-xs">
|
|
|
|
|
<div className="w-5 h-5 border-2 border-blue-500/40 border-t-blue-500 rounded-full animate-spin" />
|
|
|
|
|
Cargando preferencias...
|
|
|
|
|
</div>
|
|
|
|
|
) : (
|
|
|
|
|
<div className="space-y-4">
|
|
|
|
|
{([
|
|
|
|
|
{
|
|
|
|
|
key: "sistema" as const,
|
|
|
|
|
label: "Avisos del Sistema",
|
|
|
|
|
desc: "Vencimiento de avisos, renovaciones y alertas importantes.",
|
|
|
|
|
icon: "⚙️",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
key: "marketing" as const,
|
|
|
|
|
label: "Promociones y Marketing",
|
|
|
|
|
desc: "Ofertas especiales, recordatorio de carrito abandonado.",
|
|
|
|
|
icon: "🎁",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
key: "rendimiento" as const,
|
|
|
|
|
label: "Resumen Semanal",
|
|
|
|
|
desc: "Visitas y favoritos de tus avisos publicados.",
|
|
|
|
|
icon: "📊",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
key: "mensajes" as const,
|
|
|
|
|
label: "Recordatorio de Mensajes",
|
|
|
|
|
desc: "Aviso cuando tenés mensajes sin leer por más de 4 horas.",
|
|
|
|
|
icon: "💬",
|
|
|
|
|
},
|
|
|
|
|
] as const).map(({ key, label, desc, icon }) => (
|
|
|
|
|
<label
|
|
|
|
|
key={key}
|
|
|
|
|
className="flex items-center justify-between gap-4 p-4 rounded-2xl bg-white/3
|
|
|
|
|
border border-white/5 hover:bg-white/5 transition-all cursor-pointer group"
|
|
|
|
|
>
|
|
|
|
|
<div className="flex items-center gap-3">
|
|
|
|
|
<span className="text-xl">{icon}</span>
|
|
|
|
|
<div>
|
|
|
|
|
<p className="text-xs font-black text-white uppercase tracking-wider">
|
|
|
|
|
{label}
|
|
|
|
|
</p>
|
|
|
|
|
<p className="text-[10px] text-gray-500 font-medium mt-0.5">{desc}</p>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{/* Toggle switch */}
|
|
|
|
|
<div className="relative flex-shrink-0">
|
|
|
|
|
<input
|
|
|
|
|
type="checkbox"
|
|
|
|
|
className="sr-only"
|
|
|
|
|
checked={notifPrefs[key]}
|
|
|
|
|
onChange={(e) =>
|
|
|
|
|
setNotifPrefs((prev) => ({ ...prev, [key]: e.target.checked }))
|
|
|
|
|
}
|
|
|
|
|
/>
|
|
|
|
|
<div
|
|
|
|
|
className={`w-12 h-6 rounded-full transition-all duration-300 cursor-pointer
|
|
|
|
|
${notifPrefs[key]
|
|
|
|
|
? 'bg-blue-600 shadow-lg shadow-blue-600/30'
|
|
|
|
|
: 'bg-white/10'}`}
|
|
|
|
|
>
|
|
|
|
|
<div
|
|
|
|
|
className={`absolute top-1 w-4 h-4 bg-white rounded-full shadow transition-all duration-300
|
|
|
|
|
${notifPrefs[key] ? 'left-7' : 'left-1'}`}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</label>
|
|
|
|
|
))}
|
|
|
|
|
|
|
|
|
|
<div className="pt-4 border-t border-white/5 flex items-center gap-4">
|
|
|
|
|
<button
|
|
|
|
|
type="button"
|
|
|
|
|
onClick={handleSaveNotifPrefs}
|
|
|
|
|
disabled={savingPrefs}
|
|
|
|
|
className="bg-blue-600 hover:bg-blue-500 text-white py-3.5 px-10 rounded-2xl
|
|
|
|
|
text-[10px] font-black uppercase tracking-widest transition-all
|
|
|
|
|
shadow-lg shadow-blue-600/20 active:scale-95 disabled:opacity-50"
|
|
|
|
|
>
|
|
|
|
|
{savingPrefs ? "Guardando..." : "Guardar Preferencias"}
|
|
|
|
|
</button>
|
|
|
|
|
|
|
|
|
|
{prefsSaved && (
|
|
|
|
|
<span className="text-green-400 text-[10px] font-black uppercase tracking-widest
|
|
|
|
|
animate-pulse">
|
|
|
|
|
✓ Preferencias guardadas
|
|
|
|
|
</span>
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
2026-01-29 13:43:44 -03:00
|
|
|
</div>
|
|
|
|
|
</div>
|
2026-02-12 15:24:32 -03:00
|
|
|
{showEmailModal && (
|
|
|
|
|
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black/80 backdrop-blur-md p-4 animate-fade-in">
|
|
|
|
|
<div className="glass p-8 rounded-[2.5rem] border border-white/10 max-w-md w-full relative shadow-2xl animate-scale-up">
|
|
|
|
|
<button
|
|
|
|
|
onClick={() => setShowEmailModal(false)}
|
|
|
|
|
className="absolute top-6 right-6 text-gray-500 hover:text-white font-bold"
|
|
|
|
|
>
|
|
|
|
|
✕
|
|
|
|
|
</button>
|
|
|
|
|
|
|
|
|
|
<div className="text-center mb-6">
|
|
|
|
|
<div className="w-16 h-16 bg-blue-600/10 rounded-2xl flex items-center justify-center text-2xl mx-auto mb-4 border border-blue-500/20 text-blue-400">
|
|
|
|
|
📧
|
|
|
|
|
</div>
|
|
|
|
|
<h3 className="text-2xl font-black text-white uppercase tracking-tighter">
|
|
|
|
|
Cambiar Email
|
|
|
|
|
</h3>
|
|
|
|
|
<p className="text-xs text-gray-400 mt-2 font-medium">
|
|
|
|
|
Ingresa tu nueva dirección y valida con tu autenticador.
|
|
|
|
|
</p>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div className="space-y-5">
|
|
|
|
|
<div>
|
|
|
|
|
<label className="text-[9px] font-black uppercase tracking-widest text-gray-500 block mb-2 ml-1">
|
|
|
|
|
Nuevo Correo Electrónico
|
|
|
|
|
</label>
|
|
|
|
|
<input
|
|
|
|
|
type="email"
|
|
|
|
|
placeholder="nuevo@email.com"
|
|
|
|
|
value={newEmail}
|
|
|
|
|
onChange={(e) => setNewEmail(e.target.value)}
|
|
|
|
|
className="w-full bg-black/40 border border-white/10 rounded-xl px-4 py-3 text-white text-sm outline-none focus:border-blue-500 transition-all placeholder:text-gray-700"
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div>
|
|
|
|
|
<label className="text-[9px] font-black uppercase tracking-widest text-gray-500 block mb-2 ml-1">
|
|
|
|
|
Código Authenticator (2FA)
|
|
|
|
|
</label>
|
|
|
|
|
<input
|
|
|
|
|
type="text"
|
|
|
|
|
maxLength={6}
|
|
|
|
|
placeholder="000 000"
|
|
|
|
|
value={authCode}
|
|
|
|
|
onChange={(e) =>
|
|
|
|
|
setAuthCode(e.target.value.replace(/\D/g, ""))
|
|
|
|
|
}
|
|
|
|
|
className="w-full bg-black/40 border border-white/10 rounded-xl px-4 py-3 text-white text-center font-mono text-xl tracking-[0.3em] outline-none focus:border-blue-500 transition-all placeholder:text-gray-700 placeholder:tracking-normal"
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<button
|
|
|
|
|
onClick={async () => {
|
|
|
|
|
if (newEmail === user?.email) {
|
|
|
|
|
alert("El nuevo email debe ser diferente al actual.");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
try {
|
|
|
|
|
setLoadingEmail(true);
|
|
|
|
|
const res = await AuthService.initiateEmailChange(
|
|
|
|
|
newEmail,
|
|
|
|
|
authCode,
|
|
|
|
|
);
|
|
|
|
|
alert(res.message); // "Se ha enviado un enlace..."
|
|
|
|
|
setShowEmailModal(false);
|
|
|
|
|
setNewEmail("");
|
|
|
|
|
setAuthCode("");
|
|
|
|
|
} catch (err: any) {
|
|
|
|
|
alert(
|
|
|
|
|
err.response?.data?.message ||
|
|
|
|
|
"Error al solicitar cambio.",
|
|
|
|
|
);
|
|
|
|
|
} finally {
|
|
|
|
|
setLoadingEmail(false);
|
|
|
|
|
}
|
|
|
|
|
}}
|
|
|
|
|
disabled={
|
|
|
|
|
loadingEmail || newEmail.length < 5 || authCode.length < 6
|
|
|
|
|
}
|
|
|
|
|
className="w-full bg-blue-600 hover:bg-blue-500 text-white py-4 rounded-xl font-bold uppercase tracking-widest text-xs shadow-lg shadow-blue-600/20 transition-all disabled:opacity-50 disabled:cursor-not-allowed hover:scale-[1.02]"
|
|
|
|
|
>
|
|
|
|
|
{loadingEmail ? "Procesando..." : "Enviar Confirmación"}
|
|
|
|
|
</button>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
2026-01-29 13:43:44 -03:00
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
}
|