Skip to content

A web app to report and view illegal parking spots on a map using Leaflet and Firebase. Users can submit reports, and admins can approve, reject, or delete them via a secure dashboard.

License

Notifications You must be signed in to change notification settings

pakelcomedy/illegal-parking-map

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

17 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Illegal Parking Map

Illegal Parking Map is an interactive web application that allows users to:

  • View reported illegal parking spots on a city map.
  • Submit new illegal parking reports without requiring a login.
  • Administrators can review, approve, reject, or delete reports through a dedicated dashboard.

This project uses Leaflet for map rendering, Firebase (Firestore, Storage, Authentication) for backend services, and vanilla JavaScript/HTML/CSS for the frontend interface.


🌐 Live Demo

You can try out the application live at:

https://pakelcomedy.github.io/illegal-parking-map/


πŸ“Έ Screenshots

Screenshot (266) Screenshot (267) Screenshot (268) Screenshot (269)


πŸš€ Features

  1. Interactive Map

    • Displays markers for each reported illegal parking spot.
    • Marker colors indicate status:
      • Red = Unverified
      • Green = Approved
      • Gray = Rejected
    • Clicking a marker opens a detail popup showing description, photo (if any), date, and status.
  2. Submit a New Report

    • Accessible on pages/contribute.html without login.
    • Click the map to select coordinates or use the β€œShow My Location” button to autofill.
    • Upload a photo (JPEG/PNG, max 5 MB) and enter a description (10–500 characters).
    • If the user is offline, the report is stored locally and automatically synced once back online.
  3. Admin Dashboard

    • Accessible on pages/admin.html after logging in.
    • Real-time table displays all reports: ID, description, status, timestamp, photo thumbnail, and coordinates.
    • Buttons to β€œApprove”, β€œReject”, or β€œDelete” each report.
    • Filter by status or search by keyword in the description.
  4. Authentication & Security

    • Admin must log in (Firebase Authentication) to access admin.html.
    • Client-side route guard redirects non-authenticated users to login.html.
  5. Toast Notifications

    • All major interactions (success, error, offline, sync events) show a toast message in the top-right corner.
  6. Responsive Design

    • Sidebar legend and mobile navigation adapt to various screen sizes.
    • Layout adjusts for both desktop and mobile.

πŸ“‚ Project Structure


illegal-parking-map/
β”œβ”€β”€ index.html                  # Main page (view reports on a map)
β”œβ”€β”€ pages/                      # Separate pages
β”‚   β”œβ”€β”€ contribute.html         # Report submission page (no login)
β”‚   β”œβ”€β”€ login.html              # Admin login page
β”‚   └── admin.html              # Admin dashboard (requires login)
β”œβ”€β”€ assets/                     # Static assets (CSS, JS, images, etc.)
β”‚   β”œβ”€β”€ css/
β”‚   β”‚   β”œβ”€β”€ admin.css           # Styles specific to the admin dashboard
β”‚   β”‚   └── style.css           # Global styles (layout, toast, sidebar, etc.)
β”‚   β”œβ”€β”€ images/
β”‚   β”‚   β”œβ”€β”€ screenshot-home.png
β”‚   β”‚   β”œβ”€β”€ screenshot-contribute.png
β”‚   β”‚   └── screenshot-admin.png
β”‚   └── js/
β”‚       β”œβ”€β”€ firebase.js         # Firebase initialization (API keys, project config)
β”‚       β”œβ”€β”€ main.js             # Logic for the main page (index.html)
β”‚       β”œβ”€β”€ contribute.js       # Logic for the contribute page (contribute.html)
β”‚       └── admin.js            # Logic for the admin dashboard (admin.html)
β”œβ”€β”€ .gitignore                  # Files/folders to ignore in Git
β”œβ”€β”€ README.md                   # Project documentation (this file)
β”œβ”€β”€ LICENSE                     # Open-source license (MIT)
└── firebase.json               # (Optional) Firebase Hosting configuration


