paul.roost ca05e334a7 feat: Implement server-side API for categories, KPIs, and measurements
- Added Express server with SQLite database connection.
- Created API endpoints to fetch categories, KPIs, measurements, and statistics.
- Implemented error handling for database operations.

feat: Create ChartModal component for visualizing KPI data

- Developed ChartModal to display line charts for KPI measurements.
- Integrated Chart.js for rendering charts with responsive design.
- Added styling for modal and chart components.

feat: Add ExportModal component for exporting KPI data

- Implemented ExportModal to allow users to select data ranges for export.
- Included radio buttons for predefined time ranges (last week, month, year, all data).
- Styled modal for better user experience.

feat: Introduce RangeChartModal for dynamic range selection

- Created RangeChartModal to visualize KPI data over user-selected time ranges.
- Integrated radio buttons for selecting different time ranges.
- Enhanced chart rendering with Chart.js.

refactor: Create useSQLiteDatabase hook for data fetching

- Developed custom hook to manage fetching categories, KPIs, and measurements.
- Improved error handling and loading states for better user feedback.

style: Add CSS styles for modals and charts

- Created styles for ChartModal, ExportModal, and RangeChartModal.
- Ensured responsive design for various screen sizes.
2025-10-21 13:31:14 +02:00

93 lines
2.4 KiB
TypeScript

import React from 'react';
import { Chart as ChartJS, CategoryScale, LinearScale, PointElement, LineElement, Title, Tooltip, Legend } from 'chart.js';
import { Line } from 'react-chartjs-2';
import '../styles/ChartModal.css';
ChartJS.register(CategoryScale, LinearScale, PointElement, LineElement, Title, Tooltip, Legend);
interface ChartModalProps {
isOpen: boolean;
kpi: any;
measurements: any[];
onClose: () => void;
}
export const ChartModal: React.FC<ChartModalProps> = ({ isOpen, kpi, measurements, onClose }) => {
if (!isOpen || !kpi) return null;
// Préparer les données pour le graphique
const labels = measurements
.map(m => new Date(m.measurement_date).toLocaleDateString('fr-FR'))
.reverse();
const values = measurements
.map(m => m.value)
.reverse();
const chartData = {
labels,
datasets: [
{
label: kpi.name,
data: values,
borderColor: '#6496ff',
backgroundColor: 'rgba(100, 150, 255, 0.1)',
tension: 0.4,
fill: true,
pointRadius: 4,
pointBackgroundColor: '#6496ff',
pointBorderColor: '#fff',
pointBorderWidth: 2,
},
],
};
const chartOptions = {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
display: true,
position: 'top' as const,
},
title: {
display: true,
text: `Graphique Complet: ${kpi.name}`,
font: { size: 16, weight: 'bold' as const },
},
},
scales: {
y: {
beginAtZero: true,
title: {
display: true,
text: kpi.unit,
},
},
x: {
display: true,
},
},
};
return (
<div className="chart-modal-overlay" onClick={onClose}>
<div className="chart-modal" onClick={(e) => e.stopPropagation()}>
<div className="chart-modal-header">
<h2>📈 {kpi.name}</h2>
<button className="chart-modal-close" onClick={onClose}></button>
</div>
<div className="chart-modal-body">
<div style={{ height: '500px', width: '100%' }}>
<Line data={chartData} options={chartOptions} />
</div>
</div>
<div className="chart-modal-footer">
<p>Nombre de mesures: <strong>{measurements.length}</strong></p>
<p>Période: <strong>{labels[0]} à {labels[labels.length - 1]}</strong></p>
</div>
</div>
</div>
);
};