Files
schedule/src/components/Profile/ProfilePage.js
rafael 1458c143bc
Some checks failed
continuous-integration/drone/push Build was killed
Update ProfilePage: Replace username with email in profile form
Replaced the username field with an email field in the profile form. Updated form logic, validation messages, and input placeholders accordingly. Adjusted UI labels and input types to reflect the change.
2025-11-22 22:41:16 -04:00

255 lines
8.3 KiB
JavaScript

import React, { useEffect, useMemo, useState } from 'react';
import '../../styles/components.css';
const ProfileRow = ({ label, value, icon }) => (
<div className="form-row">
<div className="form-group" style={{ flex: 1 }}>
<label style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
{icon && <i className={icon} aria-hidden="true"></i>}
{label}
</label>
<div className="input" style={{ background: 'var(--bg-elevated)', border: '1px solid var(--border)', color: 'var(--text)' }}>
{value}
</div>
</div>
</div>
);
const storageKey = 'user.profile.v1';
const loadProfile = () => {
try {
const raw = localStorage.getItem(storageKey);
if (!raw) return null;
return JSON.parse(raw);
} catch (_e) {
return null;
}
};
const saveProfile = (profile) => {
try {
localStorage.setItem(storageKey, JSON.stringify(profile));
} catch (_e) {}
};
const computeInitials = (firstName = '', lastName = '') => {
const a = (firstName || '').trim().charAt(0).toUpperCase();
const b = (lastName || '').trim().charAt(0).toUpperCase();
return `${a}${b || ''}` || 'U';
};
const ProfilePage = () => {
const defaultProfile = useMemo(() => ({
username: 'jperez',
firstName: 'Juan',
lastName: 'Pérez',
email: 'juan.perez@empresa.com',
role: 'Administrador',
}), []);
const [profile, setProfile] = useState(() => loadProfile() || defaultProfile);
const [showModal, setShowModal] = useState(false);
useEffect(() => {
saveProfile(profile);
}, [profile]);
const initials = computeInitials(profile.firstName, profile.lastName);
const [form, setForm] = useState({
email: profile.email,
firstName: profile.firstName,
lastName: profile.lastName,
password: '',
});
useEffect(() => {
if (showModal) {
setForm({
email: profile.email,
firstName: profile.firstName,
lastName: profile.lastName,
password: '',
});
}
}, [showModal, profile]);
const openModal = () => setShowModal(true);
const closeModal = () => setShowModal(false);
const handleChange = (e) => {
const { name, value } = e.target;
setForm((prev) => ({ ...prev, [name]: value }));
};
const handleSave = (e) => {
e.preventDefault();
// Validaciones básicas
if (!form.email.trim() || !form.firstName.trim() || !form.lastName.trim()) {
alert('Por favor, completa los campos: correo, nombre y apellido.');
return;
}
if (form.password && form.password.length < 6) {
alert('La contraseña debe tener al menos 6 caracteres.');
return;
}
// En una app real, aquí llamarías a la API para actualizar perfil y contraseña.
setProfile((prev) => ({
...prev,
email: form.email.trim(),
firstName: form.firstName.trim(),
lastName: form.lastName.trim(),
// La contraseña NO se guarda en localStorage; solo se simula el flujo.
}));
if (form.password) {
// Simulación de actualización de contraseña
console.log('Contraseña actualizada (simulado).');
}
setShowModal(false);
};
return (
<section className="content-wrapper">
<div className="card" style={{ marginBottom: 24 }}>
<div className="form-header">
<h3>
<i className="fas fa-user" style={{ marginRight: 8 }}></i>
Perfil de usuario
</h3>
<div>
<button className="btn btn-primary" onClick={openModal}>
<i className="fas fa-edit"></i> Actualizar
</button>
</div>
</div>
<div style={{ display: 'flex', alignItems: 'center', gap: 16 }}>
<div className="user-avatar" aria-hidden="true">{initials}</div>
<div>
<div className="user-name" style={{ margin: 0 }}>{profile.firstName} {profile.lastName}</div>
<div className="user-role" style={{ margin: 0 }}>{profile.role}</div>
</div>
</div>
</div>
<div className="card">
<div className="form-header">
<h3>
<i className="fas fa-id-card" style={{ marginRight: 8 }}></i>
Información
</h3>
</div>
<div>
<ProfileRow label="Usuario" value={profile.username} icon="fas fa-user-circle" />
<ProfileRow label="Nombre" value={`${profile.firstName} ${profile.lastName}`} icon="fas fa-user" />
<ProfileRow label="Correo" value={profile.email} icon="fas fa-envelope" />
<ProfileRow label="Rol" value={profile.role} icon="fas fa-user-shield" />
</div>
</div>
{showModal && (
<div className="modal-overlay" onClick={closeModal}>
<div className="modal" onClick={(e) => e.stopPropagation()}>
<div className="modal-header">
<h3>
<i className="fas fa-user-cog"></i>
Actualizar perfil
</h3>
<button className="btn btn-outline btn-sm" onClick={closeModal}>
<i className="fas fa-times"></i> Cerrar
</button>
</div>
<div className="modal-body">
<form className="form-container" onSubmit={handleSave}>
<div className="form-row">
<div className="form-group" style={{ flex: 1 }}>
<label>
<i className="fas fa-envelope" aria-hidden="true"></i> Correo electrónico
</label>
<input
className="input"
type="email"
name="email"
value={form.email}
onChange={handleChange}
placeholder="correo@ejemplo.com"
required
/>
</div>
</div>
<div className="form-row">
<div className="form-group" style={{ flex: 1 }}>
<label>
<i className="fas fa-user" aria-hidden="true"></i> Nombre
</label>
<input
className="input"
type="text"
name="firstName"
value={form.firstName}
onChange={handleChange}
placeholder="Nombre"
required
/>
</div>
<div className="form-group" style={{ flex: 1 }}>
<label>
<i className="fas fa-user" aria-hidden="true"></i> Apellido
</label>
<input
className="input"
type="text"
name="lastName"
value={form.lastName}
onChange={handleChange}
placeholder="Apellido"
required
/>
</div>
</div>
<div className="form-row">
<div className="form-group" style={{ flex: 1 }}>
<label>
<i className="fas fa-lock" aria-hidden="true"></i> Contraseña (opcional)
</label>
<input
className="input"
type="password"
name="password"
value={form.password}
onChange={handleChange}
placeholder="Nueva contraseña"
minLength={6}
/>
<small style={{ color: 'var(--gray)' }}>
Déjala vacía si no deseas cambiarla.
</small>
</div>
</div>
<div className="form-row" style={{ justifyContent: 'flex-end', gap: 8 }}>
<button type="button" className="btn btn-outline" onClick={closeModal}>
Cancelar
</button>
<button type="submit" className="btn btn-primary">
<i className="fas fa-save"></i> Guardar
</button>
</div>
</form>
</div>
</div>
</div>
)}
</section>
);
};
export default ProfilePage;