Improve event popup and map positioning
- Added 'View Event Details' button in event popup that navigates to /events?id={eventId}
- Adjusted map center from Dublin (53.3498, -6.2603) to (53.4, -7.5) to better show all of Ireland
- New center point ensures Ireland is fully visible even when filter panel is open
- Button has blue styling with hover effect for better UX
This commit is contained in:
0
EVENT_MAP_FEATURES.md
Normal file
0
EVENT_MAP_FEATURES.md
Normal file
148
MAP_EVENT_INTEGRATION.md
Normal file
148
MAP_EVENT_INTEGRATION.md
Normal file
@@ -0,0 +1,148 @@
|
|||||||
|
# Map-Event Integration Implementation
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
Successfully integrated cleanup events with the interactive map, allowing users to view both litter reports and cleanup events on the same map interface.
|
||||||
|
|
||||||
|
## Changes Made
|
||||||
|
|
||||||
|
### 1. MapPage Component (`src/pages/MapPage.tsx`)
|
||||||
|
|
||||||
|
**Added:**
|
||||||
|
- Event state management with `useState` for events and loading state
|
||||||
|
- `useEffect` hook to fetch events from the API on component mount
|
||||||
|
- Sample event data as fallback when API is unavailable
|
||||||
|
- Event visibility toggle state (`showEvents`)
|
||||||
|
- Handler function `handleToggleEvents()` to show/hide events
|
||||||
|
- Fixed date filter conversion from Date objects to ISO strings for API compatibility
|
||||||
|
|
||||||
|
**Key Features:**
|
||||||
|
- Events are fetched independently from reports
|
||||||
|
- Loading states for both reports and events
|
||||||
|
- Events passed to MapView component only when `showEvents` is true
|
||||||
|
|
||||||
|
### 2. MapView Component (`src/components/map/MapView.tsx`)
|
||||||
|
|
||||||
|
**Enhanced:**
|
||||||
|
- Event marker popups with rich information display:
|
||||||
|
- Event title and description
|
||||||
|
- Location name with map pin emoji
|
||||||
|
- Scheduled date and time (formatted for Irish locale)
|
||||||
|
- Duration in minutes
|
||||||
|
- Participant count
|
||||||
|
- Litter collected (for completed events)
|
||||||
|
- Status badge with color coding
|
||||||
|
- Event markers use calendar emoji (📅)
|
||||||
|
- Different marker colors based on event status:
|
||||||
|
- **Upcoming**: Amber (#F59E0B)
|
||||||
|
- **Completed**: Green (#10B981)
|
||||||
|
- **Cancelled**: Gray (#6B7280)
|
||||||
|
|
||||||
|
**Event Marker Features:**
|
||||||
|
- Always displayed on regular layer (not clustered)
|
||||||
|
- 32x32 pixel markers with white border
|
||||||
|
- Hover effects and click interactions
|
||||||
|
- Detailed popup with formatted information
|
||||||
|
|
||||||
|
### 3. MapFilters Component (`src/components/map/MapFilters.tsx`)
|
||||||
|
|
||||||
|
**Added:**
|
||||||
|
- "Show Events" toggle switch
|
||||||
|
- Props: `onToggleEvents` and `showEvents`
|
||||||
|
- Green color scheme for event toggle (to distinguish from other toggles)
|
||||||
|
- Positioned above the Hotspots toggle
|
||||||
|
|
||||||
|
## Sample Event Data
|
||||||
|
|
||||||
|
Three sample events are provided as fallback:
|
||||||
|
1. **Sandymount Beach Cleanup** (Dublin) - Upcoming
|
||||||
|
2. **Galway Bay Cleanup** (Salthill Beach) - Upcoming
|
||||||
|
3. **Cork Harbor Cleanup** - Completed (with 45.5 kg collected)
|
||||||
|
|
||||||
|
## User Experience
|
||||||
|
|
||||||
|
### Viewing Events on Map
|
||||||
|
1. Navigate to the Map page
|
||||||
|
2. Events are displayed by default with calendar markers
|
||||||
|
3. Click on an event marker to see detailed information
|
||||||
|
4. Toggle "Show Events" in the filters panel to hide/show events
|
||||||
|
|
||||||
|
### Event Information Display
|
||||||
|
Each event popup shows:
|
||||||
|
- 📍 Location name
|
||||||
|
- 📅 Scheduled date and time
|
||||||
|
- ⏱️ Duration
|
||||||
|
- 👥 Number of participants
|
||||||
|
- ♻️ Litter collected (for completed events)
|
||||||
|
- Status badge (color-coded)
|
||||||
|
- Event description
|
||||||
|
|
||||||
|
## API Integration
|
||||||
|
|
||||||
|
### Event Service
|
||||||
|
Uses `eventService.getEvents()` to fetch events from the backend:
|
||||||
|
- Endpoint: `GET /api/events`
|
||||||
|
- Returns array of `CleanupEvent` objects
|
||||||
|
- Supports optional filters (status, date range, location)
|
||||||
|
|
||||||
|
### Error Handling
|
||||||
|
- Falls back to sample data if API call fails
|
||||||
|
- Logs errors to console for debugging
|
||||||
|
- Graceful degradation ensures map remains functional
|
||||||
|
|
||||||
|
## Technical Details
|
||||||
|
|
||||||
|
### Type Safety
|
||||||
|
- Full TypeScript support with `CleanupEvent` interface
|
||||||
|
- Type-safe props and state management
|
||||||
|
- Proper type conversion for date filters
|
||||||
|
|
||||||
|
### Performance
|
||||||
|
- Events fetched once on component mount
|
||||||
|
- Separate loading states for reports and events
|
||||||
|
- Efficient marker rendering with Leaflet
|
||||||
|
|
||||||
|
### Accessibility
|
||||||
|
- Toggle switches with proper ARIA labels
|
||||||
|
- Semantic HTML structure
|
||||||
|
- Keyboard navigation support
|
||||||
|
|
||||||
|
## Future Enhancements
|
||||||
|
|
||||||
|
Potential improvements:
|
||||||
|
1. Filter events by status (upcoming/completed/cancelled)
|
||||||
|
2. Click event marker to navigate to event detail page
|
||||||
|
3. Show event radius/coverage area on map
|
||||||
|
4. Link related reports to events
|
||||||
|
5. Real-time event updates with WebSockets
|
||||||
|
6. Event clustering for dense areas
|
||||||
|
7. Calendar view integration
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
|
||||||
|
To test the implementation:
|
||||||
|
1. Start the backend server: `cd server && npm run dev`
|
||||||
|
2. Start the frontend: `npm run dev`
|
||||||
|
3. Navigate to the Map page
|
||||||
|
4. Verify events appear on the map
|
||||||
|
5. Click event markers to see popups
|
||||||
|
6. Toggle "Show Events" to hide/show markers
|
||||||
|
7. Check that event colors match their status
|
||||||
|
|
||||||
|
## Related Requirements
|
||||||
|
|
||||||
|
This implementation addresses:
|
||||||
|
- **Requirement 4.1**: Display event markers on map
|
||||||
|
- **Requirement 4.2**: Show event details on click
|
||||||
|
- **Requirement 4.3**: Display participant count
|
||||||
|
- **Requirement 2.1**: Interactive map visualization
|
||||||
|
- **Requirement 2.2**: Marker click handlers
|
||||||
|
|
||||||
|
## Commit
|
||||||
|
|
||||||
|
Changes committed with message:
|
||||||
|
```
|
||||||
|
Link map items with events - Display cleanup events on interactive map
|
||||||
|
```
|
||||||
|
|
||||||
|
Git hash: `91ecbd2`
|
||||||
@@ -43,7 +43,7 @@ export function MapView({
|
|||||||
showClusters = true,
|
showClusters = true,
|
||||||
showHeatmap = false,
|
showHeatmap = false,
|
||||||
showHotspots = false,
|
showHotspots = false,
|
||||||
center = [53.3498, -6.2603], // Dublin, Ireland default
|
center = [53.4, -7.5], // Centered to show all of Ireland
|
||||||
zoom = 7,
|
zoom = 7,
|
||||||
}: MapViewProps) {
|
}: MapViewProps) {
|
||||||
const mapRef = useRef<HTMLDivElement>(null);
|
const mapRef = useRef<HTMLDivElement>(null);
|
||||||
@@ -277,6 +277,12 @@ export function MapView({
|
|||||||
${event.description ? `
|
${event.description ? `
|
||||||
<p class="text-xs text-gray-600 mt-2 pt-2 border-t">${event.description}</p>
|
<p class="text-xs text-gray-600 mt-2 pt-2 border-t">${event.description}</p>
|
||||||
` : ''}
|
` : ''}
|
||||||
|
<button
|
||||||
|
onclick="window.location.href='/events?id=${event.id}'"
|
||||||
|
class="mt-3 w-full px-4 py-2 bg-blue-600 hover:bg-blue-700 text-white text-sm font-medium rounded-md transition-colors"
|
||||||
|
>
|
||||||
|
View Event Details
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
`);
|
`);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user