Das Map-System bietet eine Snapchat-Maps-Γ€hnliche interaktive Kartenansicht mit:
- Hotspots: Zeigt wo gerade viel los ist (basierend auf simulierter AktivitΓ€t)
- Community Spots: Von Nutzern geteilte interessante Orte
- Events/Meetups: Lokale Treffen (IT-Meetups, Social Events, etc.)
- Angebote: Lokale Deals und Rabatte
- Fotos: Nutzerfotos an Standorten
- Local Guide System: "Ich zeige dir die Gegend" Einladungen
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β NewsLayout.vue β
β ββββββββββββ ββββββββββββββββββββββββββ ββββββββββββββββββββ β
β β Settings β β MapView.vue β β UserSidebar β β
β β (25%) β β (Snapchat-Style) β β (25%) β β
β β β β β β β β
β β Filters β β ββββββββββββββββββββ β β Online Users β β
β β Interestsβ β β Leaflet Map β β β Matches β β
β β Location β β β (Dark Theme) β β β Friends β β
β β β β β β β β β β
β β β β β π΄ Hotspots β β β β β
β β β β β π Spots β β β β β
β β β β β π° Articles β β β β β
β β β β β π Events β β β β β
β β β β β πΌ Offers β β β β β
β β β β β πΈ Photos β β β β β
β β β β ββββββββββββββββββββ β β β β
β ββββββββββββ ββββββββββββββββββββββββββ ββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Hauptkomponente mit Leaflet-Karte, Marker-Rendering und UI-Controls.
<MapView
:user-id="currentUserId"
@add-spot="showSpotModal = true"
@marker-click="handleMarkerClick"
@map-click="handleMapClick"
/>Popup fΓΌr Community Spots mit Foto, Beschreibung, Likes und Aktionen.
Popup fΓΌr Events mit Datum, Teilnehmer, Preis und Anmeldefunktion.
Popup fΓΌr Angebote mit Preis, GΓΌltigkeit und EinlΓΆse-Button.
Modal zum Erstellen neuer Community Spots mit Foto-Upload.
Modal zum Erstellen neuer Events/Meetups.
Suchkomponente fΓΌr Orte, Events, Spots und Angebote.
Karte fΓΌr Local Guide Einladungen.
Zentrales Datenmanagement fΓΌr alle Map-Daten.
const {
// State
center, bounds, zoom, isLoading, error, filters,
selectedMarker, hoveredMarker,
// Data
spots, events, offers, photos, invites, hotspots, pois,
// Computed
generateMarkers, clusteredMarkers, stats,
// Actions
initializeMap, updateBounds, setCenter,
selectMarker, updateFilters,
// CRUD
addSpot, addEvent, addOffer, addPhoto, createInvite
} = useMapDataSingleton(userId)Fetcht POIs (Points of Interest) von OpenStreetMap Overpass API.
const {
pois, isLoading, error,
fetchPOIs, getPOIsInBounds, searchPOIs
} = useOSMDataSingleton()Simuliert realistische AktivitΓ€tslevel basierend auf:
- POI-Typ (CafΓ©, Bar, Park, etc.)
- Tageszeit (Peak Hours)
- Wochentag (Wochenende vs. Wochentag)
- Spezielle Events (Friday Night, Lunch Rush, etc.)
const {
hotspots, generateHotspots, getActivityForPOI,
trendingHotspots, currentTimeInfo
} = useActivitySimulationSingleton()interface Hotspot {
id: string
geohash: string
lat: number
lng: number
activity: 'quiet' | 'low' | 'medium' | 'high' | 'trending'
userCount: number
peakHours: number[]
lastUpdate: number
source: 'osm' | 'user' | 'simulated'
}interface CommunitySpot {
id: string
title: string
description: string
photos: SpotPhoto[]
lat: number
lng: number
category: SpotCategory
tags: string[]
createdBy: string
likes: number
visits: number
status: 'pending' | 'approved' | 'rejected'
}interface LocalEvent {
id: string
title: string
description: string
category: EventCategory
subcategory?: string
date: number
venue?: string
lat: number
lng: number
attendees: string[]
maxAttendees?: number
price?: string
tags: string[]
}interface LocalOffer {
id: string
title: string
description: string
price?: string
discount?: number
lat: number
lng: number
business: { id: string, name: string, verified: boolean }
validUntil: number
status: 'active' | 'expired' | 'soldout'
}gun.get('news_plugin')
βββ .get(sphereId)
βββ .get('hotspots').get(geohash) β Hotspot
βββ .get('spots').get(spotId) β CommunitySpot
βββ .get('events').get(eventId) β LocalEvent
βββ .get('offers').get(offerId) β LocalOffer
βββ .get('photos').get(photoId) β LocationPhoto
βββ .get('invites').get(inviteId) β LocalGuideInvite
| Level | Farbe | Beschreibung |
|---|---|---|
| quiet | Grau | Wenig bis keine AktivitΓ€t |
| low | GrΓΌn | Geringe AktivitΓ€t |
| medium | Orange | Mittlere AktivitΓ€t |
| high | Rot | Hohe AktivitΓ€t |
| trending | Pink + Pulse | Sehr viel los (Animation) |
- CafΓ©: 8-10 Uhr, 14-15 Uhr
- Restaurant: 12-13 Uhr, 19-21 Uhr
- Bar: 21-23 Uhr (Fr/Sa: 22-01 Uhr)
- Coworking: 10-16 Uhr
- Park: 17-19 Uhr (Wochenende: 10-17 Uhr)
- Gym: 7-8 Uhr, 17-19 Uhr
- friday_night: +50% fΓΌr Bars, Restaurants
- saturday_night: +100% fΓΌr Nightlife
- lunch_rush: +30% fΓΌr Essen
- morning_commute: +50% fΓΌr Transport
- evening_commute: +50% fΓΌr Transport, SupermΓ€rkte
interface MapFilters {
showHotspots: boolean
showSpots: boolean
showEvents: boolean
showArticles: boolean
showOffers: boolean
showPhotos: boolean
showInvites: boolean
spotCategories: SpotCategory[]
eventCategories: EventCategory[]
offerCategories: OfferCategory[]
minActivityLevel: ActivityLevel
eventsTimeRange: 'today' | 'week' | 'month' | 'all'
maxDistance?: number
}Marker werden bei niedrigem Zoom-Level gruppiert:
- Cluster-Threshold: Zoom < 14
- Min. Cluster-GrΓΆΓe: 3 Marker
- Cluster-Precision: Geohash-basiert (angepasst an Zoom)
- Marker-Virtualisierung: Nur sichtbare Marker werden gerendert
- Geohash-Indexing: Schnelle rΓ€umliche Suche
- Debounced Updates: Map-Events werden gedrosselt
- Lazy Loading: Fotos nur bei hohem Zoom
- Singleton Pattern: Eine globale Instanz pro Composable
- Touch-Gesten: Pinch-to-zoom, Drag
- Responsive Design: Anpassung an BildschirmgrΓΆΓe
- Bottom Sheet: User-Sidebar als ausziehbares Panel
- ARIA-Labels fΓΌr alle interaktiven Elemente
- Keyboard-Navigation unterstΓΌtzt
- Fokus-Management bei Modals
const spot = await mapData.addSpot({
title: 'Geheimer Aussichtspunkt',
description: 'Toller Blick ΓΌber die Stadt',
photos: [{ url: 'base64...', caption: 'Sonnenuntergang' }],
lat: 52.52,
lng: 13.405,
category: 'scenic',
tags: ['aussicht', 'sonnenuntergang', 'geheimtipp'],
createdBy: 'user-123'
})const event = await mapData.addEvent({
title: 'Vue.js Meetup Berlin',
description: 'Monatliches Treffen der Vue.js Community',
category: 'tech',
subcategory: 'Vue.js / Frontend',
date: Date.now() + 7 * 24 * 60 * 60 * 1000,
venue: 'Coworking Space XY',
lat: 52.52,
lng: 13.405,
price: 'Free',
maxAttendees: 50,
tags: ['vue', 'javascript', 'frontend'],
createdBy: 'user-123'
})- Echte User-AktivitΓ€tsdaten (wenn User vorhanden)
- Google Places API Integration
- Meetup.com Event-Sync
- Heatmap-Overlay
- Offline-Support mit IndexedDB
- Push-Notifications fΓΌr Events in der NΓ€he