diff --git a/frontend/src/views/GrievanceMap.jsx b/frontend/src/views/GrievanceMap.jsx
new file mode 100644
index 00000000..6f424c42
--- /dev/null
+++ b/frontend/src/views/GrievanceMap.jsx
@@ -0,0 +1,102 @@
+import React, {useEffect, useState} from "react";
+import {MapContainer, TileLayer, Marker, Popup} from "react-leaflet";
+import MarkerClusterGroup from "react-leaflet-cluster";
+import L from "leaflet";
+import { grievancesApi} from "../api";
+import "leaflet/dist/leaflet.css";
+
+const GrievanceMap = () => {
+ const [grievances , setGrievances] = useState([]);
+
+ useEffect(() => {
+ loadMapData();
+ }, []);
+
+ const loadMapData = async () => {
+ try {
+ const response = await grievancesApi.getMapData();
+ const data = Array.isArray(response)?response: response.data;
+ console.log("Map data:", data);
+
+ setGrievances(data);
+ } catch(err) {
+ console.error("Error loading map data:", err);
+ }
+ };
+ const getColor = (status) => {
+ switch (status?.toLowerCase()) {
+ case "open": return "red";
+ case "in_progress": return "orange";
+ case "resolved": return "green";
+ case "escalated": return "purple";
+ default: return "blue";
+ }
+ };
+ const markerIcon = (status) =>
+ L.divIcon({
+ className: "custom-marker",
+ html: ``,
+ iconSize: [16,16],
+ iconAnchor: [8, 8],
+ });
+ return (
+
+
+
+
+ {grievances.map((g)=>
+ g.latitude && g.longitude ? (
+
+
+
+
{g.category}
+
+
+ Status:
+
+ {g.status}
+
+
+
+ Severity:
+
+ {g.severity}
+
+
+
+ Authority:
+
+ {g.assigned_authority}
+
+
+
+
+
+
+ ): null
+ )}
+
+
+
+ );
+};
+export default GrievanceMap;
\ No newline at end of file
diff --git a/frontend/src/views/Home.jsx b/frontend/src/views/Home.jsx
index c63b9d97..c3cff278 100644
--- a/frontend/src/views/Home.jsx
+++ b/frontend/src/views/Home.jsx
@@ -2,7 +2,9 @@ import React from 'react';
import { useTranslation } from 'react-i18next';
import { createPortal } from 'react-dom';
import { useNavigate } from 'react-router-dom';
-import { AnimatePresence, motion } from 'framer-motion';
+
+import { motion, AnimatePresence } from 'framer-motion';
+
import {
AlertTriangle, MapPin, Search, Activity, Camera, Trash2, ThumbsUp, Brush,
Droplets, Zap, Truck, Flame, Dog, XCircle, Lightbulb, TreeDeciduous, Bug,
@@ -253,7 +255,13 @@ const Home = ({ setView, fetchResponsibilityMap, recentIssues, handleUpvote, loa
whileInView={{ opacity: 1, scale: 1 }}
viewport={{ once: true }}
transition={{ delay: itemIdx * 0.05 }}
- onClick={() => setView(item.id)}
+ onClick={() => {
+ if(item.id === "map"){
+ navigate("/grievance-map");
+ } else {
+ setView(item.id)
+ }
+ }}
className="group bg-white/50 dark:bg-gray-900/50 backdrop-blur-xl rounded-[2rem] border border-white/50 dark:border-gray-800/50 p-8 flex flex-col items-start gap-6 hover:shadow-2xl hover:bg-white dark:hover:bg-gray-800 transition-all duration-300 h-56"
>
diff --git a/frontend/src/views/ReportForm.jsx b/frontend/src/views/ReportForm.jsx
index 8ee29018..116fc673 100644
--- a/frontend/src/views/ReportForm.jsx
+++ b/frontend/src/views/ReportForm.jsx
@@ -269,11 +269,13 @@ const ReportForm = ({ setView, setLoading, setError, setActionPlan, loading }) =
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(
(position) => {
+ const lat = position.coords.latitude;
+ const lng = position.coords.longitude;
setFormData(prev => ({
...prev,
- latitude: position.coords.latitude,
- longitude: position.coords.longitude,
- location: `Lat: ${position.coords.latitude.toFixed(4)}, Long: ${position.coords.longitude.toFixed(4)}`
+ latitude: lat,
+ longitude: lng,
+ location: `Lat: ${lat.toFixed(4)}, Long: ${lng.toFixed(4)}`
}));
setGettingLocation(false);
},
@@ -283,10 +285,11 @@ const ReportForm = ({ setView, setLoading, setError, setActionPlan, loading }) =
setGettingLocation(false);
}
);
- } else {
- setError("Geolocation is not supported by this browser.");
- setGettingLocation(false);
}
+ // else {
+ // setError("Geolocation is not supported by this browser.");
+ // setGettingLocation(false);
+ // }
};
const checkNearbyIssues = async () => {