// ── 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
Estas metas se sincronizan con tu panel de **Ventas & KPIs** y tu **Planificación** mensual.