diff --git a/map/Instuctions.md b/map/Instuctions.md
index 44fb4bb..fc45763 100644
--- a/map/Instuctions.md
+++ b/map/Instuctions.md
@@ -1,10 +1,57 @@
-# Instructions
+# Instructions
-The following are instructions for developing this project. The project is called Map and is a canvasing application for political campaigns.
+Welcome to the Map project! This application is a canvassing tool for political campaigns, built to be robust, maintainable, and easy to extend. Please read these instructions carefully before contributing.
-It uses nocodb as a backend database.
+## Project Overview
-## Rules
+- **Purpose:** Visualize, manage, and update canvassing locations and volunteer shifts on an interactive map.
+- **Backend:** Node.js/Express, with NocoDB as the database (REST API).
+- **Frontend:** Vanilla JS, Leaflet.js for mapping, modular code in `/public/js`.
+- **Admin Panel:** Accessible via `/admin.html` for managing start location, walk sheet, and settings.
-- Do not use inline event handlers. Use properly attached event listeners instead.
-- Always update the README.md, or instruct the user to update the README, when developing new features.
+## Key Principles
+
+- **Separation of Concerns:** Keep logic for API, UI, and data management in their respective files/modules.
+- **Security:** Never expose sensitive credentials. All API calls to NocoDB go through the backend.
+- **Scalability:** Write code that is easy to extend (e.g., adding new location fields, new admin features).
+- **User Experience:** Prioritize clear feedback, error handling, and mobile responsiveness.
+
+## Directory Structure
+
+- `app/` - Node.js backend (Express server, routes, controllers, services, utils)
+- `app/public/` - Frontend static files (HTML, CSS, JS)
+- `app/public/js/` - Modular JavaScript for map, UI, auth, etc.
+- `app/controllers/` - Express controllers for business logic
+- `app/routes/` - Express routers for API endpoints
+- `app/services/` - Backend services (NocoDB, geocoding, QR code)
+- `app/utils/` - Shared backend utilities
+
+## Development Rules
+
+- **No inline event handlers.** Always use `addEventListener` in JS files.
+- **Update documentation.** Always update `README.md` and `files-explainer.md` when adding features or files.
+- **Consistent style.** Follow the existing code style and naming conventions.
+- **Error handling.** Always provide user feedback for errors (both backend and frontend).
+- **Environment variables.** Use `.env` for secrets/config, never hardcode sensitive data.
+- **Testing.** Test new features locally and ensure they do not break existing functionality.
+
+## How to Add a Feature
+
+1. **Plan:** Decide where your logic belongs (backend controller, frontend JS, etc).
+2. **Backend:** Add/modify controllers, services, and routes as needed. Use NocoDB API via the service layer.
+3. **Frontend:** Add/modify JS modules in `/public/js`. Update HTML/CSS as needed.
+4. **Document:** Update `README.md` and `files-explainer.md`.
+5. **Test:** Manually test your feature in both desktop and mobile views.
+6. **Pull Request:** Submit your changes for review.
+
+## Common Tasks
+
+- **Add a new location field:** Update NocoDB schema, backend helpers, and frontend forms.
+- **Add a new admin feature:** Add a new section to `/admin.html`, backend route/controller, and frontend JS.
+- **Change map behavior:** Update `/public/js/map-manager.js` and related modules.
+
+## Contact
+
+If you have questions, reach out to the lead developer or open an issue in the repository.
+
+Happy coding!
diff --git a/map/app/controllers/shiftsController.js b/map/app/controllers/shiftsController.js
index 60358f9..f1617d1 100644
--- a/map/app/controllers/shiftsController.js
+++ b/map/app/controllers/shiftsController.js
@@ -103,6 +103,7 @@ class ShiftsController {
const transformedSignups = userSignups.map(signup => ({
id: signup.ID || signup.id,
shift_id: signup['Shift ID'],
+ shift_title: signup['Shift Title'],
user_email: signup['User Email'],
user_name: signup['User Name'],
signup_date: signup['Signup Date'],
@@ -191,6 +192,7 @@ class ShiftsController {
// Create signup
const signup = await nocodbService.create(config.nocodb.shiftSignupsSheetId, {
'Shift ID': parseInt(shiftId),
+ 'Shift Title': shift.Title,
'User Email': userEmail,
'User Name': userName,
'Signup Date': new Date().toISOString(),
diff --git a/map/app/public/js/shifts.js b/map/app/public/js/shifts.js
index 08f3fd0..353b05b 100644
--- a/map/app/public/js/shifts.js
+++ b/map/app/public/js/shifts.js
@@ -128,18 +128,23 @@ function displayMySignups() {
return;
}
- // Need to match signups with shift details
+ // Need to match signups with shift details for date/time info
const signupsWithDetails = mySignups.map(signup => {
const shift = allShifts.find(s => s.ID === signup.shift_id);
- return { ...signup, shift };
- }).filter(s => s.shift);
+ return {
+ ...signup,
+ shift,
+ // Use title from signup record if available, otherwise from shift
+ displayTitle: signup.shift_title || (shift ? shift.Title : 'Unknown Shift')
+ };
+ }).filter(s => s.shift); // Only show signups where we can find the shift details
list.innerHTML = signupsWithDetails.map(signup => {
const shiftDate = new Date(signup.shift.Date);
return `
-
${escapeHtml(signup.shift.Title)}
+
${escapeHtml(signup.displayTitle)}
📅 ${shiftDate.toLocaleDateString()} ⏰ ${signup.shift['Start Time']} - ${signup.shift['End Time']}
diff --git a/map/build-nocodb.sh b/map/build-nocodb.sh
index fb98cae..e7c7666 100755
--- a/map/build-nocodb.sh
+++ b/map/build-nocodb.sh
@@ -691,6 +691,12 @@ create_shift_signups_table() {
"uidt": "Number",
"rqd": true
},
+ {
+ "column_name": "shift_title",
+ "title": "Shift Title",
+ "uidt": "SingleLineText",
+ "rqd": false
+ },
{
"column_name": "user_email",
"title": "User Email",
diff --git a/map/files-explainer.md b/map/files-explainer.md
new file mode 100644
index 0000000..e99875c
--- /dev/null
+++ b/map/files-explainer.md
@@ -0,0 +1,204 @@
+# ADMIN_IMPLEMENTATION.md
+
+Summarizes the implementation of the admin panel and related backend/frontend changes for the NocoDB Map Viewer.
+
+# Instuctions.md
+
+Project development instructions and rules for contributors to the canvassing map application.
+
+# README.md
+
+Main documentation for the NocoDB Map Viewer project, including features, setup, and usage.
+
+# build-nocodb.md
+
+Documents the development and requirements of the NocoDB automation script for table setup.
+
+# build-nocodb.sh
+
+Bash script to automate creation of required NocoDB tables and default data for the app.
+
+# docker-compose.yml
+
+Docker Compose file to orchestrate the map-viewer app container and its environment.
+
+# app/Dockerfile
+
+Dockerfile for building the Node.js application image for deployment.
+
+# app/config/index.js
+
+Handles environment config and NocoDB URL parsing for the backend.
+
+# app/controllers/authController.js
+
+Controller for user authentication (login, logout, session check).
+
+# app/controllers/locationsController.js
+
+Controller for CRUD operations on map locations.
+
+# app/controllers/settingsController.js
+
+Controller for application settings, start location, and walk sheet config.
+
+# app/controllers/shiftsController.js
+
+Controller for volunteer shift management (public and admin). When users sign up for shifts, the signup record includes the shift title for better tracking and display.
+
+# app/controllers/usersController.js
+
+Controller for user management (list, create, delete users).
+
+# app/middleware/auth.js
+
+Express middleware for authentication and admin access control.
+
+# app/middleware/rateLimiter.js
+
+Express middleware for API rate limiting, with Cloudflare IP support.
+
+# app/package.json
+
+Node.js project manifest, dependencies, and scripts for the backend app.
+
+# app/server.js
+
+Main Express server entry point for the map application backend.
+
+# app/server copy.js
+
+Legacy or backup version of the main server file, possibly for reference or migration.
+
+# app/services/geocoding.js
+
+Service for geocoding and reverse geocoding using external APIs, with caching.
+
+# app/services/nocodb.js
+
+Service for interacting with the NocoDB API (CRUD, config, etc).
+
+# app/services/qrcode.js
+
+Service for generating QR codes and handling QR-related logic.
+
+# app/utils/helpers.js
+
+Utility functions for geographic data, validation, and helpers used across the backend.
+
+# app/utils/logger.js
+
+Winston logger configuration for backend logging.
+
+# app/public/admin.html
+
+Admin panel HTML page for managing start location, walk sheet, and settings.
+
+# app/public/css/admin.css
+
+CSS styles specific to the admin panel UI.
+
+# app/public/css/shifts.css
+
+CSS styles for the volunteer shifts page.
+
+# app/public/css/style.css
+
+The style.css file is the base .css file for the application. It is referenced in many of the .html files.
+
+# app/public/favicon.ico
+
+Favicon for the web application.
+
+# app/public/index.html
+
+Main map viewer HTML page for the canvassing application.
+
+# app/public/login.html
+
+Login page HTML for user authentication.
+
+# app/public/shifts.html
+
+Volunteer shifts management and signup page HTML.
+
+# app/public/js/admin.js
+
+JavaScript for admin panel functionality (map, start location, walk sheet, etc).
+
+# app/public/js/auth.js
+
+JavaScript for authentication logic and user session management.
+
+# app/public/js/config.js
+
+Global configuration constants for the frontend app.
+
+# app/public/js/location-manager.js
+
+JavaScript for loading, displaying, and managing map locations on the frontend.
+
+# app/public/js/main.js
+
+Main entry point for initializing the frontend application.
+
+# app/public/js/map-manager.js
+
+JavaScript for initializing and managing the Leaflet map instance.
+
+# app/public/js/map.js.backup
+
+Backup or legacy version of the main map JavaScript logic.
+
+# app/public/js/shifts.js
+
+JavaScript for volunteer shift signup, management, and UI logic. Updated to use shift titles directly from signup records.
+
+# app/public/js/ui-controls.js
+
+JavaScript for UI controls, event handlers, and user interaction logic.
+
+# app/public/js/utils.js
+
+Utility functions for the frontend (escaping HTML, parsing geolocation, etc).
+
+# app/routes/admin.js
+
+Express router for admin-only endpoints (start location, walk sheet config).
+
+# app/routes/auth.js
+
+Express router for authentication endpoints (login, logout, check).
+
+# app/routes/debug.js
+
+Express router for debug endpoints (session info, table structure, etc).
+
+# app/routes/geocoding.js
+
+Express router for geocoding and reverse geocoding endpoints.
+
+# app/routes/index.js
+
+Main router that mounts all sub-routes for the backend API.
+
+# app/routes/locations.js
+
+Express router for CRUD endpoints on map locations.
+
+# app/routes/qr.js
+
+Express router for QR code generation endpoints.
+
+# app/routes/settings.js
+
+Express router for application settings endpoints (start location, walk sheet).
+
+# app/routes/shifts.js
+
+Express router for volunteer shift management endpoints (public and admin).
+
+# app/routes/users.js
+
+Express router for user management endpoints (list, create, delete users).
+