/* PANEL SAAS · Orgullo Millonario — React + Tailwind · Liquid Glass Conectado a OM-DB: lo que se edita aquí se refleja EN VIVO en la página principal (site.html). */ const {useState,useEffect,useRef,useMemo,useSyncExternalStore,createContext,useContext}=React; const useDB=()=>useSyncExternalStore(OMDB.subscribe,OMDB.get); /* ============ ICONS ============ */ const I={ dash:, card:<>, squad:<>, spark:, gift:<>, heart:, play:<>, chat:, grid:<>, bell:, search:<>, x:, down:, eye:<>, drag:<>, users:<>, trophy:<>, video:<>, plus:, trash:<>, }; const Ic=({n,s=18,c=""})=>{I[n]}; /* ============ SHIRT 360 ============ */ function Shirt360({front,back,s=110}){ const [ang,setAng]=useState(0);const drag=useRef(null);const auto=useRef(true);const resume=useRef(); useEffect(()=>{let last=performance.now(),raf;const loop=t=>{const dt=t-last;last=t;if(auto.current)setAng(a=>(a+dt*0.05)%360);raf=requestAnimationFrame(loop);};raf=requestAnimationFrame(loop);return()=>cancelAnimationFrame(raf);},[]); const down=e=>{auto.current=false;clearTimeout(resume.current);drag.current={x:e.clientX,a:ang};e.currentTarget.setPointerCapture&&e.currentTarget.setPointerCapture(e.pointerId);}; const move=e=>{if(drag.current)setAng(drag.current.a+(e.clientX-drag.current.x)*0.8);}; const up=()=>{if(drag.current){drag.current=null;resume.current=setTimeout(()=>auto.current=true,2000);}}; return
↺ GIRA 360°
; } /* ============ TOAST ============ */ const ToastCtx=createContext(()=>{}); function ToastHost({children}){ const [msg,setMsg]=useState(null);const t=useRef(); const toast=m=>{setMsg(m);clearTimeout(t.current);t.current=setTimeout(()=>setMsg(null),2400);}; return {children}
{msg}
; } /* ============ SHARED ============ */ const Sec=({label,children,right})=>(
{label}{right}
); const Bar=({pct,cls})=>(
); /* ============ MODULES ============ */ function KpiModule(){ const db=useDB();const k=db.kpis; const kpis=[[k.viajes,"VIAJES PUBLICADOS","#2f7df6","🚌"],[k.reservas,"RESERVAS","#22c55e","📅"],[k.socios,"SOCIOS","#ffcf3e","👤"],[k.visitas,"VISITAS TOTALES","#ff2e3e","👁"]]; return
{kpis.map(([n,l,c,e],i)=>(
{n}{e}
{l}
))}
; } /* ============ SITIO & HERO — controla la página principal EN VIVO ============ */ function SiteModule(){ const db=useDB();const toast=useContext(ToastCtx);const c=db.config; const heroRef=useRef(); const [drag,setDrag]=useState(null); const secs=c.sections||[]; const modular=!!c.modular; const [ak,setAk]=useState('');const [al,setAl]=useState('128');const [at,setAt]=useState('435');const [asn,setAsn]=useState('2025'); const [live,setLive]=useState(()=>!!(window.OMDB&&OMDB.isLive&&OMDB.isLive())); const conectarAPI=async()=>{if(!ak.trim()){toast('Pegá tu API key de API-Football');return;}toast('Conectando con la API…');const ok=await OMDB.setAPI({key:ak.trim(),league:+al,season:+asn,team:+at});setLive(ok);toast(ok?'✔ Datos EN VIVO desde la API':'No se pudo conectar · sigue en DEMO');}; const F=({label,val,onChange,mono})=>( ); const onHero=e=>{const f=e.target.files&&e.target.files[0];if(!f)return;if(f.size>4.5e6){toast('Imagen muy grande (máx 4.5MB)');return;}const r=new FileReader();r.onload=()=>{OMDB.set('config.hero_img',r.result);toast('Imagen del hero actualizada en el sitio');};r.readAsDataURL(f);}; const move=(from,to)=>{if(from===to||to<0||to>=secs.length)return;OMDB.update(s=>{const a=s.config.sections;const [it]=a.splice(from,1);a.splice(to,0,it);});}; const toggleSec=i=>OMDB.update(s=>{s.config.sections[i].on=!s.config.sections[i].on;}); const toggleBlk=(i,j)=>OMDB.update(s=>{s.config.sections[i].blocks[j].on=!s.config.sections[i].blocks[j].on;}); const allOn=v=>OMDB.update(s=>{s.config.sections.forEach(x=>{x.on=v;(x.blocks||[]).forEach(b=>b.on=v);});}); return <> ABRIR SITIO ↗}/>
OMDB.set('config.hero_titulo',v)}/> OMDB.set('config.hero_subtitulo',v)}/>
OMDB.set('config.whatsapp',v)} mono/> OMDB.set('config.mp_link',v)} mono/>
IMAGEN DEL HERO
TEMA DEL SITIO
{[['dark','Oscuro'],['light','Claro']].map(([t,l])=>( ))}
{/* modularización y constructor viven en sus propias tarjetas */} {/* ===== DATOS REALES · API-FOOTBALL ===== */}
{live?'● EN VIVO':'● DEMO'}}/>

