NocoDB Map Viewer
A containerized web application that visualizes geographic data from NocoDB on an interactive map using Leaflet.js.
Features
- 🗺️ Interactive map visualization with OpenStreetMap
- 📍 Real-time geolocation support
- ➕ Add new locations directly from the map
- 🔄 Auto-refresh every 30 seconds
- 📱 Responsive design for mobile devices
- 🔒 Secure API proxy to protect credentials
- 👤 User authentication with login system
- ⚙️ Admin panel for system configuration
- 🎯 Configurable map start location
- 📋 Walk Sheet generator for door-to-door canvassing
- 🔗 QR code integration for digital resources
- 📅 Volunteer shift management system with calendar and grid views
- ✋ User shift signup and cancellation with color-coded calendar
- 👥 Admin shift creation and management
- 👨💼 User management panel for admin users (create, delete users)
- 🔐 Role-based access control (Admin vs User permissions)
- 📧 Email notifications and password recovery via SMTP
- <EFBFBD> CSV data import with batch geocoding and visual progress tracking
- <EFBFBD>🐳 Docker containerization for easy deployment
- 🆓 100% open source (no proprietary dependencies)
Quick Start
Prerequisites
- Docker and Docker Compose
- NocoDB instance with API access
- NocoDB API token
Installation
-
Get NocoDB API Token
- Login to your NocoDB instance
- Click user icon → Account Settings → API Tokens
- Create new token with read/write permissions
- Copy the token for the next step
-
Configure Environment
Edit the
.envfile with your NocoDB API and API Url:# NocoDB API Configuration NOCODB_API_URL=https://db.cmlite.org/api/v1 NOCODB_API_TOKEN=your-api-token-here # These will be populated after running build-nocodb.sh NOCODB_VIEW_URL= NOCODB_LOGIN_SHEET= NOCODB_SETTINGS_SHEET= NOCODB_SHIFTS_SHEET= NOCODB_SHIFT_SIGNUPS_SHEET= # Domain Configuration DOMAIN=cmlite.org # MkDocs Integration MKDOCS_URL=https://cmlite.org MKDOCS_SEARCH_URL=https://cmlite.org MKDOCS_SITE_SERVER_PORT=4002 # Server Configuration PORT=3000 NODE_ENV=production # Session Secret (Generate with: openssl rand -hex 32) SESSION_SECRET=your-secure-random-string # Map Defaults (Edmonton, Alberta, Canada) DEFAULT_LAT=53.5461 DEFAULT_LNG=-113.4938 DEFAULT_ZOOM=11 # Optional: Map Boundaries (prevents users from adding points outside area) # BOUND_NORTH=53.7 # BOUND_SOUTH=53.4 # BOUND_EAST=-113.3 # BOUND_WEST=-113.7 # Cloudflare Settings TRUST_PROXY=true COOKIE_DOMAIN=.cmlite.org # Allowed Origins ALLOWED_ORIGINS=https://map.cmlite.org,http://localhost:3000 # Email Configuration (Optional - for password recovery) SMTP_HOST=smtp.gmail.com SMTP_PORT=587 SMTP_SECURE=false SMTP_USER=your-email@gmail.com SMTP_PASS=your-app-password EMAIL_FROM_NAME=CMlite Support EMAIL_FROM_ADDRESS=noreply@cmlite.org APP_NAME=CMlite Map -
Auto-Create Database Structure
Run the build script to create required tables:
chmod +x build-nocodb.sh ./build-nocodb.shThis creates five tables:
- Locations - Main map data with geo-location, contact info, support levels
- Login - User authentication (email, name, admin flag)
- Settings - Admin configuration and QR codes
- Shifts - Shift scheduling and management
- Shift Signups - User shift registrations
-
Get Table URLs
After the script completes:
- Login to your NocoDB instance at https://db.cmlite.org
- Navigate to your project ("Map Viewer Project - TIMESTAMP")
- Copy the view URLs for each table from your browser address bar
- URLs should look like:
https://db.cmlite.org/dashboard/#/nc/project-id/table-id
-
Update Environment with URLs
Edit your
.envfile and add the table URLs:NOCODB_VIEW_URL=https://db.cmlite.org/dashboard/#/nc/pnsalzrup2zqvz8/m6g7bkzv7s1w2ur NOCODB_LOGIN_SHEET=https://db.cmlite.org/dashboard/#/nc/pnsalzrup2zqvz8/mizyc64e4r7ppzh NOCODB_SETTINGS_SHEET=https://db.cmlite.org/dashboard/#/nc/pnsalzrup2zqvz8/mix06f2mlep7gqb NOCODB_SHIFTS_SHEET=https://db.cmlite.org/dashboard/#/nc/pnsalzrup2zqvz8/mkx0tex0iquus1u NOCODB_SHIFT_SIGNUPS_SHEET=https://db.cmlite.org/dashboard/#/nc/pnsalzrup2zqvz8/mi8jg1tn26mu8fj -
Build and Deploy
Build the Docker image and start the application:
# Build the Docker image docker-compose build # Start the application docker-compose up -d -
Verify Installation
- Check container status:
docker-compose ps - View logs:
docker-compose logs -f map-viewer - Access the application at: http://localhost:3000
- Access shift management at: http://localhost:3000/shifts.html
- Access admin panel at: http://localhost:3000/admin.html (admin users only)
- Check container status:
Database Schema
The build script automatically creates the following table structure:
Main Locations Table
ID(ID): Auto-incrementing primary keyGeo-Location(GeoData): Geographic coordinate datalatitude(Decimal): Precision 8, Scale 8longitude(Decimal): Precision 8, Scale 8First Name(Single Line Text): Person's first nameLast Name(Single Line Text): Person's last nameEmail(Email): Email addressPhone(PhoneNumber): Phone number with validationUnit Number(Single Line Text): Unit or apartment numberSupport Level(Single Select): Options: "1" (Green), "2" (Yellow), "3" (Orange), "4" (Red)Address(Single Line Text): Street addressSign(Checkbox): Has campaign signSign Size(Single Select): Options: "Regular" (Blue), "Large" (Green), "Unsure" (Orange)Notes(Long Text): Additional details and commentscreated_by_user(Single Line Text): Creator emaillast_updated_by_user(Single Line Text): Last updater email
Login Table
ID(ID): Auto-incrementing primary keyEmail(Email): User email address (required)Password(Single Line Text): User password (required)Name(Single Line Text): User display nameAdmin(Checkbox): Admin privilegesCreated At(DateTime): Account creation timestampLast Login(DateTime): Last login timestamp
Settings Table
ID(ID): Auto-incrementing primary keycreated_at(DateTime): Record creation timestampcreated_by(Single Line Text): Creator identifierGeo-Location(Single Line Text): Format "latitude;longitude"latitude(Decimal): Precision 8, Scale 8longitude(Decimal): Precision 8, Scale 8zoom(Number): Map zoom levelWalk Sheet Title(Single Line Text): Title for walk sheetsWalk Sheet Subtitle(Single Line Text): Subtitle for walk sheetsWalk Sheet Footer(Long Text): Footer text for walk sheetsQR Code 1 URL(URL): First QR code linkQR Code 1 Label(Single Line Text): First QR code labelQR Code 2 URL(URL): Second QR code linkQR Code 2 Label(Single Line Text): Second QR code labelQR Code 3 URL(URL): Third QR code linkQR Code 3 Label(Single Line Text): Third QR code label
Shifts Table
ID(ID): Auto-incrementing primary keyTitle(Single Line Text): Shift title (required)Description(Long Text): Detailed shift descriptionDate(Date): Shift date (required)Start Time(Time): Shift start time (required)End Time(Time): Shift end time (required)Location(Single Line Text): Shift locationMax Volunteers(Number): Maximum volunteer capacity (required)Current Volunteers(Number): Current volunteer countStatus(Single Select): Options: "Open" (Green), "Full" (Orange), "Cancelled" (Red)Created By(Single Line Text): Creator identifierCreated At(DateTime): Creation timestampUpdated At(DateTime): Last update timestamp
Shift Signups Table
ID(ID): Auto-incrementing primary keyShift ID(Number): Reference to shifts table (required)Shift Title(Single Line Text): Copy of shift title for referenceUser Email(Email): User's email address (required)User Name(Single Line Text): User's display nameSignup Date(DateTime): When user signed upStatus(Single Select): Options: "Confirmed" (Green), "Cancelled" (Red)
API Endpoints
Public Endpoints
GET /api/locations- Fetch all locations (requires auth)POST /api/locations- Create new location (requires auth)GET /api/locations/:id- Get single location (requires auth)PUT /api/locations/:id- Update location (requires auth)DELETE /api/locations/:id- Delete location (requires auth)GET /api/config/start-location- Get map start locationGET /health- Health check
Shifts Endpoints (requires authentication)
GET /api/shifts- Get all available shiftsGET /api/shifts/my-signups- Get current user's shift signupsPOST /api/shifts/:shiftId/signup- Sign up for a shiftPOST /api/shifts/:shiftId/cancel- Cancel shift signup
Shifts Admin Endpoints (requires admin privileges)
GET /api/shifts/admin- Get all shifts including cancelled onesPOST /api/shifts/admin- Create new shiftPUT /api/shifts/admin/:id- Update existing shiftDELETE /api/shifts/admin/:id- Delete shift
Authentication Endpoints
POST /api/auth/login- User loginGET /api/auth/check- Check authentication statusPOST /api/auth/logout- User logout
Admin Endpoints (requires admin privileges)
GET /api/admin/start-location- Get start location with source infoPOST /api/admin/start-location- Update map start locationGET /api/admin/walk-sheet-config- Get walk sheet configurationPOST /api/admin/walk-sheet-config- Save walk sheet configuration
Shifts Management
The application includes a comprehensive volunteer shift management system accessible at /shifts.html.
User Features
- Dual View Options: Toggle between grid view and calendar view for shift display
- Calendar View: Interactive monthly calendar showing shifts with color-coded indicators:
- Green: Shifts you've signed up for
- Blue: Available shifts you can join
- Gray: Full shifts (no spots available)
- View Available Shifts: See all upcoming shifts with date, time, and capacity information
- Sign Up for Shifts: One-click signup for available shifts (works in both views)
- My Shifts Dashboard: View all your current shift signups at the top of the page
- Cancel Signups: Cancel your shift signups when needed
- Date Filtering: Filter shifts by specific dates (applies to both views)
- Real-time Updates: Shift availability updates dynamically
- Interactive Calendar: Click on calendar shifts for detailed popup with signup options
- Calendar Navigation: Navigate between months to view future shifts
Admin Features
Administrators have additional capabilities for managing shifts:
- Create New Shifts: Add new volunteer shifts with date, time, location, and capacity
- Edit Existing Shifts: Modify shift details, times, or capacity
- Cancel Shifts: Mark shifts as cancelled (they remain in system but hidden from users)
- View All Signups: See who has signed up for each shift
- Manage Capacity: Set maximum number of volunteers per shift
Shift Status System
- Active: Available for signups
- Full: Capacity reached, no more signups accepted
- Cancelled: Hidden from public view but retained in database
Admin Panel
Users with admin privileges can access the admin panel at /admin.html to configure system settings.
Features
Dashboard Analytics
- Campaign Overview: Real-time statistics and metrics
- Support Distribution: Visual breakdown of support levels (1-4)
- Sign Tracking: Monitor lawn sign requests
- User Analytics: Track user growth and daily entries
- Performance Score: Overall campaign performance metric
Start Location Configuration
- Interactive Map: Visual interface for selecting coordinates
- Real-time Preview: See changes immediately on the admin map
- Validation: Built-in coordinate and zoom level validation
Walk Sheet Generator
- Printable Forms: Generate 8.5x11 walk sheets for door-to-door canvassing
- QR Code Integration: Add up to 3 QR codes with custom URLs and labels
- Form Field Matching: Automatically matches fields from the main location form
- Live Preview: See changes as you type
- Print Optimization: Proper formatting for printing or PDF export
- Persistent Storage: All QR codes and settings saved to NocoDB
Shift Management
- Create Shifts: Set up volunteer shifts with dates, times, and capacity
- Manage Volunteers: View signups and manage shift participants
- Real-time Updates: See shift status changes immediately
User Management
- Create Users: Add new user accounts with email and password
- Role Assignment: Assign admin or user privileges
- User List: View all registered users with their details and creation dates
- Delete Users: Remove user accounts (with confirmation prompts)
- Security: Password validation and admin-only access
Convert Data
- CSV Upload: Upload CSV files containing addresses for bulk import
- Drag & Drop Interface: Easy file upload with visual feedback
- Real-time Geocoding: Addresses are geocoded in real-time with progress tracking
- Visual Progress: Live progress bar and status updates during processing
- Map Preview: Interactive map showing geocoded locations before saving
- Results Table: Detailed table with success/error status for each address
- Batch Save: Save all successfully geocoded locations to the database
- Field Mapping: Automatically maps common CSV fields (First Name, Last Name, Email, Phone, etc.)
- Error Handling: Clear error messages for failed geocoding attempts
- File Validation: CSV format validation and file size limits (10MB max)
Access Control
- Admin access is controlled via the
Admincheckbox in the Login table - Only authenticated users with admin privileges can access
/admin.html - Admin status is checked on every request to admin endpoints
- User management functions are restricted to admin users only
Start Location Priority
The system uses a cascading fallback system for map start location:
- Database: Admin-configured location stored in Settings table (highest priority)
- Environment: Default values from .env file (medium priority)
- Hardcoded: Edmonton, Canada coordinates (lowest priority)
Configuration
All configuration is done via environment variables:
| Variable | Description | Default |
|---|---|---|
NOCODB_API_URL |
NocoDB API base URL | Required |
NOCODB_API_TOKEN |
API authentication token | Required |
NOCODB_VIEW_URL |
Full NocoDB view URL for locations table | Required |
NOCODB_LOGIN_SHEET |
Login table URL for authentication | Required |
NOCODB_SETTINGS_SHEET |
Settings table URL for admin config | Required |
NOCODB_SHIFTS_SHEET |
Shifts table URL for shift management | Required |
NOCODB_SHIFT_SIGNUPS_SHEET |
Shift signups table URL for user registrations | Required |
DOMAIN |
Primary domain for the application | Required |
MKDOCS_URL |
MkDocs documentation site URL | Optional |
MKDOCS_SEARCH_URL |
MkDocs search endpoint URL | Optional |
MKDOCS_SITE_SERVER_PORT |
Port for MkDocs integration | 4002 |
PORT |
Server port | 3000 |
NODE_ENV |
Environment mode | production |
SESSION_SECRET |
Session encryption secret (generate with openssl rand -hex 32) | Required |
DEFAULT_LAT |
Default map latitude | 53.5461 |
DEFAULT_LNG |
Default map longitude | -113.4938 |
DEFAULT_ZOOM |
Default map zoom level | 11 |
BOUND_NORTH |
Northern boundary for map points (optional) | None |
BOUND_SOUTH |
Southern boundary for map points (optional) | None |
BOUND_EAST |
Eastern boundary for map points (optional) | None |
BOUND_WEST |
Western boundary for map points (optional) | None |
TRUST_PROXY |
Trust proxy headers (for Cloudflare) | true |
COOKIE_DOMAIN |
Cookie domain setting | .cmlite.org |
ALLOWED_ORIGINS |
CORS allowed origins (comma-separated) | Multiple URLs |
SMTP_HOST |
SMTP server hostname (optional) | smtp.gmail.com |
SMTP_PORT |
SMTP server port (optional) | 587 |
SMTP_SECURE |
Use SSL for SMTP (optional) | false |
SMTP_USER |
SMTP username (optional) | your-email@gmail.com |
SMTP_PASS |
SMTP password (optional) | your-app-password |
EMAIL_FROM_NAME |
Email sender name (optional) | CMlite Support |
EMAIL_FROM_ADDRESS |
Email sender address (optional) | noreply@cmlite.org |
APP_NAME |
Application name for emails (optional) | CMlite Map |
Maintenance Commands
Update Application
docker-compose down
git pull origin main
docker-compose build
docker-compose up -d
Development Mode
cd app
npm install
npm run dev
Health Check
curl http://localhost:3000/health
Development
To run in development mode:
-
Install dependencies:
cd app npm install -
Start with hot reload:
npm run dev
Security Considerations
- API tokens are kept server-side only
- CORS is configured for security
- Rate limiting prevents abuse
- Input validation on all endpoints
- Helmet.js for security headers
Troubleshooting
Locations not showing
- Verify table has
Geo-Location,latitude, andlongitudecolumns - Check that coordinates are valid numbers
- Ensure API token has read permissions
Cannot add locations
- Verify API token has write permissions
- Check browser console for errors
- Ensure coordinates are within valid ranges
Connection errors
- Verify NocoDB instance is accessible
- Check API URL format
- Confirm network connectivity
Build Script Issues
- Ensure NocoDB instance is accessible
- Verify API token has admin permissions
- Check that the NocoDB database is clean (delete all bases before running)
License
MIT License - See LICENSE file for details
Support
For issues or questions:
- Check the troubleshooting section
- Review NocoDB documentation
- Open an issue on GitHub
Known Bugs
- First load of page often fails, need to debug
- Want UI for dots to have an edit button that then brings up the form