Skip to content

Latest commit

Β 

History

History
321 lines (267 loc) Β· 9.13 KB

File metadata and controls

321 lines (267 loc) Β· 9.13 KB

Map System - LocalConnect News Plugin v2.0

Overview

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

Architektur

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                      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        β”‚  β”‚  β”‚                  β”‚ β”‚
β”‚  β”‚          β”‚  β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚  β”‚                  β”‚ β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Komponenten

MapView.vue

Hauptkomponente mit Leaflet-Karte, Marker-Rendering und UI-Controls.

<MapView
  :user-id="currentUserId"
  @add-spot="showSpotModal = true"
  @marker-click="handleMarkerClick"
  @map-click="handleMapClick"
/>

SpotPopup.vue

Popup fΓΌr Community Spots mit Foto, Beschreibung, Likes und Aktionen.

EventPopup.vue

Popup fΓΌr Events mit Datum, Teilnehmer, Preis und Anmeldefunktion.

OfferPopup.vue

Popup fΓΌr Angebote mit Preis, GΓΌltigkeit und EinlΓΆse-Button.

SpotSubmitModal.vue

Modal zum Erstellen neuer Community Spots mit Foto-Upload.

CreateEventModal.vue

Modal zum Erstellen neuer Events/Meetups.

MapSearch.vue

Suchkomponente fΓΌr Orte, Events, Spots und Angebote.

InviteCard.vue

Karte fΓΌr Local Guide Einladungen.

Composables

useMapData.ts

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)

useOSMData.ts

Fetcht POIs (Points of Interest) von OpenStreetMap Overpass API.

const {
  pois, isLoading, error,
  fetchPOIs, getPOIsInBounds, searchPOIs
} = useOSMDataSingleton()

useActivitySimulation.ts

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()

Datentypen

Hotspot

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'
}

CommunitySpot

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'
}

LocalEvent

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[]
}

LocalOffer

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.js Datenstruktur

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

AktivitΓ€ts-Simulation

Activity Levels

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)

Peak Hours nach POI-Typ

  • 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

Spezielle Modifier

  • 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

Filter

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
}

Clustering

Marker werden bei niedrigem Zoom-Level gruppiert:

  • Cluster-Threshold: Zoom < 14
  • Min. Cluster-Grâße: 3 Marker
  • Cluster-Precision: Geohash-basiert (angepasst an Zoom)

Performance

  • 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

Mobile Support

  • Touch-Gesten: Pinch-to-zoom, Drag
  • Responsive Design: Anpassung an Bildschirmgrâße
  • Bottom Sheet: User-Sidebar als ausziehbares Panel

Accessibility

  • ARIA-Labels fΓΌr alle interaktiven Elemente
  • Keyboard-Navigation unterstΓΌtzt
  • Fokus-Management bei Modals

Beispiel: Spot erstellen

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'
})

Beispiel: Event erstellen

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'
})

ZukΓΌnftige Erweiterungen

  • 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