// ── CONFIGURACIÓN — Perfil, metas y preferencias ──────────────── const ConfigScreen = () => { const [tab, setTab] = React.useState('perfil'); // perfil | metas | plan const [user, setUser] = React.useState(null); const [form, setForm] = React.useState({ name:'', business_name:'', business_type:'', email:'', whatsapp:'', country:'', currency:'USD', avatar_url:'' }); const [loading, setLoading] = React.useState(true); const [saving, setSaving] = React.useState(false); const [avatarError, setAvatarError] = React.useState(''); const [avatarPreview, setAvatarPreview] = React.useState(''); const fileInputRef = React.useRef(null); const DEFAULT_AVATAR = '/sparkle-violeta.png'; const MAX_FILE_MB = 2; const MAX_BYTES = MAX_FILE_MB * 1024 * 1024; const load = () => { setLoading(true); API.get('/me').then(r => { if (r) { setUser(r); setForm({ name: r.name || '', business_name: r.business_name || '', business_type: r.business_type || '', email: r.email || '', whatsapp: r.whatsapp || '', country: r.country || '', currency: r.currency || 'USD', avatar_url: r.avatar_url || '' }); setAvatarPreview(r.avatar_url || DEFAULT_AVATAR); } setLoading(false); }); }; React.useEffect(() => { load(); }, []); const handleAvatarChange = (e) => { const file = e.target.files[0]; if (!file) return; setAvatarError(''); if (!file.type.startsWith('image/')) { setAvatarError('Solo se permiten imágenes (JPG, PNG, WebP).'); return; } if (file.size > MAX_BYTES) { setAvatarError(`La imagen no puede superar ${MAX_FILE_MB}MB.`); return; } const reader = new FileReader(); reader.onload = (ev) => { const dataUrl = ev.target.result; setAvatarPreview(dataUrl); setForm(f => ({ ...f, avatar_url: dataUrl })); }; reader.readAsDataURL(file); }; const save = async () => { setSaving(true); const res = await API.put('/me', form); setSaving(false); if (res.ok) { showToast('Perfil actualizado ✓'); try { const stored = JSON.parse(localStorage.getItem('ej_user') || '{}'); const updated = { ...stored, ...form }; localStorage.setItem('ej_user', JSON.stringify(updated)); // Force re-render of avatars globally window.dispatchEvent(new Event('storage')); } catch {} } else { showToast('Error al guardar', 'error'); } }; const repetirOnboarding = () => { if (!confirm('¿Quieres repetir el proceso de configuración inicial?')) return; try { const stored = JSON.parse(localStorage.getItem('ej_user') || '{}'); localStorage.setItem('ej_user', JSON.stringify({ ...stored, onboarded: false })); window.location.reload(); } catch {} }; if (loading) return
Cargando configuración...
; const inp = { width: '100%', padding: '12px 16px', borderRadius: 16, border: `1.5px solid ${EJ.border}`, fontSize: 14, outline: 'none', background: '#fff', color: EJ.body, transition: 'border-color 0.2s', fontFamily: 'Nunito Sans, sans-serif', boxSizing: 'border-box' }; const isMobile = window.__isMobile; return (
{/* TABS */}
{[ { id: 'perfil', label: '👤 Mi perfil' }, { id: 'metas', label: '🎯 Metas' }, { id: 'plan', label: '✦ Plan' } ].map(t => ( ))}
{/* VISTA PERFIL */} {tab === 'perfil' && ( <>
{ e.target.src = DEFAULT_AVATAR; }} style={{ width: 100, height: 100, borderRadius: '50%', objectFit: 'cover', border: `4px solid #fff`, boxShadow: '0 4px 20px rgba(0,0,0,0.1)', display: 'block' }} alt="Avatar" />
{form.name || 'Usuaria'}
{form.email}
✦ Admin
setForm(f => ({ ...f, name: e.target.value }))} />
setForm(f => ({ ...f, whatsapp: e.target.value }))} placeholder="+58 412 000 0000" />
setForm(f => ({ ...f, country: e.target.value }))} />
{saving ? 'Guardando...' : 'Guardar perfil'}
{!isMobile && (
🚀
Tu evolución
Estás al 85% de completar tu configuración estratégica de este mes.
)} )} {/* VISTA METAS */} {tab === 'metas' && (
🎯 Definición de Metas Estratégicas

Estas metas se sincronizan con tu panel de **Ventas & KPIs** y tu **Planificación** mensual.

Guardar metas
)} {/* VISTA PLAN */} {tab === 'plan' && (
ACTIVO
🕯️
Plan Clarity
Fundamentos y orden para tu negocio.
  • Gestión de CRM & Ventas
  • Planificación Mensual
  • Rutina Diaria RQV
🚀
Plan Pro
Escalado con IA y mentoría personalizada.
Mejorar plan ✦
)}
); }; Object.assign(window, { ConfigScreen });