bunker-admin a77306fac2 Initial v2 commit: complete rebuild with unified API + React admin
Phase 1-14 complete:
- Unified Express.js API (TypeScript, Prisma ORM, PostgreSQL 16)
- React Admin GUI (Vite + Ant Design + Zustand)
- JWT auth with refresh tokens
- Influence: Campaigns, Representatives, Responses, Email Queue
- Map: Locations, Cuts, Shifts, Canvassing System
- NAR data import infrastructure (2025 format)
- Listmonk newsletter integration
- Landing page builder (GrapesJS)
- MkDocs + Code Server integration
- Volunteer portal with GPS tracking
- Monitoring stack (Prometheus, Grafana, Alertmanager)
- Pangolin tunnel integration

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-11 10:05:04 -07:00

86 lines
3.4 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">
<title>Volunteer Shifts - BNKops Map</title>
<link rel="icon" type="image/x-icon" href="/favicon.ico">
<link rel="stylesheet" href="css/style.css">
<link rel="stylesheet" href="css/shifts.css">
</head>
<body>
<div id="app">
<header class="header">
<h1>Volunteer Shifts</h1>
<div class="header-actions">
<a href="/" class="btn btn-secondary">← Back to Map</a>
<span id="user-info" class="user-info">
<span class="user-email" id="user-email"></span>
</span>
</div>
</header>
<div class="shifts-container">
<!-- Move My Signups to the top -->
<div class="my-signups">
<h2>My Shifts</h2>
<div id="my-signups-list">
<!-- User's signups will be loaded here -->
</div>
</div>
<div class="shifts-filters">
<div class="shifts-header">
<h2>Available Shifts</h2>
<div class="view-toggle">
<button class="btn btn-secondary btn-sm" id="grid-view-btn" data-view="grid">📋 List View</button>
<button class="btn btn-secondary btn-sm" id="calendar-view-btn" data-view="calendar">📅 Calendar View</button>
</div>
</div>
<div class="filter-group">
<label for="date-filter">Filter by Date:</label>
<input type="date" id="date-filter" />
<button class="btn btn-secondary btn-sm" id="clear-filters-btn">Clear</button>
</div>
</div>
<div class="shifts-grid" id="shifts-grid">
<!-- Shifts will be loaded here -->
</div>
<div class="calendar-view" id="calendar-view" style="display: none;">
<div class="calendar-header">
<button class="btn btn-secondary btn-sm" id="prev-month"> Previous</button>
<h3 id="calendar-month-year"></h3>
<button class="btn btn-secondary btn-sm" id="next-month">Next </button>
</div>
<div class="calendar-grid" id="calendar-grid">
<!-- Calendar will be loaded here -->
</div>
<div class="calendar-legend">
<div class="legend-item">
<span class="legend-color my-shift"></span>
<span>My Shifts</span>
</div>
<div class="legend-item">
<span class="legend-color available-shift"></span>
<span>Available Shifts</span>
</div>
<div class="legend-item">
<span class="legend-color full-shift"></span>
<span>Full Shifts</span>
</div>
</div>
</div>
</div>
<div id="status-container" class="status-container"></div>
</div>
<!-- Cache Management -->
<script src="js/cache-manager.js"></script>
<script src="js/shifts.js"></script>
</body>
</html>