feat: add analytics

This commit is contained in:
2026-01-19 21:40:10 +01:00
parent 0fd6bdaeb3
commit aac4d194e3
19 changed files with 1940 additions and 347 deletions

View File

@@ -0,0 +1,107 @@
<template>
<div class="bg-gray-900 rounded-lg p-4">
<h3 class="text-sm font-medium text-gray-300 mb-4">Evolution mensuelle</h3>
<div class="h-64">
<Bar
v-if="chartData.labels.length > 0"
:data="chartData"
:options="chartOptions"
/>
<div v-else class="h-full flex items-center justify-center text-gray-500 text-sm">
Aucune donnee
</div>
</div>
</div>
</template>
<script setup>
import { computed } from 'vue'
import { Bar } from 'vue-chartjs'
import {
Chart as ChartJS,
CategoryScale,
LinearScale,
BarElement,
Title,
Tooltip,
Legend
} from 'chart.js'
ChartJS.register(CategoryScale, LinearScale, BarElement, Title, Tooltip, Legend)
const props = defineProps({
data: {
type: Array,
default: () => []
}
})
const monthNames = [
'Jan', 'Fev', 'Mar', 'Avr', 'Mai', 'Juin',
'Juil', 'Aout', 'Sep', 'Oct', 'Nov', 'Dec'
]
const chartData = computed(() => {
const items = props.data.slice(-24) // Last 24 months
return {
labels: items.map(d => `${monthNames[d.month - 1]} ${d.year}`),
datasets: [
{
label: 'Debit',
data: items.map(d => d.total_debit),
backgroundColor: '#EF4444',
borderRadius: 4
},
{
label: 'Credit',
data: items.map(d => d.total_credit),
backgroundColor: '#10B981',
borderRadius: 4
}
]
}
})
const chartOptions = {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
position: 'top',
labels: {
color: '#9CA3AF',
font: { size: 11 },
boxWidth: 12,
padding: 15
}
},
tooltip: {
callbacks: {
label: (ctx) => {
const value = new Intl.NumberFormat('fr-FR', {
style: 'currency',
currency: 'EUR'
}).format(ctx.raw)
return ` ${ctx.dataset.label}: ${value}`
}
}
}
},
scales: {
x: {
ticks: { color: '#6B7280', font: { size: 10 } },
grid: { color: '#374151' }
},
y: {
ticks: {
color: '#6B7280',
callback: (value) => {
if (value >= 1000) return `${(value / 1000).toFixed(0)}k`
return value
}
},
grid: { color: '#374151' }
}
}
}
</script>