From 499cc02943cff33b5a6f860a705bcc75f63dcb54 Mon Sep 17 00:00:00 2001 From: josedario87 Date: Wed, 27 Aug 2025 21:49:33 -0600 Subject: [PATCH] refactorizacion leaderboard --- client/src/components/DataSourceSelector.vue | 123 ++++++ client/src/components/EventChart.vue | 309 +++++++++++++ client/src/components/EventFilters.vue | 232 ++++++++++ client/src/composables/useEventFilters.ts | 117 +++++ client/src/views/Leaderboard.vue | 429 ++----------------- 5 files changed, 817 insertions(+), 393 deletions(-) create mode 100644 client/src/components/DataSourceSelector.vue create mode 100644 client/src/components/EventChart.vue create mode 100644 client/src/components/EventFilters.vue create mode 100644 client/src/composables/useEventFilters.ts diff --git a/client/src/components/DataSourceSelector.vue b/client/src/components/DataSourceSelector.vue new file mode 100644 index 0000000..9b3933f --- /dev/null +++ b/client/src/components/DataSourceSelector.vue @@ -0,0 +1,123 @@ + + + + + \ No newline at end of file diff --git a/client/src/components/EventChart.vue b/client/src/components/EventChart.vue new file mode 100644 index 0000000..559118a --- /dev/null +++ b/client/src/components/EventChart.vue @@ -0,0 +1,309 @@ + + + + + \ No newline at end of file diff --git a/client/src/components/EventFilters.vue b/client/src/components/EventFilters.vue new file mode 100644 index 0000000..a32eed5 --- /dev/null +++ b/client/src/components/EventFilters.vue @@ -0,0 +1,232 @@ + + + + + \ No newline at end of file diff --git a/client/src/composables/useEventFilters.ts b/client/src/composables/useEventFilters.ts new file mode 100644 index 0000000..1dd0bcb --- /dev/null +++ b/client/src/composables/useEventFilters.ts @@ -0,0 +1,117 @@ +import { ref, computed, watch } from 'vue'; + +export interface DetailedEvent { + kind: string; + round?: number; + gameVariant?: string; +} + +export type DataSource = 'aggregated' | 'active-rooms'; +export type RoundFilter = 'all' | 1 | 2 | 3; +export type GameFilter = 'all' | 'G1' | 'G2' | 'G3' | 'G4' | 'G5'; + +export function useEventFilters() { + // Filter states + const dataSource = ref('aggregated'); + const roundFilter = ref('all'); + const gameFilter = ref('all'); + + // Event data stores + const detailedEventsAggregated = ref([]); + const detailedEventsActiveRooms = ref([]); + + // Global event counts + const globalEventCounts = ref>({}); + const globalEventCountsAggregated = ref>({}); + const globalEventCountsActiveRooms = ref>({}); + + // Function to apply filters and recalculate counts + function applyFilters(eventTypes: string[]) { + const sourceEvents = dataSource.value === 'aggregated' + ? detailedEventsAggregated.value + : detailedEventsActiveRooms.value; + + // Filter events based on round and game + const filteredEvents = sourceEvents.filter(event => { + if (roundFilter.value !== 'all' && event.round !== roundFilter.value) { + return false; + } + if (gameFilter.value !== 'all' && event.gameVariant !== gameFilter.value) { + return false; + } + return true; + }); + + // Recalculate counts from filtered events + const counts: Record = Object.fromEntries(eventTypes.map(k => [k, 0])); + filteredEvents.forEach(event => { + if (eventTypes.includes(event.kind)) { + counts[event.kind] = (counts[event.kind] || 0) + 1; + } + }); + + globalEventCounts.value = counts; + } + + // Update aggregated data + function updateAggregatedData(events: DetailedEvent[], counts: Record) { + detailedEventsAggregated.value = events; + globalEventCountsAggregated.value = counts; + } + + // Update active rooms data + function updateActiveRoomsData(events: DetailedEvent[], counts: Record) { + detailedEventsActiveRooms.value = events; + globalEventCountsActiveRooms.value = counts; + } + + // Reset filters + function resetFilters() { + roundFilter.value = 'all'; + gameFilter.value = 'all'; + } + + // Computed properties + const currentSourceEvents = computed(() => + dataSource.value === 'aggregated' ? detailedEventsAggregated.value : detailedEventsActiveRooms.value + ); + + const currentSourceCounts = computed(() => + dataSource.value === 'aggregated' ? globalEventCountsAggregated.value : globalEventCountsActiveRooms.value + ); + + const hasActiveFilters = computed(() => + roundFilter.value !== 'all' || gameFilter.value !== 'all' + ); + + const filterSummary = computed(() => { + const parts = []; + if (roundFilter.value !== 'all') parts.push(`Round ${roundFilter.value}`); + if (gameFilter.value !== 'all') parts.push(`Game ${gameFilter.value}`); + return parts.length > 0 ? parts.join(' + ') : 'Sin filtros'; + }); + + return { + // State + dataSource, + roundFilter, + gameFilter, + detailedEventsAggregated, + detailedEventsActiveRooms, + globalEventCounts, + globalEventCountsAggregated, + globalEventCountsActiveRooms, + + // Methods + applyFilters, + updateAggregatedData, + updateActiveRoomsData, + resetFilters, + + // Computed + currentSourceEvents, + currentSourceCounts, + hasActiveFilters, + filterSummary + }; +} \ No newline at end of file diff --git a/client/src/views/Leaderboard.vue b/client/src/views/Leaderboard.vue index cfaa30c..1e81888 100644 --- a/client/src/views/Leaderboard.vue +++ b/client/src/views/Leaderboard.vue @@ -10,79 +10,17 @@ -
-
Fuente de datos:
-
- - -
-
+ -
-
- -
- - -
-
- -
- -
- - -
-
-
+
@@ -115,38 +53,31 @@
-
-

Eventos y comparación

-
Cargando datos…
-
-
-
-
-
-
- {{ EVENT_STYLES[k]?.icon || '📊' }} - {{ friendlyKind(k) }} - {{ globalValueLabel(k) }} - {{ playerValueLabel(k) }} -
-
-
-
Basado en mensajes disponibles por sala. Click jugador para comparar.
-
-
+