(function () { const { useState, useEffect, useCallback, useRef } = React; // ════════════════════════════════════════════════════════════════════ // KONEKTEZ DASHBOARD v3 — Real API, no mock data // ════════════════════════════════════════════════════════════════════ const C = { bg:"#07070A", surface:"#0E0E12", surface2:"#141418", border:"#1E1E26", gold:"#D4AF37", goldDark:"#A0822A", goldLight:"#EDD066", white:"#F0EEE8", muted:"#6B6880", dim:"#3A3850", green:"#22C55E", orange:"#F97316", red:"#EF4444", blue:"#60A5FA", purple:"#A78BFA", }; const CL = { bg:"#F4F2EC", surface:"#FFFFFF", surface2:"#F0EDE4", border:"#E0D9CE", white:"#1a1a2e", muted:"#7a7060", dim:"#c0b8a8", }; const STATUS = { active: {color:C.green, bg:"#14532D22", dot:"●", label:"Actif"}, grace: {color:C.orange, bg:"#7C2D1222", dot:"◑", label:"Grâce"}, expired: {color:C.red, bg:"#7F1D1D22", dot:"○", label:"Expiré"}, inactive:{color:C.red, bg:"#7F1D1D22", dot:"○", label:"Inactif"}, }; const $f = n => `$${Number(n||0).toLocaleString("fr-FR",{minimumFractionDigits:2,maximumFractionDigits:2})}`; const Nf = n => Number(n||0).toLocaleString("fr-FR"); const HTGf = (n,rate) => `${Math.round(Number(n||0)*Number(rate||134)).toLocaleString("fr-FR")} HTG`; const clamp = (v,a,b) => Math.min(b,Math.max(a,v)); // ── API client ──────────────────────────────────────────────────── const cfg = (window.kmlmConfig || {}); const API_BASE = cfg.apiBase || '/wp-json/konekmlm/v1'; const TOKEN_KEY = 'kmlm_jwt'; const getToken = () => localStorage.getItem(TOKEN_KEY); const setToken = t => { if(t) localStorage.setItem(TOKEN_KEY, t); else localStorage.removeItem(TOKEN_KEY); }; async function api(endpoint, options = {}) { const token = getToken(); const headers = { 'Content-Type': 'application/json' }; if (token) headers['Authorization'] = 'Bearer ' + token; if (cfg.nonce) headers['X-WP-Nonce'] = cfg.nonce; const res = await fetch(API_BASE + endpoint, { ...options, headers: { ...headers, ...(options.headers||{}) }, body: options.body ? JSON.stringify(options.body) : undefined, }); const json = await res.json(); if (json.success === false) throw new Error(json.message || 'Erreur API'); return json.data !== undefined ? json.data : json; } async function apiUpload(endpoint, formData) { const token = getToken(); const headers = {}; if (token) headers['Authorization'] = 'Bearer ' + token; if (cfg.nonce) headers['X-WP-Nonce'] = cfg.nonce; const res = await fetch(API_BASE + endpoint, { method:'POST', headers, body:formData }); const json = await res.json(); if (json.success === false) throw new Error(json.message || 'Erreur upload'); return json.data; } // ── Icons ───────────────────────────────────────────────────────── const IC = { dash: "M3 9l9-7 9 7v11a2 2 0 01-2 2H5a2 2 0 01-2-2z M9 22V12h6v10", tree: "M12 3a3 3 0 100 6 3 3 0 000-6zM5 18a3 3 0 100 6 3 3 0 000-6zM19 18a3 3 0 100 6 3 3 0 000-6zM12 9v3M8.5 21H5M15.5 21H19M12 12l-6.5 7M12 12l6.5 7", earn: "M12 2v20M17 5H9.5a3.5 3.5 0 000 7h5a3.5 3.5 0 010 7H6", pack: "M21 16V8a2 2 0 00-1-1.73l-7-4a2 2 0 00-2 0l-7 4A2 2 0 003 8v8a2 2 0 001 1.73l7 4a2 2 0 002 0l7-4A2 2 0 0021 16z", rank: "M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z", badge: "M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z", wallet: "M21 7H3a2 2 0 00-2 2v10a2 2 0 002 2h18a2 2 0 002-2V9a2 2 0 00-2-2zM1 7l4-4h14l4 4", out: "M17 11l-5-5-5 5M12 6v12M21 20H3", shop: "M6 2L3 6v14a2 2 0 002 2h14a2 2 0 002-2V6l-3-4zM3 6h18M16 10a4 4 0 01-8 0", status: "M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z", logout: "M9 21H5a2 2 0 01-2-2V5a2 2 0 012-2h4M16 17l5-5-5-5M21 12H9", copy: "M8 4H6a2 2 0 00-2 2v14a2 2 0 002 2h12a2 2 0 002-2V6a2 2 0 00-2-2h-2M8 4a2 2 0 012-2h4a2 2 0 012 2M8 4h8", check: "M20 6L9 17l-5-5", clock: "M12 22a10 10 0 100-20 10 10 0 000 20zM12 6v6l4 2", bell: "M18 8A6 6 0 006 8c0 7-3 9-3 9h18s-3-2-3-9M13.73 21a2 2 0 01-3.46 0", menu: "M3 12h18M3 6h18M3 18h18", link: "M10 13a5 5 0 007.54.54l3-3a5 5 0 00-7.07-7.07l-1.72 1.71M14 11a5 5 0 00-7.54-.54l-3 3a5 5 0 007.07 7.07l1.71-1.71", down: "M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4M7 10l5 5 5-5M12 15V3", user: "M20 21v-2a4 4 0 00-4-4H8a4 4 0 00-4 4v2M12 11a4 4 0 100-8 4 4 0 000 8z", trophy: "M6 9H4.5a2.5 2.5 0 010-5H6M18 9h1.5a2.5 2.5 0 000-5H18M4 22h16M10 14.66V17c0 .55-.47.98-.97 1.21C7.85 18.75 7 20.24 7 22M14 14.66V17c0 .55.47.98.97 1.21C16.15 18.75 17 20.24 17 22M18 2H6v7a6 6 0 0012 0V2z", cam: "M23 19a2 2 0 01-2 2H3a2 2 0 01-2-2V8a2 2 0 012-2h4l2-3h6l2 3h4a2 2 0 012 2zM12 17a4 4 0 100-8 4 4 0 000 8", sun: "M12 1v2M12 21v2M4.22 4.22l1.42 1.42M18.36 18.36l1.42 1.42M1 12h2M21 12h2M4.22 19.78l1.42-1.42M18.36 5.64l1.42-1.42M17 12a5 5 0 11-10 0 5 5 0 0110 0z", moon: "M21 12.79A9 9 0 1111.21 3 7 7 0 0021 12.79z", }; function Icon({d,size=18,color="currentColor"}) { return React.createElement('svg',{width:size,height:size,viewBox:"0 0 24 24",fill:"none",stroke:color,strokeWidth:"1.8",strokeLinecap:"round",strokeLinejoin:"round"}, React.createElement('path',{d})); } // ── UI primitives ───────────────────────────────────────────────── function Card({children,style={},gold=false,dark=true}) { const colors = dark ? C : CL; return React.createElement('div',{style:{background:colors.surface,border:`1px solid ${gold?C.gold+"44":colors.border}`,borderRadius:14,padding:20,...style}},children); } function Chip({label,color=C.gold,tiny=false}) { return React.createElement('span',{style:{background:`${color}18`,border:`1px solid ${color}44`,color,padding:tiny?"1px 7px":"2px 9px",borderRadius:20,fontSize:tiny?9:11,fontWeight:700,textTransform:"uppercase",letterSpacing:1.3,whiteSpace:"nowrap"}},label); } function StatusBadge({s}) { const cfg=STATUS[s]||STATUS.inactive; return React.createElement('span',{style:{background:cfg.bg,color:cfg.color,padding:"2px 9px",borderRadius:20,fontSize:10,fontWeight:700}},`${cfg.dot} ${cfg.label}`); } function Bar({v=0,max=100,color=C.gold,h=6}) { const p=clamp(max>0?v/max*100:0,0,100); return React.createElement('div',{style:{background:C.surface2,borderRadius:h,height:h,overflow:"hidden"}}, React.createElement('div',{style:{width:`${p}%`,height:"100%",background:`linear-gradient(90deg,${color}77,${color})`,transition:"width 0.8s"}})); } function Av({name="?",size=38,color=C.gold,url=null}) { const i=(name||"?").split(" ").map(w=>w[0]).join("").slice(0,2).toUpperCase(); if(url) return React.createElement('img',{src:url,alt:"",style:{width:size,height:size,borderRadius:"50%",border:`2px solid ${color}`,objectFit:"cover",flexShrink:0}}); return React.createElement('div',{style:{width:size,height:size,borderRadius:"50%",flexShrink:0,background:`linear-gradient(135deg,${C.surface2},#16160a)`,border:`2px solid ${color}`,display:"flex",alignItems:"center",justifyContent:"center",fontSize:size*.32,fontWeight:800,color,letterSpacing:.5}},i); } function Loader({msg="Chargement...",dark=true}) { return React.createElement('div',{style:{padding:60,textAlign:"center",color:dark?C.muted:CL.muted}},msg); } function ErrBox({msg}) { return React.createElement('div',{style:{padding:16,background:"#7f1d1d22",border:`1px solid ${C.red}44`,borderRadius:10,color:C.red,fontSize:12,margin:"12px 0"}},msg); } function Sparkline({data=[],vk="total",color=C.gold,h=70}) { if(!data.length) return null; const vals=data.map(d=>Number(d[vk]||d.total||0)); const mx=Math.max(...vals,1); const W=460,H=h,px=6,py=6; const pts=vals.map((v,i)=>({x:px+(i/Math.max(1,vals.length-1))*(W-px*2),y:py+(1-v/mx)*(H-py*2)})); const path=pts.map((p,i)=>`${i===0?"M":"L"}${p.x.toFixed(1)},${p.y.toFixed(1)}`).join(" "); const fill=path+` L${pts[pts.length-1].x},${H} L${pts[0].x},${H} Z`; const gid=`g${color.replace("#","")}`; return React.createElement('svg',{viewBox:`0 0 ${W} ${H}`,style:{width:"100%"}}, React.createElement('defs',null,React.createElement('linearGradient',{id:gid,x1:"0",y1:"0",x2:"0",y2:"1"}, React.createElement('stop',{offset:"0%",stopColor:color,stopOpacity:".22"}), React.createElement('stop',{offset:"100%",stopColor:color,stopOpacity:"0"}))), React.createElement('path',{d:fill,fill:`url(#${gid})`}), React.createElement('path',{d:path,fill:"none",stroke:color,strokeWidth:"2",strokeLinecap:"round"}), pts.map((p,i)=>React.createElement('circle',{key:i,cx:p.x,cy:p.y,r:3,fill:C.bg,stroke:color,strokeWidth:"1.8"}))); } // ── Hook générique pour charger une API ────────────────────────── function useApi(endpoint, deps=[]) { const [data,setData] = useState(null); const [loading,setLoading] = useState(true); const [error,setError] = useState(null); useEffect(()=>{ let cancelled = false; setLoading(true); setError(null); api(endpoint).then(d=>{ if(!cancelled){setData(d);setLoading(false);} }) .catch(e=>{ if(!cancelled){setError(e.message);setLoading(false);} }); return ()=>{ cancelled=true; }; }, deps); return {data,loading,error}; } // ── Compte à rebours d'expiration ──────────────────────────────── function ExpiryBanner({status,onRenew}) { const [t,setT]=useState({h:0,m:0,s:0}); useEffect(()=>{ if(!status||!["urgent","grace"].includes(status.phase)) return; const target=new Date(status.expiry_date); const tick=()=>{const d=Math.max(0,target-Date.now());setT({h:Math.floor(d/3600000),m:Math.floor((d%3600000)/60000),s:Math.floor((d%60000)/1000)});}; tick(); const id=setInterval(tick,1000); return()=>clearInterval(id); },[status]); if(!status||status.phase==="active"&&status.days_remaining>10) return null; const cfg={ warning:{color:C.gold, bg:"#71350011",border:"#eab30844",icon:"⏰"}, urgent: {color:C.orange,bg:"#7c2d1211",border:"#f9731644",icon:"⚠"}, grace: {color:C.red, bg:"#7f1d1d11",border:"#ef444444",icon:"🔴"}, expired:{color:C.red, bg:"#7f1d1d11",border:"#ef444444",icon:"🚫"}, }; const c=cfg[status.phase]||cfg.warning; return React.createElement('div',{style:{background:c.bg,border:`1px solid ${c.border}`,borderRadius:13,padding:"14px 18px",marginBottom:22}}, React.createElement('div',{style:{display:"flex",alignItems:"center",justifyContent:"space-between",flexWrap:"wrap",gap:12}}, React.createElement('div',{style:{flex:1}}, React.createElement('div',{style:{display:"flex",alignItems:"center",gap:8,marginBottom:5}}, React.createElement('span',{style:{fontSize:17}},c.icon), React.createElement('span',{style:{fontWeight:800,color:c.color,fontSize:13}}, status.phase==="grace"?"Période de grâce":status.phase==="urgent"?"Renouvellement urgent":"Expiration imminente"), status.can_earn&&React.createElement('span',{style:{background:`${C.green}15`,border:`1px solid ${C.green}44`,color:C.green,padding:"1px 7px",borderRadius:10,fontSize:9,fontWeight:700}},"COMMISSIONS ACTIVES")), React.createElement('p',{style:{margin:0,fontSize:12,color:"#bbb"}},status.message||"")), ["urgent","grace"].includes(status.phase)&&React.createElement('div',{style:{display:"flex",gap:7,flexShrink:0}}, [[String(t.h).padStart(2,"0"),"H"],[String(t.m).padStart(2,"0"),"M"],[String(t.s).padStart(2,"0"),"S"]].map(([v,l])=> React.createElement('div',{key:l,style:{background:C.bg,border:`1px solid ${c.color}44`,borderRadius:9,padding:"7px 11px",textAlign:"center",minWidth:48}}, React.createElement('div',{style:{fontSize:20,fontWeight:900,color:c.color,fontVariantNumeric:"tabular-nums"}},v), React.createElement('div',{style:{fontSize:8,color:C.muted}},l))))), ["urgent","grace","expired"].includes(status.phase)&& React.createElement('button',{onClick:onRenew,style:{marginTop:12,background:`linear-gradient(90deg,${C.goldDark},${C.gold})`,border:"none",color:"#000",padding:"8px 22px",borderRadius:8,fontWeight:900,fontSize:12,cursor:"pointer"}},"Renouveler maintenant")); } // ════════════════════════════════════════════════════════════════════ // PAGES — toutes chargent les données depuis l'API // ════════════════════════════════════════════════════════════════════ function PageDashboard({dark,setPage}) { const {data,loading,error} = useApi('/dashboard'); if(loading) return React.createElement(Loader,{dark}); if(error) return React.createElement(ErrBox,{msg:`Impossible de charger le tableau de bord: ${error}`}); const {member,wallet,rank_progress,commission_stats,level_counts,referral,monthly_earnings} = data; const net = Object.values(level_counts||{}).reduce((a,b)=>a+Number(b),0); const rate = Number(cfg.exchangeRate||134); const exchangeEnabled = !!cfg.currencyConversionEnabled; return React.createElement('div',null, React.createElement('div',{style:{marginBottom:22}}, React.createElement('h2',{style:{margin:0,fontSize:20,fontWeight:800,color:dark?C.white:CL.white}},`Bonjour, ${member?.display_name||""}! 👋`), React.createElement('p',{style:{margin:"4px 0 0",fontSize:12,color:dark?C.muted:CL.muted}},"Vue d'ensemble de votre activité Konektez")), React.createElement(ExpiryBanner,{status:member,onRenew:()=>setPage("packs")}), // Carte membre React.createElement(Card,{gold:true,dark,style:{marginBottom:18,padding:"16px 20px"}}, React.createElement('div',{style:{display:"flex",alignItems:"center",justifyContent:"space-between",flexWrap:"wrap",gap:14}}, React.createElement('div',{style:{display:"flex",alignItems:"center",gap:14}}, React.createElement(Av,{name:member?.display_name,size:48,color:C.gold}), React.createElement('div',null, React.createElement('div',{style:{fontSize:16,fontWeight:800,color:dark?C.white:CL.white}},member?.display_name), React.createElement('div',{style:{display:"flex",gap:7,marginTop:4,flexWrap:"wrap"}}, React.createElement(StatusBadge,{s:member?.status}), React.createElement(Chip,{label:member?.pack_name||"Aucun pack",color:C.gold})))), React.createElement('div',{style:{display:"flex",gap:22,flexWrap:"wrap"}}, [["Pack",member?.pack_name||"—",C.gold],["Niveaux",member?.level_unlock||0,C.blue], ["Jours",member?.days_remaining||0,member?.days_remaining<=5?C.red:C.orange], ["Gains",member?.can_earn?"✓":"✗",member?.can_earn?C.green:C.red]].map(([l,v,c])=> React.createElement('div',{key:l,style:{textAlign:"center"}}, React.createElement('div',{style:{fontSize:16,fontWeight:900,color:c}},v), React.createElement('div',{style:{fontSize:9,color:dark?C.muted:CL.muted,textTransform:"uppercase",letterSpacing:1,marginTop:2}},l)))))), // KPIs React.createElement('div',{style:{display:"grid",gridTemplateColumns:"repeat(4,1fr)",gap:12,marginBottom:18}}, [["Total gagné",$f(commission_stats?.total),"earn",C.gold], ["Disponible",$f(wallet?.available),"wallet",C.green], ["Direct (L1)",$f(commission_stats?.direct_total),"earn",C.blue], ["Réseau",Nf(net),"tree",C.purple]].map(([label,val,icon,color])=> React.createElement('div',{key:label,style:{background:dark?C.surface:CL.surface,border:`1px solid ${dark?C.border:CL.border}`,borderRadius:13,padding:"16px 18px"}}, React.createElement('div',{style:{fontSize:10,color:dark?C.muted:CL.muted,textTransform:"uppercase",letterSpacing:1.5,marginBottom:8,fontWeight:600}},label), React.createElement('div',{style:{display:"flex",justifyContent:"space-between",alignItems:"flex-start"}}, React.createElement('div',{style:{fontSize:22,fontWeight:900,color:dark?C.white:CL.white}},val), React.createElement('div',{style:{width:28,height:28,borderRadius:7,background:`${color}18`,display:"flex",alignItems:"center",justifyContent:"center"}}, React.createElement(Icon,{d:IC[icon],size:14,color}))), exchangeEnabled&&label==="Disponible"&&wallet?.available>0&& React.createElement('div',{style:{fontSize:10,color:dark?C.muted:CL.muted,marginTop:3}},`≈ ${HTGf(wallet.available,rate)}`)))), // Graphique + niveaux React.createElement('div',{style:{display:"grid",gridTemplateColumns:"1fr 260px",gap:14,marginBottom:18}}, React.createElement(Card,{dark}, React.createElement('div',{style:{display:"flex",justifyContent:"space-between",marginBottom:10}}, React.createElement('span',{style:{fontWeight:700,color:dark?C.white:CL.white}},"Gains mensuels"), React.createElement(Chip,{label:"6 mois",color:C.gold})), React.createElement('div',{style:{background:dark?C.surface2:CL.surface2,borderRadius:9,padding:10}}, React.createElement(Sparkline,{data:monthly_earnings||[]}))), React.createElement(Card,{dark}, React.createElement('div',{style:{fontWeight:700,color:dark?C.white:CL.white,marginBottom:12}},"Réseau par niveau"), Object.entries(level_counts||{}).map(([lv,cnt])=> React.createElement('div',{key:lv,style:{display:"flex",alignItems:"center",gap:9,marginBottom:10}}, React.createElement('div',{style:{width:24,height:24,borderRadius:6,background:`${C.gold}15`,border:`1px solid ${C.gold}44`,display:"flex",alignItems:"center",justifyContent:"center",fontSize:9,fontWeight:800,color:C.gold,flexShrink:0}},`L${lv}`), React.createElement('div',{style:{flex:1}},React.createElement(Bar,{v:Number(cnt),max:Math.max(...Object.values(level_counts||{}).map(Number),1)})), React.createElement('span',{style:{fontSize:11,color:dark?C.muted:CL.muted,minWidth:18,textAlign:"right"}},cnt))))), // Lien de parrainage React.createElement(Card,{gold:true,dark}, React.createElement('div',{style:{display:"flex",alignItems:"center",justifyContent:"space-between",flexWrap:"wrap",gap:14}}, React.createElement('div',null, React.createElement('div',{style:{fontSize:10,color:dark?C.muted:CL.muted,textTransform:"uppercase",letterSpacing:2,marginBottom:6}},"Lien de parrainage"), React.createElement('div',{style:{display:"flex",alignItems:"center",gap:9,background:dark?C.bg:CL.bg,border:`1px solid ${C.gold}44`,borderRadius:8,padding:"7px 13px"}}, React.createElement(Icon,{d:IC.link,size:14,color:C.gold}), React.createElement('span',{style:{fontFamily:"monospace",color:C.gold,fontSize:12}},`${window.location.origin}/go/${referral?.referral_code||""}/`))), React.createElement('div',{style:{display:"flex",gap:20}}, [["Code",referral?.referral_code||"—",C.gold],["Clics",Nf(referral?.total_clicks),C.blue]].map(([l,v,c])=> React.createElement('div',{key:l,style:{textAlign:"center"}}, React.createElement('div',{style:{fontSize:18,fontWeight:900,color:c}},v), React.createElement('div',{style:{fontSize:9,color:dark?C.muted:CL.muted}},l))))))); } function PageGenealogy({dark}) { const {data,loading,error} = useApi('/genealogy?depth=3'); if(loading) return React.createElement(Loader,{dark}); if(error) return React.createElement(ErrBox,{msg:error}); function Node({node,depth=0}) { const [open,setOpen]=useState(depth<1); const sc=STATUS[node.status]||STATUS.inactive; return React.createElement('div',{style:{display:"flex",flexDirection:"column",alignItems:"center"}}, React.createElement('div',{onClick:()=>node.children?.length&&setOpen(o=>!o),style:{background:dark?C.surface:CL.surface,border:`1.5px solid ${node.rank_color||C.gold}44`,borderRadius:12,padding:"10px 13px",minWidth:130,maxWidth:155,cursor:node.children?.length?"pointer":"default",userSelect:"none",position:"relative"}}, React.createElement('div',{style:{display:"flex",alignItems:"center",gap:7,marginBottom:6}}, React.createElement(Av,{name:node.name,size:30,color:node.rank_color||C.gold}), React.createElement('div',{style:{flex:1,minWidth:0}}, React.createElement('div',{style:{fontSize:10,fontWeight:700,color:dark?C.white:CL.white,whiteSpace:"nowrap",overflow:"hidden",textOverflow:"ellipsis"}},node.name), React.createElement(Chip,{label:node.rank_name||"Starter",color:node.rank_color||C.gold,tiny:true}))), React.createElement('div',{style:{fontSize:9,color:dark?C.muted:CL.muted,display:"flex",gap:6}}, React.createElement('span',null,`${Nf(node.personal_pv||0)} PV`), React.createElement('span',{style:{color:sc.color}},sc.dot)), node.children?.length>0&&React.createElement('div',{style:{position:"absolute",top:6,right:7,color:node.rank_color,fontSize:9,fontWeight:700}},`${open?"▲":"▼"} ${node.children.length}`)), open&&node.children?.length>0&&React.createElement('div',{style:{paddingTop:20,position:"relative"}}, React.createElement('div',{style:{position:"absolute",top:0,left:"50%",width:1,height:20,background:`${C.gold}33`}}), React.createElement('div',{style:{display:"flex",gap:16}}, node.children.map(c=>React.createElement('div',{key:c.id,style:{display:"flex",flexDirection:"column",alignItems:"center"}}, React.createElement('div',{style:{width:1,height:20,background:`${C.gold}22`}}), React.createElement(Node,{node:c,depth:depth+1})))))); } return React.createElement('div',null, React.createElement('h2',{style:{margin:"0 0 20px",fontSize:20,fontWeight:800,color:dark?C.white:CL.white}},"Généalogie"), React.createElement(Card,{dark,style:{overflowX:"auto",minHeight:380,padding:28}}, React.createElement('div',{style:{display:"flex",justifyContent:"center",minWidth:"fit-content"}}, data&&React.createElement(Node,{node:data})))); } function PageEarnings({dark}) { const {data:stats,loading:ls} = useApi('/commissions/stats'); const {data:list,loading:ll} = useApi('/commissions?limit=20'); const {data:conf,loading:lc} = useApi('/settings'); if(ls||ll||lc) return React.createElement(Loader,{dark}); const tc={direct:C.green,level:C.blue,rank_bonus:C.gold,product:C.purple}; return React.createElement('div',null, React.createElement('h2',{style:{margin:"0 0 20px",fontSize:20,fontWeight:800,color:dark?C.white:CL.white}},"Gains & Commissions"), React.createElement('div',{style:{display:"grid",gridTemplateColumns:"repeat(4,1fr)",gap:12,marginBottom:18}}, [["Total",$f(stats?.total)],[" Direct",$f(stats?.direct_total)],["Niveaux",$f(stats?.level_total)],["Bonus rang",$f(stats?.rank_bonus_total)]].map(([l,v])=> React.createElement('div',{key:l,style:{background:dark?C.surface:CL.surface,border:`1px solid ${dark?C.border:CL.border}`,borderRadius:13,padding:"16px 18px"}}, React.createElement('div',{style:{fontSize:10,color:dark?C.muted:CL.muted,textTransform:"uppercase",letterSpacing:1.5,marginBottom:8}},l), React.createElement('div',{style:{fontSize:22,fontWeight:900,color:dark?C.white:CL.white}},v)))), conf?.levels&&React.createElement(Card,{dark,style:{marginBottom:14}}, React.createElement('div',{style:{display:"flex",alignItems:"center",justifyContent:"space-between",marginBottom:12}}, React.createElement('span',{style:{fontWeight:700,color:dark?C.white:CL.white}},"Structure des commissions"), React.createElement('span',{style:{fontSize:11,color:dark?C.muted:CL.muted}},`Plafond : `,React.createElement('strong',{style:{color:C.gold}},`${conf?.commission_cap_pct||40}%`))), React.createElement('div',{style:{display:"grid",gridTemplateColumns:"repeat(7,1fr)",gap:8}}, (conf.levels||[]).map(l=> React.createElement('div',{key:l.level,style:{background:l.is_active?(dark?C.surface2:CL.surface2):(dark?C.bg:CL.bg),border:`1px solid ${l.is_active?C.gold+"33":(dark?C.border:CL.border)}`,borderRadius:9,padding:"10px 0",textAlign:"center",opacity:l.is_active?1:.4}}, React.createElement('div',{style:{fontSize:9,color:dark?C.muted:CL.muted,marginBottom:2}},`L${l.level}`), React.createElement('div',{style:{fontSize:14,fontWeight:900,color:l.is_active?C.gold:C.dim}},`${l.rate}%`), React.createElement('div',{style:{fontSize:8,color:dark?C.muted:CL.muted,marginTop:2}},l.unlocked_by==="starter"?"Starter":"Pro"))))), React.createElement(Card,{dark}, React.createElement('div',{style:{fontWeight:700,color:dark?C.white:CL.white,marginBottom:12}},"Historique"), React.createElement('div',{style:{overflowX:"auto"}}, React.createElement('table',{style:{width:"100%",borderCollapse:"collapse"}}, React.createElement('thead',null,React.createElement('tr',{style:{borderBottom:`1px solid ${dark?C.border:CL.border}`}}, ["Source","Niv","Type","Taux","Montant","Date"].map(h=>React.createElement('th',{key:h,style:{padding:"7px 12px",textAlign:"left",fontSize:9,color:dark?C.muted:CL.muted,textTransform:"uppercase",letterSpacing:1.2,fontWeight:600}},h)))), React.createElement('tbody',null,(list||[]).map((c,i)=> React.createElement('tr',{key:c.id,style:{borderBottom:`1px solid ${dark?C.border:CL.border}22`}}, React.createElement('td',{style:{padding:"10px 12px",color:dark?"#bbb":CL.white,fontSize:12}},c.source_name||c.source), React.createElement('td',{style:{padding:"10px 12px"}},React.createElement(Chip,{label:`L${c.level}`,color:C.gold,tiny:true})), React.createElement('td',{style:{padding:"10px 12px"}},React.createElement(Chip,{label:c.type,color:tc[c.type]||"#888",tiny:true})), React.createElement('td',{style:{padding:"10px 12px",color:dark?C.muted:CL.muted,fontSize:11}},`${c.commission_rate}%`), React.createElement('td',{style:{padding:"10px 12px",color:C.green,fontWeight:800}},`+${$f(c.amount)}`), React.createElement('td',{style:{padding:"10px 12px",color:dark?C.dim:CL.muted,fontSize:10}},c.created_at))))))); } function PagePacks({dark,setPage}) { const {data:packs,loading:lp} = useApi('/packs'); const {data:status,loading:ls} = useApi('/status'); const {data:wallet,loading:lw} = useApi('/wallet'); const [sel,setSel]=useState(null); const [method,setMethod]=useState("moncash"); const [done,setDone]=useState(false); const [buying,setBuying]=useState(false); const [err,setErr]=useState(""); useEffect(()=>{ if(packs?.length&&!sel) setSel(packs.find(p=>p.id===(status?.pack_id||0))?.id||packs[0]?.id); },[packs,status]); if(lp||ls||lw) return React.createElement(Loader,{dark}); const selPack = (packs||[]).find(p=>p.id===sel); async function buy() { setBuying(true); setErr(""); try { await api('/packs/purchase',{method:"POST",body:{pack_id:sel,payment_method:method}}); setDone(true); } catch(e){ setErr(e.message); } finally{ setBuying(false); } } const canPayWallet = method==="wallet" && wallet?.available >= (selPack?.price||0); return React.createElement('div',null, React.createElement('h2',{style:{margin:"0 0 20px",fontSize:20,fontWeight:800,color:dark?C.white:CL.white}},"Packs d'adhésion"), React.createElement('div',{style:{display:"grid",gridTemplateColumns:"repeat(auto-fill,minmax(280px,1fr))",gap:16,marginBottom:22}}, (packs||[]).map(p=>{ const isSel=sel===p.id, isCur=status?.pack_id===p.id; return React.createElement('div',{key:p.id,onClick:()=>setSel(p.id),style:{background:isSel?`linear-gradient(135deg,#141408,#1e1c00)`:dark?C.surface:CL.surface,border:`1.5px solid ${isSel?C.gold:p.is_popular?C.gold+"44":dark?C.border:CL.border}`,borderRadius:16,padding:22,cursor:"pointer",position:"relative",transform:isSel?"translateY(-3px)":"none",transition:"all 0.2s",boxShadow:isSel?`0 6px 24px ${C.gold}18`:"none"}}, p.is_popular&&React.createElement('div',{style:{position:"absolute",top:-10,right:16,background:`linear-gradient(90deg,${C.goldDark},${C.gold})`,color:"#000",padding:"2px 12px",borderRadius:20,fontSize:9,fontWeight:800,letterSpacing:1.5}},"POPULAIRE"), isCur&&React.createElement('div',{style:{position:"absolute",top:-10,left:16,background:C.green,color:"#000",padding:"2px 12px",borderRadius:20,fontSize:9,fontWeight:800}},"ACTUEL"), React.createElement('div',null, React.createElement('div',{style:{fontSize:10,color:dark?C.muted:CL.muted,textTransform:"uppercase",letterSpacing:2}},p.name), React.createElement('div',{style:{fontSize:32,fontWeight:900,color:isSel?C.gold:dark?C.white:CL.white}},`$${p.price}`), React.createElement('div',{style:{fontSize:10,color:dark?C.muted:CL.muted}},`${Nf(p.pv_value)} PV · ${p.duration_days}j · ${p.level_unlock} niveaux`)), React.createElement('div',{style:{borderTop:`1px solid ${dark?C.border:CL.border}`,paddingTop:12,marginTop:12}}, (p.features||[]).map((f,i)=> React.createElement('div',{key:i,style:{display:"flex",alignItems:"center",gap:7,marginBottom:6,fontSize:11,color:dark?"#bbb":CL.muted}}, React.createElement(Icon,{d:IC.check,size:12,color:C.gold}),f)))); })), React.createElement(Card,{dark}, React.createElement('div',{style:{fontWeight:700,color:dark?C.white:CL.white,marginBottom:14}},"Méthode de paiement"), React.createElement('div',{style:{display:"flex",gap:9,marginBottom:16,flexWrap:"wrap"}}, [["wallet","Portefeuille",C.gold],["moncash","MonCash","#FF6B00"],["natcash","NatCash","#0072CE"],["stripe","Carte","#60A5FA"],["usdt","USDT","#26A17B"]].map(([v,l,c])=> React.createElement('button',{key:v,onClick:()=>setMethod(v),style:{flex:1,minWidth:80,padding:"10px 0",background:method===v?`${c}18`:"transparent",border:`1.5px solid ${method===v?c:dark?C.border:CL.border}`,color:method===v?c:dark?C.muted:CL.muted,borderRadius:8,cursor:"pointer",fontWeight:700,fontSize:11}},l))), method==="wallet"&&React.createElement('div',{style:{background:`${canPayWallet?C.green:C.red}18`,border:`1px solid ${canPayWallet?C.green:C.red}44`,borderRadius:8,padding:12,marginBottom:14}}, React.createElement('div',{style:{display:"flex",justifyContent:"space-between",fontSize:12,marginBottom:4}}, React.createElement('span',{style:{color:dark?C.muted:CL.muted}},"Solde disponible"), React.createElement('span',{style:{fontWeight:800,color:canPayWallet?C.green:C.red}},$f(wallet?.available))), React.createElement('div',{style:{display:"flex",justifyContent:"space-between",fontSize:12}}, React.createElement('span',{style:{color:dark?C.muted:CL.muted}},"Coût du pack"), React.createElement('span',{style:{fontWeight:800,color:dark?"#ccc":CL.muted}},$f(selPack?.price))), !canPayWallet&&React.createElement('div',{style:{fontSize:11,color:C.red,marginTop:6}},`Solde insuffisant — il manque ${$f((selPack?.price||0)-(wallet?.available||0))}`)), method==="usdt"&&React.createElement('div',{style:{background:dark?C.bg:CL.bg,border:"1px solid #26A17B44",borderRadius:9,padding:12,marginBottom:14}}, React.createElement('div',{style:{fontSize:10,color:dark?C.muted:CL.muted,marginBottom:5}},"Adresse USDT (TRC20)"), React.createElement('div',{style:{fontFamily:"monospace",color:"#26A17B",fontSize:12,wordBreak:"break-all"}},cfg.usdtAddress||"—")), err&&React.createElement(ErrBox,{msg:err}), done ?React.createElement('div',{style:{padding:12,background:"#0a1a0833",border:`1px solid ${C.green}44`,borderRadius:8,fontSize:12,color:C.green}},method==="wallet"?"✓ Pack renouvelé depuis votre portefeuille !":"✓ Commande initiée ! Activation sous peu.") :React.createElement('button',{onClick:buy,disabled:buying||(method==="wallet"&&!canPayWallet),style:{background:(method==="wallet"&&!canPayWallet)?dark?C.surface2:CL.surface2:`linear-gradient(90deg,${C.goldDark},${C.gold})`,border:"none",color:(method==="wallet"&&!canPayWallet)?C.muted:"#000",padding:"12px 36px",borderRadius:10,fontWeight:900,fontSize:13,cursor:buying||(method==="wallet"&&!canPayWallet)?"not-allowed":"pointer"}}, buying?"Traitement...":method==="wallet"?`Payer $${selPack?.price||0} avec mon solde`:`Acheter ${selPack?.name||""} — $${selPack?.price||0}`))); } function PageRanks({dark}) { const {data:ranks,loading:lr} = useApi('/ranks'); const {data:prog, loading:lp} = useApi('/rank/progress'); if(lr||lp) return React.createElement(Loader,{dark}); const cur = prog?.current_rank||{}; const next = prog?.next_rank||null; const curIdx = (ranks||[]).findIndex(r=>r.name===cur.name); return React.createElement('div',null, React.createElement('h2',{style:{margin:"0 0 20px",fontSize:20,fontWeight:800,color:dark?C.white:CL.white}},"Rangs"), React.createElement(Card,{gold:true,dark,style:{marginBottom:18}}, React.createElement('div',{style:{display:"flex",alignItems:"center",gap:18,flexWrap:"wrap"}}, React.createElement('div',{style:{width:64,height:64,borderRadius:"50%",background:`linear-gradient(135deg,${C.goldDark},${C.gold})`,display:"flex",alignItems:"center",justifyContent:"center",flexShrink:0}}, React.createElement(Icon,{d:IC.rank,size:28,color:"#000"})), React.createElement('div',{style:{flex:1}}, React.createElement('div',{style:{fontSize:10,color:dark?C.muted:CL.muted,textTransform:"uppercase",letterSpacing:2,marginBottom:3}},"Rang actuel"), React.createElement('div',{style:{fontSize:28,fontWeight:900,color:cur.badge_color||C.gold}},cur.name||"—"), next&&React.createElement('div',{style:{fontSize:11,color:dark?C.muted:CL.muted}},"Prochain : ",React.createElement('strong',{style:{color:next.badge_color}},next.name))), React.createElement('div',{style:{display:"flex",gap:18,flexWrap:"wrap"}}, [["PV Personnel",prog?.personal_pv,next?.min_pv],["PV Équipe",prog?.team_pv,next?.min_team_pv],["Directs",prog?.direct_count,next?.min_directs]].map(([l,v,m])=> m&&React.createElement('div',{key:l,style:{minWidth:120}}, React.createElement('div',{style:{fontSize:10,color:dark?C.muted:CL.muted,marginBottom:4}},l), React.createElement(Bar,{v:Number(v||0),max:Number(m||1)}), React.createElement('div',{style:{fontSize:10,color:dark?"#aaa":CL.muted,marginTop:3}},`${Nf(v||0)} / ${Nf(m)}`)))))), React.createElement('div',{style:{display:"grid",gridTemplateColumns:"repeat(auto-fill,minmax(150px,1fr))",gap:10}}, (ranks||[]).map((r,i)=>{ const isCur=r.name===cur.name, done=i React.createElement('button',{key:v,onClick:()=>setTab(v),style:{padding:"8px 16px",background:tab===v?`${C.gold}15`:"transparent",border:`1.5px solid ${tab===v?C.gold:dark?C.border:CL.border}`,color:tab===v?C.gold:dark?C.muted:CL.muted,borderRadius:8,cursor:"pointer",fontWeight:700,fontSize:12}},l)))), React.createElement(Card,{gold:true,dark,style:{marginBottom:14,padding:"16px 20px"}}, React.createElement('div',{style:{fontSize:10,color:dark?C.muted:CL.muted,textTransform:"uppercase",letterSpacing:2,marginBottom:4}},"Solde disponible"), React.createElement('div',{style:{fontSize:34,fontWeight:900,color:C.gold}},$f(wallet?.available)), exchangeEnabled&&React.createElement('div',{style:{fontSize:12,color:dark?C.muted:CL.muted,marginTop:2}},`≈ ${HTGf(wallet?.available,rate)} (taux $1 = HTG ${rate})`), React.createElement('div',{style:{display:"flex",gap:20,marginTop:10}}, [["Total gagné",$f(wallet?.total_earned)],["Total retiré",$f(wallet?.total_withdrawn)]].map(([l,v])=> React.createElement('div',{key:l},React.createElement('div',{style:{fontSize:9,color:dark?C.muted:CL.muted}},l),React.createElement('div',{style:{color:dark?"#bbb":CL.muted,fontWeight:700,fontSize:12}},v))))), tab==="withdraw"?React.createElement('div',{style:{display:"grid",gridTemplateColumns:"1fr 320px",gap:16}}, React.createElement(Card,{dark}, React.createElement('div',{style:{fontWeight:700,color:dark?C.white:CL.white,marginBottom:14}},"Nouvelle demande"), React.createElement('div',{style:{display:"flex",gap:8,marginBottom:14,flexWrap:"wrap"}}, [["moncash","MonCash (Digicel)","#FF6B00"],["natcash","NatCash (Natcom)","#0072CE"],["bank_transfer","Virement","#60A5FA"]].map(([v,l,c])=> React.createElement('button',{key:v,onClick:()=>setMethod(v),style:{flex:"1 1 100px",padding:"9px 4px",background:method===v?`${c}18`:"transparent",border:`1.5px solid ${method===v?c:dark?C.border:CL.border}`,color:method===v?c:dark?C.muted:CL.muted,borderRadius:8,cursor:"pointer",fontWeight:700,fontSize:11}},l))), (method==="moncash"||method==="natcash")&&React.createElement('div',{style:{marginBottom:12}}, React.createElement('div',{style:{fontSize:10,color:dark?C.muted:CL.muted,marginBottom:5}},`Numéro ${method==="moncash"?"MonCash":"NatCash"} (509XXXXXXXX)`), React.createElement('input',{type:"tel",value:phone,onChange:e=>setPhone(e.target.value),placeholder:"509XXXXXXXX",style:{width:"100%",background:dark?C.bg:CL.bg,border:`1px solid ${dark?C.border:CL.border}`,color:dark?C.white:CL.white,padding:"10px 12px",borderRadius:8,fontSize:13,outline:"none",boxSizing:"border-box"}})), React.createElement('div',{style:{marginBottom:6}}, React.createElement('div',{style:{fontSize:10,color:dark?C.muted:CL.muted,marginBottom:5}},"Montant ($)"), React.createElement('input',{type:"number",value:amount,onChange:e=>setAmount(e.target.value),placeholder:"0.00",style:{width:"100%",background:dark?C.bg:CL.bg,border:`1px solid ${C.gold}33`,color:dark?C.white:CL.white,padding:"11px 12px",borderRadius:8,fontSize:16,fontWeight:700,outline:"none",boxSizing:"border-box"}})), exchangeEnabled&&Number(amount)>0&&React.createElement('div',{style:{fontSize:11,color:dark?C.muted:CL.muted,marginBottom:10}},`≈ ${HTGf(amount,rate)}`), Number(amount)>0&&React.createElement('div',{style:{background:dark?C.bg:CL.bg,border:`1px solid ${C.gold}22`,borderRadius:8,padding:12,marginBottom:14}}, [[$f(amount),"Montant"],[`-${$f(fee)}`,"Frais"],[$f(net),"Vous recevez"]].map(([v,l],i)=> React.createElement('div',{key:l,style:{display:"flex",justifyContent:"space-between",marginBottom:i<2?6:0,paddingTop:i===2?7:0,borderTop:i===2?`1px solid ${dark?C.border:CL.border}`:"none"}}, React.createElement('span',{style:{fontSize:11,color:dark?C.muted:CL.muted}},l), React.createElement('span',{style:{fontWeight:i===2?900:600,color:i===2?C.gold:dark?"#bbb":CL.muted,fontSize:i===2?14:11}},v))), exchangeEnabled&&net>0&&React.createElement('div',{style:{display:"flex",justifyContent:"space-between",marginTop:6,paddingTop:6,borderTop:`1px solid ${dark?C.border:CL.border}`}}, React.createElement('span',{style:{fontSize:11,color:dark?C.muted:CL.muted}},"≈ en HTG"), React.createElement('span',{style:{fontWeight:700,color:dark?"#bbb":CL.muted,fontSize:12}},HTGf(net,rate)))), err&&React.createElement(ErrBox,{msg:err}), done&&React.createElement('div',{style:{padding:10,background:"#0a1a0833",border:`1px solid ${C.green}44`,borderRadius:8,fontSize:11,color:C.green,marginBottom:10}},"✓ Demande soumise ! Traitement sous 24-48h."), React.createElement('button',{onClick:submitWithdrawal,disabled:loading2||Number(amount)<10,style:{width:"100%",background:Number(amount)<10?dark?C.surface2:CL.surface2:`linear-gradient(90deg,${C.goldDark},${C.gold})`,border:"none",color:Number(amount)<10?C.muted:"#000",padding:"12px 0",borderRadius:10,fontWeight:900,fontSize:13,cursor:Number(amount)<10?"not-allowed":"pointer"}},loading2?"Traitement...":"Demander le retrait")), React.createElement(Card,{dark}, React.createElement('div',{style:{fontWeight:700,color:dark?C.white:CL.white,marginBottom:12}},"Historique"), (wlist||[]).length===0&&React.createElement('div',{style:{fontSize:12,color:dark?C.muted:CL.muted}},"Aucun retrait."), (wlist||[]).map(w=>React.createElement('div',{key:w.id,style:{padding:"12px 0",borderBottom:`1px solid ${dark?C.border:CL.border}22`,display:"flex",alignItems:"center",gap:10}}, React.createElement('div',{style:{flex:1}}, React.createElement('div',{style:{fontSize:13,fontWeight:700,color:dark?C.white:CL.white}},$f(w.amount)), React.createElement('div',{style:{fontSize:9,color:dark?C.muted:CL.muted,marginTop:2}},`${w.method} · ${w.created_at?.slice(0,10)||""}`)), React.createElement('div',{style:{textAlign:"right"}}, React.createElement('div',{style:{fontSize:11,fontWeight:700,color:dark?"#aaa":CL.muted}},`Net: ${$f(w.net_amount)}`), React.createElement('span',{style:{fontSize:9,color:statusColors[w.status]||"#888",fontWeight:700}},`● ${w.status}`)))))) :React.createElement(Card,{dark}, React.createElement('div',{style:{fontWeight:700,color:dark?C.white:CL.white,marginBottom:6}},"Envoyer à un affilié"), React.createElement('div',{style:{display:"flex",gap:8,marginBottom:12}}, React.createElement('input',{value:recCode,onChange:e=>{setRecCode(e.target.value.toUpperCase());setRecipient(null);setLookupErr("");},placeholder:"Code de parrainage",style:{flex:1,background:dark?C.bg:CL.bg,border:`1px solid ${dark?C.border:CL.border}`,color:dark?C.white:CL.white,padding:"10px 12px",borderRadius:8,fontSize:13,outline:"none",fontFamily:"monospace"}}), React.createElement('button',{onClick:lookupRecipient,style:{background:`${C.gold}15`,border:`1px solid ${C.gold}44`,color:C.gold,padding:"0 16px",borderRadius:8,cursor:"pointer",fontWeight:700,fontSize:12}},"Vérifier")), lookupErr&&React.createElement('div',{style:{fontSize:11,color:C.red,marginBottom:10}},lookupErr), recipient&&React.createElement('div',{style:{display:"flex",alignItems:"center",gap:10,marginBottom:12,background:"#0a1a0833",border:`1px solid ${C.green}44`,borderRadius:8,padding:"8px 12px"}}, React.createElement(Av,{name:recipient.display_name,size:32,color:C.green}), React.createElement('div',null, React.createElement('div',{style:{fontSize:12,fontWeight:700,color:dark?C.white:CL.white}},recipient.display_name), recipient.rank&&React.createElement(Chip,{label:recipient.rank,color:C.green,tiny:true}))), React.createElement('div',{style:{marginBottom:10}}, React.createElement('div',{style:{fontSize:10,color:dark?C.muted:CL.muted,marginBottom:5}},"Montant ($)"), React.createElement('input',{type:"number",value:tAmount,onChange:e=>setTAmount(e.target.value),placeholder:"0.00",style:{width:"100%",background:dark?C.bg:CL.bg,border:`1px solid ${C.gold}33`,color:dark?C.white:CL.white,padding:"11px 12px",borderRadius:8,fontSize:16,fontWeight:700,outline:"none",boxSizing:"border-box"}}), exchangeEnabled&&Number(tAmount)>0&&React.createElement('div',{style:{fontSize:10,color:dark?C.muted:CL.muted,marginTop:3}},`≈ ${HTGf(tAmount,rate)}`)), React.createElement('input',{value:tNote,onChange:e=>setTNote(e.target.value),placeholder:"Note optionnelle...",maxLength:100,style:{width:"100%",background:dark?C.bg:CL.bg,border:`1px solid ${dark?C.border:CL.border}`,color:dark?C.white:CL.white,padding:"9px 12px",borderRadius:8,fontSize:12,outline:"none",boxSizing:"border-box",marginBottom:10}}), Number(tAmount)>0&&React.createElement('div',{style:{background:dark?C.bg:CL.bg,border:`1px solid ${C.gold}22`,borderRadius:8,padding:12,marginBottom:12}}, [[$f(tAmount),"Envoyé"],[`+${$f(tFee)}`,"Frais (1%)",],[$f(tTotal),"Débité de vous"]].map(([v,l],i)=> React.createElement('div',{key:l,style:{display:"flex",justifyContent:"space-between",marginBottom:i<2?5:0,paddingTop:i===2?6:0,borderTop:i===2?`1px solid ${dark?C.border:CL.border}`:"none"}}, React.createElement('span',{style:{fontSize:11,color:dark?C.muted:CL.muted}},l), React.createElement('span',{style:{fontWeight:i===2?900:600,color:i===2?C.gold:dark?"#bbb":CL.muted}},v)))), tErr&&React.createElement(ErrBox,{msg:tErr}), tDone&&React.createElement('div',{style:{padding:10,background:"#0a1a0833",border:`1px solid ${C.green}44`,borderRadius:8,fontSize:11,color:C.green,marginBottom:10}},`✓ Transfert envoyé à ${recipient?.display_name||""}!`), React.createElement('button',{onClick:submitTransfer,disabled:tLoading||!recipient||Number(tAmount)<1,style:{width:"100%",background:(!recipient||Number(tAmount)<1)?dark?C.surface2:CL.surface2:`linear-gradient(90deg,${C.goldDark},${C.gold})`,border:"none",color:(!recipient||Number(tAmount)<1)?C.muted:"#000",padding:"12px 0",borderRadius:10,fontWeight:900,fontSize:13,cursor:"pointer"}},tLoading?"Envoi...":"Envoyer"))); } function PageShop({dark}) { const {data,loading,error} = useApi('/shop'); const [copied,setCopied]=useState(false); if(loading) return React.createElement(Loader,{dark}); if(error) return React.createElement(ErrBox,{msg:error}); const copy=t=>{ navigator.clipboard?.writeText(t); setCopied(true); setTimeout(()=>setCopied(false),2000); }; return React.createElement('div',null, React.createElement('h2',{style:{margin:"0 0 20px",fontSize:20,fontWeight:800,color:dark?C.white:CL.white}},"Ma Boutique"), React.createElement(Card,{gold:true,dark,style:{marginBottom:14}}, React.createElement('div',{style:{display:"flex",alignItems:"flex-start",justifyContent:"space-between",flexWrap:"wrap",gap:16}}, React.createElement('div',{style:{flex:1}}, React.createElement('div',{style:{fontSize:10,color:dark?C.muted:CL.muted,textTransform:"uppercase",letterSpacing:2,marginBottom:7}},"URL de votre boutique"), React.createElement('div',{style:{display:"flex",alignItems:"center",gap:8,background:dark?C.bg:CL.bg,border:`1px solid ${C.gold}44`,borderRadius:8,padding:"8px 12px"}}, React.createElement(Icon,{d:IC.shop,size:14,color:C.gold}), React.createElement('span',{style:{fontFamily:"monospace",color:C.gold,fontSize:12,flex:1}},data?.url||"—"), React.createElement('button',{onClick:()=>copy(data?.url||""),style:{background:"none",border:"none",color:copied?C.green:dark?C.muted:CL.muted,cursor:"pointer",padding:0}}, React.createElement(Icon,{d:copied?IC.check:IC.copy,size:14})))), React.createElement('div',{style:{display:"flex",gap:20}}, [[Nf(data?.total_orders),"Commandes"],[$f(data?.total_revenue),"CA"]].map(([v,l])=> React.createElement('div',{key:l,style:{textAlign:"center"}}, React.createElement('div',{style:{fontSize:20,fontWeight:900,color:C.gold}},v), React.createElement('div',{style:{fontSize:9,color:dark?C.muted:CL.muted}},l)))))), data?.coupon&&React.createElement(Card,{dark}, React.createElement('div',{style:{fontWeight:700,color:dark?C.white:CL.white,marginBottom:12}},"Mon Coupon Affilié"), React.createElement('div',{style:{background:dark?C.bg:CL.bg,border:`1px solid ${C.gold}44`,borderRadius:8,padding:"10px 14px",marginBottom:10}}, React.createElement('div',{style:{fontSize:26,fontWeight:900,color:C.gold,letterSpacing:2,fontFamily:"monospace"}},data.coupon.code), React.createElement('div',{style:{fontSize:10,color:dark?C.muted:CL.muted,marginTop:3}},`${data.coupon.discount_value}% de réduction · ${data.coupon.commission_pct}% de commission`)), React.createElement('button',{onClick:()=>copy(data.coupon.code),style:{background:`${C.gold}15`,border:`1px solid ${C.gold}44`,color:C.gold,padding:"8px 0",borderRadius:7,cursor:"pointer",fontWeight:700,fontSize:11,width:"100%"}},copied?"Copié !":"Copier le code"))); } function PageStatus({dark,setPage}) { const {data,loading,error} = useApi('/status'); if(loading) return React.createElement(Loader,{dark}); if(error) return React.createElement(ErrBox,{msg:error}); const st = data?.member||data||{}; const sc = STATUS[st.status]||STATUS.inactive; return React.createElement('div',null, React.createElement('h2',{style:{margin:"0 0 20px",fontSize:20,fontWeight:800,color:dark?C.white:CL.white}},"Statut du compte"), React.createElement(ExpiryBanner,{status:data?.countdown||st,onRenew:()=>setPage("packs")}), React.createElement('div',{style:{display:"grid",gridTemplateColumns:"1fr 1fr",gap:16}}, React.createElement(Card,{gold:true,dark}, React.createElement('div',{style:{fontSize:10,color:dark?C.muted:CL.muted,textTransform:"uppercase",letterSpacing:2,marginBottom:10}},"Statut actuel"), React.createElement('div',{style:{display:"flex",alignItems:"center",gap:14,marginBottom:14}}, React.createElement('div',{style:{width:56,height:56,borderRadius:"50%",background:`${sc.color}15`,border:`2px solid ${sc.color}`,display:"flex",alignItems:"center",justifyContent:"center",fontSize:22,color:sc.color}},sc.dot), React.createElement('div',null, React.createElement('div',{style:{fontSize:26,fontWeight:900,color:sc.color}},sc.label), React.createElement('div',{style:{fontSize:11,color:dark?C.muted:CL.muted}},st.can_earn?"Commissions actives":"Commissions bloquées"))), React.createElement('div',{style:{display:"grid",gridTemplateColumns:"1fr 1fr",gap:9}}, [["Activé le",st.activation_date?.slice(0,10)||"—"], ["Expire le",st.expiry_date?.slice(0,10)||"—"], ["Jours restants",`${st.days_remaining||0}j`], ["Auto-renew",st.auto_renew?"Activé":"Désactivé"]].map(([l,v])=> React.createElement('div',{key:l,style:{background:dark?C.bg:CL.bg,borderRadius:7,padding:"9px 11px"}}, React.createElement('div',{style:{fontSize:9,color:dark?C.muted:CL.muted,marginBottom:2}},l), React.createElement('div',{style:{fontWeight:700,color:dark?"#bbb":CL.muted,fontSize:11}},v))))), React.createElement(Card,{dark}, React.createElement('div',{style:{fontWeight:700,color:dark?C.white:CL.white,marginBottom:14}},"Pack actif & niveaux"), React.createElement('div',{style:{fontSize:24,fontWeight:900,color:C.gold}},st.pack_name||"—"), React.createElement('div',{style:{fontSize:11,color:dark?C.muted:CL.muted,marginBottom:12}},`$${st.pack_price||0} · ${st.level_unlock||0} niveaux`), React.createElement('div',{style:{display:"flex",gap:6,flexWrap:"wrap",marginBottom:16}}, [1,2,3,4,5,6,7].map(l=>{ const unlocked=l<=(st.level_unlock||0); return React.createElement('div',{key:l,style:{width:30,height:30,borderRadius:7,background:unlocked?`${C.gold}15`:dark?C.bg:CL.bg,border:`1px solid ${unlocked?C.gold:dark?C.dim:CL.dim}`,display:"flex",alignItems:"center",justifyContent:"center",fontSize:10,fontWeight:800,color:unlocked?C.gold:dark?C.dim:CL.dim}},`L${l}`);})), React.createElement('button',{onClick:()=>setPage("packs"),style:{width:"100%",background:`linear-gradient(90deg,${C.goldDark},${C.gold})`,border:"none",color:"#000",padding:"11px 0",borderRadius:9,fontWeight:800,fontSize:12,cursor:"pointer"}}, st.status==="active"?"Renouveler mon pack":"Activer / Renouveler")))); } function PageBadge({dark}) { const {data,loading,error} = useApi('/dashboard'); const [gen,setGen]=useState(false); const [busy,setBusy]=useState(false); if(loading) return React.createElement(Loader,{dark}); const member=data?.member||{}; const rc = data?.rank_progress?.current_rank?.badge_color||C.gold; async function generate() { setBusy(true); try { await api('/badge/generate',{method:"POST",body:{member_id:member.id}}); setGen(true); } catch(e){ setGen(true); } // fallback: show preview even if API fails finally{ setBusy(false); } } return React.createElement('div',null, React.createElement('h2',{style:{margin:"0 0 20px",fontSize:20,fontWeight:800,color:dark?C.white:CL.white}},"Mon Badge"), React.createElement('div',{style:{display:"grid",gridTemplateColumns:"1fr 300px",gap:16,alignItems:"start"}}, React.createElement(Card,{dark}, React.createElement('div',{style:{fontWeight:700,color:dark?C.white:CL.white,marginBottom:16}},"Aperçu"), React.createElement('div',{style:{aspectRatio:"1",maxWidth:280,margin:"0 auto",background:`radial-gradient(circle at 30% 30%,#141408,${dark?C.bg:CL.bg})`,border:`3px solid ${rc}`,borderRadius:"50%",display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",gap:10}}, React.createElement(Av,{name:member.display_name||"?",size:88,color:rc}), React.createElement('div',{style:{textAlign:"center",padding:"0 16px"}}, React.createElement('div',{style:{fontSize:15,fontWeight:900,color:dark?C.white:CL.white}},member.display_name||"—"), React.createElement('div',{style:{fontSize:10,color:rc,fontWeight:700,letterSpacing:3,textTransform:"uppercase",marginTop:2}},`Rang ${member.rank_name||"—"}`), React.createElement('div',{style:{fontSize:9,color:dark?C.muted:CL.muted,marginTop:2}},cfg.brandName||"Konektez")), React.createElement('div',{style:{background:`${rc}15`,border:`1px solid ${rc}44`,padding:"2px 16px",borderRadius:20,fontSize:9,color:rc,textTransform:"uppercase",letterSpacing:2,fontWeight:700}},member.rank_name||"—")), React.createElement('div',{style:{display:"flex",gap:9,marginTop:18}}, React.createElement('button',{onClick:generate,style:{flex:1,background:`linear-gradient(90deg,${C.goldDark},${C.gold})`,border:"none",color:"#000",padding:"11px 0",borderRadius:8,fontWeight:800,cursor:"pointer",fontSize:12}},busy?"Génération...":(gen?"Régénérer":"Générer le badge")), gen&&React.createElement('button',{style:{background:dark?C.surface2:CL.surface2,border:`1px solid ${C.gold}44`,color:C.gold,padding:"11px 12px",borderRadius:8,cursor:"pointer",display:"flex",alignItems:"center",gap:5,fontSize:11,fontWeight:700}},React.createElement(Icon,{d:IC.down,size:13,color:C.gold})," Sauver")), gen&&React.createElement('div',{style:{marginTop:9,padding:9,background:"#0a1a0833",border:`1px solid ${C.green}44`,borderRadius:7,fontSize:11,color:C.green}},"✓ Badge prêt !")), React.createElement(Card,{dark}, React.createElement('div',{style:{fontWeight:700,color:dark?C.white:CL.white,marginBottom:10}},"Code de parrainage"), React.createElement('div',{style:{background:dark?C.bg:CL.bg,border:`1px solid ${C.gold}33`,borderRadius:7,padding:"9px 12px",fontFamily:"monospace",color:C.gold,fontSize:18,fontWeight:900,letterSpacing:2}},member.referral_code||"—")))); } function PageLeaderboard({dark}) { const {data,loading,error} = useApi('/leaderboard'); const [crit,setCrit]=useState("earnings"); if(loading) return React.createElement(Loader,{dark}); if(error) return React.createElement(ErrBox,{msg:error}); const medals=["🥇","🥈","🥉"]; return React.createElement('div',null, React.createElement('div',{style:{display:"flex",justifyContent:"space-between",alignItems:"center",marginBottom:20,flexWrap:"wrap",gap:12}}, React.createElement('h2',{style:{margin:0,fontSize:20,fontWeight:800,color:dark?C.white:CL.white}},"Classement"), React.createElement('div',{style:{display:"flex",gap:6}}, [["earnings","Gains"],["recruits","Recrues"],["network","Réseau"]].map(([v,l])=> React.createElement('button',{key:v,onClick:()=>setCrit(v),style:{background:crit===v?`${C.gold}15`:"transparent",border:`1px solid ${crit===v?C.gold:dark?C.border:CL.border}`,color:crit===v?C.gold:dark?C.muted:CL.muted,padding:"6px 14px",borderRadius:7,cursor:"pointer",fontWeight:700,fontSize:11}},l)))), React.createElement('div',{style:{display:"flex",flexDirection:"column",gap:9}}, (data||[]).map((m,i)=> React.createElement('div',{key:i,style:{background:i<3?`linear-gradient(90deg,${m.badge_color||C.gold}08,transparent)`:dark?C.surface:CL.surface,border:`1px solid ${i<3?(m.badge_color||C.gold)+"33":dark?C.border:CL.border}`,borderRadius:12,padding:"14px 18px",display:"flex",alignItems:"center",gap:14}}, React.createElement('div',{style:{width:34,height:34,borderRadius:"50%",flexShrink:0,background:i<3?`linear-gradient(135deg,${C.goldDark},${C.gold})`:dark?C.surface2:CL.surface2,border:`1px solid ${i<3?C.gold:dark?C.dim:CL.dim}`,display:"flex",alignItems:"center",justifyContent:"center",fontSize:i<3?16:12,fontWeight:900,color:i<3?"#000":dark?C.muted:CL.muted}},i<3?medals[i]:`#${i+1}`), React.createElement(Av,{name:m.display_name,size:42,color:m.badge_color||C.gold}), React.createElement('div',{style:{flex:1,minWidth:0}}, React.createElement('div',{style:{fontWeight:700,color:dark?C.white:CL.white,fontSize:13,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"}},m.display_name), React.createElement(Chip,{label:m.rank_name||"Membre",color:m.badge_color||C.gold,tiny:true})), React.createElement('div',{style:{textAlign:"right",flexShrink:0}}, React.createElement('div',{style:{fontWeight:900,color:m.badge_color||C.gold,fontSize:15}},crit==="earnings"?$f(m.score):Nf(m.score)), React.createElement('div',{style:{fontSize:9,color:dark?C.muted:CL.muted}},crit==="earnings"?"Gains":crit==="recruits"?"Recrues":"Réseau")))))); } function PageProfile({dark}) { const {data,loading,error} = useApi('/profile'); const [form,setForm]=useState(null); const [saved,setSaved]=useState(false); const [saving,setSaving]=useState(false); const [errMsg,setErrMsg]=useState(""); const fileRef=useRef(); useEffect(()=>{ if(data&&!form) setForm({ display_name: data.display_name||"", bio: data.bio||"", whatsapp_number: data.whatsapp_number||"", instagram_url: data.instagram_url||"", }); },[data]); if(loading||!form) return React.createElement(Loader,{dark}); if(error) return React.createElement(ErrBox,{msg:error}); const inp={width:"100%",background:dark?C.bg:CL.bg,border:`1px solid ${dark?C.border:CL.border}`,color:dark?C.white:CL.white,padding:"9px 11px",borderRadius:8,fontSize:12,outline:"none",boxSizing:"border-box",marginTop:5}; const set=k=>e=>setForm(f=>({...f,[k]:e.target.value})); async function save() { setSaving(true); setErrMsg(""); try { await api('/profile',{method:"POST",body:form}); setSaved(true); setTimeout(()=>setSaved(false),2500); } catch(e){ setErrMsg(e.message); } finally{ setSaving(false); } } async function handleAvatar(e) { const file = e.target.files[0]; if(!file) return; const fd = new FormData(); fd.append('avatar', file); try { await apiUpload('/profile/avatar', fd); } catch(e){ setErrMsg(e.message); } } return React.createElement('div',null, React.createElement('h2',{style:{margin:"0 0 20px",fontSize:20,fontWeight:800,color:dark?C.white:CL.white}},"Mon Profil"), React.createElement('div',{style:{display:"grid",gridTemplateColumns:"260px 1fr",gap:16,alignItems:"start"}}, React.createElement('div',{style:{display:"flex",flexDirection:"column",gap:12}}, React.createElement(Card,{dark}, React.createElement('div',{style:{fontWeight:700,color:dark?C.white:CL.white,marginBottom:14}},"Photo"), React.createElement('div',{style:{display:"flex",flexDirection:"column",alignItems:"center",gap:12}}, React.createElement('div',{style:{position:"relative"}}, React.createElement(Av,{name:data.display_name,size:96,color:C.gold}), React.createElement('button',{onClick:()=>fileRef.current?.click(),style:{position:"absolute",bottom:0,right:0,background:`linear-gradient(135deg,${C.goldDark},${C.gold})`,border:"none",color:"#000",width:28,height:28,borderRadius:"50%",cursor:"pointer",display:"flex",alignItems:"center",justifyContent:"center"}}, React.createElement(Icon,{d:IC.cam,size:13,color:"#000"})), React.createElement('input',{ref:fileRef,type:"file",accept:"image/*",style:{display:"none"},onChange:handleAvatar})), React.createElement('div',{style:{textAlign:"center"}}, React.createElement('div',{style:{fontWeight:700,color:dark?C.white:CL.white,fontSize:13}},data.display_name), React.createElement('div',{style:{fontSize:10,color:dark?C.muted:CL.muted,marginTop:2}},data.user_email)), React.createElement('button',{onClick:()=>fileRef.current?.click(),style:{width:"100%",background:`${C.gold}15`,border:`1px solid ${C.gold}44`,color:C.gold,padding:"8px 0",borderRadius:7,cursor:"pointer",fontWeight:700,fontSize:11}},"Changer la photo"))), React.createElement(Card,{dark}, React.createElement('div',{style:{fontWeight:700,color:dark?C.white:CL.white,marginBottom:10}},"Identifiants"), [["Code parrainage",data.referral_code,C.gold],["Boutique",`/shop/${data.username}/`,C.blue]].map(([l,v,c])=> React.createElement('div',{key:l,style:{marginBottom:9}}, React.createElement('div',{style:{fontSize:9,color:dark?C.muted:CL.muted,marginBottom:2}},l), React.createElement('div',{style:{fontFamily:"monospace",fontSize:10,color:c,background:dark?C.bg:CL.bg,border:`1px solid ${c}33`,borderRadius:6,padding:"5px 9px",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"}},v))))), React.createElement(Card,{dark}, React.createElement('div',{style:{fontWeight:700,color:dark?C.white:CL.white,marginBottom:18}},"Informations"), React.createElement('div',{style:{display:"grid",gridTemplateColumns:"1fr 1fr",gap:13,marginBottom:13}}, [["Nom d'affichage","display_name","text"],["WhatsApp","whatsapp_number","tel"]].map(([label,key,type])=> React.createElement('div',{key}, React.createElement('label',{style:{fontSize:10,color:dark?C.muted:CL.muted,textTransform:"uppercase",letterSpacing:1}},label), React.createElement('input',{type,value:form[key],onChange:set(key),style:inp})))), React.createElement('div',{style:{marginBottom:13}}, React.createElement('label',{style:{fontSize:10,color:dark?C.muted:CL.muted,textTransform:"uppercase",letterSpacing:1}},"Bio"), React.createElement('textarea',{value:form.bio,onChange:set("bio"),rows:3,style:{...inp,resize:"vertical"}})), React.createElement('div',{style:{marginBottom:18}}, React.createElement('label',{style:{fontSize:10,color:dark?C.muted:CL.muted,textTransform:"uppercase",letterSpacing:1}},"Instagram URL"), React.createElement('input',{type:"url",value:form.instagram_url,onChange:set("instagram_url"),placeholder:"https://",style:inp})), errMsg&&React.createElement(ErrBox,{msg:errMsg}), React.createElement('button',{onClick:save,disabled:saving,style:{background:`linear-gradient(90deg,${C.goldDark},${C.gold})`,border:"none",color:"#000",padding:"11px 32px",borderRadius:9,fontWeight:900,fontSize:13,cursor:"pointer"}},saving?"Enregistrement...":"Enregistrer"), saved&&React.createElement('span',{style:{marginLeft:12,color:C.green,fontSize:12,fontWeight:700}},"✓ Profil mis à jour !")))); } // ════════════════════════════════════════════════════════════════════ // LOGIN / REGISTER — calls real API // ════════════════════════════════════════════════════════════════════ function PageLogin({onLogin}) { const [mode,setMode]=useState("login"); const [form,setForm]=useState({username:"",password:"",email:"",name:"",ref:""}); const [loading,setLoading]=useState(false); const [err,setErr]=useState(""); const set=k=>e=>setForm(f=>({...f,[k]:e.target.value})); async function submit() { setLoading(true); setErr(""); try { let data; if(mode==="login") { data = await api('/auth/login',{method:"POST",body:{username:form.username,password:form.password}}); } else { data = await api('/auth/register',{method:"POST",body:{username:form.username,password:form.password,email:form.email,name:form.name,ref:form.ref}}); } setToken(data.token); onLogin(data.user); } catch(e){ setErr(e.message); } finally{ setLoading(false); } } const inp={width:"100%",background:"#0a0a0c",border:`1px solid ${C.gold}33`,color:C.white,padding:"11px 13px",borderRadius:9,fontSize:13,outline:"none",boxSizing:"border-box",marginBottom:11}; return React.createElement('div',{style:{minHeight:"100vh",display:"flex",alignItems:"center",justifyContent:"center",padding:20,background:`radial-gradient(ellipse at 20% 50%,${C.gold}09,transparent),radial-gradient(ellipse at 80% 20%,${C.purple}07,transparent),${C.bg}`}}, React.createElement('div',{style:{width:"100%",maxWidth:380}}, React.createElement('div',{style:{textAlign:"center",marginBottom:32}}, React.createElement('div',{style:{fontSize:9,color:C.muted,letterSpacing:7,textTransform:"uppercase",marginBottom:7}},"Plateforme MLM Premium"), React.createElement('h1',{style:{margin:0,fontSize:36,fontWeight:900,background:`linear-gradient(135deg,${C.goldDark},${C.gold},${C.goldLight})`,WebkitBackgroundClip:"text",WebkitTextFillColor:"transparent",letterSpacing:-1}},cfg.brandName||"Konektez")), React.createElement('div',{style:{background:C.surface,border:`1px solid ${C.border}`,borderRadius:16,padding:24}}, React.createElement('div',{style:{display:"flex",background:C.bg,borderRadius:9,padding:4,marginBottom:20}}, [["login","Connexion"],["register","Inscription"]].map(([v,l])=> React.createElement('button',{key:v,onClick:()=>{setMode(v);setErr("");},style:{flex:1,padding:"9px 0",background:mode===v?`linear-gradient(90deg,${C.goldDark},${C.gold})`:"transparent",border:"none",color:mode===v?"#000":C.muted,borderRadius:7,cursor:"pointer",fontWeight:700,fontSize:12}},l))), mode==="register"&&React.createElement('input',{style:inp,placeholder:"Prénom et nom",value:form.name,onChange:set("name")}), mode==="register"&&React.createElement('input',{style:inp,placeholder:"Email",type:"email",value:form.email,onChange:set("email")}), React.createElement('input',{style:inp,placeholder:"Nom d'utilisateur",value:form.username,onChange:set("username"),autoComplete:"username"}), React.createElement('input',{style:inp,placeholder:"Mot de passe",type:"password",value:form.password,onChange:set("password"),autoComplete:"current-password", onKeyDown:e=>e.key==="Enter"&&submit()}), mode==="register"&&React.createElement('input',{style:{...inp,borderColor:C.border},placeholder:"Code de parrainage (optionnel)",value:form.ref,onChange:set("ref")}), err&&React.createElement('div',{style:{background:"#7f1d1d22",border:`1px solid ${C.red}44`,color:C.red,padding:"8px 12px",borderRadius:8,fontSize:12,marginBottom:10}},err), React.createElement('button',{onClick:submit,disabled:loading,style:{width:"100%",background:`linear-gradient(90deg,${C.goldDark},${C.gold})`,border:"none",color:"#000",padding:"13px 0",borderRadius:10,fontWeight:900,fontSize:14,cursor:"pointer",opacity:loading?.75:1,boxShadow:`0 3px 18px ${C.gold}33`}},loading?"Chargement...":(mode==="login"?"Se connecter":"Créer mon compte")), mode==="login"&&React.createElement('div',{style:{textAlign:"center",marginTop:12,fontSize:11,color:C.muted,cursor:"pointer"}},"Mot de passe oublié ?")), React.createElement('div',{style:{textAlign:"center",marginTop:18,fontSize:10,color:C.dim}},"© 2026 Konektez · Plateforme sécurisée"))); } // ════════════════════════════════════════════════════════════════════ // NAVIGATION // ════════════════════════════════════════════════════════════════════ const NAV=[ {id:"dashboard", label:"Tableau de bord", icon:"dash"}, {id:"status", label:"Statut", icon:"status"}, {id:"genealogy", label:"Généalogie", icon:"tree"}, {id:"earnings", label:"Gains", icon:"earn"}, {id:"packs", label:"Packs", icon:"pack"}, {id:"ranks", label:"Rangs", icon:"rank"}, {id:"shop", label:"Ma boutique", icon:"shop"}, {id:"withdraw", label:"Portefeuille", icon:"wallet"}, {id:"badge", label:"Badge", icon:"badge"}, {id:"leaderboard",label:"Classement", icon:"trophy"}, {id:"profile", label:"Profil", icon:"user"}, ]; // ════════════════════════════════════════════════════════════════════ // ROOT // ════════════════════════════════════════════════════════════════════ window.KonektezDashboard = function KonektezDashboard({ initialPage, config: propConfig } = {}) { // Merge config prop into global cfg if(propConfig) Object.assign(cfg, propConfig); const [authed,setAuthed] = useState(!!getToken()&&!!cfg.loggedIn); const [user,setUser] = useState(null); const [page,setPage] = useState(NAV.find(n=>n.id===initialPage)?initialPage:"dashboard"); const [collapsed,setCollapsed] = useState(false); const [dark,setDark] = useState(cfg.darkMode!==false); const colors = dark?C:CL; // Verify token on mount useEffect(()=>{ if(!getToken()) return; api('/dashboard').then(d=>{ setAuthed(true); setUser(d?.member||null); }) .catch(()=>{ setToken(null); setAuthed(false); }); },[]); function handleLogin(userData) { setUser(userData); setAuthed(true); setPage("dashboard"); } function handleLogout() { setToken(null); setAuthed(false); setUser(null); setPage("dashboard"); } if(!authed) return React.createElement(PageLogin,{onLogin:handleLogin}); const PAGES = { dashboard: React.createElement(PageDashboard, {dark,setPage}), status: React.createElement(PageStatus, {dark,setPage}), genealogy: React.createElement(PageGenealogy, {dark}), earnings: React.createElement(PageEarnings, {dark}), packs: React.createElement(PagePacks, {dark,setPage}), ranks: React.createElement(PageRanks, {dark}), shop: React.createElement(PageShop, {dark}), withdraw: React.createElement(PageWithdraw, {dark}), badge: React.createElement(PageBadge, {dark}), leaderboard: React.createElement(PageLeaderboard,{dark}), profile: React.createElement(PageProfile, {dark}), }; return React.createElement('div',{style:{minHeight:"100vh",background:dark?C.bg:CL.bg,color:dark?C.white:CL.white,fontFamily:"Inter,system-ui,sans-serif",display:"flex",flexDirection:"column",transition:"background 0.3s"}}, // Glow ambiant React.createElement('div',{style:{position:"fixed",inset:0,pointerEvents:"none",zIndex:0,background:`radial-gradient(ellipse at 10% 80%,${C.gold}06,transparent)`}}), React.createElement('div',{style:{display:"flex",flex:1,position:"relative",zIndex:1,width:"100%"}}, // SIDEBAR React.createElement('div',{style:{width:collapsed?56:220,minHeight:"100vh",background:dark?C.surface:CL.surface,borderRight:`1px solid ${dark?C.border:CL.border}`,display:"flex",flexDirection:"column",transition:"width 0.2s",overflow:"hidden",flexShrink:0}}, React.createElement('div',{style:{padding:collapsed?"13px 11px":"17px 17px",borderBottom:`1px solid ${dark?C.border:CL.border}`,display:"flex",alignItems:"center",gap:10}}, React.createElement('div',{style:{width:32,height:32,borderRadius:8,flexShrink:0,background:`linear-gradient(135deg,${C.goldDark},${C.gold})`,display:"flex",alignItems:"center",justifyContent:"center"}}, React.createElement(Icon,{d:IC.rank,size:16,color:"#000"})), !collapsed&&React.createElement('div',null, React.createElement('div',{style:{fontWeight:900,fontSize:13,color:dark?C.white:CL.white}},cfg.brandName||"Konektez"), React.createElement('div',{style:{fontSize:8,color:C.gold,letterSpacing:2,textTransform:"uppercase"}},"MLM PRO"))), React.createElement('nav',{style:{flex:1,padding:"8px 0",overflowY:"auto",overflowX:"hidden"}}, NAV.map(item=>{ const isA=page===item.id; return React.createElement('button',{key:item.id,onClick:()=>setPage(item.id),style:{display:"flex",alignItems:"center",gap:11,width:"100%",padding:collapsed?"10px 12px":"9px 16px",background:isA?`${C.gold}0e`:"transparent",borderLeft:`2px solid ${isA?C.gold:"transparent"}`,border:"none",borderRight:"none",color:isA?C.gold:dark?C.muted:CL.muted,cursor:"pointer",fontSize:11,fontWeight:isA?700:500,textAlign:"left",whiteSpace:"nowrap"}}, React.createElement(Icon,{d:IC[item.icon]||IC.dash,size:16,color:isA?C.gold:dark?C.muted:CL.muted}), !collapsed&&item.label);})), !collapsed&&React.createElement('div',{style:{padding:"11px 14px",borderTop:`1px solid ${dark?C.border:CL.border}`,display:"flex",alignItems:"center",gap:9}}, React.createElement(Av,{name:user?.display_name||"—",size:30,color:C.gold}), React.createElement('div',{style:{flex:1,minWidth:0}}, React.createElement('div',{style:{fontSize:10,fontWeight:700,color:dark?"#bbb":CL.muted,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"}},user?.display_name||"—"), user?.status&&React.createElement(StatusBadge,{s:user.status})))), // MAIN React.createElement('div',{style:{flex:1,display:"flex",flexDirection:"column",minWidth:0,overflow:"hidden"}}, // TOPBAR React.createElement('div',{style:{height:56,background:dark?C.surface:CL.surface,borderBottom:`1px solid ${dark?C.border:CL.border}`,display:"flex",alignItems:"center",padding:"0 20px",gap:12,position:"sticky",top:0,zIndex:100,flexShrink:0}}, React.createElement('button',{onClick:()=>setCollapsed(c=>!c),style:{background:"none",border:"none",color:dark?C.muted:CL.muted,cursor:"pointer",padding:3,display:"flex"}}, React.createElement(Icon,{d:IC.menu,size:18,color:dark?C.muted:CL.muted})), React.createElement('div',{style:{flex:1,fontSize:14,fontWeight:700,color:dark?C.white:CL.white}},NAV.find(n=>n.id===page)?.label||""), // Toggle thème clair/sombre React.createElement('button',{onClick:()=>setDark(d=>!d),title:dark?"Passer en mode clair":"Passer en mode sombre",style:{background:`${C.gold}10`,border:`1px solid ${C.gold}33`,borderRadius:20,padding:"5px 12px",cursor:"pointer",display:"flex",alignItems:"center",gap:6,fontSize:11,fontWeight:700,color:dark?C.goldLight:C.goldDark}}, React.createElement(Icon,{d:dark?IC.sun:IC.moon,size:14,color:dark?C.goldLight:C.goldDark}), dark?"Clair":"Sombre"), React.createElement('div',{style:{display:"flex",alignItems:"center",gap:7}}, React.createElement(Av,{name:user?.display_name||"—",size:30,color:C.gold}), React.createElement('button',{onClick:handleLogout,style:{background:"none",border:"none",color:dark?C.muted:CL.muted,cursor:"pointer",padding:3}}, React.createElement(Icon,{d:IC.logout,size:16,color:dark?C.muted:CL.muted})))), // CONTENT — full width, no container limit React.createElement('main',{style:{flex:1,padding:"24px 32px",overflowY:"auto",maxWidth:"100%",boxSizing:"border-box"}}, PAGES[page]||React.createElement(PageDashboard,{dark,setPage})))))); }; })();