A comprehensive React application for reporting and managing civic issues in communities. Built with React, TypeScript, Firebase, and Tailwind CSS.
- Multi-Authentication: Email/password, Google Sign-In, and Phone OTP authentication
- Issue Reporting: Submit reports with photos, location, and categorization
- Interactive Maps: View all reports on an interactive map with clustered markers
- Real-time Updates: Live status updates and notifications via Firebase Cloud Messaging
- Admin Dashboard: Manage reports, assign agents, and update statuses
- Mobile Responsive: Optimized for all device sizes with PWA capabilities
- Image Handling: Automatic WebP conversion and compression
- Geolocation: Automatic location capture with manual adjustment
- Push Notifications: Firebase Cloud Messaging for status updates
- Security: Firebase Security Rules with role-based access control
- Real-time: Live updates using Firestore real-time listeners
- Frontend: React 18, TypeScript, Tailwind CSS
- Backend: Firebase (Authentication, Firestore, Storage, Cloud Messaging)
- Maps: Leaflet with React Leaflet
- State Management: React Hooks, Context API
- Forms: React Hook Form
- Routing: React Router v6
- Image Processing: React Image File Resizer
- Icons: Lucide React
- Node.js 18+ and npm
- Firebase account
- Modern web browser with geolocation support
- Clone the repository
git clone <repository-url>
cd civic-issue-reporting- Install dependencies
npm install- Firebase Setup
- Go to Firebase Console
- Click "Create a project"
- Follow the setup wizard
- Enable Google Analytics (optional)
- In Firebase Console, go to Authentication > Sign-in method
- Enable the following providers:
- Email/Password
- Phone (optional)
- Go to Firestore Database
- Click "Create database"
- Choose "Start in test mode" (we'll add security rules later)
- Select a location for your database
- Go to Storage
- Click "Get started"
- Choose "Start in test mode"
- Select a location
- Go to Project Settings > Cloud Messaging
- Generate a new key pair for VAPID
- Note down the VAPID key
-
Go to Project Settings > General
-
Scroll down to "Your apps"
-
Click "Add app" and select Web
-
Register your app
-
Copy the configuration object
-
Environment Variables Create a
.envfile in the root directory and add your Firebase configuration:
VITE_FIREBASE_API_KEY=your_api_key_here
VITE_FIREBASE_AUTH_DOMAIN=your_project_id.firebaseapp.com
VITE_FIREBASE_PROJECT_ID=your_project_id
VITE_FIREBASE_STORAGE_BUCKET=your_project_id.appspot.com
VITE_FIREBASE_MESSAGING_SENDER_ID=your_sender_id
VITE_FIREBASE_APP_ID=your_app_id
VITE_FIREBASE_MEASUREMENT_ID=your_measurement_id
VITE_FIREBASE_VAPID_KEY=your_vapid_key_for_fcm- Firebase Security Rules
Replace the default rules in Firestore with:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
// Profiles collection
match /profiles/{userId} {
allow read: if true;
allow write: if request.auth != null && request.auth.uid == userId;
allow update: if request.auth != null &&
(request.auth.uid == userId ||
get(/databases/$(database)/documents/profiles/$(request.auth.uid)).data.role in ['admin', 'agent']);
}
// Reports collection
match /reports/{reportId} {
allow read: if true;
allow create: if request.auth != null && request.auth.uid == request.resource.data.userId;
allow update: if request.auth != null &&
(request.auth.uid == resource.data.userId ||
get(/databases/$(database)/documents/profiles/$(request.auth.uid)).data.role in ['admin', 'agent']);
}
// Report comments
match /reportComments/{commentId} {
allow read: if true;
allow create: if request.auth != null && request.auth.uid == request.resource.data.userId;
}
// Status history
match /statusHistory/{historyId} {
allow read: if true;
allow create: if request.auth != null && request.auth.uid == request.resource.data.changedBy;
}
}
}Replace the default rules in Storage with:
rules_version = '2';
service firebase.storage {
match /b/{bucket}/o {
match /reports/{allPaths=**} {
allow read: if true;
allow write: if request.auth != null;
}
}
}- Update Service Worker
Update the Firebase configuration in
public/firebase-messaging-sw.jswith your project details.
# Start the development server
npm run dev
# Build for production
npm run build
# Preview production build
npm run preview
# Lint code
npm run lintsrc/
├── components/ # Reusable UI components
│ ├── AuthProvider.tsx
│ ├── Layout.tsx
│ ├── MapView.tsx
│ └── ReportCard.tsx
├── hooks/ # Custom React hooks
│ └── useAuth.ts
├── lib/ # External service configurations
│ └── firebase.ts
├── pages/ # Page components
│ ├── Dashboard.tsx
│ ├── ReportForm.tsx
│ ├── ReportDetail.tsx
│ ├── MyReports.tsx
│ └── AdminDashboard.tsx
├── utils/ # Utility functions
│ └── imageUtils.ts
└── App.tsx
- Register/Login: Create account using email, Google, or phone
- Report Issues: Use the floating + button to report new issues
- Upload Photos: Take photos or upload from gallery (auto-compressed to WebP)
- Set Location: Auto-detect location or manually set on map
- Track Progress: Follow status updates and receive push notifications
- Dashboard Access: Admin users can access the admin dashboard
- Manage Reports: View, verify, assign, and resolve reports
- User Management: Assign agent roles to users
- Real-time Updates: See live updates as reports come in
{
id: string, // User UID
email: string,
fullName: string,
photoURL?: string,
role: 'user' | 'admin' | 'agent',
fcmToken?: string, // For push notifications
createdAt: Timestamp,
updatedAt: Timestamp
}{
id: string, // Auto-generated
title: string,
description: string,
category: string,
severity: 'low' | 'medium' | 'high' | 'critical',
status: 'submitted' | 'verified' | 'assigned' | 'resolved',
latitude: number,
longitude: number,
address?: string,
images: string[], // Firebase Storage URLs
thumbnail?: string, // Base64 thumbnail
userId: string, // Reporter's UID
assignedTo?: string, // Agent's UID
createdAt: Timestamp,
updatedAt: Timestamp
}{
id: string,
reportId: string,
userId: string,
comment: string,
createdAt: Timestamp
}{
id: string,
reportId: string,
status: 'submitted' | 'verified' | 'assigned' | 'resolved',
changedBy: string, // User UID who made the change
notes?: string,
createdAt: Timestamp
}- Firebase Authentication with multiple providers
- Firestore Security Rules for data protection
- Role-based access control (user, agent, admin)
- Secure image upload with automatic compression
- Input validation and sanitization
- Image compression and WebP conversion
- Map marker clustering for better performance
- Lazy loading of components
- Real-time listeners with proper cleanup
- Responsive design for all devices
The app supports Firebase Cloud Messaging for real-time notifications:
- Setup: VAPID key configured in environment variables
- Permission: Automatic permission request on login
- Background: Service worker handles background notifications
- Targeting: Notifications sent based on user roles and report ownership
# Install Firebase CLI
npm install -g firebase-tools
# Login to Firebase
firebase login
# Initialize hosting
firebase init hosting
# Build and deploy
npm run build
firebase deployThe app can be deployed to any static hosting service (Vercel, Netlify, etc.) since it's a client-side React application.
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests if applicable
- Submit a pull request
MIT License - see LICENSE file for details
For support, please create an issue in the GitHub repository or contact the development team.
- Firebase Configuration: Ensure all environment variables are set correctly
- Authentication: Check that authentication providers are enabled in Firebase Console
- Permissions: Verify Firestore and Storage security rules are properly configured
- Location Services: Ensure location permissions are granted in browser
- Push Notifications: Check VAPID key configuration and service worker registration
- Use Firebase Emulator Suite for local development
- Enable Firebase Debug mode for detailed logging
- Test security rules using Firebase Console simulator
- Monitor usage and performance in Firebase Console