feat(reporting) : add Reporting dashboard front layer

LST-59 (3.1) front. Completes the Reporting module.

- New frontend/modules/reporting/ layer (auto-detected): /reporting page
  (admin middleware) consuming the 4 read-only report endpoints.
- Filters (period presets + custom dates, project, user). 4 sections (time per
  project, time per user, tasks by status, absences by type) each with a
  DataTable + a Chart.js chart (reused global registration).
- Front-side CSV export per section (useCsvExport: BOM UTF-8, ; separator).
- i18n keys (reporting.*, sidebar.admin.reporting).

nuxt build passes; /reporting routed; no route regression.
This commit is contained in:
Matthieu
2026-06-21 00:16:03 +02:00
parent b3b29fd753
commit f4ffc02028
9 changed files with 713 additions and 1 deletions
@@ -0,0 +1,52 @@
<template>
<div class="h-64">
<Bar
v-if="hasData"
:data="chartData"
:options="options"
/>
<p v-else class="flex h-full items-center justify-center text-sm text-neutral-400">
{{ emptyMessage ?? $t('reporting.empty') }}
</p>
</div>
</template>
<script setup lang="ts">
import { Bar } from 'vue-chartjs'
const props = defineProps<{
labels: string[]
values: number[]
color?: string
emptyMessage?: string
}>()
const hasData = computed(() => props.values.some(v => v > 0))
const chartData = computed(() => ({
labels: props.labels,
datasets: [{
data: props.values,
backgroundColor: props.color ?? '#6366f1',
borderWidth: 0,
borderRadius: 6,
}],
}))
const options = {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: { display: false },
},
scales: {
y: {
beginAtZero: true,
grid: { color: '#f3f4f6' },
},
x: {
grid: { display: false },
},
},
}
</script>