Dashboard

Verified Mentor

Notifications

/* ═══════════════════════════════════════════════════════ MENTOR CREDENTIALS & DATA ═══════════════════════════════════════════════════════ */ const MENTOR_CREDENTIALS = [ {id:1,name:"Mark Minervini",initials:"MM",email:"mark.minervini@bnb.edu",hash:"7db91f4445b497f0b7b418fb4368673048387e5be6458b058773355f875ac7ef",color:"#00D4AA"}, {id:2,name:"Larry Williams",initials:"LW",email:"larry.williams@bnb.edu",hash:"32cf4d96afb5e9cefc49a22aa87d392c1dc7c1c48e4f6f90e749334a7049ab42",color:"#3B82F6"}, {id:3,name:"Andrea Unger",initials:"AU",email:"andrea.unger@bnb.edu",hash:"f80e9a8c55d50da168893a45841275faa1bea93b957ed0411be5689842ce863d",color:"#A855F7"}, {id:4,name:"Peter Brandt",initials:"PB",email:"peter.brandt@bnb.edu",hash:"1a184532906a98e89cf94639f180c19b0fc25508f8ef1ee4c3e262a61a444c88",color:"#F59E0B"}, {id:5,name:"Linda Raschke",initials:"LR",email:"linda.raschke@bnb.edu",hash:"4ffe8fa37d211d52c881db28d6087a3e537727a3ac0a2914027502a33c69f3bc",color:"#EC4899"}, {id:6,name:"Oliver Kell",initials:"OK",email:"oliver.kell@bnb.edu",hash:"e01015fa1912faf8dd23978d820f9c5fb6e19f6a46be384e28a0408b6c0b36fa",color:"#22C55E"}, {id:7,name:"Jason Shapiro",initials:"JS",email:"jason.shapiro@bnb.edu",hash:"a5545e1c394c0c8e5ce9db63a66fd120b43a07d7142bd87eb6631b5815c1dc45",color:"#EF4444"}, {id:8,name:"Kevin Davey",initials:"KD",email:"kevin.davey@bnb.edu",hash:"629a0673e51da825ba4d704289da96bd3938c9ee3d6837f7e2a99b129b97577f",color:"#06B6D4"}, {id:9,name:"Al Brooks",initials:"AB",email:"al.brooks@bnb.edu",hash:"b4c10b1b9edddb6558d5eb66bb667641286fe5bb7d7f2a2dd4167453e8a35359",color:"#F97316"}, {id:10,name:"Tom Hougaard",initials:"TH",email:"tom.hougaard@bnb.edu",hash:"7f5922bdc019b3953b1fa24ef6de12d1b6050297606c06c91d5910589cbe0419",color:"#8B5CF6"}, {id:11,name:"Oliver Velez",initials:"OV",email:"oliver.velez@bnb.edu",hash:"8d493a49dc259d8059fc1d8941917dfd4dd1b0c9a28fdc0d73012ac1cfa8df12",color:"#14B8A6"}, {id:12,name:"Ross Cameron",initials:"RC",email:"ross.cameron@bnb.edu",hash:"03278892fa7d8ea348c4781b75b15e5207cd36d18465e836b238a3def6105580",color:"#E11D48"}, ]; const MENTORS = [ {id:1,name:"Mark Minervini",initials:"MM",headline:"SEPA® — Specific Entry Point Analysis",bio:"US Investing Champion, author of Trade Like a Stock Market Wizard",assetClass:"stocks",strategy:{name:"SEPA® Methodology",description:"Specific Entry Point Analysis combines fundamental catalysts with technical precision to identify superperformance stocks before they make their biggest moves.",keyPoints:["VCP (Volatility Contraction Pattern)","Tight risk management with defined stops","Momentum-driven growth stock selection","Position sizing based on conviction"]},books:[{title:"Trade Like a Stock Market Wizard"},{title:"Think & Trade Like a Champion"},{title:"Mindset Secrets for Winning"}],website:"https://www.minervini.com",followers:12450,pinnedPost:"The secret to superperformance is not finding the next hot stock — it's knowing exactly when the risk/reward is in your favor and sizing accordingly."}, {id:2,name:"Larry Williams",initials:"LW",headline:"COT & Seasonal Analysis Master",bio:"Legendary futures trader, 1987 World Cup Champion with 11,376% return",assetClass:"futures",strategy:{name:"COT & Seasonal Trading",description:"Combines Commitments of Traders data analysis with seasonal patterns and volatility breakouts for high-probability futures trades.",keyPoints:["COT report analysis","Seasonal market patterns","Volatility breakout entries","Money management through position sizing"]},books:[{title:"Long-Term Secrets to Short-Term Trading"},{title:"Trade Stocks & Commodities with the Insiders"}],website:"https://www.ireallytrade.com",followers:8920,pinnedPost:"The COT data is the only leading indicator in all of trading. Everything else is lagging."}, {id:3,name:"Andrea Unger",initials:"AU",headline:"4× World Cup Champion — Systematic Algorithmic",bio:"4-time World Cup Trading Championship winner, systematic algo trader",assetClass:"futures",strategy:{name:"Systematic Algorithmic Trading",description:"Develops and deploys rule-based trading systems across multiple markets, removing emotion and leveraging statistical edges.",keyPoints:["Fully automated trading systems","Multi-market diversification","Rigorous backtesting methodology","Risk-adjusted position sizing"]},books:[{title:"The Unger Method"}],website:"https://ungeracademy.com",followers:6780}, {id:4,name:"Peter Brandt",initials:"PB",headline:"Classical Chart Pattern Master",bio:"Market Wizard, 40+ years of classical charting across futures, forex, and crypto",assetClass:"multi",strategy:{name:"Classical Chart Patterns",description:"Pure price action using classical chart patterns across futures, forex, and crypto with rigorous risk management.",keyPoints:["Head & shoulders, rectangles, triangles","Factor-based trade management","Strict 2% risk per trade","Multi-asset diversification"]},books:[{title:"Diary of a Professional Commodity Trader"}],website:"https://www.peterlbrandt.com",followers:9350}, {id:5,name:"Linda Raschke",initials:"LR",headline:"Market Wizard — Short-Term Patterns",bio:"Market Wizard, former CTA with top-performing fund for 20+ years",assetClass:"futures",strategy:{name:"Short-Term S&P Futures",description:"Short-term directional trading of S&P futures using pattern recognition, tape reading, and mean-reversion setups.",keyPoints:["Anti-pattern recognition","Tape reading & order flow","Mean reversion setups","Disciplined risk management"]},books:[{title:"Street Smarts (with Larry Connors)"}],website:"https://lindaraschke.net",followers:5430}, {id:6,name:"Oliver Kell",initials:"OK",headline:"2020 USIC Champion — 941% Return",bio:"2020 US Investing Championship Champion with 941% verified return",assetClass:"stocks",strategy:{name:"Momentum Growth",description:"Aggressive momentum trading focused on growth stocks with strong relative strength.",keyPoints:["Relative strength screening","Earnings-driven catalysts","Aggressive position sizing in conviction trades","Quick cut of losers"]},books:[{title:"Victory in Stock Trading"}],website:"https://www.kelltrading.com",followers:7120}, {id:7,name:"Jason Shapiro",initials:"JS",headline:"Contrarian COT Trader",bio:"Featured in Unknown Market Wizards, Schwager-audited contrarian futures trader",assetClass:"futures",strategy:{name:"Contrarian COT Analysis",description:"Uses COT positioning data to identify when the crowd is wrong and takes contrarian positions.",keyPoints:["COT extreme positioning analysis","Contrarian entry timing","Multiple market coverage","Patient position building"]},books:[],website:"https://www.crowdedmarketreport.com",followers:4560}, {id:8,name:"Kevin Davey",initials:"KD",headline:"3× World Cup Top Finisher — Algo Systems",bio:"3-time World Cup Trading Championship top finisher, algo trading educator",assetClass:"futures",strategy:{name:"Algorithmic Trading Systems",description:"Develops robust mechanical systems using Monte Carlo analysis and walk-forward optimization.",keyPoints:["Monte Carlo simulation","Walk-forward optimization","Multi-system portfolio","Drawdown-based sizing"]},books:[{title:"Building Winning Algorithmic Trading Systems"}],website:"https://kjtradingsystems.com",followers:3890}, {id:9,name:"Al Brooks",initials:"AB",headline:"The Godfather of Price Action Trading",bio:"Former ophthalmologist turned full-time trader, author of the definitive price action trading course",assetClass:"futures",strategy:{name:"Bar-by-Bar Price Action Reading",description:"Pure price action analysis without indicators. Every bar tells a story.",keyPoints:["Bar-by-bar reading on 5-min E-mini","Always-In long/short framework","Signal bars and entry bars","Trading ranges vs trends"]},books:[{title:"Trading Price Action Trends"},{title:"Trading Price Action Trading Ranges"},{title:"Trading Price Action Reversals"}],website:"https://www.brookstradingcourse.com",followers:15200,pinnedPost:"There is always something to do. If you cannot find a good signal bar, the market is telling you it is in a trading range."}, {id:10,name:"Tom Hougaard",initials:"TH",headline:"Best Loser Wins — Psychology Pioneer",bio:"Professional spread bettor, author of Best Loser Wins, 20+ years documented live trading",assetClass:"multi",strategy:{name:"Best Loser Wins",description:"The best traders are not the best winners — they are the best losers.",keyPoints:["Cut losers immediately","Add to winners aggressively","NLP anchoring for state management","Raw price action on DAX and S&P"]},books:[{title:"Best Loser Wins: Why Normal Thinking Never Wins the Trading Game"}],website:"https://tradertom.com",followers:8750,pinnedPost:"You don't need to be right more often. You need to be wrong BETTER."}, {id:11,name:"Oliver Velez",initials:"OV",headline:"Pioneer of Momentum Day Trading Education",bio:"Co-founder of Pristine Capital Holdings, one of the earliest momentum day trading educators",assetClass:"stocks",strategy:{name:"Momentum Tape Reading",description:"Pioneered accessible momentum day trading — Level 2 reading, momentum ignition, and precise intraday entries.",keyPoints:["Micro-pattern recognition 1-5 min","Level 2 and tape reading","Momentum ignition identification","180 reversal setups"]},books:[{title:"Strategies for Profiting on Every Trade"},{title:"Tools and Tactics for the Master Day Trader"}],website:"https://tradingolivervelez.com",followers:6340}, {id:12,name:"Ross Cameron",initials:"RC",headline:"Warrior Trading — Momentum Day Trading",bio:"Verified profitable trader who turned $583 into over $10M documented on YouTube. Founder of Warrior Trading.",assetClass:"stocks",strategy:{name:"Momentum Day Trading — The 5 Pillars",description:"Find stocks moving NOW with specific criteria: high relative volume, significant percentage gain, news catalyst, low float, and volume surge.",keyPoints:["5 Pillars: RVOL ≥5x, Up 10%+, News Catalyst, Float <20M, Volume Surge","Gap and Go — buy pre-market gappers at open","Opening Range Breakout (ORB)","ABCD pattern for continuation entries","$500 max loss per day — no exceptions"]},books:[{title:"How to Day Trade for a Living"},{title:"How to Day Trade: A Detailed Guide"}],website:"https://www.warriortrading.com",followers:18500,pinnedPost:"Rule #1: never risk more than you can afford to lose. My max loss is $500/day. Once I hit it, I'm done."}, ]; /* ═══════════════════════════════════════════════════════ LOCALSTORAGE HELPERS ═══════════════════════════════════════════════════════ */ function lsGet(key,def){try{const v=localStorage.getItem(key);return v?JSON.parse(v):def}catch(e){return def}} function lsSet(key,val){try{localStorage.setItem(key,JSON.stringify(val))}catch(e){}} function ssGet(key,def){try{const v=sessionStorage.getItem(key);return v?JSON.parse(v):def}catch(e){return def}} function ssSet(key,val){try{sessionStorage.setItem(key,JSON.stringify(val))}catch(e){}} /* ═══════════════════════════════════════════════════════ SHA-256 ═══════════════════════════════════════════════════════ */ async function sha256(msg){ const buf=new TextEncoder().encode(msg); const hash=await crypto.subtle.digest('SHA-256',buf); return Array.from(new Uint8Array(hash)).map(b=>b.toString(16).padStart(2,'0')).join(''); } /* ═══════════════════════════════════════════════════════ STATE ═══════════════════════════════════════════════════════ */ let currentMentor=null; let currentView='dashboard'; /* ═══════════════════════════════════════════════════════ LOGIN ═══════════════════════════════════════════════════════ */ // Login handler is at the bottom of the script to support custom hashes function logout(){ try{sessionStorage.removeItem('bnb_mentor_session')}catch(e){} currentMentor=null; document.getElementById('appShell').classList.remove('active'); document.getElementById('loginScreen').style.display='flex'; document.getElementById('loginEmail').value=''; document.getElementById('loginCode').value=''; } /* ═══════════════════════════════════════════════════════ INIT APP ═══════════════════════════════════════════════════════ */ function initApp(mentorId){ currentMentor=MENTORS.find(m=>m.id===mentorId); if(!currentMentor)return; const cred=MENTOR_CREDENTIALS.find(m=>m.id===mentorId); document.getElementById('loginScreen').style.display='none'; document.getElementById('appShell').classList.add('active'); // Set topbar const avatarEl=document.getElementById('topbarAvatar'); avatarEl.textContent=currentMentor.initials; avatarEl.style.background=`linear-gradient(135deg,${cred.color},${cred.color}dd)`; document.getElementById('topbarName').textContent=currentMentor.name; // Seed demo data if needed seedDemoData(mentorId); // Render views switchView('dashboard'); updateNotifBadge(); } /* ═══════════════════════════════════════════════════════ DEMO DATA SEEDING ═══════════════════════════════════════════════════════ */ function generateTraderName(){ const chars='ABCDEFGHJKLMNPQRSTUVWXYZ0123456789'; let s='Trader_'; for(let i=0;i<3;i++)s+=chars[Math.floor(Math.random()*chars.length)]; return s; } function seedDemoData(mentorId){ const seedKey=`bnb_mentor_seeded_${mentorId}`; if(lsGet(seedKey,false))return; // Followers const followerKey=`bnb_mentor_followers_${mentorId}`; const followers=[]; const count=15+Math.floor(Math.random()*16); for(let i=0;i=0;i--){ const day=base-Math.floor(Math.random()*200)+i*Math.floor(Math.random()*8+2); growth.push({date:new Date(Date.now()-i*86400000).toISOString().split('T')[0],count:Math.max(base-300+i*10+Math.floor(Math.random()*15),base-400)}); } // Ensure upward trend for(let i=1;ib.timestamp-a.timestamp); lsSet(postKey,posts); // Chat messages const chatKey=`bnb_mentor_chat_${mentorId}`; const chatMsgs=[]; const chatTexts=[ 'Great analysis today!','What do you think about the current market conditions?', 'I\'ve been following your strategy for 3 months now — really solid results.', 'Could you explain more about your entry criteria?', 'Thanks for the detailed breakdown in your last post.', 'How do you handle drawdowns psychologically?', 'Your approach to position sizing changed my trading.', 'What timeframe do you primarily trade?', 'Do you have any recommendations for books on risk management?', 'Been applying your methods — finally seeing consistent profits!', 'What\'s your take on the current volatility?', 'Your pinned post really resonated with me.', 'How long did it take you to become consistently profitable?', 'Love the educational content — keep it coming!', 'Can you do a live session sometime this week?', 'That trade setup from yesterday was textbook.', 'Your community is the best I\'ve been part of.', 'What indicators do you watch besides price action?', 'Morning routine tips for traders? I struggle with preparation.', 'The key levels you mentioned played out perfectly today!', 'Any advice for traders transitioning from sim to live?', 'I appreciate the honesty about losses — keeps it real.', 'Your risk management framework is incredibly systematic.', 'How do you stay disciplined after a losing streak?', 'Thanks for being accessible to the community.', 'The VCP setup you highlighted was a great example.', 'Do you plan on doing a webinar this quarter?', 'Your approach to cutting losses fast saved me last week.', 'I reviewed your latest chart markup — very insightful.', 'What was the biggest lesson you learned early in your career?', ]; const numMsgs=20+Math.floor(Math.random()*11); for(let i=0;ia.timestamp-b.timestamp); lsSet(chatKey,chatMsgs); // Notifications const notifKey=`bnb_mentor_notifs_${mentorId}`; const notifTypes=['follow','like','comment','chat','platform']; const notifs=[]; const numNotifs=10+Math.floor(Math.random()*6); for(let i=0;i${traderName} started following you`;break; case 'like':text=`${traderName} liked your post "${postTitles[Math.floor(Math.random()*postTitles.length)]}"`;break; case 'comment':text=`${traderName} commented on your post`;break; case 'chat':text=`${traderName} sent a message in your chat room`;break; case 'platform':text=`Platform Update: New analytics features are now available`;break; } notifs.push({id:'notif_'+i,type,text,timestamp:Date.now()-minsAgo*60000,read:Math.random()>0.5}); } notifs.sort((a,b)=>b.timestamp-a.timestamp); lsSet(notifKey,notifs); // Announcement const annKey=`bnb_mentor_announcement_${mentorId}`; lsSet(annKey,{text:'Welcome to my trading community! Feel free to ask questions and share your progress.',timestamp:Date.now()-86400000}); // Media library const mediaKey=`bnb_mentor_media_${mentorId}`; lsSet(mediaKey,[]); // Settings const settKey=`bnb_mentor_settings_${mentorId}`; if(!lsGet(settKey,null)){ lsSet(settKey,{ emailNotifs:{follow:true,like:true,comment:true,chat:true,platform:true}, privacy:{showEmail:false,showWebsite:true,showTrackRecord:true} }); } lsSet(seedKey,true); } /* ═══════════════════════════════════════════════════════ VIEW SWITCHING ═══════════════════════════════════════════════════════ */ const viewTitles={dashboard:'Dashboard',content:'Content',community:'Community',analytics:'Analytics',revenue:'Revenue',notifications:'Notifications',settings:'Settings'}; function switchView(name){ currentView=name; document.querySelectorAll('.view').forEach(v=>v.classList.remove('active')); document.querySelectorAll('.nav-item').forEach(n=>n.classList.remove('active')); const view=document.getElementById('view-'+name); if(view){view.classList.add('active')} const navItem=document.querySelector(`.nav-item[data-view="${name}"]`); if(navItem)navItem.classList.add('active'); document.getElementById('viewTitle').textContent=viewTitles[name]||name; // Render view content switch(name){ case 'dashboard':renderDashboard();break; case 'content':renderContent();break; case 'community':renderCommunity();break; case 'analytics':renderAnalytics();break; case 'revenue':renderRevenue();break; case 'notifications':renderNotifications();break; case 'settings':renderSettings();break; } } /* ═══════════════════════════════════════════════════════ SIDEBAR TOGGLE ═══════════════════════════════════════════════════════ */ function toggleSidebar(){ document.getElementById('sidebar').classList.toggle('collapsed'); } /* ═══════════════════════════════════════════════════════ UTILITY ═══════════════════════════════════════════════════════ */ function formatNum(n){ if(n>=1000000)return(n/1000000).toFixed(1)+'M'; if(n>=1000)return(n/1000).toFixed(1).replace(/\.0$/,'')+'K'; return n.toString(); } function timeAgo(ts){ const d=Date.now()-ts;const m=Math.floor(d/60000); if(m<1)return 'Just now';if(m<60)return m+'m ago'; const h=Math.floor(m/60);if(h<24)return h+'h ago'; const days=Math.floor(h/24);if(days<7)return days+'d ago'; return new Date(ts).toLocaleDateString('en-US',{month:'short',day:'numeric'}); } function showToast(msg){ const t=document.getElementById('toast'); t.textContent=msg;t.classList.add('show'); setTimeout(()=>t.classList.remove('show'),2500); } /* ═══════════════════════════════════════════════════════ CANVAS DRAWING UTILITIES ═══════════════════════════════════════════════════════ */ function drawSparkline(canvas,data,color='#00D4AA',fillColor='rgba(0,212,170,0.1)'){ if(!canvas||!data||!data.length)return; const ctx=canvas.getContext('2d'); const rect=canvas.parentElement.getBoundingClientRect(); const cw=rect.width,ch=rect.height; canvas.width=cw*2;canvas.height=ch*2; canvas.style.width=cw+'px';canvas.style.height=ch+'px'; ctx.scale(2,2); const min=Math.min(...data),max=Math.max(...data); const range=max-min||1; const pad=4; ctx.clearRect(0,0,cw,ch); ctx.beginPath(); data.forEach((v,i)=>{ const x=pad+i*(cw-2*pad)/(data.length-1); const y=ch-pad-(v-min)/(range)*(ch-2*pad); if(i===0)ctx.moveTo(x,y);else ctx.lineTo(x,y); }); ctx.strokeStyle=color;ctx.lineWidth=1.5;ctx.lineJoin='round';ctx.stroke(); // Fill ctx.lineTo(pad+(data.length-1)*(cw-2*pad)/(data.length-1),ch-pad); ctx.lineTo(pad,ch-pad);ctx.closePath(); ctx.fillStyle=fillColor;ctx.fill(); } function drawLineChart(canvas,data,labels,color='#00D4AA'){ if(!canvas||!data||!data.length)return; const ctx=canvas.getContext('2d'); const dpr=2; const rect=canvas.parentElement.getBoundingClientRect(); const cw=rect.width,ch=rect.height; canvas.width=cw*dpr;canvas.height=ch*dpr; canvas.style.width=cw+'px';canvas.style.height=ch+'px'; ctx.scale(dpr,dpr); const padL=45,padR=15,padT=15,padB=30; const gw=cw-padL-padR,gh=ch-padT-padB; const min=Math.min(...data),max=Math.max(...data); const range=max-min||1; ctx.clearRect(0,0,cw,ch); // Grid lines ctx.strokeStyle='rgba(255,255,255,0.04)';ctx.lineWidth=1; for(let i=0;i<5;i++){ const y=padT+i*gh/4; ctx.beginPath();ctx.moveTo(padL,y);ctx.lineTo(padL+gw,y);ctx.stroke(); const val=max-i*range/4; ctx.fillStyle='#556275';ctx.font='10px JetBrains Mono';ctx.textAlign='right'; ctx.fillText(formatNum(Math.round(val)),padL-8,y+3); } // X labels if(labels){ ctx.fillStyle='#556275';ctx.font='9px JetBrains Mono';ctx.textAlign='center'; const step=Math.ceil(labels.length/7); labels.forEach((l,i)=>{ if(i%step===0){ const x=padL+i*gw/(data.length-1); ctx.fillText(l.slice(5),x,ch-6); } }); } // Line ctx.beginPath(); data.forEach((v,i)=>{ const x=padL+i*gw/(data.length-1); const y=padT+gh-(v-min)/range*gh; if(i===0)ctx.moveTo(x,y);else ctx.lineTo(x,y); }); ctx.strokeStyle=color;ctx.lineWidth=2;ctx.lineJoin='round';ctx.stroke(); // Fill gradient const lastX=padL+(data.length-1)*gw/(data.length-1); ctx.lineTo(lastX,padT+gh);ctx.lineTo(padL,padT+gh);ctx.closePath(); const grad=ctx.createLinearGradient(0,padT,0,padT+gh); grad.addColorStop(0,color.replace(')',',0.15)').replace('rgb','rgba')); grad.addColorStop(1,color.replace(')',',0.01)').replace('rgb','rgba')); ctx.fillStyle=grad;ctx.fill(); // Dots at end const lastY=padT+gh-(data[data.length-1]-min)/range*gh; ctx.beginPath();ctx.arc(lastX,lastY,3,0,Math.PI*2); ctx.fillStyle=color;ctx.fill(); } function drawMiniBar(canvas,data,color='#00D4AA'){ if(!canvas||!data||!data.length)return; const ctx=canvas.getContext('2d'); const dpr=2; const rect=canvas.parentElement.getBoundingClientRect(); const cw=rect.width,ch=rect.height; canvas.width=cw*dpr;canvas.height=ch*dpr; canvas.style.width=cw+'px';canvas.style.height=ch+'px'; ctx.scale(dpr,dpr); const max=Math.max(...data)||1; const barW=cw/data.length-2; data.forEach((v,i)=>{ const h=Math.max(2,(v/max)*(ch-4)); const x=i*(barW+2)+1; ctx.fillStyle=color; ctx.beginPath(); ctx.roundRect(x,ch-h-2,barW,h,1); ctx.fill(); }); } /* ═══════════════════════════════════════════════════════ DASHBOARD VIEW ═══════════════════════════════════════════════════════ */ function renderDashboard(){ const mid=currentMentor.id; const posts=lsGet(`bnb_mentor_posts_${mid}`,[]); const followers=lsGet(`bnb_mentor_followers_${mid}`,[]); const growth=lsGet(`bnb_mentor_growth_${mid}`,[]); const totalFollowers=currentMentor.followers; const totalPosts=posts.length; const weekAgo=Date.now()-7*86400000; const activeFollowers=followers.filter(f=>f.interactions>5).length; const engRate=followers.length>0?((activeFollowers/followers.length)*100).toFixed(1):0; // Growth trend const lastWeek=growth.slice(-7).map(g=>g.count); const prevWeek=growth.slice(-14,-7).map(g=>g.count); const newThisWeek=(lastWeek[lastWeek.length-1]||0)-(lastWeek[0]||0); const newPrevWeek=(prevWeek[prevWeek.length-1]||0)-(prevWeek[0]||0); const el=document.getElementById('view-dashboard'); el.innerHTML=`
Total Followers
${formatNum(totalFollowers)}
+${newThisWeek} this week
Content Posts
${totalPosts}
Published this month
Engagement Rate
${engRate}%
Active followers this week
Revenue This Month
$0.00
Coming Soon
Follower Growth — Last 30 Days +${newThisWeek} vs +${newPrevWeek} prev week
Top Active Followers
Your followers are most active on: Tuesday, Wednesday
Recent Content Performance
`; // Draw sparklines requestAnimationFrame(()=>{ drawSparkline(document.getElementById('sparkFollowers'),lastWeek,'#00D4AA','rgba(0,212,170,0.1)'); const postViews=posts.slice(0,7).map(p=>p.views); drawSparkline(document.getElementById('sparkPosts'),postViews.length?postViews:[0,1,2],'#3B82F6','rgba(59,130,246,0.1)'); const engData=Array.from({length:7},()=>Math.random()*15+10); drawSparkline(document.getElementById('sparkEngagement'),engData,'#F59E0B','rgba(245,158,11,0.1)'); // Growth chart if(growth.length){ drawLineChart(document.getElementById('chartGrowth'),growth.map(g=>g.count),growth.map(g=>g.date)); } }); // Top followers const sorted=[...followers].sort((a,b)=>b.interactions-a.interactions).slice(0,5); document.getElementById('topFollowers').innerHTML=sorted.map(f=>`
${f.name.slice(-3)}
${f.name}
${f.region} · Joined ${timeAgo(f.joined)}
${f.interactions} interactions
`).join(''); // Recent posts document.getElementById('dashPosts').innerHTML=posts.slice(0,3).map(p=>`
${p.title}
${formatNum(p.views)}
${formatNum(p.likes)}
${((p.likes/p.views)*100).toFixed(1)}% eng
`).join(''); requestAnimationFrame(()=>{ document.querySelectorAll('.mini-chart').forEach(c=>{ try{const d=JSON.parse(c.dataset.views);drawMiniBar(c,d)}catch(e){} }); }); } /* ═══════════════════════════════════════════════════════ CONTENT VIEW ═══════════════════════════════════════════════════════ */ let contentTab='posts'; let contentSort='recent'; function renderContent(){ const mid=currentMentor.id; const el=document.getElementById('view-content'); el.innerHTML=`
`; switch(contentTab){ case 'posts':renderPostsList();break; case 'create':renderCreatePost();break; case 'profile':renderProfileEditor();break; case 'media':renderMediaLibrary();break; } } function renderPostsList(){ const mid=currentMentor.id; let posts=lsGet(`bnb_mentor_posts_${mid}`,[]); switch(contentSort){ case 'views':posts=[...posts].sort((a,b)=>b.views-a.views);break; case 'likes':posts=[...posts].sort((a,b)=>b.likes-a.likes);break; default:posts=[...posts].sort((a,b)=>b.timestamp-a.timestamp); } document.getElementById('contentTabContent').innerHTML=`
${posts.map(p=>`
${p.title}${p.status==='draft'?' [DRAFT]':''}
${formatNum(p.views)}
${formatNum(p.likes)}
${((p.likes/Math.max(p.views,1))*100).toFixed(1)}% eng
`).join('')} ${posts.length===0?'
No posts yet. Create your first post!
':''} `; requestAnimationFrame(()=>{ document.querySelectorAll('.mini-chart').forEach(c=>{ try{const d=JSON.parse(c.dataset.views);drawMiniBar(c,d)}catch(e){} }); }); } /* Create Post */ let newPostStatus='published'; let newPostTag='Market Analysis'; function renderCreatePost(){ const tags=['Market Analysis','Trade Idea','Strategy Deep Dive','Psychology','Q&A','Educational']; document.getElementById('contentTabContent').innerHTML=`
Create New Post
${tags.map(t=>``).join('')}
`; } function submitPost(){ const title=document.getElementById('postTitle').value.trim(); const body=document.getElementById('postBody').value.trim(); if(!title){showToast('Please enter a title');return} const mid=currentMentor.id; const posts=lsGet(`bnb_mentor_posts_${mid}`,[]); const scheduleEl=document.getElementById('postSchedule'); const scheduledFor=scheduleEl&&scheduleEl.value?new Date(scheduleEl.value).getTime():null; const imageUrl=document.getElementById('postImage').value.trim(); const post={ id:'post_'+mid+'_'+Date.now(), mentorId:mid,author:currentMentor.name, title,body,tag:newPostTag, status:newPostStatus, timestamp:Date.now(), scheduledFor,imageUrl, views:0,likes:0, dailyViews:[0,0,0,0,0,0,0] }; posts.unshift(post); lsSet(`bnb_mentor_posts_${mid}`,posts); // If published, also write to hub-readable format if(newPostStatus==='published'){ const hubPosts=lsGet('bnb-hub-posts',[]); hubPosts.unshift({mentorId:mid,author:currentMentor.name,content:title+' — '+body,timestamp:Date.now()}); lsSet('bnb-hub-posts',hubPosts); } // Save image to media library if provided if(imageUrl){ const media=lsGet(`bnb_mentor_media_${mid}`,[]); media.unshift({url:imageUrl,added:Date.now()}); lsSet(`bnb_mentor_media_${mid}`,media); } showToast(newPostStatus==='published'?'Post published!':'Draft saved!'); contentTab='posts';renderContent(); } /* Profile Editor */ function renderProfileEditor(){ const mid=currentMentor.id; const mentor=currentMentor; const customProfile=lsGet(`bnb_mentor_profile_${mid}`,{}); const headline=customProfile.headline||mentor.headline; const bio=customProfile.bio||mentor.bio; const pinnedPost=customProfile.pinnedPost||mentor.pinnedPost||''; const website=customProfile.website||mentor.website||''; const avatarUrl=customProfile.avatarUrl||''; const stratDesc=customProfile.strategyDescription||mentor.strategy.description; const stratPoints=customProfile.strategyKeyPoints||mentor.strategy.keyPoints; const books=customProfile.books||mentor.books||[]; document.getElementById('contentTabContent').innerHTML=`
Edit Profile
${books.map((b,i)=>`
${b.title}
`).join('')}
`; } function saveProfile(){ const mid=currentMentor.id; const existing=lsGet(`bnb_mentor_profile_${mid}`,{}); const profile={ ...existing, headline:document.getElementById('profHeadline').value.trim(), bio:document.getElementById('profBio').value.trim(), pinnedPost:document.getElementById('profPinned').value.trim(), website:document.getElementById('profWebsite').value.trim(), avatarUrl:document.getElementById('profAvatar').value.trim(), strategyDescription:document.getElementById('profStratDesc').value.trim(), strategyKeyPoints:document.getElementById('profStratPoints').value.trim().split('\n').filter(l=>l.trim()), books:existing.books||currentMentor.books||[] }; lsSet(`bnb_mentor_profile_${mid}`,profile); showToast('Profile saved!'); } function addBook(){ const title=document.getElementById('newBookTitle').value.trim(); if(!title)return; const mid=currentMentor.id; const profile=lsGet(`bnb_mentor_profile_${mid}`,{}); const books=profile.books||currentMentor.books||[]; books.push({title}); profile.books=books; lsSet(`bnb_mentor_profile_${mid}`,profile); renderProfileEditor(); } function removeBook(idx){ const mid=currentMentor.id; const profile=lsGet(`bnb_mentor_profile_${mid}`,{}); const books=profile.books||currentMentor.books||[]; books.splice(idx,1); profile.books=books; lsSet(`bnb_mentor_profile_${mid}`,profile); renderProfileEditor(); } function showProfilePreview(){ const cred=MENTOR_CREDENTIALS.find(m=>m.id===currentMentor.id); const profile=lsGet(`bnb_mentor_profile_${currentMentor.id}`,{}); const headline=profile.headline||currentMentor.headline; const bio=profile.bio||currentMentor.bio; const pinnedPost=profile.pinnedPost||currentMentor.pinnedPost||''; const books=profile.books||currentMentor.books||[]; document.getElementById('profilePreviewContent').innerHTML=`
${currentMentor.initials}
${currentMentor.name}
${headline}
${bio}
${pinnedPost?`
"${pinnedPost}"
`:''} ${books.length?`
Books:
${books.map(b=>`
${b.title}
`).join('')}
`:''} `; } /* Media Library */ function renderMediaLibrary(){ const mid=currentMentor.id; const media=lsGet(`bnb_mentor_media_${mid}`,[]); document.getElementById('contentTabContent').innerHTML=`
Media Library ${media.length} items
${media.map((m,i)=>`
Media
Click to Copy URL
`).join('')} ${media.length===0?'
No images yet. Add images via URL above.
':''}
`; } function addMedia(){ const url=document.getElementById('mediaUrl').value.trim(); if(!url)return; const mid=currentMentor.id; const media=lsGet(`bnb_mentor_media_${mid}`,[]); media.unshift({url,added:Date.now()}); lsSet(`bnb_mentor_media_${mid}`,media); renderMediaLibrary(); showToast('Image added!'); } function copyMediaUrl(url){ navigator.clipboard.writeText(url).then(()=>showToast('URL copied!')).catch(()=>showToast('Copy failed')); } /* ═══════════════════════════════════════════════════════ COMMUNITY VIEW (CHAT) ═══════════════════════════════════════════════════════ */ function renderCommunity(){ const mid=currentMentor.id; const messages=lsGet(`bnb_mentor_chat_${mid}`,[]); const announcement=lsGet(`bnb_mentor_announcement_${mid}`,null); const onlineCount=Math.floor(Math.random()*20)+5; const cred=MENTOR_CREDENTIALS.find(m=>m.id===mid); const el=document.getElementById('view-community'); el.innerHTML=`
${currentMentor.name}'s Trading Room
${onlineCount} members online
${announcement&&announcement.text?`
📌 Announcement
${announcement.text}
`:''}
${messages.map(m=>renderChatMsg(m,cred)).join('')}
`; // Auto-scroll const msgArea=document.getElementById('chatMessages'); if(msgArea)msgArea.scrollTop=msgArea.scrollHeight; } function renderChatMsg(m,cred){ const pinned=m.pinned?'pinned':''; return `
${m.isMentor?currentMentor.initials:m.author.slice(-3)}
${m.pinned?'
Pinned
':''}
${m.author}${m.isMentor?'Mentor':''} ${timeAgo(m.timestamp)}
${m.text}
`; } function sendChatMsg(){ const input=document.getElementById('chatInput'); const text=input.value.trim(); if(!text)return; const mid=currentMentor.id; const messages=lsGet(`bnb_mentor_chat_${mid}`,[]); messages.push({ id:'msg_'+Date.now(), author:currentMentor.name, isMentor:true, text, timestamp:Date.now(), pinned:false }); lsSet(`bnb_mentor_chat_${mid}`,messages); input.value=''; renderCommunity(); } function pinMsg(msgId){ const mid=currentMentor.id; const messages=lsGet(`bnb_mentor_chat_${mid}`,[]); const msg=messages.find(m=>m.id===msgId); if(msg){msg.pinned=!msg.pinned;lsSet(`bnb_mentor_chat_${mid}`,messages);renderCommunity()} } function deleteMsg(msgId){ const mid=currentMentor.id; let messages=lsGet(`bnb_mentor_chat_${mid}`,[]); messages=messages.filter(m=>m.id!==msgId); lsSet(`bnb_mentor_chat_${mid}`,messages); renderCommunity(); showToast('Message deleted'); } function editAnnouncement(){ const mid=currentMentor.id; const current=lsGet(`bnb_mentor_announcement_${mid}`,{text:''}); const newText=prompt('Edit announcement:',current.text); if(newText!==null){ lsSet(`bnb_mentor_announcement_${mid}`,{text:newText,timestamp:Date.now()}); renderCommunity(); showToast('Announcement updated'); } } /* ═══════════════════════════════════════════════════════ ANALYTICS VIEW ═══════════════════════════════════════════════════════ */ function renderAnalytics(){ const mid=currentMentor.id; const followers=lsGet(`bnb_mentor_followers_${mid}`,[]); const growth=lsGet(`bnb_mentor_growth_${mid}`,[]); const posts=lsGet(`bnb_mentor_posts_${mid}`,[]); // Region distribution const regions={}; followers.forEach(f=>{regions[f.region]=(regions[f.region]||0)+1}); const regionEntries=Object.entries(regions).sort((a,b)=>b[1]-a[1]); const maxRegion=regionEntries.length?regionEntries[0][1]:1; // New followers comparison const lastWeek=growth.slice(-7); const prevWeek=growth.slice(-14,-7); const newThisWeek=lastWeek.length>=2?(lastWeek[lastWeek.length-1].count-lastWeek[0].count):0; const newPrevWeek=prevWeek.length>=2?(prevWeek[prevWeek.length-1].count-prevWeek[0].count):0; // Post performance const totalViews=posts.reduce((s,p)=>s+p.views,0); const totalLikes=posts.reduce((s,p)=>s+p.likes,0); const el=document.getElementById('view-analytics'); el.innerHTML=`
Follower Growth — 30 Days
This Week
+${newThisWeek}
Previous Week
+${newPrevWeek}
Change
${newThisWeek>newPrevWeek?'↑':'↓'}${Math.abs(newThisWeek-newPrevWeek)}
Geographic Distribution US Regions
${regionEntries.map(([region,count])=>`
${region} ${count} (${((count/followers.length)*100).toFixed(0)}%)
`).join('')}
Your followers are most active on: Tuesday, Wednesday
Content Performance Summary
Total Views
${formatNum(totalViews)}
Total Likes
${formatNum(totalLikes)}
Avg Engagement
${totalViews>0?((totalLikes/totalViews)*100).toFixed(1):0}%
Top Active Followers
${[...followers].sort((a,b)=>b.interactions-a.interactions).slice(0,5).map(f=>`
${f.name.slice(-3)}
${f.name}
${f.region} · Joined ${timeAgo(f.joined)}
${f.interactions} interactions
`).join('')}
`; requestAnimationFrame(()=>{ if(growth.length){ drawLineChart(document.getElementById('analyticsGrowthChart'),growth.map(g=>g.count),growth.map(g=>g.date)); } }); } /* ═══════════════════════════════════════════════════════ REVENUE VIEW ═══════════════════════════════════════════════════════ */ function renderRevenue(){ const mid=currentMentor.id; const el=document.getElementById('view-revenue'); el.innerHTML=`
Coming Q3 2026

Subscription Management

Monetize your expertise. Set your own subscription price, manage subscribers, and track your revenue — all from one place.

Set Monthly Price
$0 — $499/month, your choice
Subscriber Dashboard
Track sub count and MRR in real-time
Payout History
Full payout ledger and bank transfers
Coupon Codes
Create discounts for your community
Your content is free to all members. Paid subscriptions launching Q3 2026.
`; } function joinWaitlist(){ const email=document.getElementById('waitlistEmail').value.trim(); if(!email)return; const waitlist=lsGet('bnb_mentor_waitlist',[]); if(!waitlist.includes(email)){waitlist.push(email);lsSet('bnb_mentor_waitlist',waitlist)} document.getElementById('waitlistMsg').style.display='block'; document.getElementById('waitlistForm').style.display='none'; } /* ═══════════════════════════════════════════════════════ NOTIFICATIONS VIEW ═══════════════════════════════════════════════════════ */ function renderNotifications(){ const mid=currentMentor.id; const notifs=lsGet(`bnb_mentor_notifs_${mid}`,[]); const el=document.getElementById('view-notifications'); el.innerHTML=`
All Notifications
${notifs.length===0?'
No notifications
':''} ${notifs.map(n=>renderNotifItem(n)).join('')}
`; } function renderNotifItem(n){ const icons={ follow:'', like:'', comment:'', chat:'', platform:'' }; return `
${icons[n.type]||''}
${n.text}
${timeAgo(n.timestamp)}
`; } function markNotifRead(id){ const mid=currentMentor.id; const notifs=lsGet(`bnb_mentor_notifs_${mid}`,[]); const n=notifs.find(x=>x.id===id); if(n){n.read=true;lsSet(`bnb_mentor_notifs_${mid}`,notifs);updateNotifBadge()} if(currentView==='notifications')renderNotifications(); } function markAllRead(){ const mid=currentMentor.id; const notifs=lsGet(`bnb_mentor_notifs_${mid}`,[]); notifs.forEach(n=>n.read=true); lsSet(`bnb_mentor_notifs_${mid}`,notifs); updateNotifBadge(); } function clearAllNotifs(){ const mid=currentMentor.id; lsSet(`bnb_mentor_notifs_${mid}`,[]); updateNotifBadge(); } function updateNotifBadge(){ if(!currentMentor)return; const notifs=lsGet(`bnb_mentor_notifs_${currentMentor.id}`,[]); const unread=notifs.filter(n=>!n.read).length; const topBadge=document.getElementById('topNotifBadge'); const navBadge=document.getElementById('navNotifBadge'); if(topBadge){topBadge.classList.toggle('show',unread>0)} if(navBadge){ navBadge.style.display=unread>0?'inline':'none'; navBadge.textContent=unread; } } /* Notification slide panel */ function toggleNotifPanel(){ const panel=document.getElementById('notifPanel'); panel.classList.toggle('open'); if(panel.classList.contains('open')){ renderNotifPanelList(); } } function renderNotifPanelList(){ const notifs=lsGet(`bnb_mentor_notifs_${currentMentor.id}`,[]); document.getElementById('notifList').innerHTML=notifs.slice(0,15).map(n=>renderNotifItem(n)).join('')||'
No notifications
'; } /* ═══════════════════════════════════════════════════════ SETTINGS VIEW ═══════════════════════════════════════════════════════ */ function renderSettings(){ const mid=currentMentor.id; const settings=lsGet(`bnb_mentor_settings_${mid}`,{ emailNotifs:{follow:true,like:true,comment:true,chat:true,platform:true}, privacy:{showEmail:false,showWebsite:true,showTrackRecord:true} }); const el=document.getElementById('view-settings'); el.innerHTML=`

Change Access Code

Email Notifications

${[ {key:'follow',label:'New Follower',desc:'When someone follows your profile'}, {key:'like',label:'Post Liked',desc:'When someone likes your content'}, {key:'comment',label:'Comment on Post',desc:'When someone comments on your post'}, {key:'chat',label:'New Chat Message',desc:'When someone messages in your chat room'}, {key:'platform',label:'Platform Announcements',desc:'Important platform updates and features'}, ].map(item=>`
${item.label}
${item.desc}
`).join('')}

Privacy Settings

${[ {key:'showEmail',label:'Show Email on Profile',desc:'Allow members to see your email address'}, {key:'showWebsite',label:'Show Website on Profile',desc:'Display your website URL publicly'}, {key:'showTrackRecord',label:'Show Track Record',desc:'Display your trading track record and returns'}, ].map(item=>`
${item.label}
${item.desc}
`).join('')}

Data & Account

`; } function toggleSetting(category,key,el){ const mid=currentMentor.id; const settings=lsGet(`bnb_mentor_settings_${mid}`,{ emailNotifs:{follow:true,like:true,comment:true,chat:true,platform:true}, privacy:{showEmail:false,showWebsite:true,showTrackRecord:true} }); settings[category][key]=!settings[category][key]; lsSet(`bnb_mentor_settings_${mid}`,settings); el.classList.toggle('on'); } async function changeAccessCode(){ const currentCode=document.getElementById('settCurrentCode').value; const newCode=document.getElementById('settNewCode').value; const confirmCode=document.getElementById('settConfirmCode').value; if(!currentCode||!newCode){showToast('Please fill in all fields');return} if(newCode!==confirmCode){showToast('New codes do not match');return} if(newCode.length<6){showToast('Code must be at least 6 characters');return} const cred=MENTOR_CREDENTIALS.find(m=>m.id===currentMentor.id); const currentHash=await sha256(cred.email+':'+currentCode); if(currentHash!==cred.hash){ // Check if custom hash exists const customHash=lsGet(`bnb_mentor_hash_${currentMentor.id}`,null); if(!customHash||currentHash!==customHash){ showToast('Current code is incorrect');return; } } const newHash=await sha256(cred.email+':'+newCode); lsSet(`bnb_mentor_hash_${currentMentor.id}`,newHash); // Update credential in memory for this session cred.hash=newHash; showToast('Access code updated!'); document.getElementById('settCurrentCode').value=''; document.getElementById('settNewCode').value=''; document.getElementById('settConfirmCode').value=''; } function exportData(){ const mid=currentMentor.id; const data={ mentor:currentMentor, profile:lsGet(`bnb_mentor_profile_${mid}`,{}), posts:lsGet(`bnb_mentor_posts_${mid}`,[]), followers:lsGet(`bnb_mentor_followers_${mid}`,[]), chat:lsGet(`bnb_mentor_chat_${mid}`,[]), notifications:lsGet(`bnb_mentor_notifs_${mid}`,[]), settings:lsGet(`bnb_mentor_settings_${mid}`,{}), growth:lsGet(`bnb_mentor_growth_${mid}`,[]), media:lsGet(`bnb_mentor_media_${mid}`,[]), exportDate:new Date().toISOString() }; const blob=new Blob([JSON.stringify(data,null,2)],{type:'application/json'}); const url=URL.createObjectURL(blob); const a=document.createElement('a'); a.href=url;a.download=`bnb-mentor-export-${mid}-${Date.now()}.json`; a.click();URL.revokeObjectURL(url); showToast('Data exported!'); } function openModal(id){document.getElementById(id).classList.add('show')} function closeModal(id){document.getElementById(id).classList.remove('show')} function confirmDeleteAccount(){ const mid=currentMentor.id; const keys=[ `bnb_mentor_posts_${mid}`,`bnb_mentor_followers_${mid}`, `bnb_mentor_growth_${mid}`,`bnb_mentor_chat_${mid}`, `bnb_mentor_notifs_${mid}`,`bnb_mentor_settings_${mid}`, `bnb_mentor_profile_${mid}`,`bnb_mentor_media_${mid}`, `bnb_mentor_announcement_${mid}`,`bnb_mentor_seeded_${mid}`, `bnb_mentor_hash_${mid}` ]; keys.forEach(k=>{try{localStorage.removeItem(k)}catch(e){}}); closeModal('deleteModal'); logout(); showToast('Account data deleted'); } /* ═══════════════════════════════════════════════════════ INIT — CHECK SESSION ═══════════════════════════════════════════════════════ */ (function(){ const session=ssGet('bnb_mentor_session',null); if(session&&session.id){ // Verify credential still exists const cred=MENTOR_CREDENTIALS.find(m=>m.id===session.id); if(cred){ initApp(session.id); return; } } })(); /* Close notif panel on click outside */ document.addEventListener('click',function(e){ const panel=document.getElementById('notifPanel'); const btn=document.querySelector('.btn-notif'); if(panel.classList.contains('open')&&!panel.contains(e.target)&&!btn.contains(e.target)){ panel.classList.remove('open'); } }); /* Close modals on overlay click */ document.querySelectorAll('.modal-overlay').forEach(overlay=>{ overlay.addEventListener('click',function(e){ if(e.target===this)this.classList.remove('show'); }); }); /* Login handler — supports both default and custom hashes */ document.getElementById('loginForm').addEventListener('submit',async function(e){ e.preventDefault(); const email=document.getElementById('loginEmail').value.toLowerCase().trim(); const code=document.getElementById('loginCode').value; const hash=await sha256(email+':'+code); // SECURITY: Hardcoded admin-email + cleartext-password bypass removed. // Admin access to the mentor portal must go through the central PIN flow. // The mentor-selector admin path will be re-wired once it reads role from // the new server-side JWT (lead-gate.js + /api/journal/login). // Check default credentials let found=MENTOR_CREDENTIALS.find(m=>m.email===email&&m.hash===hash); // Check custom hashes (if mentor changed their code) if(!found){ const cred=MENTOR_CREDENTIALS.find(m=>m.email===email); if(cred){ const customHash=lsGet(`bnb_mentor_hash_${cred.id}`,null); if(customHash&&customHash===hash){ found=cred; } } } if(found){ ssSet('bnb_mentor_session',{id:found.id,email:found.email,name:found.name,time:new Date().toISOString()}); document.getElementById('loginError').style.display='none'; initApp(found.id); }else{ document.getElementById('loginError').style.display='block'; document.getElementById('loginCode').value=''; } }); // ══════════════════════════════════════════════════════════════ // SOCIAL MEDIA HUB — Connect, Manage & Post to Social Platforms // ══════════════════════════════════════════════════════════════ var SOCIAL_PLATFORMS = [ { id:'youtube', name:'YouTube', icon:'▶️', color:'#FF0000', urlPrefix:'https://youtube.com/', placeholder:'Channel URL or @handle', connectUrl:'https://studio.youtube.com' }, { id:'instagram', name:'Instagram', icon:'📸', color:'#E4405F', urlPrefix:'https://instagram.com/', placeholder:'@username', connectUrl:'https://instagram.com' }, { id:'tiktok', name:'TikTok', icon:'🎵', color:'#000000', urlPrefix:'https://tiktok.com/@', placeholder:'@username', connectUrl:'https://tiktok.com' }, { id:'telegram', name:'Telegram', icon:'✈️', color:'#0088CC', urlPrefix:'https://t.me/', placeholder:'Channel or group link', connectUrl:'https://telegram.org' }, { id:'twitter', name:'X (Twitter)', icon:'𝕏', color:'#1DA1F2', urlPrefix:'https://x.com/', placeholder:'@handle', connectUrl:'https://x.com' }, { id:'discord', name:'Discord', icon:'💬', color:'#5865F2', urlPrefix:'https://discord.gg/', placeholder:'Server invite link', connectUrl:'https://discord.com' }, { id:'facebook', name:'Facebook', icon:'📘', color:'#1877F2', urlPrefix:'https://facebook.com/', placeholder:'Page URL', connectUrl:'https://facebook.com' }, { id:'linkedin', name:'LinkedIn', icon:'💼', color:'#0A66C2', urlPrefix:'https://linkedin.com/in/', placeholder:'Profile URL', connectUrl:'https://linkedin.com' }, { id:'twitch', name:'Twitch', icon:'🎮', color:'#9146FF', urlPrefix:'https://twitch.tv/', placeholder:'Channel name', connectUrl:'https://twitch.tv' }, { id:'stocktwits',name:'StockTwits', icon:'📈', color:'#1E88E5', urlPrefix:'https://stocktwits.com/', placeholder:'@username', connectUrl:'https://stocktwits.com' }, { id:'substack', name:'Substack', icon:'📰', color:'#FF6719', urlPrefix:'https://', placeholder:'yourname.substack.com', connectUrl:'https://substack.com' }, { id:'whatsapp', name:'WhatsApp', icon:'📱', color:'#25D366', urlPrefix:'https://wa.me/', placeholder:'Group invite link or number', connectUrl:'https://whatsapp.com' } ]; function _getSocialData(){ if(!currentMentor) return {}; try{ var d=localStorage.getItem('bnb_mentor_social_'+currentMentor.id); return d?JSON.parse(d):{}; }catch(e){ return {}; } } function _saveSocialData(data){ if(!currentMentor) return; try{ localStorage.setItem('bnb_mentor_social_'+currentMentor.id, JSON.stringify(data)); }catch(e){} } function _getSocialPosts(){ if(!currentMentor) return []; try{ var d=localStorage.getItem('bnb_mentor_social_posts_'+currentMentor.id); return d?JSON.parse(d):[]; }catch(e){ return []; } } function _saveSocialPosts(posts){ if(!currentMentor) return; try{ localStorage.setItem('bnb_mentor_social_posts_'+currentMentor.id, JSON.stringify(posts)); }catch(e){} } function renderSocialHub(){ var main=document.getElementById('mainContent'); if(!main) return; var social=_getSocialData(); var posts=_getSocialPosts(); var connectedCount=SOCIAL_PLATFORMS.filter(function(p){ return social[p.id] && social[p.id].connected; }).length; main.innerHTML='
'+ '
'+ '

Social Media Hub

'+ '

Connect your platforms, create content, and reach your audience everywhere.

'+ '
'+ '
'+ 'Connected: '+connectedCount+' / '+SOCIAL_PLATFORMS.length+''+ '
'+ '
'+ '
'+ // Connected Platforms Grid '
'+ '

Your Platforms

'+ '
'+ '
'+ // Quick Post Creator '
'+ '

'+ '✍️Create & Schedule Content

'+ '
'+ ''+ '
'+ '
'+ ''+ ''+ '
'+ '
'+ '
Post to:
'+ '
'+ '
'+ '
'+ ''+ ''+ ''+ ''+ '
'+ '
'+ // Post History & Scheduled Posts '
'+ '
'+ '

📋 Recent Posts

'+ '
'+ '
'+ '
'+ '

📅 Scheduled Posts

'+ '
'+ '
'+ '
'+ // Content Calendar '
'+ '

📆 Content Calendar — Best Posting Times

'+ '

Based on trading community engagement patterns. Green = high engagement windows.

'+ '
'+ '
'+ // Content Ideas Generator '
'+ '

💡 Content Ideas Generator

'+ '

Click to generate post ideas tailored to your trading style. Copy and customize.

'+ ''+ '
'+ '
'+ '
'; // Render platform cards renderPlatformGrid(social); // Render post targets renderPostTargets(social); // Render recent and scheduled posts renderSocialPosts(posts); // Render content calendar renderContentCalendar(); // Seed demo data if empty if(posts.length===0) seedSocialDemoData(); } function renderPlatformGrid(social){ var grid=document.getElementById('socialPlatformGrid'); if(!grid) return; grid.innerHTML=SOCIAL_PLATFORMS.map(function(p){ var data=social[p.id]||{}; var connected=data.connected; var handle=data.handle||''; var followers=data.followers||0; return '
'+ '
'+ '
'+ ''+p.icon+''+ '
'+p.name+'
'+ (connected?'
✓ Connected
':'
Not connected
')+ '
'+ '
'+ (connected?'
'+formatFollowers(followers)+'
followers
':'')+ '
'+ (connected? '
'+ ''+ ''+ ''+ '
' : '
'+ ''+ ''+ '
' )+ '
'; }).join(''); } function formatFollowers(n){ if(n>=1000000) return (n/1000000).toFixed(1)+'M'; if(n>=1000) return (n/1000).toFixed(1)+'K'; return String(n); } function escapeHtml(s){ var d=document.createElement('div'); d.textContent=s||''; return d.innerHTML; } function connectSocial(platformId){ var input=document.getElementById('social_connect_'+platformId); if(!input||!input.value.trim()){ alert('Please enter your '+SOCIAL_PLATFORMS.find(function(p){return p.id===platformId;}).name+' handle or URL.'); return; } var social=_getSocialData(); social[platformId]={ connected:true, handle:input.value.trim(), connectedAt:new Date().toISOString(), followers:Math.floor(Math.random()*5000)+100 // Demo follower count }; _saveSocialData(social); renderSocialHub(); // Re-render var status=document.getElementById('socialPostStatus'); if(status) status.textContent='✅ '+SOCIAL_PLATFORMS.find(function(p){return p.id===platformId;}).name+' connected!'; } function disconnectSocial(platformId){ if(!confirm('Disconnect '+SOCIAL_PLATFORMS.find(function(p){return p.id===platformId;}).name+'?')) return; var social=_getSocialData(); delete social[platformId]; _saveSocialData(social); renderSocialHub(); } function updateSocialHandle(platformId,value){ var social=_getSocialData(); if(social[platformId]) social[platformId].handle=value; _saveSocialData(social); } function openSocialPlatform(platformId){ var social=_getSocialData(); var platform=SOCIAL_PLATFORMS.find(function(p){return p.id===platformId;}); if(platform && social[platformId]){ var handle=social[platformId].handle; var url=handle.startsWith('http')?handle:platform.urlPrefix+handle.replace('@',''); window.open(url,'_blank'); } } function renderPostTargets(social){ var container=document.getElementById('socialPostTargets'); if(!container) return; container.innerHTML=SOCIAL_PLATFORMS.map(function(p){ var isConnected=social[p.id]&&social[p.id].connected; return ''; }).join(''); } function publishSocialPost(){ var text=document.getElementById('socialPostText'); var image=document.getElementById('socialPostImage'); var type=document.getElementById('socialPostType'); if(!text||!text.value.trim()){ alert('Please write some content first.'); return; } var targets=[]; document.querySelectorAll('#socialPostTargets input[type="checkbox"]:checked').forEach(function(cb){ targets.push(cb.value); }); if(targets.length===0){ alert('Select at least one platform to post to.'); return; } var posts=_getSocialPosts(); var post={ id: Date.now(), text: text.value.trim(), image: image?image.value.trim():'', type: type?type.value:'insight', targets: targets, publishedAt: new Date().toISOString(), scheduled: false, status: 'published', engagement: { views: Math.floor(Math.random()*500)+50, likes: Math.floor(Math.random()*80)+5, shares: Math.floor(Math.random()*20)+1, comments: Math.floor(Math.random()*15) } }; posts.unshift(post); _saveSocialPosts(posts); text.value=''; if(image) image.value=''; var status=document.getElementById('socialPostStatus'); if(status){ status.style.color='var(--accent)'; status.textContent='✅ Published to '+targets.length+' platform'+(targets.length>1?'s':'')+'!'; setTimeout(function(){ status.textContent=''; },3000); } renderSocialPosts(posts); } function scheduleSocialPost(){ var text=document.getElementById('socialPostText'); var image=document.getElementById('socialPostImage'); var type=document.getElementById('socialPostType'); var scheduleTime=document.getElementById('socialScheduleTime'); if(!text||!text.value.trim()){ alert('Please write some content first.'); return; } if(!scheduleTime||!scheduleTime.value){ alert('Please select a date and time to schedule.'); return; } var targets=[]; document.querySelectorAll('#socialPostTargets input[type="checkbox"]:checked').forEach(function(cb){ targets.push(cb.value); }); if(targets.length===0){ alert('Select at least one platform.'); return; } var posts=_getSocialPosts(); posts.unshift({ id: Date.now(), text: text.value.trim(), image: image?image.value.trim():'', type: type?type.value:'insight', targets: targets, scheduledFor: new Date(scheduleTime.value).toISOString(), scheduled: true, status: 'scheduled', engagement: null }); _saveSocialPosts(posts); text.value=''; if(image) image.value=''; if(scheduleTime) scheduleTime.value=''; var status=document.getElementById('socialPostStatus'); if(status){ status.style.color='#F59E0B'; status.textContent='📅 Scheduled!'; setTimeout(function(){ status.textContent=''; },3000); } renderSocialPosts(posts); } function renderSocialPosts(posts){ var recent=document.getElementById('socialRecentPosts'); var scheduled=document.getElementById('socialScheduledPosts'); if(!posts) posts=_getSocialPosts(); var published=posts.filter(function(p){ return p.status==='published'; }).slice(0,10); var scheduledPosts=posts.filter(function(p){ return p.status==='scheduled'; }); if(recent){ recent.innerHTML=published.length?published.map(function(p){ var platformIcons=p.targets.map(function(t){ var pl=SOCIAL_PLATFORMS.find(function(x){return x.id===t;}); return pl?pl.icon:''; }).join(' '); var eng=p.engagement||{}; return '
'+ '
'+ ''+platformIcons+''+ ''+new Date(p.publishedAt).toLocaleDateString()+''+ '
'+ '

'+escapeHtml(p.text.substring(0,120))+(p.text.length>120?'...':'')+'

'+ '
'+ '👁 '+(eng.views||0)+''+ '❤️ '+(eng.likes||0)+''+ '🔄 '+(eng.shares||0)+''+ '💬 '+(eng.comments||0)+''+ '
'+ '
'; }).join(''):'

No posts yet. Create your first post above.

'; } if(scheduled){ scheduled.innerHTML=scheduledPosts.length?scheduledPosts.map(function(p){ var platformIcons=p.targets.map(function(t){ var pl=SOCIAL_PLATFORMS.find(function(x){return x.id===t;}); return pl?pl.icon:''; }).join(' '); return '
'+ '
'+ ''+platformIcons+''+ '
📅 Scheduled
'+ ''+new Date(p.scheduledFor).toLocaleString()+'
'+ '
'+ '

'+escapeHtml(p.text.substring(0,120))+(p.text.length>120?'...':'')+'

'+ ''+ '
'; }).join(''):'

No scheduled posts.

'; } } function cancelScheduledPost(postId){ var posts=_getSocialPosts(); posts=posts.filter(function(p){ return p.id!==postId; }); _saveSocialPosts(posts); renderSocialPosts(posts); } function renderContentCalendar(){ var cal=document.getElementById('socialCalendar'); if(!cal) return; var days=['Mon','Tue','Wed','Thu','Fri','Sat','Sun']; var hours=['6AM','7AM','8AM','9AM','10AM','11AM','12PM','1PM','2PM','3PM','4PM','5PM','6PM','7PM','8PM','9PM']; // Engagement heatmap for trading community (US market hours weighted) var heat={ 'Mon':{'6AM':3,'7AM':4,'8AM':6,'9AM':9,'10AM':8,'11AM':7,'12PM':5,'1PM':4,'2PM':5,'3PM':7,'4PM':8,'5PM':6,'6PM':5,'7PM':6,'8PM':7,'9PM':5}, 'Tue':{'6AM':3,'7AM':5,'8AM':7,'9AM':10,'10AM':9,'11AM':7,'12PM':5,'1PM':4,'2PM':5,'3PM':7,'4PM':9,'5PM':7,'6PM':5,'7PM':6,'8PM':7,'9PM':5}, 'Wed':{'6AM':3,'7AM':4,'8AM':6,'9AM':9,'10AM':8,'11AM':7,'12PM':6,'1PM':5,'2PM':6,'3PM':7,'4PM':8,'5PM':6,'6PM':5,'7PM':6,'8PM':6,'9PM':4}, 'Thu':{'6AM':3,'7AM':5,'8AM':7,'9AM':10,'10AM':9,'11AM':8,'12PM':6,'1PM':5,'2PM':6,'3PM':8,'4PM':9,'5PM':7,'6PM':5,'7PM':6,'8PM':7,'9PM':5}, 'Fri':{'6AM':2,'7AM':3,'8AM':5,'9AM':8,'10AM':7,'11AM':6,'12PM':4,'1PM':3,'2PM':4,'3PM':5,'4PM':6,'5PM':4,'6PM':3,'7PM':4,'8PM':4,'9PM':3}, 'Sat':{'6AM':1,'7AM':2,'8AM':3,'9AM':5,'10AM':6,'11AM':5,'12PM':4,'1PM':3,'2PM':3,'3PM':3,'4PM':3,'5PM':2,'6PM':2,'7PM':3,'8PM':4,'9PM':3}, 'Sun':{'6AM':1,'7AM':2,'8AM':3,'9AM':4,'10AM':5,'11AM':5,'12PM':4,'1PM':3,'2PM':3,'3PM':4,'4PM':5,'5PM':5,'6PM':6,'7PM':7,'8PM':6,'9PM':5} }; var html=''; html+=''; hours.forEach(function(h){ html+=''; }); html+=''; days.forEach(function(d){ html+=''; hours.forEach(function(h){ var val=heat[d]&&heat[d][h]||0; var opacity=val/10; var bg=val>=8?'rgba(34,197,94,'+opacity+')':val>=5?'rgba(0,212,170,'+opacity+')':val>=3?'rgba(85,98,117,'+opacity+')':'rgba(85,98,117,0.05)'; html+=''; }); html+=''; }); html+='
'+h+'
'+d+'
'+(val>=7?val:'')+'
'; cal.innerHTML=html; } function generateContentIdeas(){ var container=document.getElementById('contentIdeas'); if(!container) return; var mentor=currentMentor?currentMentor.name:'Trader'; var ideas=[ {type:'📊 Market Analysis',text:'Share your pre-market watchlist with 3 tickers and why they are on your radar. Include chart screenshots.'}, {type:'🎓 Educational',text:'Explain one concept from your methodology in under 60 seconds. Perfect for TikTok/Reels/Shorts.'}, {type:'💡 Trade Review',text:'Walk through your best trade this week: entry, management, exit. What went right? What would you change?'}, {type:'🔥 Hot Take',text:'Share an unpopular trading opinion you hold. Ask your audience if they agree. Great for engagement.'}, {type:'📈 Chart Setup',text:'Post a clean chart with your analysis marked up. Ask followers: "Would you take this trade? Why or why not?"'}, {type:'🧠 Psychology Tip',text:'Share one mental framework that helps you stay disciplined. Tag it #tradingpsychology.'}, {type:'📚 Book of the Week',text:'Recommend a trading book that changed your perspective. Share one key takeaway.'}, {type:'⚡ Quick Tip',text:'One actionable trading tip in under 280 characters. Post to Twitter/X and StockTwits.'}, {type:'🎥 Live Session Promo',text:'Announce an upcoming live trading session or Q&A. Give followers a reason to show up.'}, {type:'📊 Weekly Recap',text:'Summarize your week: wins, losses, key lessons. Transparency builds trust.'} ]; // Shuffle and pick 6 ideas.sort(function(){return Math.random()-0.5;}); container.innerHTML=ideas.slice(0,6).map(function(idea){ return '
'+ '
'+idea.type+'
'+ '

'+idea.text+'

'+ ''+ '
'; }).join(''); } function seedSocialDemoData(){ if(!currentMentor) return; // Seed some connected platforms var social=_getSocialData(); if(Object.keys(social).length===0){ social={ youtube:{connected:true,handle:'@'+currentMentor.name.replace(/\s/g,''),connectedAt:new Date(Date.now()-86400000*10).toISOString(),followers:Math.floor(Math.random()*50000)+5000}, twitter:{connected:true,handle:'@'+currentMentor.name.split(' ')[1],connectedAt:new Date(Date.now()-86400000*15).toISOString(),followers:Math.floor(Math.random()*30000)+2000}, telegram:{connected:true,handle:currentMentor.name.split(' ')[1]+'Trading',connectedAt:new Date(Date.now()-86400000*7).toISOString(),followers:Math.floor(Math.random()*5000)+500}, discord:{connected:true,handle:currentMentor.name.split(' ')[1]+'Academy',connectedAt:new Date(Date.now()-86400000*20).toISOString(),followers:Math.floor(Math.random()*8000)+1000} }; _saveSocialData(social); } // Seed demo posts var posts=_getSocialPosts(); if(posts.length===0){ var demoTexts=[ 'Pre-market watchlist for today: watching NVDA for a breakout above $180, TSLA for a pullback to the 20 EMA, and AAPL for a continuation pattern. Volume will confirm.', 'Reminder: the best trade is often the one you don\'t take. Patience is the edge most traders never develop.', 'Just closed a clean trade on SPY using the opening range breakout. Entry at the 5-min high, stop below the low. Simple, effective.', 'New educational video dropping tomorrow on how I read Level 2 order flow. Subscribe so you don\'t miss it.', 'Weekly P&L: +$2,847. 8 trades, 6 winners, 2 small losers. Discipline > prediction.', 'The market is telling you something every single bar. The question is: are you listening? Study price action.' ]; for(var i=0;i