diff --git a/components/map/mockData.ts b/components/map/mockData.ts
new file mode 100644
index 0000000..24cb725
--- /dev/null
+++ b/components/map/mockData.ts
@@ -0,0 +1,36 @@
+export type MapItem = {
+ id: number;
+ title: string;
+ lat: number;
+ lng: number;
+};
+
+export const requests: MapItem[] = [
+ {
+ id: 1,
+ title: "Food Assistance – Petaling Jaya",
+ lat: 3.1073,
+ lng: 101.6067,
+ },
+ {
+ id: 2,
+ title: "Medical Help – Cheras",
+ lat: 3.0800,
+ lng: 101.7350,
+ },
+];
+
+export const offers: MapItem[] = [
+ {
+ id: 3,
+ title: "Free Meals – Bangsar",
+ lat: 3.1303,
+ lng: 101.6640,
+ },
+ {
+ id: 4,
+ title: "Clothes Donation – Setapak",
+ lat: 3.2100,
+ lng: 101.7200,
+ },
+];
diff --git a/package-lock.json b/package-lock.json
index 07c49e5..6d8706c 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,11 +1,11 @@
{
- "name": "openhelpmap",
+ "name": "open-help-map",
"version": "0.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
- "name": "openhelpmap",
+ "name": "open-help-map",
"version": "0.0.0",
"dependencies": {
"@supabase/supabase-js": "^2.90.1",
@@ -65,6 +65,7 @@
"integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"@babel/code-frame": "^7.27.1",
"@babel/generator": "^7.28.5",
@@ -1562,6 +1563,7 @@
"integrity": "sha512-MWtvHrGZLFttgeEj28VXHxpmwYbor/ATPYbBfSFZEIRK0ecCFLl2Qo55z52Hss+UV9CRN7trSeq1zbgx7YDWWg==",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"csstype": "^3.2.2"
}
@@ -1630,6 +1632,7 @@
"integrity": "sha512-iIACsx8pxRnguSYhHiMn2PvhvfpopO9FXHyn1mG5txZIsAaB6F0KwbFnUQN3KCiG3Jcuad/Cao2FAs1Wp7vAyg==",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"@typescript-eslint/scope-manager": "8.52.0",
"@typescript-eslint/types": "8.52.0",
@@ -1881,6 +1884,7 @@
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
"dev": true,
"license": "MIT",
+ "peer": true,
"bin": {
"acorn": "bin/acorn"
},
@@ -1986,6 +1990,7 @@
}
],
"license": "MIT",
+ "peer": true,
"dependencies": {
"baseline-browser-mapping": "^2.9.0",
"caniuse-lite": "^1.0.30001759",
@@ -2226,6 +2231,7 @@
"integrity": "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.8.0",
"@eslint-community/regexpp": "^4.12.1",
@@ -2736,7 +2742,8 @@
"version": "1.9.4",
"resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.9.4.tgz",
"integrity": "sha512-nxS1ynzJOmOlHp+iL3FyWqK89GtNL8U8rvlMOsQdTTssxZwCXh8N2NB3GDQOL+YR3XnWyZAxwQixURb+FA74PA==",
- "license": "BSD-2-Clause"
+ "license": "BSD-2-Clause",
+ "peer": true
},
"node_modules/levn": {
"version": "0.4.1",
@@ -2943,6 +2950,7 @@
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
"dev": true,
"license": "MIT",
+ "peer": true,
"engines": {
"node": ">=12"
},
@@ -3004,6 +3012,7 @@
"resolved": "https://registry.npmjs.org/react/-/react-19.2.3.tgz",
"integrity": "sha512-Ku/hhYbVjOQnXDZFv2+RibmLFGwFdeeKHFcOTlrt7xplBnya5OGn/hIRDsqDiSUcfORsDC7MPxwork8jBwsIWA==",
"license": "MIT",
+ "peer": true,
"engines": {
"node": ">=0.10.0"
}
@@ -3013,6 +3022,7 @@
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.3.tgz",
"integrity": "sha512-yELu4WmLPw5Mr/lmeEpox5rw3RETacE++JgHqQzd2dg+YbJuat3jH4ingc+WPZhxaoFzdv9y33G+F7Nl5O0GBg==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"scheduler": "^0.27.0"
},
@@ -3294,6 +3304,7 @@
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
"dev": true,
"license": "Apache-2.0",
+ "peer": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
@@ -3379,6 +3390,7 @@
"integrity": "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"esbuild": "^0.27.0",
"fdir": "^6.5.0",
@@ -3541,6 +3553,7 @@
"integrity": "sha512-k7Nwx6vuWx1IJ9Bjuf4Zt1PEllcwe7cls3VNzm4CQ1/hgtFUK2bRNG3rvnpPUhFjmqJKAKtjV576KnUkHocg/g==",
"dev": true,
"license": "MIT",
+ "peer": true,
"funding": {
"url": "https://github.com/sponsors/colinhacks"
}
diff --git a/public/markers/blue.png b/public/markers/blue.png
new file mode 100644
index 0000000..e2e9f75
Binary files /dev/null and b/public/markers/blue.png differ
diff --git a/public/markers/red.png b/public/markers/red.png
new file mode 100644
index 0000000..3e64e06
Binary files /dev/null and b/public/markers/red.png differ
diff --git a/public/markers/shadow.png b/public/markers/shadow.png
new file mode 100644
index 0000000..9fd2979
Binary files /dev/null and b/public/markers/shadow.png differ
diff --git a/src/components/map/MapPin.tsx b/src/components/map/MapPin.tsx
new file mode 100644
index 0000000..4ac5dcb
--- /dev/null
+++ b/src/components/map/MapPin.tsx
@@ -0,0 +1,38 @@
+import { Marker, Popup } from "react-leaflet";
+import "../../styles/map.css";
+import type { MapItem } from "./mockData";
+
+type Props = {
+ item: MapItem;
+};
+
+export default function MapPin({ item }: Props) {
+
+ // 🔹 Simulated logged-in user role
+ // Change to "user" to test restriction
+ const userRole: "user" | "volunteer" = "volunteer";
+
+ return (
+
+ Delivery assistance available for volunteers only
+ {item.title}
+
+ {item.pickup_allowed ? (
+
+ ) : userRole === "volunteer" ? (
+
+ ) : (
+