Files
eship/Extension/popup/popup.js
2026-01-17 17:07:46 +01:00

320 lines
9.1 KiB
JavaScript

// EShip Extension Popup Logic
// DOM Elements
const loadingEl = document.getElementById('loading');
const loginFormEl = document.getElementById('login-form');
const toolsMenuEl = document.getElementById('tools-menu');
const authForm = document.getElementById('auth-form');
const emailInput = document.getElementById('email');
const passwordInput = document.getElementById('password');
const errorMessage = document.getElementById('error-message');
const loginBtn = document.getElementById('login-btn');
const logoutBtn = document.getElementById('logout-btn');
const userEmailEl = document.getElementById('user-email');
const toolsListEl = document.getElementById('tools-list');
const openSiteBtn = document.getElementById('open-site-btn');
// Protected site URL (should match config.js)
const PROTECTED_SITE_URL = 'http://localhost:5173';
// State
let currentUser = null;
let tools = [];
// Initialize popup
document.addEventListener('DOMContentLoaded', init);
async function init() {
showState('loading');
try {
// Check if service worker is available
if (!chrome.runtime || !chrome.runtime.id) {
throw new Error('Chrome Runtime nicht verfuegbar');
}
// First, test if service worker is alive
console.log('Testing service worker...');
const pingResponse = await sendMessage({ action: 'PING' });
console.log('PING response:', pingResponse);
if (!pingResponse) {
throw new Error('Service Worker antwortet nicht. Bitte Extension in chrome://extensions neu laden und Service Worker Konsole pruefen.');
}
if (!pingResponse.success) {
throw new Error('Service Worker Fehler: ' + (pingResponse.error || 'Unbekannter Fehler'));
}
console.log('Service Worker ist aktiv!');
console.log('Checking auth status...');
// Check current auth status
const response = await sendMessage({ action: 'CHECK_AUTH' });
if (!response) {
throw new Error('Keine Antwort vom Service Worker');
}
console.log('Auth response:', response);
// If there's an error, show it but still allow login
if (response.error && !response.success) {
console.error('Service Worker Error:', response.error);
showError('Hinweis: ' + response.error + ' - Login sollte trotzdem funktionieren.');
}
if (response.success && response.authenticated) {
currentUser = response.user;
await loadTools();
showLoggedInState();
} else {
// Not authenticated - show login form
showState('login-form');
}
} catch (error) {
console.error('Init error:', error);
showError('Fehler beim Laden: ' + error.message + '. Bitte Extension in chrome://extensions neu laden.');
showState('login-form');
}
}
// Show a specific state (loading, login-form, tools-menu)
function showState(stateId) {
loadingEl.classList.add('hidden');
loginFormEl.classList.add('hidden');
toolsMenuEl.classList.add('hidden');
document.getElementById(stateId).classList.remove('hidden');
}
// Show logged in state with user info
function showLoggedInState() {
userEmailEl.textContent = currentUser.email || currentUser.name || 'Benutzer';
renderTools();
showState('tools-menu');
}
// Send message to service worker
function sendMessage(message) {
return new Promise((resolve) => {
// Add timeout to prevent hanging
const timeout = setTimeout(() => {
console.error('Message timeout:', message.action);
resolve({
success: false,
error: 'Service Worker antwortet nicht. Bitte Extension in chrome://extensions neu laden und Service Worker Konsole pruefen.'
});
}, 2000); // Reduced timeout to 2 seconds for faster feedback
try {
if (!chrome.runtime || !chrome.runtime.id) {
clearTimeout(timeout);
resolve({ success: false, error: 'Chrome Runtime nicht verfuegbar' });
return;
}
chrome.runtime.sendMessage(message, (response) => {
clearTimeout(timeout);
if (chrome.runtime.lastError) {
console.error('Chrome runtime error:', chrome.runtime.lastError);
resolve({
success: false,
error: chrome.runtime.lastError.message || 'Service Worker Fehler'
});
} else {
console.log('Response received:', response);
resolve(response || { success: false, error: 'Keine Antwort vom Service Worker' });
}
});
} catch (error) {
clearTimeout(timeout);
console.error('Send message error:', error);
resolve({ success: false, error: error.message || 'Fehler beim Senden der Nachricht' });
}
});
}
// Login form submission
authForm.addEventListener('submit', async (e) => {
e.preventDefault();
const email = emailInput.value.trim();
const password = passwordInput.value;
if (!email || !password) {
showError('Bitte E-Mail und Passwort eingeben');
return;
}
setLoginLoading(true);
hideError();
const response = await sendMessage({
action: 'LOGIN',
email,
password
});
setLoginLoading(false);
if (response.success) {
currentUser = response.user;
await loadTools();
showLoggedInState();
// Open protected site after successful login
openProtectedSite();
} else {
showError(response.error || 'Anmeldung fehlgeschlagen');
}
});
// Logout button
logoutBtn.addEventListener('click', async () => {
const response = await sendMessage({ action: 'LOGOUT' });
if (response.success) {
currentUser = null;
tools = [];
emailInput.value = '';
passwordInput.value = '';
showState('login-form');
}
});
// Open site button
openSiteBtn.addEventListener('click', () => {
openProtectedSite();
});
// Open protected site in new tab
function openProtectedSite() {
chrome.tabs.create({ url: PROTECTED_SITE_URL });
}
// Load tools settings
async function loadTools() {
const response = await sendMessage({ action: 'GET_SETTINGS' });
if (response.success) {
tools = response.tools;
}
}
// Render tools list
function renderTools() {
toolsListEl.innerHTML = '';
tools.forEach((tool, index) => {
const toolEl = document.createElement('div');
toolEl.className = 'tool-item';
toolEl.innerHTML = `
<div class="tool-header">
<span class="tool-name">${escapeHtml(tool.name)}</span>
<label class="toggle">
<input type="checkbox" data-tool-id="${tool.id}" ${tool.enabled ? 'checked' : ''}>
<span class="toggle-slider"></span>
</label>
</div>
<div class="tool-settings ${tool.enabled ? 'visible' : ''}" id="settings-${tool.id}">
${renderToolSettings(tool)}
</div>
`;
toolsListEl.appendChild(toolEl);
// Toggle event listener
const toggle = toolEl.querySelector('input[type="checkbox"]');
toggle.addEventListener('change', (e) => {
handleToolToggle(tool.id, e.target.checked);
});
// Settings change listeners
const settingsInputs = toolEl.querySelectorAll('.setting-row input');
settingsInputs.forEach(input => {
input.addEventListener('change', (e) => {
handleSettingChange(tool.id, e.target.dataset.setting, e.target.value);
});
});
});
}
// Render settings inputs for a tool
function renderToolSettings(tool) {
if (!tool.settings) return '';
let html = '';
for (const [key, value] of Object.entries(tool.settings)) {
html += `
<div class="setting-row">
<label>${escapeHtml(formatSettingName(key))}</label>
<input type="text" data-setting="${key}" value="${escapeHtml(value)}">
</div>
`;
}
return html;
}
// Format setting key to readable name
function formatSettingName(key) {
return key
.replace(/([A-Z])/g, ' $1')
.replace(/^./, str => str.toUpperCase())
.replace(/_/g, ' ');
}
// Handle tool toggle
async function handleToolToggle(toolId, enabled) {
const tool = tools.find(t => t.id === toolId);
if (tool) {
tool.enabled = enabled;
// Show/hide settings
const settingsEl = document.getElementById(`settings-${toolId}`);
if (settingsEl) {
settingsEl.classList.toggle('visible', enabled);
}
await saveTools();
}
}
// Handle setting value change
async function handleSettingChange(toolId, settingKey, value) {
const tool = tools.find(t => t.id === toolId);
if (tool && tool.settings) {
tool.settings[settingKey] = value;
await saveTools();
}
}
// Save tools to storage
async function saveTools() {
await sendMessage({ action: 'SAVE_SETTINGS', settings: tools });
}
// Show error message
function showError(message) {
errorMessage.textContent = message;
errorMessage.classList.remove('hidden');
}
// Hide error message
function hideError() {
errorMessage.classList.add('hidden');
}
// Set login button loading state
function setLoginLoading(loading) {
loginBtn.disabled = loading;
loginBtn.querySelector('.btn-text').classList.toggle('hidden', loading);
loginBtn.querySelector('.btn-spinner').classList.toggle('hidden', !loading);
}
// Escape HTML to prevent XSS
function escapeHtml(text) {
const div = document.createElement('div');
div.textContent = text;
return div.innerHTML;
}