diff options
| author | Ahmed AbdelHalim <[email protected]> | 2025-09-06 23:55:19 +0200 |
|---|---|---|
| committer | Ahmed AbdelHalim <[email protected]> | 2025-09-07 02:20:46 +0200 |
| commit | 17168a489392847794de0aed15fe395230a38261 (patch) | |
| tree | 60914d9df4b9b37852e54dcf72818b0df1a958fb /static/js | |
Initial commit
This cleaned up and added linting/readme to the already created web app
that I have been using to control vpn on my raspberry setup
Diffstat (limited to 'static/js')
| -rw-r--r-- | static/js/app.js | 135 |
1 files changed, 135 insertions, 0 deletions
diff --git a/static/js/app.js b/static/js/app.js new file mode 100644 index 0000000..db8ed8a --- /dev/null +++ b/static/js/app.js @@ -0,0 +1,135 @@ +// Application state and configuration +const App = { + apiBase: "/api", + elements: { + connectionList: document.getElementById('connections__container'), + statusArea: document.getElementById('status__container'), + messageArea: document.getElementById('notifications__container') + } +}; + +// Utility functions +const Utils = { + // Show message to user + renderError(element, message) { + Utils.renderMessage(element, message, "error"); + }, + renderWarning(element, message) { + Utils.renderMessage(element, message, "warning"); + }, + renderSuccess(element, message) { + Utils.renderMessage(element, message, "success"); + }, + renderMessage(element, message, type = '') { + element.innerHTML = ` + <div class="message ${type}">${message}</div> + `; + }, + // Make API calls with proper error handling + async apiCall(endpoint, options = {}) { + try { + const response = await fetch(`${App.apiBase}${endpoint}`, { + headers: { + 'Content-Type': 'application/json', + ...options.headers + }, + ...options + }); + + const data = await response.json(); + + if (!response.ok) { + throw new Error(data.error || `HTTP ${response.status}`); + } + + if (!data.success) { + throw new Error(data.error || 'API request failed'); + } + + return data.data; + } catch (error) { + console.error('API call failed:', error); + throw error; + } + } +}; + +// Connection management +const ConnectionManager = { + // Load and display all connections + async loadConnections() { + try { + const connections = await Utils.apiCall('/connections'); + this.renderConnections(connections); + } catch (error) { + Utils.renderError(App.elements.connectionList, + `Failed to load connections: ${error.message}`); + } + }, + + // Render connections to the DOM + renderConnections(connections) { + if (!connections || connections.length === 0) { + Utils.renderWarning(App.elements.connectionList, + "No WireGuard connections found in /etc/wireguard/"); + return; + } + + const html = connections.map(conn => ` + <div class="connection ${conn.active ? 'active' : ''}" + data-connection="${conn.name}" + onclick="ConnectionManager.toggleConnection('${conn.name}')"> + <div class="connection__name ${conn.active ? 'active' : ''}">${conn.name}</div> + </div> + `).join(''); + App.elements.connectionList.innerHTML = html; + }, + + // Toggle connection state + async toggleConnection(name) { + const connection = document.querySelector(`[data-connection="${name}"]`); + + try { + connection.disabled = true; + connection.textContent = 'Processing...'; + connection.className = "connection loading" + + await Utils.apiCall('/connections/toggle', { + method: 'POST', + body: JSON.stringify({ name }) + }); + await this.loadConnections(); // Refresh the list + await StatusManager.loadStatus(); // Refresh the status + Utils.renderSuccess(App.elements.messageArea, `No Errors Found.`); + } catch (error) { + Utils.renderError(App.elements.messageArea, `Failed to toggle ${name}: ${error.message}`); + connection.disabled = false; + connection.textContent = name; + connection.className = "connection" + } + } +}; + +// Status management +const StatusManager = { + // Load and display WireGuard status + async loadStatus() { + try { + const statusData = await Utils.apiCall('/status'); + const statusText = statusData.status; + if (statusText) { + Utils.renderSuccess(App.elements.statusArea, statusText); + } else { + Utils.renderWarning(App.elements.statusArea, "No active connections."); + } + } catch (error) { + Utils.renderError(App.elements.statusArea, error.message); + } + }, +}; + +// Initialize the application +document.addEventListener('DOMContentLoaded', () => { + StatusManager.loadStatus(); + ConnectionManager.loadConnections(); +}); |