Liga 128 = Liga Profesional Argentina · Equipo 435 = River Plate · sin key funciona en DEMO

{/* constructor movido a su propia tarjeta */}
; } /* ============ MODULARIZACIÓN (tarjeta separada) ============ */ function ModularModule(){ const db=useDB();const toast=useContext(ToastCtx);const modular=!!db.config.modular; return <>
{modular?'ON':'OFF'}ESTADO
ABRIR SITIO ↗
; } /* ============ CONSTRUCTOR DEL SITIO (3 tarjetas) ============ */ function ConstructorModule(){ const db=useDB();const toast=useContext(ToastCtx); const secs=db.config.sections||[];const modular=!!db.config.modular; const [drag,setDrag]=useState(null); const move=(from,to)=>{if(from===to||to<0||to>=secs.length)return;OMDB.update(s=>{const a=s.config.sections;const [it]=a.splice(from,1);a.splice(to,0,it);});}; const toggleSec=i=>OMDB.update(s=>{s.config.sections[i].on=!s.config.sections[i].on;}); const toggleBlk=(i,j)=>OMDB.update(s=>{s.config.sections[i].blocks[j].on=!s.config.sections[i].blocks[j].on;}); const allOn=v=>OMDB.update(s=>{s.config.sections.forEach(x=>{x.on=v;(x.blocks||[]).forEach(b=>b.on=v);});}); const per=Math.max(1,Math.ceil(secs.length/3)); const groups=[[0,secs.slice(0,per)],[per,secs.slice(per,per*2)],[per*2,secs.slice(per*2)]]; const row=(sc,i)=>(
setDrag(i)} onDragEnd={()=>setDrag(null)} onDragOver={e=>{e.preventDefault();if(drag!==null&&drag!==i){move(drag,i);setDrag(i);}}} className="flex items-center gap-2 px-2.5 py-2 cursor-grab active:cursor-grabbing"> {sc.label} {sc.blocks&&{sc.blocks.filter(b=>b.on).length}/{sc.blocks.length}}
{sc.on&&sc.blocks&&sc.blocks.length>0&&
{sc.blocks.map((b,j)=>(
{b.label}
))}
}
); return <>
}/>
{groups.map(([base,g],gi)=>(
GRUPO {gi+1} {g.map((sc,k)=>row(sc,base+k))}
))}
; } function RevenueModule(){ const [pts,setPts]=useState(()=>Array.from({length:56},(_,i)=>48+Math.sin(i/5)*13)); const [val,setVal]=useState(24900); useEffect(()=>{let raf,last=performance.now(),acc=0; const tick=t=>{acc+=t-last;last=t; if(acc>110){acc=0; setPts(p=>{const nx=Math.max(12,Math.min(82,p[p.length-1]+(Math.random()-.48)*9));return[...p.slice(1),nx];}); setVal(v=>Math.max(18500,Math.min(41000,v+Math.round((Math.random()-.44)*180))));} raf=requestAnimationFrame(tick);}; raf=requestAnimationFrame(tick);return()=>cancelAnimationFrame(raf);},[]); const W=260,H=88,n=pts.length; const xy=i=>[(i/(n-1))*W,H-(pts[i]/94*H)]; const line=pts.map((_,i)=>xy(i).join(',')).join(' '); const [hx,hy]=xy(n-1); const up=pts[n-1]>=pts[n-2];const col=up?'#22c55e':'#ff3b45'; const users=(window.OMAuth&&typeof OMAuth.users==='function')?(OMAuth.users()||[]):[]; const PLAN=[['VIP','#8b5cf6'],['Oro','#ffcf3e'],['Plata','#c0c0cb'],['Bronce','#c97b3a'],['Gratuito','#5b93ff']]; const price={VIP:8490,ORO:4490,PLATA:2490,BRONCE:1290};const pp=x=>price[(x||'').toUpperCase()]||0; const dist=PLAN.map(([k,c])=>[k,c,users.filter(u=>(u.nivel||'').toUpperCase()===k.toUpperCase()).length]); let totU=dist.reduce((s,d)=>s+d[2],0);if(!totU){dist[0][2]=1;totU=1;} const R=26,CC=2*Math.PI*R;let off=0; const arcs=dist.filter(d=>d[2]>0).map(([k,c,v])=>{const dash=v/totU*CC;const seg={c,dash,off};off+=dash;return seg;}); const payers=users.filter(u=>u.nivel&&!/GRAT/i.test(u.nivel)); const fmt=x=>'$'+Math.round(x).toLocaleString('es-AR'); return <> {fmt(val)}/mes}/>
{up?'▲':'▼'} LIVE
{[[fmt(val),"MES ACTUAL","text-gold2"],["$1.22M","META ANUAL","text-ink"],["20,41%","PROGRESO","text-green-400"],[String(payers.length||users.length),"OPERACIONES","text-ink"]].map(([b,s,cc],i)=>(
{b}{s}
))}
{arcs.map((a,i)=>)}
{totU}SOCIOS
SOCIOS POR PLAN
{dist.map(([k,c,v])=>
{k}{v}
)}
USUARIOS QUE GENERARON EL PAGO
{payers.length?payers.map((u,i)=>(
{(u.nombre||'?')[0]} {u.nombre||u.email} {u.nivel} {fmt(pp(u.nivel))}
)):
Sin pagos registrados aún · aparecerán cuando un socio pague.
}
; } function WorldModule(){ const dots=useMemo(()=>{ let seed=77;const rnd=()=>((seed=(seed*1103515245+12345)&0x7fffffff)/0x7fffffff); const zones=[[18,18,55,32,.5],[55,52,28,48,.6],[112,12,40,26,.5],[118,40,32,38,.55],[150,14,60,40,.5],[196,60,26,20,.45]]; const a=[];zones.forEach(z=>{for(let i=0;i EN VIVO}/> {dots.map((d,i)=>)} {hot.map((p,i)=>)}
882VISITAS
138HOY
; } function ReferidosModule(){ const db=useDB();const toast=useContext(ToastCtx);const r=db.referidos; const list=[...r.lista].sort((a,b)=>b.ganancia-a.ganancia); const total=list.reduce((s,x)=>s+x.ganancia,0); const invit=list.reduce((s,x)=>s+x.invitados,0); const activos=list.reduce((s,x)=>s+x.activos,0); const max=Math.max(...list.map(x=>x.ganancia),1); const fmt=n=>'$'+n.toLocaleString('es-AR'); return <> {r.comision_pct}% C/SOCIO}/>
{[[fmt(total),'GANANCIA TOTAL','text-green-400'],[invit,'INVITADOS','text-ink'],[activos,'SOCIOS ACTIVOS','text-gold2']].map(([b,s,cc],i)=>(
{b}{s}
))}
{list.map((x,i)=>(
{i+1}
{x.nombre}{x.codigo}
{fmt(x.ganancia)} {x.invitados} inv · {x.activos} act
))}
; } function FiguritasModule(){ const toast=useContext(ToastCtx); const RZ=[["COMÚN","#9a9aa6"],["PLATA","#c0c0cb"],["ORO","#ffcf3e"],["LEYENDA","#ff2e3e"],["HOLOGRÁFICA","#8b5cf6"],["ULTRA PREMIUM","#22d3ee"]]; const CLUBS=[["River","assets/river.png"],["Boca","assets/boca.png"],["Barracas","assets/barracas.png"],["Racing","assets/racing.png"],["Talleres","assets/talleres.png"],["Argentinos","assets/argentinos.png"],["Gimnasia","assets/gimnasia.png"],["Rosario","assets/rosario.png"]]; const FLAGS=[["Argentina","ar"],["Brasil","br"],["Uruguay","uy"],["Colombia","co"],["Chile","cl"],["Paraguay","py"],["Venezuela","ve"],["Perú","pe"]]; const flagUrl=(cc,w=80)=>`https://flagcdn.com/w${w}/${cc}.png`; const [rz,setRz]=useState(4); const [name,setName]=useState("Franco Armani"); const [num,setNum]=useState("23"); const [pos,setPos]=useState("ARQ"); const [club,setClub]=useState(0); const [flag,setFlag]=useState(0); const [photo,setPhoto]=useState("assets/armani.png"); const fileRef=useRef();const addRef=useRef();const cardRef=useRef();const drag=useRef(null); const [sel,setSel]=useState('foto'); const [layers,setLayers]=useState(()=>[ {id:'foto', label:'Foto del jugador', tipo:'foto', x:50, y:60, w:84, on:true}, {id:'escudo',label:'Escudo del club', tipo:'escudo', x:15, y:11, w:20, on:true}, {id:'flag', label:'Bandera + año', tipo:'flag', x:85, y:10, w:22, on:true}, {id:'pitch', label:'Cancha / posición',tipo:'pitch', x:15, y:35, w:16, on:true}, ]); const patch=(id,p)=>setLayers(ls=>ls.map(l=>l.id===id?{...l,...p}:l)); const zOf=t=>t==='foto'?10:t==='custom'?24:30; const startDrag=(e,id)=>{e.stopPropagation();setSel(id);const r=cardRef.current.getBoundingClientRect();const L=layers.find(l=>l.id===id);drag.current={id,sx:e.clientX,sy:e.clientY,ox:L.x,oy:L.y,rw:r.width,rh:r.height}; const mv=ev=>{const d=drag.current;if(!d)return;patch(d.id,{x:Math.max(2,Math.min(98,d.ox+(ev.clientX-d.sx)/d.rw*100)),y:Math.max(2,Math.min(98,d.oy+(ev.clientY-d.sy)/d.rh*100))});}; const up=()=>{drag.current=null;window.removeEventListener('pointermove',mv);window.removeEventListener('pointerup',up);}; window.addEventListener('pointermove',mv);window.addEventListener('pointerup',up);}; const addImage=e=>{const f=e.target.files&&e.target.files[0];if(!f)return;if(f.size>4.5e6){toast('Imagen muy grande (máx 4.5MB)');return;}const r=new FileReader();r.onload=()=>{const id='u'+Date.now();setLayers(ls=>[...ls,{id,label:'Imagen '+(ls.filter(l=>l.tipo==='custom').length+1),tipo:'custom',src:r.result,x:50,y:45,w:34,on:true}]);setSel(id);toast('Imagen agregada · arrastrala en la tarjeta');};r.readAsDataURL(f);e.target.value='';}; const removeLayer=id=>{setLayers(ls=>ls.filter(l=>l.id!==id));if(sel===id)setSel(null);}; const srcOf=l=>l.tipo==='foto'?photo:l.tipo==='escudo'?CLUBS[club][1]:l.tipo==='flag'?flagUrl(FLAGS[flag][1],160):l.src; const selLayer=layers.find(l=>l.id===sel); const [year,setYear]=useState('2001');const [alt,setAlt]=useState('1,70');const [peso,setPeso]=useState('67'); const [nac,setNac]=useState('03-11-1979');const [sigla,setSigla]=useState('CARP');const [posab,setPosab]=useState('AM'); const [enr,setEnr]=useState('EN RIVER PLATE: 1996 - 2000'); const TEX=['comun','plata','oro','leyenda','holografica','premium']; const tex='assets/rareza/'+TEX[rz]+'.png'; const dark=[1,2,3].includes(rz);const tcol=dark?'#2a1c08':'#f4f4f6';const tsh=dark?'0 1px 0 rgba(255,255,255,.35)':'0 2px 6px rgba(0,0,0,.8)'; const c=RZ[rz][1]; const onFile=e=>{const f=e.target.files&&e.target.files[0];if(!f)return;if(f.size>4.5e6){toast('Imagen muy grande (máx 4.5MB)');return;}const r=new FileReader();r.onload=()=>{setPhoto(r.result);toast('Imagen del jugador cargada');};r.readAsDataURL(f);}; const crear=()=>{ if(!name.trim()){toast('Poné un nombre');return;} OMDB.update(s=>{s.figuritas=[{clave:'c'+Date.now(),nombre:name.trim(),tier:RZ[rz][0],img:photo,tenida:true,cant:1,num,pos,flag:FLAGS[flag][1],club:CLUBS[club][1]},...s.figuritas].slice(0,20);}); toast(`✔ ${name} (${RZ[rz][0]}) publicada en el álbum del sitio`); }; const exportPNG=async()=>{ const W=520,H=728,cv=document.createElement('canvas');cv.width=W;cv.height=H;const x=cv.getContext('2d'); const rr=(a,b,w,h,r)=>{x.beginPath();x.moveTo(a+r,b);x.arcTo(a+w,b,a+w,b+h,r);x.arcTo(a+w,b+h,a,b+h,r);x.arcTo(a,b+h,a,b,r);x.arcTo(a,b,a+w,b,r);x.closePath();}; rr(0,0,W,H,40);x.clip(); const g=x.createLinearGradient(0,0,W,H);g.addColorStop(0,c+'55');g.addColorStop(.5,'#1a1226');g.addColorStop(1,'#0b0714');x.fillStyle=g;x.fillRect(0,0,W,H); const load=src=>new Promise(res=>{const im=new Image();im.crossOrigin='anonymous';im.onload=()=>res(im);im.onerror=()=>res(null);im.src=src;}); const drawImgLayer=async l=>{const cx=W*l.x/100,cy=H*l.y/100,w=W*l.w/100;const im=await load(srcOf(l));if(!im)return;const h=w*(im.height/im.width);x.drawImage(im,cx-w/2,cy-h/2,w,h);return{cx,cy,w,h};}; const drawPitch=l=>{const cx=W*l.x/100,cy=H*l.y/100,w=W*l.w/100,h=w*4/3;x.save();rr(cx-w/2,cy-h/2,w,h,8);x.clip();const pg=x.createLinearGradient(0,cy-h/2,0,cy+h/2);pg.addColorStop(0,'#2f7a2f');pg.addColorStop(1,'#1c4d1c');x.fillStyle=pg;x.fillRect(cx-w/2,cy-h/2,w,h);x.strokeStyle='rgba(255,255,255,.4)';x.lineWidth=1.5;x.beginPath();x.moveTo(cx-w/2,cy-h/2+5);x.lineTo(cx+w/2,cy-h/2+5);x.moveTo(cx-w/2,cy+h/2-5);x.lineTo(cx+w/2,cy+h/2-5);x.stroke();x.restore();x.fillStyle='#fff';x.textAlign='center';x.textBaseline='middle';x.font='700 '+(w*0.42)+'px Oswald,sans-serif';x.shadowColor='#000';x.shadowBlur=4;x.fillText(posab,cx,cy);x.shadowBlur=0;x.textBaseline='alphabetic';}; const vis=layers.filter(l=>l.on); for(const l of vis.filter(l=>zOf(l.tipo)<20)) await drawImgLayer(l); // dark gradient + iridiscente + streak (rareza / holográfico) const ov=x.createLinearGradient(0,H*0.45,0,H);ov.addColorStop(0,'rgba(0,0,0,0)');ov.addColorStop(1,'rgba(0,0,0,.95)');x.fillStyle=ov;x.fillRect(0,H*0.45,W,H*0.55); x.save();x.globalCompositeOperation='overlay';x.globalAlpha=.45;x.translate(W/2,H*0.42);x.rotate(-0.9);const cols=['#ff0078','#00c8ff','#78ff50','#ffdc00'];for(let i=-34;i<34;i++){x.fillStyle=cols[((i%4)+4)%4];x.fillRect(i*24,-H,12,H*2);}x.restore(); x.save();x.globalCompositeOperation='color-dodge';x.globalAlpha=.32;x.translate(W/2,H*0.42);x.rotate(-0.9);for(let i=-34;i<34;i++){x.fillStyle=(i%2?c:'#ffffff');x.fillRect(i*18,-H,7,H*2);}x.restore(); const hs=x.createLinearGradient(0,0,W,H);hs.addColorStop(.3,'rgba(255,255,255,0)');hs.addColorStop(.46,'rgba(255,255,255,.5)');hs.addColorStop(.5,c);hs.addColorStop(.54,'rgba(255,255,255,.4)');hs.addColorStop(.68,'rgba(255,255,255,0)');x.fillStyle=hs;x.fillRect(0,0,W,H); // chrome: capas superiores (escudo/flag/pitch/custom) for(const l of vis.filter(l=>zOf(l.tipo)>=20)){ if(l.tipo==='pitch'){drawPitch(l);continue;} const d=await drawImgLayer(l);if(!d)continue; if(l.tipo==='flag'){x.strokeStyle='rgba(255,255,255,.7)';x.lineWidth=2.5;rr(d.cx-d.w/2,d.cy-d.h/2,d.w,d.h,8);x.stroke();x.fillStyle=tcol;x.textAlign='center';x.font='700 28px Oswald,sans-serif';x.fillText(year,d.cx,d.cy+d.h/2+26);} if(l.tipo==='escudo'){x.fillStyle=tcol;x.textAlign='center';x.font='700 20px Oswald,sans-serif';x.fillText(sigla,d.cx,d.cy+d.h/2+20);} } x.fillStyle='rgba(255,255,255,.14)';x.font='900 130px Oswald, sans-serif';x.textAlign='right';x.fillText(num,W-30,158); x.textAlign='center';x.fillStyle='#fff';x.font='700 46px Oswald, sans-serif';x.fillText(name.toUpperCase().slice(0,16),W/2,H-92); x.fillStyle=c;x.font='700 22px "JetBrains Mono", monospace';x.fillText(RZ[rz][0]+' · #'+num,W/2,H-54); x.strokeStyle=c;x.lineWidth=8;rr(4,4,W-8,H-8,36);x.stroke(); const a=document.createElement('a');a.download=`figurita-${name.toLowerCase().replace(/\s+/g,'-')||'cromo'}.png`;a.href=cv.toDataURL('image/png');a.click(); toast('PNG descargado ✔'); }; return <>
setName(e.target.value)} className="w-full bg-white/[.06] border border-white/10 rounded-2xl px-4 py-3 text-[13px] font-semibold outline-none focus:border-river/60 transition-colors" placeholder="Nombre del jugador"/>
setNum(e.target.value.slice(0,3))} className="bg-white/[.06] border border-white/10 rounded-xl px-3 py-2 text-[11px] font-mono text-center outline-none focus:border-river/60 min-w-0" placeholder="N°"/>

PNG recortado del jugador · fondo transparente ideal · máx 4.5MB

{RZ.map(([r,cc],i)=>( ))}
{CLUBS.map(([n,src],i)=>)}
{FLAGS.map((f,i)=>)}
addRef.current.click()} className="press font-mono text-[8px] tracking-[1px] text-cyanx border border-cyanx/40 rounded-lg px-2.5 py-1 hover:bg-cyanx/10">+ IMAGEN}/>
{layers.map(l=>(
setSel(l.id)} className={`flex items-center gap-2 rounded-xl px-2.5 py-2 border cursor-pointer transition-colors ${sel===l.id?'border-river bg-river/10':'border-white/[.08] bg-white/[.05]'} ${l.on?'':'opacity-45'}`}> {l.tipo==='pitch'?🟩:} {l.label} {l.tipo==='custom'&&}
))}
{selLayer&&
EDITAR · {selLayer.label.toUpperCase()}
{[['x','X ◄ ►',0,100],['y','Y ▲ ▼',0,100],['w','TAMAÑO',6,120]].map(([k,lb,mn,mx])=>(
{lb}patch(selLayer.id,{[k]:+e.target.value})} className="flex-1"/>{Math.round(selLayer[k])}
))}