πŸ“ Installation & Setup

  1. Clone the Repository
   git clone https://github.com/pakelcomedy/illegal-parking-map.git
   cd illegal-parking-map
  1. Configure Firebase

    • Create or use an existing Firebase project.
    • In the Firebase Console, enable Authentication (Email/Password) under β€œSign-in method.”
    • Create a Firestore database (mode: β€œStart in test mode” or set rules as needed).
    • Enable Storage (configure rules to allow authenticated uploads or adjust as needed).
    • Copy your Firebase SDK configuration into assets/js/firebase.js:
   // assets/js/firebase.js
   // Replace with your Firebase project’s settings
   const firebaseConfig = {
     apiKey: "YOUR_API_KEY",
     authDomain: "YOUR_AUTH_DOMAIN",
     projectId: "YOUR_PROJECT_ID",
     storageBucket: "YOUR_STORAGE_BUCKET",
     messagingSenderId: "YOUR_SENDER_ID",
     appId: "YOUR_APP_ID"
   };
   firebase.initializeApp(firebaseConfig);
   ```
  1. Run a Local Web Server Serve the files over HTTP (not directly via file://). For example, using Python:
   python -m http.server 8000

Then open http://localhost:8000/index.html in your browser.

  1. Access Application Pages

    • Home: index.html
    • Contribute: pages/contribute.html
    • Login: pages/login.html
    • Admin: pages/admin.html (login required)

πŸ” Firebase Security Rules

Firestore Rules

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    // Anyone can read reports
    match /reports/{reportId} {
      allow read: if true;
      // Anyone can create (no auth required)
      allow create: if true;
      // Only authenticated users (admins) can update or delete
      allow update, delete: if request.auth != null;
    }
  }
}

Storage Rules

rules_version = '2';
service firebase.storage {
  match /b/{bucket}/o {
    match /report_photos/{reportId}/{allPaths=**} {
      // Only authenticated users can upload or delete
      allow write: if request.auth != null;
      // Public can read
      allow read: if true;
    }
  }
}

πŸ” File Overview

1. index.html & assets/js/main.js

  • index.html

    • Loads Leaflet CSS/JS and global styles (assets/css/style.css).
    • Contains <div id="map"></div> for the map, a filter form, a legend toggle, and a modal template for report details.
    • Navigation links to Contribute and Admin pages.
  • main.js

    • Initializes Leaflet map centered on Jakarta by default.
    • Adds an OpenStreetMap tile layer.
    • Sets up a real-time Firestore listener:
    db.collection('reports')
      .orderBy('createdAt', 'desc')
      .onSnapshot(...)
  • Creates custom markers for each report, colored by status:

    • Red marker for unverified reports
    • Green marker for approved reports
    • Gray marker for rejected reports
  • Adds a β€œShow My Location” button (using browser geolocation).

  • Implements filter controls for status and date range.

  • Binds click events on markers to open a detail modal.

  • Displays toast notifications.

2. pages/contribute.html & assets/js/contribute.js

  • contribute.html

    • Form fields:

      • Hidden text inputs for latitude (#location-lat) and longitude (#location-lng).
      • Textarea for description (#report-description).
      • File input for photo (#report-photo).
      • Photo preview container (#photo-preview with <img id="preview-img"> and <button id="remove-photo">Remove Photo</button>).
    • <div id="contribute-map"></div> for the Leaflet map.

    • Buttons and containers for toast notifications and sidebar legend.

  • contribute.js

    • Initializes Leaflet map in #contribute-map, centered on Jakarta by default.

    • Popup instructs: β€œClick on the map to select the location of the illegal parking spot.”

    • Map click event:

      • If no marker exists β†’ create a draggable marker at clicked location.
      • If marker exists β†’ move it to the clicked location.
      • Always update latitude and longitude form inputs to six decimal places.
    • Adds a β€œShow My Location” button in the top-left corner (custom Leaflet control):

      • Calls navigator.geolocation.getCurrentPosition(...).
      • Centers map on user location, adds a blue marker and an accuracy circle, and fills form inputs.
    • Validates description length (10–500 chars).

    • Validates photo type (JPEG/PNG) and size (≀ 5 MB), then shows preview.

    • On form submit:

      • If offline: save payload (description, lat, lng, timestamp, file) to localStorage.
      • If online: upload photo (if any) to Firebase Storage, then write report document to Firestore.
      • Shows appropriate toast notifications on success/failure.
      • Resets form and removes markers/preview.

3. pages/login.html

  • A simple login form (Email/Password) using Firebase Authentication.
  • Redirects to admin.html upon successful login.

4. pages/admin.html & assets/js/admin.js

  • admin.html

    • Checks authentication status on page load: if not authenticated β†’ redirect to login.html.
    • Contains a table (<table class="admin-table"><tbody id="reports-table-body"></tbody></table>) to list all reports.
    • Filter form (status & keyword) above the table.
    • Logout button.
  • admin.js

    • Sets up Firebase Auth listener:
    firebase.auth().onAuthStateChanged(user => {
      if (!user) window.location.href = 'login.html';
    });
  • Sets up a real-time Firestore listener:
    firestore.collection('reports')
      .orderBy('createdAt', 'desc')
      .onSnapshot(snapshot => { … });
  • Renders each report as a table row (<tr>), with columns:

    1. Report ID

    2. Description

    3. Status (capitalized)

    4. Reported At (formatted date)

    5. Photo (thumbnail or β€œβ€“β€ if none)

    6. Coordinates (latitude, longitude)

    7. Actions:

      • Approve (button β†’ update status to "approved")
      • Reject (button β†’ update status to "rejected")
      • Delete (button β†’ delete Firestore document + delete photo in Storage if exists)
  • Filter functionality:

    • Status filter uses Firestore .where('status', '==', …) if not β€œall”.
    • Keyword filter (client-side) matches description (lowercase substring).
  • Logout button calls firebase.auth().signOut() and redirects back to login.html.


🀝 Contributing

  1. Fork this repository.
  2. Create a new branch (git checkout -b feature/XYZ).
  3. Make your changes and commit (git commit -m "Add awesome feature").
  4. Push to your branch (git push origin feature/XYZ).
  5. Open a Pull Request describing your changes.

Contributions of any kindβ€”bug fixes, new features, documentation improvementsβ€”are very welcome!


πŸ“¦ Dependencies

  • Leaflet – version 1.9.x
  • Firebase Web SDK – version 9.x compat libraries (App, Firestore, Auth, Storage)
  • Vanilla JavaScript, HTML5, and CSS3 (no frontend framework)

πŸ“„ LICENSE

This project is licensed under the LGPL-2.1 LICENSE. See the LICENSE file for details.


Thank you for using Illegal Parking Map. Feel free to open issues or submit pull requests for improvements!

About

A web app to report and view illegal parking spots on a map using Leaflet and Firebase. Users can submit reports, and admins can approve, reject, or delete them via a secure dashboard.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published