TypeScript 50.6%
JavaScript 46.1%
SQL 2.1%
Shell 0.6%
CSS 0.5%
1"use client";2import { Area, AreaChart, CartesianGrid, Line, LineChart, ResponsiveContainer, Tooltip, XAxis, YAxis } from "recharts";3import { fmtPrice, fmtDate } from "@/lib/format";45const RED = "#e0263c";6export function PriceHistoryChart({ events, rent = false }: { events: { ts: string; price: number }[]; rent?: boolean }) {7 if (events.length < 2) return null;8 const data = events.map((e) => ({ t: new Date(e.ts).getTime(), price: e.price }));9 return (10 <div className="h-44">11 <ResponsiveContainer>12 <LineChart data={data} margin={{ top: 8, right: 8, bottom: 0, left: 0 }}>13 <CartesianGrid stroke="#eef0f3" vertical={false} />14 <XAxis dataKey="t" type="number" domain={["dataMin", "dataMax"]} tickFormatter={(v) => fmtDate(new Date(v).toISOString())} tick={{ fontSize: 11, fill: "#7a8190" }} axisLine={false} tickLine={false} minTickGap={40} />15 <YAxis tickFormatter={(v) => fmtPrice(v, { compact: true })} tick={{ fontSize: 11, fill: "#7a8190" }} axisLine={false} tickLine={false} width={56} domain={["auto", "auto"]} />16 <Tooltip formatter={(v) => [fmtPrice(Number(v), { rent }), "Prix demandé"]} labelFormatter={(v) => fmtDate(new Date(Number(v)).toISOString(), "long")} contentStyle={{ borderRadius: 10, border: "1px solid #e6e8ec", fontSize: 12 }} />17 <Line type="stepAfter" dataKey="price" stroke={RED} strokeWidth={2} dot={{ r: 3, fill: RED }} isAnimationActive={false} />18 </LineChart>19 </ResponsiveContainer>20 </div>21 );22}2324export function IndexChart({ points, label = "Indice de prix" }: { points: { month: string; idx: number; ppm2?: number; n?: number }[]; label?: string }) {25 if (points.length < 2) return null;26 const data = points.map((p) => ({ m: p.month, v: Math.round(p.idx * 1000) / 10, ppm2: p.ppm2 }));27 return (28 <div className="h-52">29 <ResponsiveContainer>30 <AreaChart data={data} margin={{ top: 8, right: 8, bottom: 0, left: 0 }}>31 <defs><linearGradient id="tvg" x1="0" y1="0" x2="0" y2="1"><stop offset="0%" stopColor={RED} stopOpacity={0.25} /><stop offset="100%" stopColor={RED} stopOpacity={0} /></linearGradient></defs>32 <CartesianGrid stroke="#eef0f3" vertical={false} />33 <XAxis dataKey="m" tick={{ fontSize: 11, fill: "#7a8190" }} axisLine={false} tickLine={false} minTickGap={32} tickFormatter={(m) => m.slice(0, 4)} />34 <YAxis tick={{ fontSize: 11, fill: "#7a8190" }} axisLine={false} tickLine={false} width={40} domain={["auto", "auto"]} tickFormatter={(v) => `${v}`} />35 <Tooltip formatter={(v, _n, p) => [`${v} (base 100 = dernier mois)${p?.payload?.ppm2 ? ` · ${Math.round(p.payload.ppm2).toLocaleString("fr-CA")} $/m²` : ""}`, label]} contentStyle={{ borderRadius: 10, border: "1px solid #e6e8ec", fontSize: 12 }} />36 <Area type="monotone" dataKey="v" stroke={RED} strokeWidth={2} fill="url(#tvg)" isAnimationActive={false} />37 </AreaChart>38 </ResponsiveContainer>39 </div>40 );41}42