refactor: migrate frontend from shadcn/Tailwind to Mantine v9
Reescribe todos los componentes UI para usar Mantine v9 en lugar de shadcn/Tailwind. Elimina cn(), CVA, components.json, theme_provider custom y globals.css con Tailwind. Añade 25+ componentes nuevos (AppShell, AuthForm, DatePickerInput, Dropzone, etc.) y MantineProvider como wrapper estándar del sistema de temas. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,7 +1,5 @@
|
||||
import {
|
||||
PieChart as RechartsPieChart, Pie, Cell, Tooltip, Legend, ResponsiveContainer,
|
||||
} from 'recharts'
|
||||
import { cn } from '../core/cn'
|
||||
import { PieChart as MantinePieChart, DonutChart } from '@mantine/charts'
|
||||
import { Paper } from '@mantine/core'
|
||||
|
||||
const DEFAULT_COLORS = [
|
||||
'#3b82f6', '#10b981', '#f59e0b', '#ef4444', '#8b5cf6',
|
||||
@@ -14,12 +12,9 @@ interface PieChartProps {
|
||||
valueKey: string
|
||||
colors?: string[]
|
||||
donut?: boolean
|
||||
innerRadius?: number
|
||||
outerRadius?: number
|
||||
showLegend?: boolean
|
||||
showLabels?: boolean
|
||||
height?: number | string
|
||||
className?: string
|
||||
height?: number
|
||||
valueFormatter?: (value: number) => string
|
||||
}
|
||||
|
||||
@@ -29,59 +24,33 @@ function PieChartComponent({
|
||||
valueKey,
|
||||
colors = DEFAULT_COLORS,
|
||||
donut = false,
|
||||
innerRadius,
|
||||
outerRadius = 100,
|
||||
showLegend = true,
|
||||
showLegend: _showLegend = true,
|
||||
showLabels = true,
|
||||
height = 300,
|
||||
className,
|
||||
valueFormatter = (v) => v.toLocaleString(),
|
||||
}: PieChartProps) {
|
||||
// Ensure numeric values for Recharts Pie
|
||||
const pieData = data.map(row => ({
|
||||
...row,
|
||||
[valueKey]: Number(row[valueKey]) || 0,
|
||||
const chartData = data.map((row, i) => ({
|
||||
name: String(row[nameKey] ?? ''),
|
||||
value: Number(row[valueKey]) || 0,
|
||||
color: colors[i % colors.length] as string,
|
||||
}))
|
||||
|
||||
const resolvedInnerRadius = donut ? (innerRadius ?? 50) : (innerRadius ?? 0)
|
||||
|
||||
const labelRenderer = showLabels
|
||||
? ({ name, percent }: Record<string, unknown>) =>
|
||||
`${name ?? ''} ${(((percent as number) ?? 0) * 100).toFixed(0)}%`
|
||||
: undefined
|
||||
const Chart = donut ? DonutChart : MantinePieChart
|
||||
|
||||
return (
|
||||
<ResponsiveContainer width="100%" height={height} className={cn(className)}>
|
||||
<RechartsPieChart>
|
||||
<Pie
|
||||
data={pieData}
|
||||
dataKey={valueKey}
|
||||
nameKey={nameKey}
|
||||
cx="50%"
|
||||
cy="50%"
|
||||
outerRadius={outerRadius}
|
||||
innerRadius={resolvedInnerRadius}
|
||||
strokeWidth={0}
|
||||
fontSize={11}
|
||||
label={labelRenderer}
|
||||
labelLine={showLabels}
|
||||
>
|
||||
{pieData.map((_, i) => (
|
||||
<Cell key={i} fill={colors[i % colors.length]} />
|
||||
))}
|
||||
</Pie>
|
||||
<Tooltip
|
||||
contentStyle={{
|
||||
backgroundColor: 'var(--card)',
|
||||
border: '1px solid var(--border)',
|
||||
borderRadius: 8,
|
||||
fontSize: 12,
|
||||
}}
|
||||
formatter={(value: unknown) => [valueFormatter(value as number)]}
|
||||
/>
|
||||
{showLegend && <Legend wrapperStyle={{ fontSize: 11 }} />}
|
||||
</RechartsPieChart>
|
||||
</ResponsiveContainer>
|
||||
<Paper p="md">
|
||||
<Chart
|
||||
h={height}
|
||||
data={chartData}
|
||||
withLabels={showLabels}
|
||||
withLabelsLine={showLabels}
|
||||
withTooltip
|
||||
tooltipDataSource="segment"
|
||||
valueFormatter={valueFormatter}
|
||||
/>
|
||||
{/* Mantine PieChart/DonutChart does not have a built-in legend prop;
|
||||
legend is handled via withLabels. showLegend kept for API compat. */}
|
||||
</Paper>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user