// popup.js — Settings popup logic // ─── Helpers ──────────────────────────────────────────────────────────────── function showToast(msg, type = '') { const toast = document.getElementById('toast'); toast.textContent = msg; toast.className = 'toast show ' + type; setTimeout(() => { toast.className = 'toast'; }, 2500); } function setKeyStatus(state) { const badge = document.getElementById('key-status'); badge.style.display = 'inline-flex'; if (state === 'ok') { badge.className = 'status-badge success'; badge.innerHTML = ' Valid'; } else if (state === 'error') { badge.className = 'status-badge error'; badge.innerHTML = ' Invalid'; } else if (state === 'checking') { badge.className = 'status-badge checking'; badge.innerHTML = ' Testing...'; } } function updateUsageUI(count) { const max = 1000; const pct = Math.min((count / max) * 100, 100).toFixed(1); document.getElementById('usage-count').textContent = `${count} / 1,000 requests`; document.getElementById('usage-fill').style.width = pct + '%'; } // ─── Load saved settings ──────────────────────────────────────────────────── function loadSettings() { chrome.storage.sync.get(['apiKey', 'userProfile', 'language'], (data) => { if (data.apiKey) { document.getElementById('api-key-input').value = data.apiKey; setKeyStatus('ok'); } let profile = data.userProfile || DEFAULT_PROFILE; if (profile.includes('hamzaayed@intaleqapp.com') || profile.includes('hamzaayedflutter@gmail.com') || profile.includes('hamzaayed@tripz-egypt.com')) { profile = profile .replace(/hamzaayed@intaleqapp\.com/g, 'hamzaayed.dev@gmail.com') .replace(/hamzaayedflutter@gmail\.com/g, 'hamzaayed.dev@gmail.com') .replace(/hamzaayed@tripz-egypt\.com/g, 'hamzaayed.dev@gmail.com'); chrome.storage.sync.set({ userProfile: profile }); } document.getElementById('profile-textarea').value = profile; document.getElementById('lang-select').value = data.language || 'auto'; }); // Usage counter from local storage const today = new Date().toDateString(); chrome.storage.local.get(['usageDate', 'usageCount'], (data) => { if (data.usageDate === today) { updateUsageUI(data.usageCount || 0); } else { updateUsageUI(0); } }); } // ─── Save settings ────────────────────────────────────────────────────────── document.getElementById('save-btn').addEventListener('click', () => { const apiKey = document.getElementById('api-key-input').value.trim(); const userProfile = document.getElementById('profile-textarea').value.trim(); const language = document.getElementById('lang-select').value; if (!apiKey) { showToast('⚠️ Please enter your API Key', 'error'); return; } if (!userProfile) { showToast('⚠️ Profile cannot be empty', 'error'); return; } chrome.storage.sync.set({ apiKey, userProfile, language }, () => { showToast('✅ Settings saved!', 'success'); }); }); // ─── Toggle API key visibility ─────────────────────────────────────────────── document.getElementById('toggle-key').addEventListener('click', () => { const input = document.getElementById('api-key-input'); const btn = document.getElementById('toggle-key'); if (input.type === 'password') { input.type = 'text'; btn.textContent = '🙈'; } else { input.type = 'password'; btn.textContent = '👁'; } }); // ─── Test API Key ─────────────────────────────────────────────────────────── document.getElementById('test-key-btn').addEventListener('click', async () => { const apiKey = document.getElementById('api-key-input').value.trim(); if (!apiKey) { showToast('⚠️ Enter your API key first', 'error'); return; } setKeyStatus('checking'); try { const response = await fetch( `https://generativelanguage.googleapis.com/v1beta/models/gemini-flash-lite-latest:generateContent?key=${apiKey}`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ contents: [{ parts: [{ text: 'Say "OK" in one word.' }] }], generationConfig: { maxOutputTokens: 5 } }) } ); if (response.ok) { setKeyStatus('ok'); showToast('✅ API Key is valid!', 'success'); } else { const err = await response.json(); setKeyStatus('error'); showToast('❌ Invalid key: ' + (err.error?.message || response.status), 'error'); } } catch (e) { setKeyStatus('error'); showToast('❌ Network error: ' + e.message, 'error'); } }); // ─── Reset profile ────────────────────────────────────────────────────────── document.getElementById('reset-profile-btn').addEventListener('click', () => { if (confirm('Reset profile to default?')) { document.getElementById('profile-textarea').value = DEFAULT_PROFILE; showToast('🔄 Profile reset to default'); } }); // ─── Clear cache ───────────────────────────────────────────────────────────── document.getElementById('clear-cache-btn').addEventListener('click', () => { chrome.storage.local.remove(['analysisCache'], () => { showToast('🗑️ Analysis cache cleared'); }); }); // ─── Clear all data ────────────────────────────────────────────────────────── document.getElementById('clear-all-btn').addEventListener('click', () => { if (confirm('Clear ALL data including API key and profile?')) { chrome.storage.sync.clear(() => { chrome.storage.local.clear(() => { document.getElementById('api-key-input').value = ''; document.getElementById('profile-textarea').value = DEFAULT_PROFILE; document.getElementById('lang-select').value = 'auto'; document.getElementById('key-status').style.display = 'none'; updateUsageUI(0); showToast('🗑️ All data cleared'); }); }); } }); // ─── Autofill Functionality ────────────────────────────────────────────────── function parseProfileText(text) { const emailRegex = /[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/; const phoneRegex = /\+?[0-9]{1,4}[ \t.-]?[0-9]{3,4}[ \t.-]?[0-9]{3,4}/; const linkedinRegex = /(https?:\/\/)?(www\.)?linkedin\.com\/in\/[a-zA-Z0-9_-]+/; const githubRegex = /(https?:\/\/)?(www\.)?github\.com\/[a-zA-Z0-9_-]+/; const emailMatch = text.match(emailRegex); const phoneMatch = text.match(phoneRegex); const linkedinMatch = text.match(linkedinRegex); const githubMatch = text.match(githubRegex); // Extract Name (first line usually) const lines = text.split('\n').map(l => l.trim()).filter(Boolean); let fullName = "Hamza Ayed"; if (lines.length > 0) { const firstLine = lines[0].replace(/—.*/, '').replace(/:.*/, '').trim(); fullName = firstLine; } const nameParts = fullName.split(' '); const firstName = nameParts[0] || ""; const lastName = nameParts.slice(1).join(' ') || ""; // Extract Summary let summary = ""; const summaryIdx = text.toLowerCase().indexOf("summary:"); if (summaryIdx !== -1) { const skillsIdx = text.toLowerCase().indexOf("core skills:", summaryIdx); if (skillsIdx !== -1) { summary = text.substring(summaryIdx + 8, skillsIdx).trim(); } else { summary = text.substring(summaryIdx + 8, summaryIdx + 500).trim(); } } return { fullName, firstName, lastName, email: emailMatch ? emailMatch[0] : "", phone: phoneMatch ? phoneMatch[0] : "", linkedin: linkedinMatch ? linkedinMatch[0] : "", github: githubMatch ? githubMatch[0] : "", summary, cvText: text }; } document.getElementById('autofill-btn').addEventListener('click', async () => { const userProfile = document.getElementById('profile-textarea').value.trim(); if (!userProfile) { showToast('⚠️ Please enter profile info first', 'error'); return; } const profileData = parseProfileText(userProfile); try { const [tab] = await chrome.tabs.query({ active: true, currentWindow: true }); if (!tab) { showToast('❌ No active tab found', 'error'); return; } // Set the profile data on the tab window context await chrome.scripting.executeScript({ target: { tabId: tab.id }, func: (data) => { window.__autofillProfileData = data; }, args: [profileData] }); // Execute the filler script const results = await chrome.scripting.executeScript({ target: { tabId: tab.id }, files: ['filler.js'] }); if (results && results[0]) { showToast('✨ ' + results[0].result, 'success'); } else { showToast('✨ Autofill completed!', 'success'); } } catch (e) { console.error(e); showToast('❌ Error: ' + e.message, 'error'); } }); // ─── Init ──────────────────────────────────────────────────────────────────── loadSettings();