Files
turnosxpress/txadmin/src/components/ui/EditUserModal.tsx
T
horacio 28295e346c feat: add TypeScript definitions and utility functions for date formatting
- Created a global TypeScript declaration for the txadmin interface on the Window object.
- Implemented date formatting utilities using date-fns with Spanish locale support.
- Added TypeScript configuration files for app, Electron, and Node environments.
- Set up Vite configuration for React application.
2026-08-14 19:13:32 -03:00

128 lines
5.8 KiB
TypeScript

import React, { useState } from 'react';
import { motion } from 'framer-motion';
import { X } from 'lucide-react';
import { updateUserProfile, setVerifiedStatus } from '../../api/sysadmin';
export const EditUserModal = ({ user, onClose, onSaved }: { user: any, onClose: () => void, onSaved: () => void }) => {
const [formData, setFormData] = useState({
firstName: user.firstName || '',
lastName: user.lastName || '',
street: user.street || '',
streetNumber: user.streetNumber || '',
city: user.city || '',
state: user.state || '',
country: user.country || '',
phoneCountryCode: user.phoneCountryCode || '',
phoneAreaCode: user.phoneAreaCode || '',
phoneNumber: user.phoneNumber || '',
verificated: user.verificated || false,
});
const [loading, setLoading] = useState(false);
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
setLoading(true);
try {
const promises: Promise<any>[] = [
updateUserProfile({ userId: user._id, ...formData })
];
if (formData.verificated !== user.verificated) {
promises.push(setVerifiedStatus(user._id, formData.verificated));
}
await Promise.all(promises);
onSaved();
onClose();
} catch (err) {
alert('Error guardando perfil');
}
setLoading(false);
};
return (
<div style={{ position: 'fixed', inset: 0, zIndex: 50, display: 'flex', alignItems: 'center', justifyContent: 'center', background: 'rgba(0,0,0,0.5)', backdropFilter: 'blur(4px)' }}>
<motion.div
initial={{ scale: 0.9, opacity: 0 }}
animate={{ scale: 1, opacity: 1 }}
className="glass-panel"
style={{ width: '90%', maxWidth: '600px', maxHeight: '90vh', overflowY: 'auto', padding: '2rem', position: 'relative' }}
>
<button onClick={onClose} style={{ position: 'absolute', top: '1.5rem', right: '1.5rem', background: 'transparent', color: 'var(--text-muted)' }}>
<X size={24} />
</button>
<h2 style={{ fontSize: '1.5rem', marginBottom: '1.5rem' }}>Editar Perfil: {user.email}</h2>
<form onSubmit={handleSubmit} style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '1rem' }}>
<div>
<label className="modal-label">Nombre</label>
<input className="input-glass" value={formData.firstName} onChange={e => setFormData({...formData, firstName: e.target.value})} />
</div>
<div>
<label className="modal-label">Apellido</label>
<input className="input-glass" value={formData.lastName} onChange={e => setFormData({...formData, lastName: e.target.value})} />
</div>
<div style={{ gridColumn: '1 / -1', display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
<h3 style={{ margin: '1rem 0 0.5rem', color: 'var(--primary)', fontSize: '1.1rem' }}>Contacto</h3>
<button
type="button"
onClick={() => setFormData({...formData, verificated: !formData.verificated})}
className="btn-secondary"
style={{ display: 'flex', alignItems: 'center', gap: '8px', color: formData.verificated ? 'var(--success)' : 'var(--warning)', padding: '4px 12px' }}
>
{formData.verificated ? 'Usuario Verificado' : 'Usuario No Verificado'}
</button>
</div>
<div>
<label className="modal-label">Cód. País</label>
<input className="input-glass" value={formData.phoneCountryCode} onChange={e => setFormData({...formData, phoneCountryCode: e.target.value})} />
</div>
<div>
<label className="modal-label">Cód. Área</label>
<input className="input-glass" value={formData.phoneAreaCode} onChange={e => setFormData({...formData, phoneAreaCode: e.target.value})} />
</div>
<div style={{ gridColumn: '1 / -1' }}>
<label className="modal-label">Teléfono</label>
<input className="input-glass" value={formData.phoneNumber} onChange={e => setFormData({...formData, phoneNumber: e.target.value})} />
</div>
<div style={{ gridColumn: '1 / -1' }}>
<h3 style={{ margin: '1rem 0 0.5rem', color: 'var(--primary)', fontSize: '1.1rem' }}>Dirección</h3>
</div>
<div>
<label className="modal-label">Calle</label>
<input className="input-glass" value={formData.street} onChange={e => setFormData({...formData, street: e.target.value})} />
</div>
<div>
<label className="modal-label">Número</label>
<input className="input-glass" value={formData.streetNumber} onChange={e => setFormData({...formData, streetNumber: e.target.value})} />
</div>
<div>
<label className="modal-label">Ciudad</label>
<input className="input-glass" value={formData.city} onChange={e => setFormData({...formData, city: e.target.value})} />
</div>
<div>
<label className="modal-label">País</label>
<input className="input-glass" value={formData.country} onChange={e => setFormData({...formData, country: e.target.value})} />
</div>
<div style={{ gridColumn: '1 / -1', marginTop: '1.5rem', display: 'flex', justifyContent: 'flex-end', gap: '1rem' }}>
<button type="button" className="btn-secondary" onClick={onClose}>Cancelar</button>
<button type="submit" className="btn-primary" disabled={loading}>{loading ? 'Guardando...' : 'Guardar Cambios'}</button>
</div>
</form>
<style dangerouslySetInnerHTML={{__html: `
.modal-label {
display: block;
font-size: 0.85rem;
color: var(--text-muted);
margin-bottom: 0.5rem;
}
`}} />
</motion.div>
</div>
);
};