/* 11 Partners — "Cupido cobra" (Fase 1e) Alta de partner, login y mini-panel con su código PART-XXXXXX, sus números y sus referidos (SOLO el ID del cliente: privacidad RGPD por diseño). */ function Partner({ go }) { const [mode, setMode] = React.useState(() => (CruceAPI.Partner.Session.get() ? 'panel' : 'hero')); const [form, setForm] = React.useState({ name:'', email:'', phone:'', city:'', iban:'', password:'', accepts_terms:false }); const [login, setLogin] = React.useState({ email:'', password:'' }); const [panel, setPanel] = React.useState(null); const [referrals, setReferrals] = React.useState(null); const [error, setError] = React.useState(''); const [busy, setBusy] = React.useState(false); const [copied, setCopied] = React.useState(''); const set = (k, v) => setForm(f => ({ ...f, [k]: v })); const setL = (k, v) => setLogin(f => ({ ...f, [k]: v })); async function loadPanel() { const [me, refs] = await Promise.all([CruceAPI.Partner.me(), CruceAPI.Partner.referrals()]); setPanel(me); setReferrals(refs.referrals || []); if (me && me.partner) CruceAPI.Partner.Session.set(CruceAPI.Partner.Session.get().token, me.partner); } React.useEffect(() => { if (mode === 'panel') loadPanel().catch(e => { setError(e.message); setMode('hero'); }); }, [mode]); async function doRegister(ev) { ev.preventDefault(); setError(''); setBusy(true); try { const r = await CruceAPI.Partner.register({ name: form.name.trim(), email: form.email.trim(), phone: form.phone.trim() || undefined, city: form.city.trim() || undefined, iban: form.iban.trim() || undefined, password: form.password, accepts_terms: form.accepts_terms, }); CruceAPI.Partner.Session.set(r.token, r.partner); setMode('panel'); } catch (e) { setError(e.message); } finally { setBusy(false); } } async function doLogin(ev) { ev.preventDefault(); setError(''); setBusy(true); try { const r = await CruceAPI.Partner.login(login.email.trim(), login.password); CruceAPI.Partner.Session.set(r.token, r.partner); setMode('panel'); } catch (e) { setError(e.message); } finally { setBusy(false); } } function logout() { CruceAPI.Partner.Session.clear(); setPanel(null); setReferrals(null); setMode('hero'); } function copy(text, what) { navigator.clipboard && navigator.clipboard.writeText(text); setCopied(what); setTimeout(() => setCopied(''), 1500); } if (mode === 'panel' && panel) { const p = panel.partner, s = panel.stats || {}; const saleLabel = { pending_payment: 'Pendiente de pago', paid: 'Pagado', refunded: 'Reembolsado', cancelled: 'Cancelado' }; return (
Quien se registre con tu código queda vinculado a ti: aparece en tu panel como cliente tuyo y, cuando pague el Club, se confirma tu comisión de 10€. El pago siempre lo hace el cliente con Stripe — tú nunca tocas su dinero ni su tarjeta.
Todavía no has registrado a nadie. Comparte tu código en la calle, en tus redes o por WhatsApp.
) : (| ID cliente | Alta | Plan | Venta | Comisión |
|---|---|---|---|---|
| #{r.client_id} | {(r.registered_at || '').slice(0, 16)} | {r.plan} | {saleLabel[r.sale_status] || r.sale_status} | {r.sale_status === 'refunded' ? '0€' : r.commission + '€'}{r.commission_paid ? ' · cobrada' : ''} |
En la feria, en el concierto, en la fiesta de pueblo: registras gente en 2 minutos desde tu móvil. El cliente paga online cuando quiera (Stripe, 3DS2), tú cobras 10€ por cada suscripción. Tú nunca pides tarjeta: solo compartes tu código.