Tip: también podés arrastrar la imagen directamente sobre la tarjeta.

}
VISTA PREVIA EN VIVO
setSel(null)}/> {layers.filter(l=>l.on).map(l=>(
startDrag(e,l.id)} className={`absolute cursor-grab active:cursor-grabbing ${sel===l.id?'ring-1 ring-river2/80 ring-offset-0':''}`} style={{left:l.x+'%',top:l.y+'%',width:l.w+'%',transform:'translate(-50%,-50%)',zIndex:zOf(l.tipo),touchAction:'none'}}> {l.tipo==='pitch' ?
{posab}
: {l.label}} {l.tipo==='escudo'&&{sigla}} {l.tipo==='flag'&&{year}}
))} {/* sheen + holo */} {rz>=4&&} {/* escudo + sigla */} {/* pitch + posición */} {/* flag + año */} {/* stats altura/peso */}
{[['↥',alt],['KG',peso]].map(([k,v],i)=>(
{k} {v}
))}
{/* nameplate + ribbon + footer */}
{(name||'—').toUpperCase()} {nac}
{enr}
CARP Official Collection
; } function PlantillaModule(){ const toast=useContext(ToastCtx);const db=useDB();const f=db.formacion; const PRESETS={'4-3-3':{def:4,med:3,del:3},'4-4-2':{def:4,med:4,del:2},'3-5-2':{def:3,med:5,del:2},'4-2-3-1':{def:4,med:5,del:1},'3-4-3':{def:3,med:4,del:3}}; const setEsquema=e=>OMDB.update(s=>{const p=PRESETS[e];s.formacion.esquema=e;['def','med','del'].forEach(k=>{const cur=s.formacion[k]||[];const arr=[];for(let i=0;iOMDB.update(s=>{if(line==='arq')s.formacion.arq.n=v;else s.formacion[line][i].n=v;}); const upPhoto=(line,i,file)=>{if(!file)return;if(file.size>4.5e6){toast('Imagen muy grande (máx 4.5MB)');return;}const r=new FileReader();r.onload=()=>{OMDB.update(s=>{if(line==='arq')s.formacion.arq.foto=r.result;else s.formacion[line][i].foto=r.result;});toast('Rostro actualizado ✔');};r.readAsDataURL(file);}; const pick=(line,i)=>{const inp=document.createElement('input');inp.type='file';inp.accept='image/*';inp.onchange=e=>upPhoto(line,i,e.target.files[0]);inp.click();}; const Line=({line,label,arr,gk})=>(
{label}
{arr.map((p,i)=>(
setName(line,i,e.target.value)} className="flex-1 bg-transparent text-[11.5px] font-semibold outline-none min-w-0" placeholder="Nombre"/>
))}
); return <> {f.esquema}}/>
{Object.keys(PRESETS).map(e=>)}

Tocá el círculo o “FOTO” para subir el rostro · editá el nombre · cambiá el esquema arriba

; } function SponsorsModule(){ const toast=useContext(ToastCtx); const tiers=[["ORO","text-gold2","rgba(212,164,55,.35)",[Betano,"CODERE","GATORADE"]], ["PLATA","text-[#c0c0cb]","rgba(192,192,203,.25)",["STANLEY","KONAMI","MOSTAZA"]], ["BRONCE","text-[#b0763a]","rgba(176,118,58,.3)",["TIENDA RIVER","QUILMES","ASSIST CARD"]]]; return <>
{tiers.map(([t,tc,bc,logos])=>(
{t}
{logos.map((l,i)=>( {l}))}
))}
; } function HistoriasModule(){ const toast=useContext(ToastCtx); const viajes=[["Boca Juniors vs River Plate","La Bombonera · 25/05",["BUS","ENTRADA"]],["River Plate vs Talleres","Más Monumental · 01/06",["BUS","COMIDA"]],["River Plate vs Independiente","Más Monumental · 08/06",["BUS"]]]; return <> ⚡ IA}/>
{viajes.map(([t,s,tags])=>(
{t}{s}
{tags.map(g=>{g})}
))}
{`VAMOS A LA BOMBONERA\nBOCA JRS VS RIVER PLATE\nVIERNES 25/05 · BUS 10:00 HS + ENTRADA\nDESDE EL OBELISCO · RESERVA AL 11 2234-5678\n¡CUPOS LIMITADOS!`}
; } function SorteosModule(){ const toast=useContext(ToastCtx); const db=useDB();const s=db.sorteo;const sold=useMemo(()=>new Set(s.sold),[s.sold]); const toggle=n=>OMDB.update(st=>{const set=new Set(st.sorteo.sold);set.has(n)?set.delete(n):set.add(n);st.sorteo.sold=[...set].sort((a,b)=>a-b);}); return <> ${s.precio} C/U}/>
{Array.from({length:s.total},(_,n)=>( ))}
■ VENDIDOS {sold.size}□ DISPONIBLES {s.total-sold.size}
; } function ReelsModule(){ const db=useDB();const toast=useContext(ToastCtx); const [txt,setTxt]=useState('');const [url,setUrl]=useState('');const [plat,setPlat]=useState('YOUTUBE'); const add=()=>{ if(!txt.trim()){toast('Poné un título');return;} if(!url.trim()){toast('Pegá el link de YouTube o TikTok');return;} OMDB.update(s=>{s.reels=[{titulo:txt.trim(),vistas:'0',plataforma:plat,url:url.trim()},...s.reels];}); setTxt('');setUrl('');toast('Video publicado en el sitio'); }; const del=i=>OMDB.update(s=>{s.reels.splice(i,1);}); return <>
setTxt(e.target.value)} placeholder="Título del video…" className="bg-white/[.06] border border-white/10 rounded-xl px-3 py-2 text-[11px] outline-none focus:border-river/60 min-w-0"/>
{['YOUTUBE','TIKTOK'].map(p=>( ))}
setUrl(e.target.value)} onKeyDown={e=>e.key==='Enter'&&add()} placeholder="Pegá el link…" className="flex-1 bg-white/[.06] border border-white/10 rounded-xl px-3 py-2 text-[10px] font-mono outline-none focus:border-river/60 min-w-0"/>
{db.reels.map((r,i)=>(
{r.titulo}{r.plataforma} · {r.url?r.url.slice(0,26)+'…':r.vistas+' vistas'}
))}
; } /* ============ PUBLICIDADES · BANNERS DEL SITIO ============ */ function PublicidadesModule(){ const db=useDB();const toast=useContext(ToastCtx); const ads=db.config.banners||[]; const [drag,setDrag]=useState(null); const setImg=(i,file)=>{if(!file)return;if(!/^image\//.test(file.type)){toast('Solo imágenes');return;}if(file.size>4.5e6){toast('Máx 4.5MB');return;}const r=new FileReader();r.onload=()=>{OMDB.update(s=>{s.config.banners[i].img=r.result;});toast('Banner #'+(i+1)+' actualizado en el sitio');};r.readAsDataURL(file);}; const setUrl=(i,v)=>OMDB.update(s=>{s.config.banners[i].img=v;}); const setLink=(i,v)=>OMDB.update(s=>{s.config.banners[i].link=v;}); return <> {ads.length} SLOTS}/>
{ads.map((a,i)=>(
{i+1}{a.pos}
setUrl(i,e.target.value)} placeholder="…o pegá la URL de la imagen" className="bg-white/[.06] border border-white/10 rounded-lg px-2.5 py-1.5 text-[9.5px] font-mono outline-none focus:border-river/60"/> setLink(i,e.target.value)} placeholder="Link de destino (https://…)" className="bg-white/[.06] border border-white/10 rounded-lg px-2.5 py-1.5 text-[9.5px] font-mono outline-none focus:border-river/60"/>
))}
; } /* ============ MODULE REGISTRY (hiper modular) ============ */ const MODULES=[ {id:'kpi', title:'Dashboard & Métricas', icon:'dash', span:'lg:col-span-6', bare:true, C:KpiModule}, {id:'site', title:'Sitio & Hero', icon:'eye', span:'lg:col-span-3', C:SiteModule}, {id:'modular',title:'Modularización', icon:'grid', span:'lg:col-span-3', C:ModularModule}, {id:'constr',title:'Constructor del Sitio', icon:'drag', span:'lg:col-span-6', C:ConstructorModule}, {id:'ads', title:'Publicidades · Banners',icon:'card', span:'lg:col-span-6', C:PublicidadesModule}, {id:'rev', title:'Facturación', icon:'down', span:'lg:col-span-3', C:RevenueModule}, {id:'world', title:'Visitas', icon:'eye', span:'lg:col-span-3', C:WorldModule}, {id:'refs', title:'Referidos · Socios', icon:'users', span:'lg:col-span-3', C:ReferidosModule}, {id:'figus', title:'Figuritas Builder', icon:'card', span:'lg:col-span-6', C:FiguritasModule}, {id:'squad', title:'Plantilla', icon:'squad', span:'lg:col-span-2 lg:row-span-2', C:PlantillaModule}, {id:'hist', title:'Historias · Telegram', icon:'chat', span:'lg:col-span-2', C:HistoriasModule}, {id:'sorteo',title:'Sorteos', icon:'gift', span:'lg:col-span-4', C:SorteosModule}, {id:'spons', title:'Sponsors', icon:'heart', span:'lg:col-span-2', C:SponsorsModule}, {id:'reels', title:'Reels TikTok', icon:'play', span:'lg:col-span-2', C:ReelsModule}, ]; const LS_KEY='om-panel-modules-v1'; /* ============ MODULE MANAGER SHEET ============ */ function ModuleSheet({open,onClose,enabled,setEnabled}){ if(!open)return null; return
e.stopPropagation()} className="glass-deep relative rounded-t-glass md:rounded-glass w-full md:w-[420px] p-6 safe-b" style={{animation:'sheetUp .35s cubic-bezier(.22,1,.36,1) both'}}>
MÓDULOS DEL PANEL
{MODULES.map(m=>{ const on=enabled.includes(m.id); return ;})}

