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
  • <EFBFBD> Volunteer shift management system
  • User shift signup and cancellation
  • 👥 Admin shift creation and management
  • <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

  1. Get NocoDB API Token

    1. Login to your NocoDB instance
    2. Click user icon → Account SettingsAPI Tokens
    3. Create new token with read/write permissions
    4. Copy the token for the next step
  2. Configure Environment

    Edit the .env file 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=
    
    # Server Configuration
    PORT=3000
    NODE_ENV=production
    SESSION_SECRET=your-secure-random-string
    
    # Map Defaults (Edmonton, AB)
    DEFAULT_LAT=53.5461
    DEFAULT_LNG=-113.4938
    DEFAULT_ZOOM=11
    
    # Cloudflare Settings
    TRUST_PROXY=true
    COOKIE_DOMAIN=.cmlite.org
    
    # Allowed Origins
    ALLOWED_ORIGINS=https://map.cmlite.org,http://localhost:3000
    
  3. Auto-Create Database Structure

    Run the build script to create required tables:

    chmod +x build-nocodb.sh
    ./build-nocodb.sh
    

    This 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
  4. Get Table URLs

    After the script completes:

    1. Login to your NocoDB instance at https://db.cmlite.org
    2. Navigate to your project ("Map Viewer Project - TIMESTAMP")
    3. Copy the view URLs for each table from your browser address bar
    4. URLs should look like: https://db.cmlite.org/dashboard/#/nc/project-id/table-id
  5. Update Environment with URLs

    Edit your .env file 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
    
  6. 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
    
  7. Verify Installation

Database Schema

The build script automatically creates the following table structure:

Main Locations Table

  • Geo-Location (Geo-Data): Format "latitude;longitude"
  • latitude (Decimal): Precision 10, Scale 8
  • longitude (Decimal): Precision 11, Scale 8
  • First Name (Single Line Text): Person's first name
  • Last Name (Single Line Text): Person's last name
  • Email (Email): Email address
  • Phone (Single Line Text): Phone number
  • Unit Number (Single Line Text): Unit or apartment number
  • Support Level (Single Select): Options: "1", "2", "3", "4" (1=Strong Support/Green, 2=Moderate Support/Yellow, 3=Low Support/Orange, 4=No Support/Red)
  • Address (Single Line Text): Street address
  • Sign (Checkbox): Has campaign sign
  • Sign Size (Single Select): Options: "Small", "Medium", "Large"
  • Notes (Long Text): Additional details and comments
  • title (Text): Location name (legacy field)
  • category (Single Select): Classification (legacy field)

Login Table

  • Email (Email): User email address
  • Name (Single Line Text): User display name
  • Admin (Checkbox): Admin privileges

Settings Table

  • key (Single Line Text): Setting identifier
  • title (Single Line Text): Display name
  • value (Long Text): Setting value
  • Geo-Location (Text): Format "latitude;longitude"
  • latitude (Decimal): Precision 10, Scale 8
  • longitude (Decimal): Precision 11, Scale 8
  • zoom (Number): Map zoom level
  • category (Single Select): Setting category
  • updated_by (Single Line Text): Last updater email
  • updated_at (DateTime): Last update time
  • qr_code_1_image (Attachment): QR code 1 image
  • qr_code_2_image (Attachment): QR code 2 image
  • qr_code_3_image (Attachment): QR code 3 image

Shifts Table

  • Standard NocoDB fields for shift scheduling and management
  • Contains shift dates, times, locations, capacity limits
  • Status tracking (Active, Cancelled, Full)
  • Created automatically by build script with basic structure

Shift Signups Table

  • Links users to shifts they've signed up for
  • Tracks signup timestamps and user information
  • Handles cancellations and waitlist management
  • Created automatically by build script with basic structure

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 location
  • GET /health - Health check

Shifts Endpoints (requires authentication)

  • GET /api/shifts - Get all available shifts
  • GET /api/shifts/my-signups - Get current user's shift signups
  • POST /api/shifts/:shiftId/signup - Sign up for a shift
  • POST /api/shifts/:shiftId/cancel - Cancel shift signup

Shifts Admin Endpoints (requires admin privileges)

  • GET /api/shifts/admin - Get all shifts including cancelled ones
  • POST /api/shifts/admin - Create new shift
  • PUT /api/shifts/admin/:id - Update existing shift
  • DELETE /api/shifts/admin/:id - Delete shift

Authentication Endpoints

  • POST /api/auth/login - User login
  • GET /api/auth/check - Check authentication status
  • POST /api/auth/logout - User logout

Admin Endpoints (requires admin privileges)

  • GET /api/admin/start-location - Get start location with source info
  • POST /api/admin/start-location - Update map start location
  • GET /api/admin/walk-sheet-config - Get walk sheet configuration
  • POST /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

  • View Available Shifts: See all upcoming shifts with date, time, and capacity information
  • Sign Up for Shifts: One-click signup for available shifts
  • My Shifts Dashboard: View all your current shift signups
  • Cancel Signups: Cancel your shift signups when needed
  • Date Filtering: Filter shifts by specific dates
  • Real-time Updates: Shift availability updates dynamically

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

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
  • Real-time Preview: See changes immediately on the admin map
  • Validation: Built-in coordinate and zoom level validation

Access Control

  • Admin access is controlled via the Admin checkbox in the Login table
  • Only authenticated users with admin privileges can access /admin.html
  • Admin status is checked on every request to admin endpoints

Start Location Priority

The system uses a cascading fallback system for map start location:

  1. Database: Admin-configured location stored in Settings table (highest priority)
  2. Environment: Default values from .env file (medium priority)
  3. 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
PORT Server port 3000
NODE_ENV Environment mode production
SESSION_SECRET Session encryption secret Required
DEFAULT_LAT Default map latitude 53.5461
DEFAULT_LNG Default map longitude -113.4938
DEFAULT_ZOOM Default map zoom level 11
TRUST_PROXY Trust proxy headers (for Cloudflare) true
COOKIE_DOMAIN Cookie domain setting .cmlite.org
ALLOWED_ORIGINS CORS allowed origins Multiple URLs

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:

  1. Install dependencies:

    cd app
    npm install
    
  2. 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 geodata, latitude, and longitude columns
  • 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:

  1. Check the troubleshooting section
  2. Review NocoDB documentation
  3. 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