145 lines
6.1 KiB
TypeScript
145 lines
6.1 KiB
TypeScript
|
|
import { useState, useEffect } from 'react';
|
||
|
|
import { ProfileService } from '../services/profile.service';
|
||
|
|
import { useAuth } from '../context/AuthContext';
|
||
|
|
|
||
|
|
export default function PerfilPage() {
|
||
|
|
const { user, refreshSession } = useAuth();
|
||
|
|
const [loading, setLoading] = useState(true);
|
||
|
|
const [saving, setSaving] = useState(false);
|
||
|
|
|
||
|
|
const [formData, setFormData] = useState({
|
||
|
|
firstName: '',
|
||
|
|
lastName: '',
|
||
|
|
phoneNumber: ''
|
||
|
|
});
|
||
|
|
|
||
|
|
useEffect(() => {
|
||
|
|
loadProfile();
|
||
|
|
}, []);
|
||
|
|
|
||
|
|
const loadProfile = async () => {
|
||
|
|
try {
|
||
|
|
const data = await ProfileService.getProfile();
|
||
|
|
setFormData({
|
||
|
|
firstName: data.firstName || '',
|
||
|
|
lastName: data.lastName || '',
|
||
|
|
phoneNumber: data.phoneNumber || ''
|
||
|
|
});
|
||
|
|
} 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);
|
||
|
|
alert('Perfil actualizado con éxito');
|
||
|
|
if (refreshSession) refreshSession();
|
||
|
|
} catch (err) {
|
||
|
|
alert('Error al actualizar el perfil');
|
||
|
|
} 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">
|
||
|
|
<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>
|
||
|
|
</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>
|
||
|
|
<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>
|
||
|
|
|
||
|
|
<div className="flex flex-col gap-2">
|
||
|
|
<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'}
|
||
|
|
</span>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
{/* Edit Form */}
|
||
|
|
<div className="lg:col-span-2">
|
||
|
|
<form onSubmit={handleSubmit} className="glass p-8 rounded-[2.5rem] border border-white/5 space-y-8">
|
||
|
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||
|
|
<div className="space-y-2">
|
||
|
|
<label className="text-[10px] font-black uppercase tracking-widest text-gray-500 ml-1">Nombre</label>
|
||
|
|
<input
|
||
|
|
type="text"
|
||
|
|
value={formData.firstName}
|
||
|
|
onChange={e => setFormData({ ...formData, firstName: e.target.value })}
|
||
|
|
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">
|
||
|
|
<label className="text-[10px] font-black uppercase tracking-widest text-gray-500 ml-1">Apellido</label>
|
||
|
|
<input
|
||
|
|
type="text"
|
||
|
|
value={formData.lastName}
|
||
|
|
onChange={e => setFormData({ ...formData, lastName: e.target.value })}
|
||
|
|
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">
|
||
|
|
<label className="text-[10px] font-black uppercase tracking-widest text-gray-500 ml-1">Teléfono de Contacto</label>
|
||
|
|
<input
|
||
|
|
type="text"
|
||
|
|
value={formData.phoneNumber}
|
||
|
|
onChange={e => setFormData({ ...formData, phoneNumber: e.target.value })}
|
||
|
|
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">
|
||
|
|
<label className="text-[10px] font-black uppercase tracking-widest text-gray-500 ml-1">Email <span className="text-[8px] text-gray-600 font-normal">(No editable)</span></label>
|
||
|
|
<input
|
||
|
|
type="email"
|
||
|
|
value={user?.email}
|
||
|
|
disabled
|
||
|
|
className="w-full 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"
|
||
|
|
/>
|
||
|
|
</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"
|
||
|
|
>
|
||
|
|
{saving ? 'Guardando...' : 'Guardar Cambios'}
|
||
|
|
</button>
|
||
|
|
</div>
|
||
|
|
</form>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
);
|
||
|
|
}
|