temporal.tsx 5,85 ko
Newer Older
Adrien Delmastro's avatar
Adrien Delmastro a validé
'use client'

import { useState } from 'react'
import {
    LineChart,
    Line,
    XAxis,
    YAxis,
    Tooltip,
    Legend,
    ResponsiveContainer,
    CartesianGrid,
} from 'recharts'
import { getTimeSeries, type TimeSeriesData } from '../../services/temporal.services'

const TAX_TYPES = ['tfpnb', 'tfpb', 'th', 'cfe'] as const
const YEARS = [2019, 2020, 2021, 2022] as const
const COLORS = [
    '#8884d8',
    '#82ca9d',
    '#ffc658',
    '#ff7300',
    '#00C49F',
    '#0088FE',
    '#FF8042',
    '#A4DE6C',
    '#D0ED57',
    '#FFBB28',
    '#FF4444',
    '#44AAFF',
    '#AA44FF',
    '#E91E63',
    '#4CAF50',
    '#9C27B0',
    '#00BCD4',
    '#FF5722',
    '#607D8B',
    '#795548',
]

export default function Temporal() {
    const [taxType, setTaxType] = useState<string>('tfpb')
    const [startYear, setStartYear] = useState<number>(2019)
    const [endYear, setEndYear] = useState<number>(2022)
    const [data, setData] = useState<TimeSeriesData | null>(null)
    const [loading, setLoading] = useState(false)

    const handleSubmit = async () => {
        setLoading(true)
        const result = await getTimeSeries([], taxType, startYear, endYear)
        setData(result)
        setLoading(false)
    }

    const chartData = data
        ? YEARS.filter((y) => y >= startYear && y <= endYear).map((year) => {
              const point: Record<string, number | string> = { year }
              for (const region of Object.keys(data)) {
                  const entry = data[region]?.find((e) => e.year === year)
                  if (entry) point[region] = parseFloat(entry.avg_rate)
              }
              return point
          })
        : []

    return (
        <div className="p-6 text-white flex flex-col gap-6">
            <h2 className="text-lg font-semibold">
                Taux d&apos;imposition moyen par region
            </h2>

            <div className="flex flex-wrap gap-4 items-end">
                <div className="flex flex-col gap-1">
                    <label className="text-xs text-[#b0afaf] uppercase">
                        Taxe
                    </label>
                    <select
                        value={taxType}
                        onChange={(e) => setTaxType(e.target.value)}
                        className="bg-[#212529] border border-[#3a3f44] rounded px-3 py-1.5 text-white text-sm"
                    >
                        {TAX_TYPES.map((t) => (
                            <option key={t} value={t}>
                                {t.toUpperCase()}
                            </option>
                        ))}
                    </select>
                </div>

                <div className="flex flex-col gap-1">
                    <label className="text-xs text-[#b0afaf] uppercase">
                        De
                    </label>
                    <select
                        value={startYear}
                        onChange={(e) => setStartYear(Number(e.target.value))}
                        className="bg-[#212529] border border-[#3a3f44] rounded px-3 py-1.5 text-white text-sm"
                    >
                        {YEARS.map((y) => (
                            <option key={y} value={y}>
                                {y}
                            </option>
                        ))}
                    </select>
                </div>

                <div className="flex flex-col gap-1">
                    <label className="text-xs text-[#b0afaf] uppercase">
                        A
                    </label>
                    <select
                        value={endYear}
                        onChange={(e) => setEndYear(Number(e.target.value))}
                        className="bg-[#212529] border border-[#3a3f44] rounded px-3 py-1.5 text-white text-sm"
                    >
                        {YEARS.map((y) => (
                            <option key={y} value={y}>
                                {y}
                            </option>
                        ))}
                    </select>
                </div>

                <button
                    onClick={handleSubmit}
                    disabled={loading}
                    className="bg-[#8884d8] hover:bg-[#7773c7] disabled:opacity-50 text-white text-sm px-4 py-1.5 rounded transition-colors"
                >
                    {loading ? 'Chargement...' : 'Afficher'}
                </button>
            </div>

            {chartData.length > 0 && (
                <ResponsiveContainer width="100%" height={400}>
                    <LineChart data={chartData}>
                        <CartesianGrid strokeDasharray="3 3" stroke="#3a3f44" />
                        <XAxis dataKey="year" stroke="#b0afaf" />
                        <YAxis
                            stroke="#b0afaf"
                            tickFormatter={(v: number) => `${v}%`}
                        />
                        <Tooltip
                            contentStyle={{
                                backgroundColor: '#212529',
                                border: '1px solid #3a3f44',
                                borderRadius: 8,
                            }}
                            formatter={(value: number) => [`${value}%`, '']}
                        />
                        <Legend />
                        {Object.keys(data!).map((region, i) => (
                            <Line
                                key={region}
                                type="monotone"
                                dataKey={region}
                                stroke={COLORS[i % COLORS.length]}
                                strokeWidth={2}
                                dot={{ r: 4 }}
                                activeDot={{ r: 6 }}
                            />
                        ))}
                    </LineChart>
                </ResponsiveContainer>
            )}
        </div>
    )
}