freealberta/map/app/public/admin.html

434 lines
21 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
<meta name="description" content="Admin Panel - BNKops Map - Interactive canvassing web-app & viewer">
<title>Admin Panel</title>
<!-- Favicon -->
<link rel="icon" type="image/x-icon" href="/favicon.ico">
<link rel="shortcut icon" href="/favicon.ico">
<!-- Leaflet CSS -->
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css"
integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY="
crossorigin="" />
<!-- Custom CSS -->
<link rel="stylesheet" href="css/style.css">
<link rel="stylesheet" href="css/admin.css">
</head>
<body>
<div id="app">
<!-- Header -->
<header class="header">
<button id="mobile-menu-toggle" class="mobile-menu-toggle">
<span></span>
<span></span>
<span></span>
</button>
<h1>Admin Panel</h1>
<div class="header-actions">
<a href="/" class="btn btn-secondary">← Back to Map</a>
<span id="admin-info" class="admin-info desktop-only"></span>
</div>
</header>
<!-- Main Content -->
<div class="admin-container">
<div class="admin-sidebar" id="admin-sidebar">
<div class="sidebar-header">
<h2>Admin Menu</h2>
<button id="close-sidebar" class="close-sidebar">×</button>
</div>
<nav class="admin-nav">
<a href="#dashboard">
<span class="nav-icon">📊</span>
<span class="nav-text">Dashboard</span>
</a>
<a href="#start-location" class="active">
<span class="nav-icon">📍</span>
<span class="nav-text">Start Location</span>
</a>
<a href="#walk-sheet">
<span class="nav-icon">📄</span>
<span class="nav-text">Walk Sheet</span>
</a>
<a href="#shifts">
<span class="nav-icon">📅</span>
<span class="nav-text">Shifts</span>
</a>
<a href="#users">
<span class="nav-icon">👥</span>
<span class="nav-text">Users</span>
</a>
</nav>
<div class="sidebar-footer">
<div id="mobile-admin-info" class="mobile-admin-info mobile-only"></div>
</div>
</div>
<div class="admin-content">
<!-- Dashboard Section -->
<section id="dashboard" class="admin-section" style="display: none;">
<h2>Campaign Dashboard</h2>
<p>Overview of campaign metrics and statistics</p>
<div class="dashboard-container">
<!-- Summary Cards -->
<div class="dashboard-cards">
<div class="dashboard-card">
<h3>Total Locations</h3>
<div class="card-value" id="total-locations">-</div>
</div>
<div class="dashboard-card">
<h3>Overall Score</h3>
<div class="card-value" id="overall-score">-</div>
<div class="card-subtitle">out of 4.0</div>
</div>
<div class="dashboard-card">
<h3>Signs Delivered</h3>
<div class="card-value" id="sign-delivered">-</div>
</div>
<div class="dashboard-card">
<h3>Total Users</h3>
<div class="card-value" id="total-users">-</div>
</div>
</div>
<!-- Charts -->
<div class="dashboard-charts">
<div class="chart-container">
<h3>Support Level Distribution</h3>
<canvas id="support-chart"></canvas>
</div>
<div class="chart-container">
<h3>Sign Sizes Requested</h3>
<canvas id="sign-sizes-chart"></canvas>
</div>
<div class="chart-container chart-full-width">
<h3>Daily Entries (Last 30 Days)</h3>
<canvas id="entries-chart"></canvas>
</div>
</div>
</div>
</section>
<!-- Start Location Section -->
<section id="start-location" class="admin-section">
<h2>Map Start Location</h2>
<p>Set the default center point and zoom level for the map when users first load the application.</p>
<div class="admin-map-container">
<div id="admin-map" class="admin-map"></div>
<div class="location-controls">
<div class="form-group">
<label for="start-lat">Latitude</label>
<input type="number" id="start-lat" step="0.000001" min="-90" max="90">
</div>
<div class="form-group">
<label for="start-lng">Longitude</label>
<input type="number" id="start-lng" step="0.000001" min="-180" max="180">
</div>
<div class="form-group">
<label for="start-zoom">Zoom Level</label>
<input type="number" id="start-zoom" min="2" max="19" step="1">
</div>
<div class="form-actions">
<button id="use-current-view" class="btn btn-secondary">
Use Current Map View
</button>
<button id="save-start-location" class="btn btn-primary">
Save Start Location
</button>
</div>
<div class="help-text">
<p>💡 Tip: Navigate the map to your desired location and zoom level, then click "Use Current Map View" to capture the coordinates.</p>
</div>
</div>
</div>
</section>
<!-- Walk Sheet Section -->
<section id="walk-sheet" class="admin-section" style="display: none;">
<h2>Walk Sheet Configuration</h2>
<p>Design and configure printable walk sheets for door-to-door canvassing.</p>
<div class="walk-sheet-container">
<div class="walk-sheet-config">
<h3>Sheet Information</h3>
<div class="form-group">
<label for="walk-sheet-title">Sheet Title</label>
<input type="text" id="walk-sheet-title" placeholder="Campaign Walk Sheet">
</div>
<div class="form-group">
<label for="walk-sheet-subtitle">Subtitle</label>
<input type="text" id="walk-sheet-subtitle" placeholder="Door-to-Door Canvassing Form">
</div>
<div class="form-group">
<label for="walk-sheet-footer">Footer Text</label>
<textarea id="walk-sheet-footer" rows="3" placeholder="Contact info, legal text, etc."></textarea>
</div>
<h3>QR Codes</h3>
<p class="help-text-inline">Add up to 3 QR codes for quick access to digital resources.</p>
<!-- QR Code 1 -->
<div class="qr-code-group">
<h4>QR Code 1</h4>
<div class="form-row">
<div class="form-group">
<label for="qr-code-1-url">URL</label>
<input type="url" id="qr-code-1-url" placeholder="https://example.com/signup">
</div>
<div class="form-group">
<label for="qr-code-1-label">Label</label>
<input type="text" id="qr-code-1-label" placeholder="Sign Up">
</div>
</div>
</div>
<!-- QR Code 2 -->
<div class="qr-code-group">
<h4>QR Code 2</h4>
<div class="form-row">
<div class="form-group">
<label for="qr-code-2-url">URL</label>
<input type="url" id="qr-code-2-url" placeholder="https://example.com/donate">
</div>
<div class="form-group">
<label for="qr-code-2-label">Label</label>
<input type="text" id="qr-code-2-label" placeholder="Donate">
</div>
</div>
</div>
<!-- QR Code 3 -->
<div class="qr-code-group">
<h4>QR Code 3</h4>
<div class="form-row">
<div class="form-group">
<label for="qr-code-3-url">URL</label>
<input type="url" id="qr-code-3-url" placeholder="https://example.com/volunteer">
</div>
<div class="form-group">
<label for="qr-code-3-label">Label</label>
<input type="text" id="qr-code-3-label" placeholder="Volunteer">
</div>
</div>
</div>
<div class="form-actions">
<button id="save-walk-sheet" class="btn btn-primary">
Save Configuration
</button>
<button id="print-walk-sheet" class="btn btn-secondary">
🖨️ Print Sheet
</button>
</div>
</div>
<div class="walk-sheet-preview">
<h3>Preview</h3>
<div class="preview-controls">
<span class="preview-info">8.5" x 11" format</span>
</div>
<div id="walk-sheet-preview-content" class="walk-sheet-page">
<!-- Preview content will be generated here -->
</div>
</div>
</div>
</section>
<!-- Shifts Section -->
<section id="shifts" class="admin-section" style="display: none;">
<h2>Shift Management</h2>
<p>Create and manage volunteer shifts.</p>
<div class="shifts-admin-container">
<div class="shift-form">
<h3>Create New Shift</h3>
<form id="shift-form">
<div class="form-group">
<label for="shift-title">Title</label>
<input type="text" id="shift-title" required>
</div>
<div class="form-group">
<label for="shift-description">Description</label>
<textarea id="shift-description" rows="3"></textarea>
</div>
<div class="form-row">
<div class="form-group">
<label for="shift-date">Date</label>
<input type="date" id="shift-date" required>
</div>
<div class="form-group">
<label for="shift-start">Start Time</label>
<input type="time" id="shift-start" required>
</div>
<div class="form-group">
<label for="shift-end">End Time</label>
<input type="time" id="shift-end" required>
</div>
</div>
<div class="form-row">
<div class="form-group">
<label for="shift-location">Location</label>
<input type="text" id="shift-location">
</div>
<div class="form-group">
<label for="shift-max-volunteers">Max Volunteers</label>
<input type="number" id="shift-max-volunteers" min="1" required>
</div>
</div>
<div class="form-actions">
<button type="submit" class="btn btn-primary">Create Shift</button>
<button type="button" class="btn btn-secondary" id="clear-shift-form">Clear</button>
</div>
</form>
</div>
<div class="shifts-list">
<h3>Existing Shifts</h3>
<div id="admin-shifts-list">
<!-- Shifts will be loaded here -->
</div>
</div>
</div>
</section>
<!-- Users Section -->
<section id="users" class="admin-section" style="display: none;">
<h2>User Management</h2>
<p>Create and manage user accounts for the application.</p>
<div class="users-admin-container">
<div class="user-form">
<h3>Create New User</h3>
<form id="create-user-form">
<div class="form-group">
<label for="user-email">Email</label>
<input type="email" id="user-email" required>
</div>
<div class="form-group">
<label for="user-name">Name</label>
<input type="text" id="user-name" required>
</div>
<div class="form-group">
<label for="user-password">Password</label>
<input type="password" id="user-password" required>
</div>
<div class="form-group">
<label>
<input type="checkbox" id="user-is-admin">
Is Admin
</label>
</div>
<div class="form-actions">
<button type="submit" class="btn btn-primary">Create User</button>
<button type="button" id="clear-user-form" class="btn btn-secondary">Clear</button>
</div>
</form>
</div>
<div class="users-list">
<!-- User table will be dynamically inserted here -->
<p id="users-loading" class="loading-message">Loading users...</p>
</div>
</div>
</section>
</div>
</div>
<!-- Status Messages -->
<div id="status-container" class="status-container"></div>
</div>
<!-- Leaflet JS -->
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"
integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo="
crossorigin=""></script>
<!-- Custom QR Code Implementation -->
<script>
// Simple QR Code implementation using our server
window.QRCode = {
toCanvas: function(canvas, text, options, callback) {
if (typeof options === 'function') {
callback = options;
options = {};
}
const size = options.width || 200;
const qrUrl = `/api/qr?text=${encodeURIComponent(text)}&size=${size}`;
const img = new Image();
img.crossOrigin = 'anonymous';
img.onload = function() {
canvas.width = size;
canvas.height = size;
const ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0, size, size);
if (callback) callback(null);
};
img.onerror = function() {
console.error('Failed to load QR code from server');
// Fallback: draw a simple placeholder
canvas.width = size;
canvas.height = size;
const ctx = canvas.getContext('2d');
ctx.fillStyle = '#ffffff';
ctx.fillRect(0, 0, size, size);
ctx.fillStyle = '#000000';
ctx.font = '12px Arial';
ctx.textAlign = 'center';
ctx.fillText('QR Code', size/2, size/2 - 10);
ctx.fillText('(Failed)', size/2, size/2 + 10);
if (callback) callback(new Error('Failed to load QR code'));
};
img.src = qrUrl;
}
};
console.log('Local QR Code implementation loaded');
</script>
<!-- Cache Management -->
<script src="js/cache-manager.js"></script>
<!-- Chart.js library -->
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.0/dist/chart.umd.min.js"></script>
<!-- Dashboard JavaScript -->
<script src="js/dashboard.js"></script>
<!-- Admin JavaScript -->
<script src="js/admin.js"></script>
</body>
</html>