TU CONFIGURACIÓN SE GUARDA AUTOMÁTICAMENTE

; } /* ============ SEARCH FULLSCREEN ============ */ function SearchOverlay({open,onClose,onGo}){ const [q,setQ]=useState(''); const inRef=useRef(); useEffect(()=>{if(open){setQ('');setTimeout(()=>inRef.current&&inRef.current.focus(),80);}},[open]); if(!open)return null; const ql=q.trim().toLowerCase(); const res=MODULES.filter(m=>!ql||m.title.toLowerCase().includes(ql)); return
setQ(e.target.value)} placeholder="Buscar módulos, secciones, herramientas…" className="flex-1 bg-transparent text-[17px] md:text-[20px] font-semibold outline-none placeholder:text-dim min-w-0"/>
{ql?`${res.length} RESULTADO(S)`:'TODOS LOS MÓDULOS'} {res.map(m=>( ))} {res.length===0&&
Sin resultados para “{q}”.
}
; } /* ============ APP ============ */ function App(){ const toast=useContext(ToastCtx); const [enabled,setEnabledRaw]=useState(()=>{const all=MODULES.map(m=>m.id);try{const v=JSON.parse(localStorage.getItem(LS_KEY));if(!Array.isArray(v))return all;return[...v.filter(id=>all.includes(id)),...all.filter(id=>!v.includes(id))];}catch(e){return all;}}); const setEnabled=v=>{setEnabledRaw(v);try{localStorage.setItem(LS_KEY,JSON.stringify(v));}catch(e){}}; const [sheet,setSheet]=useState(false); const [search,setSearch]=useState(false); const [notif,setNotif]=useState(false); const [dragId,setDragId]=useState(null); const [clock,setClock]=useState(''); useEffect(()=>{const f=()=>{const d=new Date(),p=n=>String(n).padStart(2,'0');setClock(`${p(d.getDate())}/${p(d.getMonth()+1)}/${d.getFullYear()} · ${p(d.getHours())}:${p(d.getMinutes())} HS`);};f();const t=setInterval(f,30000);return()=>clearInterval(t);},[]); const mods=enabled.map(id=>MODULES.find(m=>m.id===id)).filter(Boolean); const reorder=(toId)=>{if(!dragId||dragId===toId)return;const a=[...enabled];const from=a.indexOf(dragId),to=a.indexOf(toId);if(from<0||to<0)return;a.splice(from,1);a.splice(to,0,dragId);setEnabled(a);}; const navGo=id=>{const el=document.getElementById('mod-'+id);if(el){const y=el.getBoundingClientRect().top+window.scrollY-84;window.scrollTo({top:y,behavior:'smooth'});}else toast('Activá ese módulo desde “Módulos”');}; return <> {/* fondo liquid */}
{/* topbar glass */}
OM
PANEL SAAS ORGULLO MILLONARIO
{notif&&<>
setNotif(false)}/>
NOTIFICACIONESEN VIVO
{(()=>{const u=(window.OMAuth&&OMAuth.users&&OMAuth.users())||[];const k=(window.OMDB&&OMDB.get&&OMDB.get().kpis)||{};return [ ['users','Socios registrados',(u.length||k.socios||0)+' en total','#8b5cf6'], ['ticket','Reservas de viaje',(k.reservas||0)+' activas','#22c55e'], ['eye','Visitas al sitio',(k.visitas||0)+' totales','#5b93ff'], ['gift','Sorteo en curso','Camiseta firmada','#ffcf3e'], ].map(([ic,t,s,cc],i)=>(
{t}{s}
));})()}
}
{/* grid de módulos */}
{mods.map((m,i)=>m.bare ?
setDragId(m.id)} onDragEnd={()=>setDragId(null)} onDragOver={e=>{e.preventDefault();reorder(m.id);}} className={`${m.span} md:col-span-2 rise ${dragId===m.id?'opacity-50':''}`} style={{animationDelay:i*60+'ms'}}>
:
setDragId(m.id)} onDragEnd={()=>setDragId(null)} onDragOver={e=>{e.preventDefault();reorder(m.id);}} className={`glass rounded-glass p-5 flex flex-col h-full ${m.span} rise ${dragId===m.id?'opacity-50 ring-2 ring-river':''}`} style={{animationDelay:i*60+'ms'}}>
{m.title.toUpperCase()}
)} {mods.length===0&&
No hay módulos activos. Tocá Módulos para activarlos.
}
{/* footer */}
ORGULLO MILLONARIO ® 2026PANEL SAAS v3.0 · LIQUID SERVIDORES: ONLINE ●ACTUALIZADO: {clock}
{/* tab bar móvil */} setSheet(false)} enabled={enabled} setEnabled={setEnabled}/> setSearch(false)} onGo={navGo}/> ; } /* ============ ADMIN LOGIN (privado) ============ */ function AdminLogin({onOk}){ const [email,setEmail]=useState('');const [pass,setPass]=useState('');const [show,setShow]=useState(false); const [err,setErr]=useState('');const [loading,setLoading]=useState(false); const submit=async()=>{setErr('');setLoading(true);const r=await OMAdmin.login(email,pass);if(r.ok){onOk();}else{setErr(r.error);setLoading(false);}}; return
OM PANEL SAAS · PRIVADO ACCESO SOLO ADMINISTRADORES
{err&&
{err}
}

🔒 Sesión cifrada · las credenciales nunca se almacenan en claro

; } function AdminGate(){ const [authed,setAuthed]=useState(()=>!!(window.OMAdmin&&OMAdmin.isAuthed())); if(!authed) return setAuthed(true)}/>; return ; } ReactDOM.createRoot(document.getElementById('root')).render();