Home
Jobs 47
Applications 0
Messages
Career tools
Resume
Interview
Salary
Recruiters
Agents
Profile
Knowra AI
Sign Out
SK
Sravan Kumar
Free plan
Knowra AI
Career coach · Always on
Hi! Ask me anything — interview prep, salary negotiation, resume tips, or which roles to target.
/* ── CONFIG ── */ const SB_URL='https://shepqaryjfsrcdxapshn.supabase.co'; const SB_KEY='eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InNoZXBxYXJ5amZzcmNkeGFwc2huIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NzM3MTk5MDgsImV4cCI6MjA4OTI5NTkwOH0.cv_z4sOuVBHmkLJKEj-tb_da8FDBnUa73xhiO7pW99M'; const {createClient}=supabase; const sb=createClient(SB_URL,SB_KEY); let agentOn=true,appCount=47,notifOpen=false,chatOpen=false,swipeIdx=0; const logCos=['Google','Meta','Netflix','Stripe','Uber','Airbnb','OpenAI','Databricks','Snowflake','Figma']; let allBrowseJobs=[]; let swipeJobs=[ {co:'⚡ Databricks · Remote',role:'Senior Data Scientist — Platform AI',match:'91%',sal:'$160k–$220k'}, {co:'🧠 Anthropic · SF/Remote',role:'Research Data Scientist',match:'96%',sal:'$200k–$280k'}, {co:'🤖 OpenAI · SF',role:'Applied Data Scientist',match:'88%',sal:'$180k–$260k'}, {co:'💳 Stripe · SF/Remote',role:'Senior Data Scientist, Risk',match:'85%',sal:'$160k–$200k'}, {co:'🔍 Google · Mountain View',role:'ML Research Engineer',match:'94%',sal:'$200k–$320k'}, ]; const chatReplies=[ 'Based on your AB InBev and Knowra AI experience, focus on your RAG pipeline and Spark optimization stories. Those are your strongest differentiators.', 'For Google DeepMind, they care deeply about research fundamentals — attention mechanisms, gradient descent intuition, and your model evaluation approach.', 'Your Knowra AI project is a massive differentiator. Building a production GenAI SaaS from scratch shows end-to-end engineering capability. Lead with it.', 'For salary, always anchor high first. Your market value based on skills is $175k–$220k in the US. Counter Stripe\'s offer at $195k.', 'Target Anthropic, OpenAI, Databricks, and Snowflake this week — all are actively hiring for your exact profile right now.', ]; let chatIdx=0; /* ── AUTH ── */ window.addEventListener('load', async () => { // Theme const t = localStorage.getItem('kjTheme') || 'light'; document.documentElement.setAttribute('data-theme', t); // ── Handle token from home.html redirect (#access_token=...&refresh_token=...) ── const hash = window.location.hash; if (hash && hash.includes('access_token=')) { try { const params = new URLSearchParams(hash.replace('#', '')); const at = params.get('access_token'); const rt = params.get('refresh_token'); if (at) { await sb.auth.setSession({ access_token: at, refresh_token: rt || '' }); // Clean the URL hash without reloading history.replaceState(null, '', window.location.pathname); } } catch(e) { console.log('Hash session error:', e); } } // ── Auth check with refresh ── try { let { data: { session } } = await sb.auth.getSession(); // If no session or expired, try refreshing if (!session) { const refreshed = await sb.auth.refreshSession(); session = refreshed.data?.session; } if (!session) { window.location.href = 'https://knowraai.com/login.html'; return; } const u = session.user; const name = u.user_metadata?.full_name || u.email?.split('@')[0] || 'User'; const ini = name.split(' ').map(n => n[0]).join('').toUpperCase().slice(0, 2); ['navAv','sideAv','createAv','profileAv'].forEach(id => { const el = document.getElementById(id); if (el) el.textContent = ini; }); ['sideName','profileName'].forEach(id => { const el = document.getElementById(id); if (el) el.textContent = name; }); const saved = localStorage.getItem('kj_apps'); if (saved) { appCount = parseInt(saved) || 47; updateCounts(); } } catch(e) { console.log('Auth error:', e); } startAgent(); }); /* ── NAVIGATION ── */ /* ── THEME ── */ /* ── AGENT ── */ let agentTimer; function startAgent(){ clearInterval(agentTimer); agentTimer=setInterval(()=>{ appCount++; localStorage.setItem('kj_apps',appCount); updateCounts(); // Log entry const co=logCos[Math.floor(Math.random()*logCos.length)]; addLog('✅',co); },9000); } function addLog(ico,co){ const log=document.getElementById('agentLog'); if(!log)return; const d=document.createElement('div');d.className='lg'; d.innerHTML=`
${ico}
Applied → ${co}
now
`; log.insertBefore(d,log.firstChild); if(log.children.length>6)log.removeChild(log.lastChild); } /* ── NOTIFICATIONS ── */ document.addEventListener('click',e=>{ if(notifOpen&&!e.target.closest('.notif-panel')&&!e.target.closest('.nav-tab')){ notifOpen=false;document.getElementById('notifPanel').classList.remove('show'); } }); /* ── CHAT ── */ function toggleChat(){ chatOpen=!chatOpen; document.getElementById('chatPanel').classList.toggle('open',chatOpen); document.getElementById('chatFab').style.display=chatOpen?'none':'flex'; } function openChat(msg){ chatOpen=true; document.getElementById('chatPanel').classList.add('open'); document.getElementById('chatFab').style.display='none'; document.getElementById('chatInp').value=msg; setTimeout(sendChat,200); } function sendChat(){ const inp=document.getElementById('chatInp'); const msgs=document.getElementById('chatMsgs'); const txt=inp.value.trim(); if(!txt)return; const u=document.createElement('div');u.className='c-msg user';u.textContent=txt;msgs.appendChild(u); inp.value=''; const ty=document.createElement('div');ty.className='typing';ty.innerHTML=''; msgs.appendChild(ty);msgs.scrollTop=msgs.scrollHeight; setTimeout(()=>{ msgs.removeChild(ty); const a=document.createElement('div');a.className='c-msg ai'; a.textContent=chatReplies[chatIdx%chatReplies.length];chatIdx++; msgs.appendChild(a);msgs.scrollTop=msgs.scrollHeight; },1200); } /* ── SWIPE JOBS ── */ function swipeApply(){appCount++;updateCounts();swipeIdx++;nextJob();addLog('✅',swipeJobs[(swipeIdx-1)%swipeJobs.length].co.replace(/^[^ ]+ /,'').split(' ·')[0]);} function swipePass(){swipeIdx++;nextJob();} function nextJob(){ const j=swipeJobs[swipeIdx%swipeJobs.length]; document.querySelector('.sj-co').textContent=j.co; document.querySelector('.sj-role').textContent=j.role; document.querySelector('.sj-tags').innerHTML=`✓ ${j.match}${j.sal}Full-time`; document.getElementById('swipeCtr').innerHTML=`Job ${swipeIdx+1} of 12 · ${Math.max(0,12-swipeIdx-1)} remaining`; } /* ── MISC ── */ async function rlGetToken() { try { let { data: { session } } = await sb.auth.getSession(); if (!session) { // Try refresh const r = await sb.auth.refreshSession(); session = r.data?.session; } return session ? session.access_token : null; } catch(e) { return null; } } /* ── LOAD USER PROFILE ── */ async function loadUserProfile() { const token = await rlGetToken(); if (!token) return; try { const res = await fetch(API_URL + '/auth/me', { headers: {'authorization': 'Bearer ' + token} }); if (!res.ok) return; const data = await res.json(); const name = data.full_name || data.email?.split('@')[0] || 'User'; const ini = name.split(' ').map(n=>n[0]).join('').toUpperCase().slice(0,2); ['navAv','sideAv','createAv','profileAv'].forEach(id=>{ const el=document.getElementById(id); if(el) el.textContent=ini; }); ['sideName','profileName'].forEach(id=>{ const el=document.getElementById(id); if(el) el.textContent=name; }); const appsUsed = data.apps_used || 0; const appsLimit = data.apps_limit || 5; const pct = Math.min((appsUsed/appsLimit)*100,100).toFixed(1); const fill = document.getElementById('usageFill'); if (fill) fill.style.width = pct + '%'; const txt = document.getElementById('usageTxt'); if (txt) txt.textContent = appsUsed + ' / ' + appsLimit; const cnt = document.getElementById('apCount'); if (cnt) cnt.textContent = appsUsed; const sAps = document.getElementById('sAps'); if (sAps) sAps.textContent = appsUsed; } catch(e) { console.log('Profile error:', e); } } /* ── LOAD AGENT EVENTS ── */ async function loadAgentEvents() { const token = await rlGetToken(); if (!token) return; try { const res = await fetch(API_URL + '/agent-events?limit=20', { headers: {'authorization': 'Bearer ' + token} }); if (!res.ok) return; const data = await res.json(); if (!data.events?.length) return; const icos = {upload:'📄',tailor:'✏️',apply:'✅',cover_letter:'✉️',interview:'🎤',salary:'💰',followup:'📧',discover:'🔍'}; ['agentLog','agentLog2'].forEach(id => { const log = document.getElementById(id); if (!log) return; log.innerHTML = ''; data.events.slice(0,8).forEach(e => { const ico = icos[e.event_type] || '🤖'; const d = document.createElement('div'); d.className = 'lg'; const t = new Date(e.created_at).toLocaleTimeString(); d.innerHTML = `
${ico}
${e.description}
${t}
`; log.appendChild(d); }); }); } catch(e) { console.log('Events error:', e); } } /* ── LOAD APPLICATIONS ── */ async function loadApplications() { const token = await rlGetToken(); if (!token) return; try { const res = await fetch(API_URL + '/applications', { headers: {'authorization': 'Bearer ' + token} }); if (!res.ok) return; const data = await res.json(); if (!data.applications?.length) return; const table = document.querySelector('.at-table'); if (!table) return; const header = table.querySelector('.at-head'); table.innerHTML = ''; if (header) table.appendChild(header); const badge = s => ({'interview':'atb-int','applied':'atb-app','offered':'atb-off','pending':'atb-pend'}[s]||'atb-pend'); data.applications.forEach(app => { const diff = Math.floor((Date.now() - new Date(app.applied_at))/60000); const t = diff < 60 ? diff+'m' : diff < 1440 ? Math.floor(diff/60)+'h' : Math.floor(diff/1440)+'d'; const row = document.createElement('div'); row.className = 'at-row'; row.innerHTML = `
${app.company}
${app.role}
${app.match_score||0}%
${app.status}
${t}
`; table.appendChild(row); }); const count = data.applications.length; document.querySelectorAll('.sn-badge.g').forEach(el => el.textContent = count); const sAps = document.getElementById('sAps'); if (sAps) sAps.textContent = count; } catch(e) { console.log('Apps error:', e); } } /* ── RESUME LAB ── */ let rlResumeText = '', rlTailoredText = '', rlCoverText = ''; function rlShowStatus(elId, msg, type='info') { const el = document.getElementById(elId); if (!el) return; el.style.display = 'block'; const bg = {info:'var(--s2)',success:'var(--s2)',error:'rgba(220,38,38,0.1)',loading:'var(--s2)'}; const tc = {info:'var(--text)',success:'var(--text)',error:'#dc2626',loading:'var(--text)'}; el.style.background = bg[type]||bg.info; el.style.color = tc[type]||tc.info; el.style.border = `1px solid ${tc[type]||tc.info}44`; el.textContent = msg; } function rlHideStatus(elId) { const el = document.getElementById(elId); if (el) el.style.display = 'none'; } async function rlHandleFile(event) { const file = event.target.files[0]; if (file) await rlUploadFile(file); } async function rlHandleDrop(event) { event.preventDefault(); document.getElementById('rl-drop-zone').style.borderColor = 'var(--border2)'; const file = event.dataTransfer.files[0]; if (file) await rlUploadFile(file); } async function rlUploadFile(file) { const token = await rlGetToken(); if (!token) { rlShowStatus('rl-status','⚠️ Please log in first','error'); return; } document.getElementById('rl-drop-icon').textContent = '⏳'; document.getElementById('rl-drop-text').textContent = `Uploading ${file.name}...`; rlShowStatus('rl-status','📤 Uploading and parsing your resume...','loading'); const formData = new FormData(); formData.append('file', file); try { const res = await fetch(API_URL + '/upload-resume', { method: 'POST', headers: {'authorization': 'Bearer ' + token}, body: formData }); const data = await res.json(); if (!res.ok) { rlShowStatus('rl-status','❌ ' + (data.detail||'Upload failed'),'error'); document.getElementById('rl-drop-icon').textContent = '📄'; document.getElementById('rl-drop-text').textContent = 'Drop your resume or click to upload'; return; } rlResumeText = data.resume_text; document.getElementById('rl-drop-icon').textContent = '✅'; document.getElementById('rl-drop-text').textContent = file.name + ' uploaded!'; document.getElementById('rl-drop-zone').style.borderColor = 'var(--text)'; document.getElementById('rl-drop-zone').style.background = 'var(--s2)'; rlShowStatus('rl-status',`✅ Parsed ${data.chars.toLocaleString()} characters from your resume`,'success'); document.getElementById('rl-tailor-card').style.display = 'block'; document.getElementById('rl-tailor-card').scrollIntoView({behavior:'smooth',block:'start'}); await loadAgentEvents(); } catch(err) { rlShowStatus('rl-status','❌ Network error. Check your connection.','error'); document.getElementById('rl-drop-icon').textContent = '📄'; document.getElementById('rl-drop-text').textContent = 'Drop your resume or click to upload'; } } async function rlTailorResume() { if (!rlResumeText) { alert('Please upload your resume first.'); return; } const company = document.getElementById('rl-company').value.trim(); const role = document.getElementById('rl-role').value.trim(); const jd = document.getElementById('rl-jd').value.trim(); if (!company || !role || !jd) { alert('Please fill in company, role, and job description.'); return; } const token = await rlGetToken(); if (!token) { alert('Please log in first.'); return; } const btn = document.getElementById('rl-tailor-btn'); btn.textContent = '⏳ AI is tailoring...'; btn.disabled = true; rlShowStatus('rl-tailor-status','🤖 GPT-4o-mini is rewriting your resume for ' + company + '...','loading'); const formData = new FormData(); formData.append('job_description', jd); formData.append('company_name', company); formData.append('role', role); formData.append('resume_text', rlResumeText); try { const res = await fetch(API_URL + '/tailor-resume', { method: 'POST', headers: {'authorization': 'Bearer ' + token}, body: formData }); const data = await res.json(); if (!res.ok) { rlShowStatus('rl-tailor-status','❌ ' + (data.detail||'Tailoring failed'),'error'); btn.textContent = '🤖 Tailor with AI'; btn.disabled = false; return; } rlTailoredText = data.tailored_resume; document.getElementById('rl-score').textContent = data.match_score + '%'; document.getElementById('rl-result-meta').textContent = `Optimized for ${company} — ${role}`; document.getElementById('rl-preview').textContent = rlTailoredText.substring(0,600) + '...'; document.getElementById('rl-result-card').style.display = 'block'; document.getElementById('rl-result-card').scrollIntoView({behavior:'smooth',block:'start'}); rlHideStatus('rl-tailor-status'); btn.textContent = '🤖 Tailor with AI'; btn.disabled = false; await loadAgentEvents(); } catch(err) { rlShowStatus('rl-tailor-status','❌ Network error. Try again.','error'); btn.textContent = '🤖 Tailor with AI'; btn.disabled = false; } } async function rlDownloadDocx() { if (!rlTailoredText) { alert('Please tailor your resume first.'); return; } const token = await rlGetToken(); const company = document.getElementById('rl-company').value.trim(); const role = document.getElementById('rl-role').value.trim(); const btn = event.target; btn.textContent = '⏳ Generating .docx...'; btn.disabled = true; const formData = new FormData(); formData.append('resume_text', rlTailoredText); formData.append('company_name', company); formData.append('role', role); try { const res = await fetch(API_URL + '/generate-docx', { method: 'POST', headers: {'authorization': 'Bearer ' + token}, body: formData }); if (!res.ok) { alert('Failed to generate .docx'); btn.textContent='⬇️ Download Tailored Resume (.docx)'; btn.disabled=false; return; } const blob = await res.blob(); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = `Tailored_Resume_${company}_${role}.docx`.replace(/\\s+/g,'_'); document.body.appendChild(a); a.click(); document.body.removeChild(a); URL.revokeObjectURL(url); btn.textContent = '✅ Downloaded!'; setTimeout(() => { btn.textContent='⬇️ Download Tailored Resume (.docx)'; btn.disabled=false; }, 2000); } catch(err) { alert('Download failed.'); btn.textContent='⬇️ Download Tailored Resume (.docx)'; btn.disabled=false; } } async function rlGenerateCoverLetter() { if (!rlTailoredText) { alert('Please tailor your resume first.'); return; } const token = await rlGetToken(); const company = document.getElementById('rl-company').value.trim(); const role = document.getElementById('rl-role').value.trim(); const jd = document.getElementById('rl-jd').value.trim(); document.getElementById('rl-cover-card').style.display = 'block'; document.getElementById('rl-cover-text').textContent = '⏳ Writing your cover letter...'; document.getElementById('rl-cover-card').scrollIntoView({behavior:'smooth'}); const formData = new FormData(); formData.append('job_description', jd); formData.append('company_name', company); formData.append('role', role); formData.append('resume_text', rlTailoredText); try { const res = await fetch(API_URL + '/generate-cover-letter', { method: 'POST', headers: {'authorization': 'Bearer ' + token}, body: formData }); const data = await res.json(); rlCoverText = data.cover_letter; document.getElementById('rl-cover-text').textContent = rlCoverText; } catch(err) { document.getElementById('rl-cover-text').textContent = 'Failed. Try again.'; } } async function rlDownloadCoverLetter() { if (!rlCoverText) { alert('Generate cover letter first.'); return; } const token = await rlGetToken(); const company = document.getElementById('rl-company').value.trim(); const btn = event.target; btn.textContent = '⏳ Generating...'; btn.disabled = true; const formData = new FormData(); formData.append('cover_letter_text', rlCoverText); formData.append('company_name', company); try { const res = await fetch(API_URL + '/generate-cover-letter-docx', { method: 'POST', headers: {'authorization': 'Bearer ' + token}, body: formData }); const blob = await res.blob(); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = `Cover_Letter_${company}.docx`.replace(/\\s+/g,'_'); document.body.appendChild(a); a.click(); document.body.removeChild(a); URL.revokeObjectURL(url); btn.textContent = '✅ Downloaded!'; setTimeout(() => { btn.textContent='⬇️ Download Cover Letter (.docx)'; btn.disabled=false; }, 2000); } catch(err) { alert('Download failed.'); btn.textContent='⬇️ Download Cover Letter (.docx)'; btn.disabled=false; } } async function rlATSScore() { if (!rlResumeText) { alert('Upload your resume first.'); return; } const jd = document.getElementById('rl-jd').value.trim(); if (!jd) { alert('Paste the job description first.'); return; } const token = await rlGetToken(); document.getElementById('rl-ats-card').style.display = 'block'; document.getElementById('rl-ats-result').innerHTML = '
⏳ Analyzing ATS compatibility...
'; document.getElementById('rl-ats-card').scrollIntoView({behavior:'smooth'}); const formData = new FormData(); formData.append('resume_text', rlResumeText); formData.append('job_description', jd); try { const res = await fetch(API_URL + '/ats-score', { method: 'POST', headers: {'authorization': 'Bearer ' + token}, body: formData }); const data = await res.json(); const a = data.ats_analysis; document.getElementById('rl-ats-result').innerHTML = `
${a.ats_score}%
ATS Score
Keywords Found
${(a.keyword_matches||[]).join(', ')||'Analyzing...'}
Missing Keywords
${(a.missing_keywords||[]).join(', ')||'None detected'}
Recommendations
${(a.recommendations||[]).map(r=>`
• ${r}
`).join('')}
`; } catch(err) { document.getElementById('rl-ats-result').innerHTML = '
Analysis failed.
'; } } function rlReset() { rlResumeText = ''; rlTailoredText = ''; rlCoverText = ''; document.getElementById('rl-drop-icon').textContent = '📄'; document.getElementById('rl-drop-text').textContent = 'Drop your resume or click to upload'; document.getElementById('rl-drop-zone').style.borderColor = 'var(--border2)'; document.getElementById('rl-drop-zone').style.background = 'var(--surface2)'; document.getElementById('rl-file-input').value = ''; ['rl-tailor-card','rl-result-card','rl-cover-card','rl-ats-card'].forEach(id => { const el = document.getElementById(id); if(el) el.style.display = 'none'; }); rlHideStatus('rl-status'); } /* ── INTERVIEW PREP ── */ function setIPType(el, type) { el.closest('div').querySelectorAll('.af').forEach(b => b.classList.remove('active')); el.classList.add('active'); document.getElementById('ip-type').value = type; } function setIPNum(el, num) { el.closest('div').querySelectorAll('.af').forEach(b => b.classList.remove('active')); el.classList.add('active'); if (document.getElementById('ip-num')) document.getElementById('ip-num').value = num; } async function loadInterviewPrep() { const token = await rlGetToken(); if (!token) { alert('Please log in first.'); return; } const company = document.getElementById('ip-company')?.value?.trim(); const role = document.getElementById('ip-role')?.value?.trim(); const type = document.getElementById('ip-type')?.value || 'behavioral'; const numQ = parseInt(document.getElementById('ip-num')?.value || '10'); if (!company || !role) { alert('Please enter company and role.'); return; } const btn = document.getElementById('ip-btn'); btn.textContent = '⏳ Generating...'; btn.disabled = true; try { const res = await fetch(API_URL + '/interview-prep', { method: 'POST', headers: {'authorization': 'Bearer ' + token, 'Content-Type': 'application/json'}, body: JSON.stringify({company, role, job_description: role + ' position at ' + company, resume_text: 'Senior Data Scientist with 5+ years experience in ML, GenAI, RAG pipelines, Python, SQL, Spark, LangChain, FAISS. Built production AI systems at AB InBev and NantHealth.', num_questions: numQ}) }); const data = await res.json(); if (!res.ok) { alert('Error: ' + (data.detail||'Failed')); return; } const container = document.getElementById('ip-results'); container.innerHTML = ''; (data.questions||[]).forEach((q,i) => { container.innerHTML += `
Q${i+1} · ${type}
"${q.question}"
${q.why_asked?`
Why asked: ${q.why_asked}
`:''}
${q.answer_framework||q.suggested_answer||''}
${(q.key_points||[]).length?`
${(q.key_points||[]).map(p=>`${p}`).join('')}
`:''}
`; }); container.style.display = 'block'; container.scrollIntoView({behavior:'smooth'}); await loadAgentEvents(); } catch(err) { alert('Network error: ' + err.message); } finally { btn.textContent = '🎤 Generate Questions + Answers'; btn.disabled = false; } } /* ── SALARY INSIGHTS ── */ async function loadSalaryInsights() { const token = await rlGetToken(); if (!token) { alert('Please log in first.'); return; } const role = document.getElementById('si-role')?.value?.trim(); const location = document.getElementById('si-location')?.value?.trim(); const years = document.getElementById('si-years')?.value || '5'; if (!role || !location) { alert('Please enter role and location.'); return; } const btn = document.getElementById('si-btn'); btn.textContent = '⏳ Analyzing market...'; btn.disabled = true; try { const res = await fetch(API_URL + '/salary-insights', { method: 'POST', headers: {'authorization': 'Bearer ' + token, 'Content-Type': 'application/json'}, body: JSON.stringify({role, location, experience_years: parseInt(years), skills: ''}) }); const data = await res.json(); if (!res.ok) { alert('Error: ' + (data.detail||'Failed')); return; } const s = data.salary_data; const fmt = n => '$' + ((n||0)/1000).toFixed(0) + 'k'; const container = document.getElementById('si-results'); container.innerHTML = `
25th %ile
${fmt(s.percentiles?.['25th']||s.salary_range?.min||120000)}
Median
${fmt(s.median_salary||150000)}
90th %ile
${fmt(s.percentiles?.['90th']||s.salary_range?.max||200000)}
💡 Market Insight
${s.market_insight||'Strong market demand for this role.'}
🎯 Negotiation Target: ${fmt(s.negotiation_target||s.median_salary||150000)}
${(s.negotiation_tips||[]).map(t=>`
• ${t}
`).join('')}
`; container.style.display = 'block'; container.scrollIntoView({behavior:'smooth'}); await loadAgentEvents(); } catch(err) { alert('Network error: ' + err.message); } finally { btn.textContent = '💰 Get Salary Insights'; btn.disabled = false; } } /* ── BRAND BUILDER ── */ async function generateLinkedInPost() { const token = await rlGetToken(); if (!token) { alert('Please log in.'); return; } const achievement = document.getElementById('bb-achievement')?.value?.trim() || 'Built Knowra AI - production GenAI SaaS'; const btn = document.getElementById('bb-btn'); if (btn) { btn.textContent = '⏳ Generating...'; btn.disabled = true; } try { const res = await fetch(API_URL + '/generate-linkedin-post', { method: 'POST', headers: {'authorization': 'Bearer ' + token, 'Content-Type': 'application/json'}, body: JSON.stringify({resume_text: 'Senior Data Scientist 5+ years ML GenAI RAG LangChain FAISS Python Spark. Built Knowra AI SaaS. AB InBev $2M savings.', recent_achievement: achievement, target_role: 'Senior Data Scientist / GenAI Engineer'}) }); const data = await res.json(); const el = document.getElementById('bb-result'); if (el) { el.textContent = data.linkedin_post||'Failed'; el.style.display='block'; } } catch(err) { alert('Error: ' + err.message); } finally { if (btn) { btn.textContent = '✨ Generate LinkedIn Post'; btn.disabled = false; } } } /* ── SIGN OUT ── */ async function doSignOut() { try { await sb.auth.signOut(); } catch(e) {} localStorage.removeItem('kj_apps'); window.location.href = 'https://knowraai.com/login.html'; } /* ── MISC UI ── */ function clearLog() { const el = document.getElementById('agentLog'); if (el) el.innerHTML = '
Log cleared
'; } function exportCSV() { alert('Downloading applications.csv...'); } function showUpgrade() { alert('Upgrade to Pro for $29/month\\n\\nEmail: uppojusravan@gmail.com'); } function handleResume(e) { const f = e.target.files[0]; if (f) { document.getElementById('uploadTxt').textContent = '✓ ' + f.name; document.getElementById('uploadZone').style.background = 'var(--s2)'; document.getElementById('uploadZone').style.borderColor = 'var(--text)'; } } function launchCampaign() { const r = document.getElementById('fRole')?.value?.trim(); const c = document.getElementById('fCountry')?.value; if (!r) { document.getElementById('fRole')?.focus(); return; } if (!c) { alert('Please select a country'); return; } alert(`✅ Campaign launched!\\n\\nRole: ${r}\\nAgent will find companies and apply automatically.`); nav('feed', null); } /* ── AUTO INIT ── */ setTimeout(async () => { await loadUserProfile(); await loadAgentEvents(); await loadApplications(); setInterval(loadAgentEvents, 30000); setInterval(loadApplications, 60000); setInterval(loadUserProfile, 120000); }, 2500); /* ── REAL JOB LOADING ── */ const API_URL = 'https://knowra-jobs-backend.onrender.com'; async function loadRealJobs(role, country) { role = role || 'Data Scientist'; country = country || 'USA'; let token = null; try { const {data:{session}} = await sb.auth.getSession(); if (session) token = session.access_token; } catch(e) {} if (!token) { console.log('No token'); return; } try { const res = await fetch(API_URL + '/find-jobs', { method: 'POST', headers: {'Content-Type':'application/json','Authorization':'Bearer ' + token}, body: JSON.stringify({role, country, exp_level:'senior', max_apps:50}) }); if (!res.ok) return; const data = await res.json(); allBrowseJobs = data.jobs || []; swipeJobs = allBrowseJobs.slice(0,10).map(j => ({ co: j.company + ' · ' + j.location, role: j.title, match: (j.match_score || 80) + '%', sal: j.salary || 'Competitive', url: j.url, platform: j.platform })); swipeIdx = 0; if (swipeJobs.length) nextJob(); renderBrowseJobs(allBrowseJobs); } catch(e) { console.log('Job error:', e); } } function searchJobs() { const role = (document.getElementById('jobSearchRole')||{}).value || 'Data Scientist'; const country = (document.getElementById('jobSearchCountry')||{}).value || 'USA'; const bl = document.getElementById('browseJobsList'); if (bl) bl.innerHTML = '
Searching...
'; loadRealJobs(role, country); } function recruiterConnect(btn, name, company) { btn.textContent = '⏳ Connecting...'; btn.disabled = true; setTimeout(() => { btn.textContent = '✅ Sent!'; btn.style.background = 'var(--text)'; addLog('🤝', name + ' @ ' + company); openChat('Help me follow up with ' + name + ' at ' + company); }, 1200); } function recruiterResearch(btn, name, company) { btn.textContent = '⏳ Researching...'; btn.disabled = true; setTimeout(() => { btn.textContent = '📊 Ready'; btn.disabled = false; openChat('Research ' + name + ' at ' + company); }, 800); } async function generateOutreach() { var name = document.getElementById('rec-name').value.trim(); var company = document.getElementById('rec-company').value.trim(); if (!name || !company) { alert('Enter recruiter name and company.'); return; } var btn = document.getElementById('rec-btn'); btn.textContent = 'Generating...'; btn.disabled = true; document.getElementById('rec-result').style.display = 'block'; document.getElementById('rec-result').textContent = 'Writing your message...'; await new Promise(function(r) { setTimeout(r, 1500); }); var msg = [ 'Hi ' + name + ',', '', 'I noticed you are at ' + company + ' and wanted to reach out.', 'I am a Senior Data Scientist and GenAI Engineer with 5+ years experience.', '', 'At Anheuser-Busch I improved forecasting accuracy from 78% to 87%, saving $2M.', 'I also founded Knowra AI, a production GenAI SaaS platform.', '', 'I would love to connect about opportunities at ' + company + '.', '', 'Best,', 'Sravan Kumar Uppoju', 'sravankumaruppoju2@gmail.com | knowraai.com' ].join('\n'); document.getElementById('rec-result').textContent = msg; document.getElementById('rec-copy-btn').style.display = 'block'; btn.textContent = 'Generate Outreach Message'; btn.disabled = false; addLog('outreach', name + ' @ ' + company); } function copyOutreach() { const text = document.getElementById('rec-result').textContent; navigator.clipboard.writeText(text).then(() => { const btn = document.getElementById('rec-copy-btn'); btn.textContent = '✅ Copied!'; setTimeout(() => { btn.textContent = '📋 Copy Message'; }, 2000); }); } let brandPostText = 'Just shipped Knowra AI — production GenAI SaaS. RAG pipeline, FAISS, multi-agent. knowraai.com #GenAI'; var brandPosts = ['5 lessons from building a production RAG pipeline. Chunk size matters. Metadata filtering beats pure semantic. Reranking doubles quality. #GenAI #RAG', 'Best Data Scientists in 2025 build prod AI not just notebooks. 5yr DS experience now building Knowra AI full-stack. #DataScience #GenAI']; let brandIdx = 0; function brandPost() { window.open('https://www.linkedin.com/sharing/share-offsite/?url=' + encodeURIComponent('https://knowraai.com'), '_blank', 'width=600,height=500'); addLog('📢', 'LinkedIn post'); } function brandEdit() { const el = document.querySelector('#mod-brand .c-highlight'); if (!el) return; el.contentEditable = 'true'; el.focus(); el.style.border = '2px solid var(--text)'; el.onblur = () => { el.contentEditable = 'false'; el.style.border = ''; brandPostText = el.textContent; }; } function brandGenerate() { brandIdx = (brandIdx+1) % brandPosts.length; brandPostText = brandPosts[brandIdx]; var el = document.querySelector('#mod-brand .c-highlight'); if (el) { el.style.opacity = '0'; setTimeout(function() { el.innerHTML = brandPostText.replace(/\n/g,'
'); el.style.opacity = '1'; }, 300); } } /* ═══════════════════════════════════════ NEW UI LAYER — Sample 6 shell wiring ═══════════════════════════════════════ */ var _sbOpen = true, _dark = false; /* ── NEW UI ── */ var _sbOpen = true, _dark = false; var _sbOpen = true, _dark = false; function toggleSb() { _sbOpen = !_sbOpen; document.getElementById('sb').classList.toggle('closed', !_sbOpen); } function nav(id, el) { document.querySelectorAll('.ni').forEach(function(i) { i.classList.remove('on'); }); if (el) el.classList.add('on'); var fb = document.getElementById('filterBar'); if (fb) fb.style.display = id === 'jobs' ? 'flex' : 'none'; var pj = document.getElementById('panel-jobs'); var pm = document.getElementById('panel-main'); if (id === 'jobs') { if (pj) pj.style.display = 'flex'; if (pm) pm.style.display = 'none'; setTimeout(function() { var role = (document.getElementById('topSearchRole')||{}).value || 'Data Scientist'; var country = (document.getElementById('jobSearchCountry')||{}).value || 'USA'; loadRealJobs(role, country); }, 600); } else { if (pj) pj.style.display = 'none'; if (pm) pm.style.display = 'flex'; document.querySelectorAll('.mod').forEach(function(m) { m.style.display = 'none'; }); var mod = document.getElementById('mod-' + id); if (mod) { mod.style.display = 'flex'; mod.style.flexDirection = 'column'; } } notifOpen = false; } function fpill(el) { document.querySelectorAll('.fpill').forEach(function(p) { p.classList.remove('on'); }); el.classList.add('on'); } function selJob(el, company, title, loc, sal, posted, logo, match, t1, t2arg, t3) { document.querySelectorAll('.jcard').forEach(function(c) { c.classList.remove('selected'); }); el.classList.add('selected'); function set(id, v) { var e = document.getElementById(id); if (e) e.textContent = v; } set('detLogo', logo); set('detCo', company); set('detTitle', title); set('detMatch', match); set('detSalary', sal); var badges = document.getElementById('detBadges'); if (badges) { badges.innerHTML = [loc, sal, t1, t2arg, t3].filter(Boolean) .map(function(b, i) { return '' + b + ''; }).join(''); } var btn = document.getElementById('detApplyBtn'); if (btn) btn.onclick = function() { appCount++; updateCounts(); addLog('applied', company); alert('Applied to ' + company + ' — ' + title); }; } function topSearch() { var role = (document.getElementById('topSearchRole')||{}).value || 'Data Scientist'; var loc = (document.getElementById('topSearchLoc')||{}).value || 'USA'; var country = loc.indexOf('United') >= 0 ? 'USA' : loc; // Find the Jobs nav item by data-tip attribute var jobsNi = null; document.querySelectorAll('.ni').forEach(function(el) { if (el.getAttribute('data-tip') === 'Jobs') jobsNi = el; }); nav('jobs', jobsNi); var ac = document.getElementById('apiJobCards'); if (ac) ac.innerHTML = '
Searching ' + role + ' in ' + loc + '...
'; loadRealJobs(role, country); } function renderBrowseJobs(jobs) { var bList = document.getElementById('browseJobsList'); if (bList) { if (!jobs || !jobs.length) { bList.innerHTML = '
No jobs found.
'; } else { var rows = ''; for (var i = 0; i < Math.min(jobs.length, 20); i++) { var j = jobs[i]; rows += '
'; rows += '
' + (j.company||'') + ' — ' + (j.title||'') + '
'; rows += '
' + (j.location||'') + ' · ' + (j.salary||'Competitive') + '
'; rows += '
' + (j.match_score||80) + '%
'; } bList.innerHTML = rows; } } var apiCards = document.getElementById('apiJobCards'); if (apiCards && jobs && jobs.length) { apiCards.innerHTML = ''; for (var k = 0; k < Math.min(jobs.length, 20); k++) { (function(j) { var logo = (j.company||'?').slice(0,2); var co = (j.company||'').replace(/'+ '
'+co+'
'+ '
'+ti+'
'+ '
'+src+'
'+ '
'+loc+'
'+ '
'+pct+' match'+ ''+(src||'Job board')+'
'+ '
'+sal+''+ '
'+ '
'; card.onclick = function() { selJob(this,co,ti,loc,sal,'',logo,pct,src,'',''); }; card.querySelector('.s2b').onclick = function(e){ e.stopPropagation(); }; card.querySelector('.a2b').onclick = function(e){ e.stopPropagation(); appCount++; updateCounts(); addLog('applied',co); this.textContent='Applied'; }; apiCards.appendChild(card); })(jobs[k]); } var cnt=jobs.length; ['jobsCount','listJobsCount','niJobsCount'].forEach(function(id){ var e=document.getElementById(id); if(e) e.textContent = id==='jobsCount' ? cnt+' jobs' : cnt; }); } } function toggleTheme() { _dark = !_dark; document.documentElement.setAttribute('data-theme', _dark?'dark':'light'); localStorage.setItem('kjTheme', _dark?'dark':'light'); var pupil=document.getElementById('pupil'); if(pupil) pupil.setAttribute('fill', _dark?'#141414':'#f5f5f5'); var icon=document.getElementById('themeIcon'); if(icon) icon.innerHTML = _dark ? '' : ''; } function updateCounts() { function set(id,v){var e=document.getElementById(id);if(e)e.textContent=v;} set('apCount',appCount);set('sAps',appCount);set('icAps',appCount); var fill=document.getElementById('usageFill'); if(fill)fill.style.width=Math.min((appCount/200)*100,100).toFixed(1)+'%'; set('usageTxt',appCount+' / 200'); } function setFT(el){document.querySelectorAll('.ft').forEach(function(t){t.classList.remove('active');});el.classList.add('active');} function setFilter(el){el.closest('div').querySelectorAll('.af').forEach(function(b){b.classList.remove('active');});el.classList.add('active');} function setMob(el){document.querySelectorAll('.bn').forEach(function(b){b.classList.remove('active');});el.classList.add('active');} function toggleNotif(){notifOpen=!notifOpen;} function markRead(){notifOpen=false;} function toggleAgent(){ agentOn=!agentOn; var dot=document.getElementById('apDot'),txt=document.getElementById('apTxt'); if(dot)dot.className=agentOn?'ap-dot':'ap-dot off'; if(txt)txt.textContent=agentOn?'Agent running':'Agent paused'; agentOn?startAgent():clearInterval(agentTimer); } document.addEventListener('DOMContentLoaded', function() { var saved=localStorage.getItem('kjTheme')||'light'; saved==='dark'; document.documentElement.setAttribute('data-theme',saved); var pupil=document.getElementById('pupil'); if(pupil)pupil.setAttribute('fill',_dark?'#141414':'#f5f5f5'); if(_dark){var icon=document.getElementById('themeIcon');if(icon)icon.innerHTML='';} var pj=document.getElementById('panel-jobs'),pm=document.getElementById('panel-main'); if(pj)pj.style.display='none'; if(pm)pm.style.display='flex'; var feedMod=document.getElementById('mod-feed'); if(feedMod){feedMod.style.display='flex';feedMod.style.flexDirection='column';} setTimeout(function(){loadUserProfile();loadAgentEvents();loadApplications();},2500); document.querySelectorAll('.fpill').forEach(function(p){p.onclick=function(){fpill(this);};}); });