'use strict'; const $ = (sel) => document.querySelector(sel); const MASTER_KEY = 'enabled'; const PROFILES_KEY = 'profiles'; let editingProfileId = null; // ---- Master toggle ---- async function loadMaster() { const { enabled } = await browser.storage.local.get(MASTER_KEY); $('#masterToggle').checked = enabled !== false; $('#masterLabel').textContent = enabled === false ? 'Disabled' : 'Enabled'; } $('#masterToggle').addEventListener('change', async (e) => { await browser.storage.local.set({ [MASTER_KEY]: e.target.checked }); $('#masterLabel').textContent = e.target.checked ? 'Enabled' : 'Disabled'; }); // ---- Profiles ---- async function getProfiles() { const { profiles } = await browser.storage.local.get(PROFILES_KEY); return profiles || []; } async function saveProfiles(profiles) { await browser.storage.local.set({ [PROFILES_KEY]: profiles }); } function renderProfiles(profiles) { const list = $('#profileList'); list.innerHTML = ''; for (const p of profiles) { const li = document.createElement('li'); const name = document.createElement('div'); name.className = 'name'; name.innerHTML = '' + escapeHtml(p.name) + '
' + escapeHtml(p.username) + ''; const toggle = document.createElement('input'); toggle.type = 'checkbox'; toggle.checked = !!p.enabled; toggle.title = 'Enable/disable'; toggle.addEventListener('change', async () => { p.enabled = toggle.checked; await saveProfiles(profiles); }); const edit = document.createElement('button'); edit.className = 'btn'; edit.textContent = 'Edit'; edit.addEventListener('click', () => openProfileForm(p)); const del = document.createElement('button'); del.className = 'btn'; del.textContent = 'Delete'; del.addEventListener('click', async () => { await saveProfiles(profiles.filter((x) => x.id !== p.id)); renderProfiles(await getProfiles()); }); li.append(toggle, name, edit, del); list.appendChild(li); } } function escapeHtml(s) { return String(s).replace(/[&<>"']/g, (c) => ({ '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' }[c])); } function openProfileForm(p) { editingProfileId = p ? p.id : null; $('#pName').value = p ? p.name : ''; $('#pUsername').value = p ? p.username : ''; $('#pPassword').value = p ? p.password : ''; $('#pEnabled').checked = p ? !!p.enabled : true; $('#profileForm').hidden = false; } $('#addProfile').addEventListener('click', () => openProfileForm(null)); $('#cancelProfile').addEventListener('click', () => { $('#profileForm').hidden = true; }); $('#saveProfile').addEventListener('click', async () => { const profiles = await getProfiles(); const data = { id: editingProfileId || Date.now().toString(), name: $('#pName').value.trim(), username: $('#pUsername').value.trim(), password: $('#pPassword').value, enabled: $('#pEnabled').checked }; if (!data.name || !data.username) return; if (editingProfileId) { const i = profiles.findIndex((x) => x.id === editingProfileId); if (i >= 0) profiles[i] = data; } else { profiles.push(data); } await saveProfiles(profiles); $('#profileForm').hidden = true; renderProfiles(profiles); }); // ---- Tabs ---- document.querySelectorAll('.tabs button').forEach((btn) => { btn.addEventListener('click', () => { document.querySelectorAll('.tabs button').forEach((b) => b.classList.remove('active')); btn.classList.add('active'); $('#tab-login').hidden = btn.dataset.tab !== 'login'; $('#tab-studyload').hidden = btn.dataset.tab !== 'studyload'; }); }); // ---- Study Load ---- function setStatus(msg, cls) { const el = $('#status'); el.textContent = msg; el.className = 'status ' + (cls || ''); } function renderCourses(courses) { const box = $('#coursesEditor'); box.innerHTML = ''; courses.forEach((c, i) => { const row = document.createElement('div'); row.className = 'course-row'; row.innerHTML = '
' + '' + '' + '' + '' + '' + '' + '
' + '' + ''; box.appendChild(row); }); box.querySelectorAll('input').forEach((inp) => { inp.addEventListener('input', () => { const i = +inp.dataset.i; const f = inp.dataset.f; studyLoadCourses[i][f] = inp.value; }); }); box.querySelectorAll('.remove-course').forEach((btn) => { btn.addEventListener('click', () => { studyLoadCourses.splice(+btn.dataset.i, 1); renderCourses(studyLoadCourses); }); }); } let studyLoadCourses = []; $('#loadFromPortal').addEventListener('click', async () => { setStatus('Loading from portal...'); try { const res = await browser.runtime.sendMessage({ type: 'scrape-study-load' }); if (!res || !res.ok) throw new Error((res && res.error) || 'Scrape failed'); const d = res.data; $('#hFullName').value = d.header.fullName || ''; $('#hStudentId').value = d.header.studentId || ''; $('#hProgram').value = d.header.program || ''; $('#hYearLevel').value = d.header.yearLevel || ''; $('#hSemester').value = d.header.semester || ''; $('#hDateEnrolled').value = d.header.dateEnrolled || ''; $('#hDateRange').value = d.header.dateRange || ''; $('#totalUnits').value = d.totalUnits || ''; studyLoadCourses = d.courses || []; renderCourses(studyLoadCourses); $('#studyLoadForm').hidden = false; setStatus('Loaded. Review and generate.', 'ok'); } catch (err) { setStatus('Could not load from portal: ' + err.message + ' — enter manually below.', 'error'); studyLoadCourses = []; renderCourses(studyLoadCourses); $('#studyLoadForm').hidden = false; } }); $('#addCourse').addEventListener('click', () => { studyLoadCourses.push({ group: '', courseCode: '', description: '', units: '', teacher: '', schedule: '', status: '' }); renderCourses(studyLoadCourses); }); $('#generatePdf').addEventListener('click', async () => { const data = { header: { fullName: $('#hFullName').value.trim(), studentId: $('#hStudentId').value.trim(), program: $('#hProgram').value.trim(), yearLevel: $('#hYearLevel').value.trim(), semester: $('#hSemester').value.trim(), dateEnrolled: $('#hDateEnrolled').value.trim(), dateRange: $('#hDateRange').value.trim() }, courses: studyLoadCourses, totalUnits: $('#totalUnits').value.trim() }; if (!data.courses.length) { setStatus('Add at least one course.', 'error'); return; } setStatus('Generating PDF...'); try { const res = await browser.runtime.sendMessage({ type: 'generate-pdf', data }); if (!res || !res.ok) throw new Error((res && res.error) || 'Generation failed'); setStatus('PDF downloaded.', 'ok'); } catch (err) { setStatus('Error: ' + err.message, 'error'); } }); // ---- Init ---- (async function init() { await loadMaster(); renderProfiles(await getProfiles()); })();