feat: add CountryHistogram and AnalyticsMap components and update build script to use legacy-peer-deps

This commit is contained in:
2026-05-10 22:01:03 +02:00
parent 197594f84f
commit 1b47498f6e
3 changed files with 72 additions and 49 deletions

View File

@@ -60,6 +60,12 @@ const countryToISO: Record<string, string> = {
}; };
export default function AnalyticsMap({ data, title }: AnalyticsMapProps) { export default function AnalyticsMap({ data, title }: AnalyticsMapProps) {
const [mounted, setMounted] = React.useState(false);
React.useEffect(() => {
setMounted(true);
}, []);
const maxCount = useMemo(() => { const maxCount = useMemo(() => {
if (data.length === 0) return 1; if (data.length === 0) return 1;
return Math.max(...data.map((d) => d.count)); return Math.max(...data.map((d) => d.count));
@@ -132,7 +138,13 @@ export default function AnalyticsMap({ data, title }: AnalyticsMapProps) {
</div> </div>
</div> </div>
<div className="p-4 flex justify-center bg-slate-950/20 h-[600px]"> <div className="p-4 flex justify-center bg-slate-950/20 h-[600px] items-center">
{!mounted ? (
<div className="flex flex-col items-center gap-4 animate-pulse">
<div className="w-16 h-16 border-4 border-indigo-500/20 border-t-indigo-500 rounded-full animate-spin"></div>
<p className="text-slate-500 text-xs font-bold uppercase tracking-widest">Chargement de la carte...</p>
</div>
) : (
<ComposableMap <ComposableMap
projectionConfig={{ projectionConfig={{
rotate: [-10, 0, 0], rotate: [-10, 0, 0],
@@ -179,6 +191,7 @@ export default function AnalyticsMap({ data, title }: AnalyticsMapProps) {
)} )}
</ZoomableGroup> </ZoomableGroup>
</ComposableMap> </ComposableMap>
)}
</div> </div>
{/* Legend / Instructions */} {/* Legend / Instructions */}

View File

@@ -19,6 +19,12 @@ interface CountryHistogramProps {
} }
export default function CountryHistogram({ data, title }: CountryHistogramProps) { export default function CountryHistogram({ data, title }: CountryHistogramProps) {
const [mounted, setMounted] = React.useState(false);
React.useEffect(() => {
setMounted(true);
}, []);
// Take top 10 for readability // Take top 10 for readability
const chartData = data.slice(0, 10).map(item => ({ const chartData = data.slice(0, 10).map(item => ({
name: item.country || 'Inconnu', name: item.country || 'Inconnu',
@@ -32,7 +38,10 @@ export default function CountryHistogram({ data, title }: CountryHistogramProps)
{title} {title}
</h2> </h2>
<div className="h-[400px] w-full"> <div className="h-[400px] w-full flex items-center justify-center">
{!mounted ? (
<p className="text-slate-500 text-xs font-bold uppercase tracking-widest animate-pulse">Chargement du graphique...</p>
) : (
<ResponsiveContainer width="100%" height="100%"> <ResponsiveContainer width="100%" height="100%">
<BarChart <BarChart
data={chartData} data={chartData}
@@ -91,6 +100,7 @@ export default function CountryHistogram({ data, title }: CountryHistogramProps)
/> />
</BarChart> </BarChart>
</ResponsiveContainer> </ResponsiveContainer>
)}
</div> </div>
</div> </div>
); );

View File

@@ -11,7 +11,7 @@
"dev:admin": "npm run dev --prefix admin -- -p 3001", "dev:admin": "npm run dev --prefix admin -- -p 3001",
"all": "concurrently \"npm run dev\" \"npm run dev:admin\"", "all": "concurrently \"npm run dev\" \"npm run dev:admin\"",
"build": "prisma generate && next build && npm run build:admin", "build": "prisma generate && next build && npm run build:admin",
"build:admin": "npm install --prefix admin && prisma generate && npm run build --prefix admin", "build:admin": "npm install --prefix admin --legacy-peer-deps && prisma generate && npm run build --prefix admin",
"generate": "npx prisma generate && cd admin && npx prisma generate && cd ..", "generate": "npx prisma generate && cd admin && npx prisma generate && cd ..",
"start": "npx prisma migrate deploy && next start", "start": "npx prisma migrate deploy && next start",
"start:admin": "npm run start --prefix admin", "start:admin": "npm run start --prefix admin",