From 167b82ff3524b2b21fed3fcb1fe1eb525e170389 Mon Sep 17 00:00:00 2001 From: admin Date: Wed, 16 Jul 2025 17:47:11 -0600 Subject: [PATCH] added shift titles to the shift signup sheets to make tracking easier and adding shifts easier --- map/Instuctions.md | 59 ++++++- map/app/controllers/shiftsController.js | 2 + map/app/public/js/shifts.js | 13 +- map/build-nocodb.sh | 6 + map/files-explainer.md | 204 ++++++++++++++++++++++++ 5 files changed, 274 insertions(+), 10 deletions(-) create mode 100644 map/files-explainer.md 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']}