diff --git a/lang/de.json b/lang/de.json
index b36a247..898721e 100644
--- a/lang/de.json
+++ b/lang/de.json
@@ -460,5 +460,16 @@
"Über den Kurs": "",
"Über uns": "",
"Alle Meetups": "",
- "Welt-Karte": ""
+ "Welt-Karte": "",
+ "Aktivitäten": "",
+ "Neue Meetups und Termine": "",
+ "Neues Meetup": "",
+ "Neuer Termin": "",
+ "Keine Aktivitäten": "",
+ "Top Länder": "",
+ "Länder mit den meisten Usern": "",
+ "User": "",
+ "Keine Daten verfügbar": "",
+ "Top Meetups": "",
+ "Meetups mit den meisten Usern": ""
}
\ No newline at end of file
diff --git a/lang/en.json b/lang/en.json
index 6ee6dcc..9c1fbff 100644
--- a/lang/en.json
+++ b/lang/en.json
@@ -460,5 +460,16 @@
"Über den Kurs": "About the course",
"Über uns": "About us",
"Alle Meetups": "All Meetups",
- "Welt-Karte": "World Map"
+ "Welt-Karte": "World Map",
+ "Aktivitäten": "Activities",
+ "Neue Meetups und Termine": "New Meetups and Events",
+ "Neues Meetup": "New Meetup",
+ "Neuer Termin": "New Event",
+ "Keine Aktivitäten": "No Activities",
+ "Top Länder": "Top Countries",
+ "Länder mit den meisten Usern": "Countries with Most Users",
+ "User": "Users",
+ "Keine Daten verfügbar": "No Data Available",
+ "Top Meetups": "Top Meetups",
+ "Meetups mit den meisten Usern": "Meetups with Most Users"
}
diff --git a/lang/es.json b/lang/es.json
index f6a520c..ae4d106 100644
--- a/lang/es.json
+++ b/lang/es.json
@@ -459,5 +459,16 @@
"Über den Kurs": "Sobre el curso",
"Über uns": "Sobre nosotros",
"Alle Meetups": "Todos los encuentros",
- "Welt-Karte": "Mapa mundial"
+ "Welt-Karte": "Mapa mundial",
+ "Aktivitäten": "Actividades",
+ "Neue Meetups und Termine": "Nuevos encuentros y eventos",
+ "Neues Meetup": "Nuevo encuentro",
+ "Neuer Termin": "Nuevo evento",
+ "Keine Aktivitäten": "Sin actividades",
+ "Top Länder": "Países principales",
+ "Länder mit den meisten Usern": "Países con más usuarios",
+ "User": "Usuarios",
+ "Keine Daten verfügbar": "No hay datos disponibles",
+ "Top Meetups": "Encuentros principales",
+ "Meetups mit den meisten Usern": "Encuentros con más usuarios"
}
diff --git a/lang/hu.json b/lang/hu.json
index 46eafd0..b397fc7 100644
--- a/lang/hu.json
+++ b/lang/hu.json
@@ -454,5 +454,16 @@
"Über den Kurs": "A kurzusról",
"Über uns": "Rólunk",
"Alle Meetups": "Minden meetup",
- "Welt-Karte": "Világtérkép"
+ "Welt-Karte": "Világtérkép",
+ "Aktivitäten": "Tevékenységek",
+ "Neue Meetups und Termine": "Új meetupok és időpontok",
+ "Neues Meetup": "Új meetup",
+ "Neuer Termin": "Új időpont",
+ "Keine Aktivitäten": "Nincsenek tevékenységek",
+ "Top Länder": "Top országok",
+ "Länder mit den meisten Usern": "Legtöbb felhasználóval rendelkező országok",
+ "User": "Felhasználó",
+ "Keine Daten verfügbar": "Nincsenek elérhető adatok",
+ "Top Meetups": "Top meetupok",
+ "Meetups mit den meisten Usern": "Legtöbb felhasználóval rendelkező meetupok"
}
diff --git a/lang/nl.json b/lang/nl.json
index 558defc..7b9f720 100644
--- a/lang/nl.json
+++ b/lang/nl.json
@@ -456,5 +456,16 @@
"Über den Kurs": "Over de cursus",
"Über uns": "Over ons",
"Alle Meetups": "Alle Meetups",
- "Welt-Karte": "Wereldkaart"
+ "Welt-Karte": "Wereldkaart",
+ "Aktivitäten": "Activiteiten",
+ "Neue Meetups und Termine": "Nieuwe Meetups en afspraken",
+ "Neues Meetup": "Nieuwe Meetup",
+ "Neuer Termin": "Nieuwe afspraak",
+ "Keine Aktivitäten": "Geen activiteiten",
+ "Top Länder": "Top landen",
+ "Länder mit den meisten Usern": "Landen met de meeste gebruikers",
+ "User": "Gebruikers",
+ "Keine Daten verfügbar": "Geen gegevens beschikbaar",
+ "Top Meetups": "Top Meetups",
+ "Meetups mit den meisten Usern": "Meetups met de meeste gebruikers"
}
diff --git a/lang/pt.json b/lang/pt.json
index eec64b4..cb5f432 100644
--- a/lang/pt.json
+++ b/lang/pt.json
@@ -454,5 +454,16 @@
"Über den Kurs": "Sobre o curso",
"Über uns": "Sobre nós",
"Alle Meetups": "Todos os Meetups",
- "Welt-Karte": "Mapa Mundial"
+ "Welt-Karte": "Mapa Mundial",
+ "Aktivitäten": "Atividades",
+ "Neue Meetups und Termine": "Novos Meetups e eventos",
+ "Neues Meetup": "Novo Meetup",
+ "Neuer Termin": "Novo evento",
+ "Keine Aktivitäten": "Nenhuma atividade",
+ "Top Länder": "Principais países",
+ "Länder mit den meisten Usern": "Países com mais usuários",
+ "User": "Usuário",
+ "Keine Daten verfügbar": "Nenhum dado disponível",
+ "Top Meetups": "Principais Meetups",
+ "Meetups mit den meisten Usern": "Meetups com mais usuários"
}
diff --git a/resources/views/livewire/dashboard.blade.php b/resources/views/livewire/dashboard.blade.php
index 95fcf71..ae9f028 100644
--- a/resources/views/livewire/dashboard.blade.php
+++ b/resources/views/livewire/dashboard.blade.php
@@ -204,4 +204,11 @@ class extends Component {
+
+ {{-- Neue Statistiken und Activities (Lazy loaded) --}}
+
+
+
+
+
diff --git a/resources/views/livewire/dashboard/activities.blade.php b/resources/views/livewire/dashboard/activities.blade.php
new file mode 100644
index 0000000..a53a1b1
--- /dev/null
+++ b/resources/views/livewire/dashboard/activities.blade.php
@@ -0,0 +1,114 @@
+orderBy('created_at', 'desc')
+ ->limit(5)
+ ->get();
+
+ $recentEvents = MeetupEvent::with(['meetup.city.country'])
+ ->orderBy('created_at', 'desc')
+ ->limit(5)
+ ->get();
+
+ // Kombiniere und sortiere Activities
+ $activities = collect($recentMeetups->map(fn($m) => ['type' => 'meetup', 'data' => $m, 'created_at' => $m->created_at]))
+ ->merge($recentEvents->map(fn($e) => ['type' => 'event', 'data' => $e, 'created_at' => $e->created_at]))
+ ->sortByDesc('created_at')
+ ->take(10);
+
+ return [
+ 'activities' => $activities,
+ ];
+ }
+
+ public function placeholder(): string
+ {
+ return <<<'HTML'
+
+
+
{{ __('Aktivitäten') }}
+
{{ __('Neue Meetups und Termine') }}
+
+
+
+
+
+
+ HTML;
+ }
+}; ?>
+
+
+
+
{{ __('Aktivitäten') }}
+
{{ __('Neue Meetups und Termine') }}
+
+ @if($activities->count() > 0)
+
+
+ @else
+
{{ __('Keine Aktivitäten') }}
+ @endif
+
+
diff --git a/resources/views/livewire/dashboard/top-countries.blade.php b/resources/views/livewire/dashboard/top-countries.blade.php
new file mode 100644
index 0000000..02d7093
--- /dev/null
+++ b/resources/views/livewire/dashboard/top-countries.blade.php
@@ -0,0 +1,118 @@
+join('cities', 'cities.country_id', '=', 'countries.id')
+ ->join('meetups', 'meetups.city_id', '=', 'cities.id')
+ ->join('meetup_user', 'meetup_user.meetup_id', '=', 'meetups.id')
+ ->groupBy('countries.id')
+ ->selectRaw('COUNT(DISTINCT meetup_user.user_id) as user_count')
+ ->orderBy('user_count', 'desc')
+ ->limit(10)
+ ->get()
+ ->map(function ($country) {
+ // Optimierte Query: Hole alle User-Erstellungsdaten für dieses Land auf einmal
+ $userCreationDates = \DB::table('users')
+ ->join('meetup_user', 'users.id', '=', 'meetup_user.user_id')
+ ->join('meetups', 'meetup_user.meetup_id', '=', 'meetups.id')
+ ->join('cities', 'meetups.city_id', '=', 'cities.id')
+ ->where('cities.country_id', $country->id)
+ ->whereNotNull('users.created_at')
+ ->orderBy('users.created_at')
+ ->pluck('users.created_at')
+ ->unique()
+ ->values();
+
+ if ($userCreationDates->isEmpty()) {
+ $country->sparkline = [0];
+ return $country;
+ }
+
+ // Berechne monatliche Buckets für kumulative Zählung
+ $startDate = \Carbon\Carbon::parse($userCreationDates->first())->startOfMonth();
+ $endDate = now()->endOfMonth();
+ $monthsDiff = max(1, $startDate->diffInMonths($endDate));
+ $interval = max(1, ceil($monthsDiff / 12));
+
+ // Generiere 12 Zeitpunkte
+ $sparklineData = [];
+ $currentDate = $startDate->copy();
+
+ for ($i = 0; $i < 12 && $currentDate <= $endDate; $i++) {
+ // Zähle kumulative User bis zu diesem Zeitpunkt
+ $count = $userCreationDates->filter(function ($date) use ($currentDate) {
+ return \Carbon\Carbon::parse($date) <= $currentDate;
+ })->count();
+
+ $sparklineData[] = $count;
+ $currentDate->addMonths($interval);
+ }
+
+ $country->sparkline = $sparklineData;
+ return $country;
+ });
+
+ return [
+ 'topCountries' => $topCountries,
+ ];
+ }
+
+ public function placeholder(): string
+ {
+ return <<<'HTML'
+
+
+
{{ __('Top Länder') }}
+
{{ __('Länder mit den meisten Usern') }}
+
+
+
+
+
+
+ HTML;
+ }
+}; ?>
+
+
+
+
{{ __('Top Länder') }}
+
{{ __('Länder mit den meisten Usern') }}
+
+ @if($topCountries->count() > 0)
+
+
+ @foreach($topCountries as $country)
+
+ @endforeach
+
+ @else
+
{{ __('Keine Daten verfügbar') }}
+ @endif
+
+
diff --git a/resources/views/livewire/dashboard/top-meetups.blade.php b/resources/views/livewire/dashboard/top-meetups.blade.php
new file mode 100644
index 0000000..6881e80
--- /dev/null
+++ b/resources/views/livewire/dashboard/top-meetups.blade.php
@@ -0,0 +1,112 @@
+with(['city.country'])
+ ->orderBy('users_count', 'desc')
+ ->limit(10)
+ ->get()
+ ->map(function ($meetup) {
+ // Optimierte Query: Hole alle User-Erstellungsdaten für dieses Meetup auf einmal
+ $userCreationDates = \DB::table('users')
+ ->join('meetup_user', 'users.id', '=', 'meetup_user.user_id')
+ ->where('meetup_user.meetup_id', $meetup->id)
+ ->whereNotNull('users.created_at')
+ ->orderBy('users.created_at')
+ ->pluck('users.created_at')
+ ->unique()
+ ->values();
+
+ if ($userCreationDates->isEmpty()) {
+ $meetup->sparkline = [0];
+ return $meetup;
+ }
+
+ // Berechne monatliche Buckets für kumulative Zählung
+ $startDate = \Carbon\Carbon::parse($userCreationDates->first())->startOfMonth();
+ $endDate = now()->endOfMonth();
+ $monthsDiff = max(1, $startDate->diffInMonths($endDate));
+ $interval = max(1, ceil($monthsDiff / 12));
+
+ // Generiere 12 Zeitpunkte
+ $sparklineData = [];
+ $currentDate = $startDate->copy();
+
+ for ($i = 0; $i < 12 && $currentDate <= $endDate; $i++) {
+ // Zähle kumulative User bis zu diesem Zeitpunkt
+ $count = $userCreationDates->filter(function ($date) use ($currentDate) {
+ return \Carbon\Carbon::parse($date) <= $currentDate;
+ })->count();
+
+ $sparklineData[] = $count;
+ $currentDate->addMonths($interval);
+ }
+
+ $meetup->sparkline = $sparklineData;
+ return $meetup;
+ });
+
+ return [
+ 'topMeetups' => $topMeetups,
+ ];
+ }
+
+ public function placeholder(): string
+ {
+ return <<<'HTML'
+
+
+
{{ __('Top Meetups') }}
+
{{ __('Meetups mit den meisten Usern') }}
+
+
+
+
+
+
+ HTML;
+ }
+}; ?>
+
+
+
+
{{ __('Top Meetups') }}
+
{{ __('Meetups mit den meisten Usern') }}
+
+ @if($topMeetups->count() > 0)
+
+
+ @else
+
{{ __('Keine Daten verfügbar') }}
+ @endif
+
+