feat: filtre utilisateurs analytics, améliorations dashboard + autres modifs
All checks were successful
Deploy Preprod / Build and Deploy to Preprod (push) Successful in 34s

- Multiselect Kirby pour filtrer par utilisateur(s)
- Données de test alignées sur les vrais comptes
- Suppression bloc utilisateurs les plus actifs
- Route get-data supporte le filtre emails
- Améliorations UI filtres (layout dates + users)
- Autres modifs : menu, router, dialog, deploy workflow

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
isUnknown 2026-03-03 11:27:27 +01:00
parent 8a73da920f
commit de104dc7dd
9 changed files with 243 additions and 42 deletions

View file

@ -1,14 +1,33 @@
<template>
<div class="k-analytics-dashboard">
<div class="k-analytics-filters">
<label>
Du
<input type="date" v-model="startDate" @change="fetchData" />
</label>
<label>
Au
<input type="date" v-model="endDate" @change="fetchData" />
</label>
<div class="k-analytics-date-filter">
<header class="k-field-header">
<label class="k-label k-field-label" title="Filtrer par dates">
<span class="k-label-text">Filtrer par dates </span>
</label>
</header>
<div class="k-date-inputs-wrapper">
<label>
Du
<input type="date" v-model="startDate" @change="fetchData" />
</label>
<label>
Au
<input type="date" v-model="endDate" @change="fetchData" />
</label>
</div>
</div>
<div class="k-analytics-user-filter">
<k-multiselect-field
:options="userOptions"
:value="selectedEmails"
label="Filtrer par utilisateur(s)"
search="true"
name="user"
@input="onUserSelectionChange"
/>
</div>
</div>
<div v-if="!hasData" class="k-analytics-empty">
@ -36,31 +55,17 @@
<canvas ref="chartCanvas"></canvas>
</div>
<div class="k-analytics-grid k-analytics-grid--2col">
<div
class="k-analytics-card"
v-if="data.visitsByPage && Object.keys(data.visitsByPage).length"
>
<h3>Pages les plus visitées</h3>
<ul class="k-analytics-list">
<li v-for="(count, page) in data.visitsByPage" :key="page">
<span class="k-analytics-list-label">{{ page }}</span>
<span class="k-analytics-list-value">{{ count }}</span>
</li>
</ul>
</div>
<div
class="k-analytics-card"
v-if="data.visitsByUser && Object.keys(data.visitsByUser).length"
>
<h3>Utilisateurs les plus actifs</h3>
<ul class="k-analytics-list">
<li v-for="(count, user) in data.visitsByUser" :key="user">
<span class="k-analytics-list-label">{{ user }}</span>
<span class="k-analytics-list-value">{{ count }}</span>
</li>
</ul>
</div>
<div
class="k-analytics-card"
v-if="data.visitsByPage && Object.keys(data.visitsByPage).length"
>
<h3>Pages les plus visitées</h3>
<ul class="k-analytics-list">
<li v-for="(count, page) in data.visitsByPage" :key="page">
<span class="k-analytics-list-label">{{ page }}</span>
<span class="k-analytics-list-value">{{ count }}</span>
</li>
</ul>
</div>
</template>
</div>
@ -102,6 +107,8 @@ export default {
endDate: '',
data: this.analyticsData || {},
chart: null,
users: [],
selectedEmails: [],
};
},
@ -113,6 +120,9 @@ export default {
if (!this.data?.uniqueSessions) return '0';
return (this.data.totalVisits / this.data.uniqueSessions).toFixed(1);
},
userOptions() {
return this.users.map((u) => ({ value: u.email, text: u.label }));
},
},
watch: {
@ -141,19 +151,33 @@ export default {
this.startDate = thirtyDaysAgo.toISOString().split('T')[0];
},
onUserSelectionChange(emails) {
this.selectedEmails = emails;
this.fetchData();
},
async fetchData() {
const params = new URLSearchParams();
if (this.startDate) params.set('startDate', this.startDate);
if (this.endDate) params.set('endDate', this.endDate);
if (this.selectedEmails.length) {
params.set('emails', this.selectedEmails.join(','));
}
try {
const response = await fetch(`/analytics-data.json?${params}`);
const json = await response.json();
console.log(json.data);
if (json.status === 'success') {
this.data = json.data;
}
if (json.users && !this.users.length) {
this.users = json.users;
}
this.renderChart();
} catch (e) {
console.error('Analytics fetch error:', e);
@ -247,6 +271,11 @@ export default {
color: var(--color-text-light);
}
.k-date-inputs-wrapper {
display: flex;
column-gap: 1rem;
}
.k-analytics-filters input[type='date'] {
padding: 0.375rem 0.5rem;
border: 1px solid var(--color-border);
@ -262,8 +291,17 @@ export default {
margin-bottom: 1.5rem;
}
.k-analytics-grid--2col {
grid-template-columns: repeat(2, 1fr);
.k-analytics-user-filter {
display: flex;
align-items: center;
gap: 0.5rem;
font-size: 0.875rem;
color: var(--color-text-light);
margin-left: 2rem;
}
.k-field-name-user {
min-width: 15rem;
}
.k-analytics-card {