fix(dashboard): mover useMemo antes de early returns (React hooks)
- DashboardVendedor: useMemo de comparativa mensual movido antes de los returns condicionales - Corrige React error #310 (rendered fewer hooks than expected) - 5 apps construidas
This commit is contained in:
@@ -68,39 +68,8 @@ export default function DashboardVendedor() {
|
|||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
useEffect(() => { void cargar() }, [cargar])
|
useEffect(() => { void cargar() }, [cargar])
|
||||||
|
|
||||||
if (cargando && !tablero) return <SkeletonChart />
|
|
||||||
if (error) {
|
|
||||||
return (
|
|
||||||
<div className="rounded-xl border border-red-200 bg-red-50 p-6 text-center dark:border-red-900/50 dark:bg-red-950/30">
|
|
||||||
<p className="text-sm font-medium text-red-700 dark:text-red-400">{error}</p>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
onClick={() => void cargar()}
|
|
||||||
className="mt-3 rounded-lg bg-accent px-4 py-2 text-xs font-medium text-white transition-colors hover:bg-accent-hover"
|
|
||||||
>
|
|
||||||
Reintentar
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
if (!tablero) return null
|
|
||||||
|
|
||||||
const totalFunnel = tablero.conversion.leads || 1
|
|
||||||
|
|
||||||
// Datos para gráfica de origen (solo top 6)
|
|
||||||
const datosOrigen = tablero.porOrigen.slice(0, 6)
|
|
||||||
|
|
||||||
// Datos para ranking de desarrollos
|
|
||||||
const datosDesarrollo = tablero.porDesarrollo.slice(0, 5)
|
|
||||||
|
|
||||||
// F2: KPIs adicionales
|
|
||||||
const tasaConversion = totalFunnel > 0
|
|
||||||
? ((tablero.conversion.oportunidades / totalFunnel) * 100).toFixed(1)
|
|
||||||
: '0'
|
|
||||||
|
|
||||||
// F1: Datos de comparativa mensual (calculados de leadsPorDia)
|
|
||||||
const comparativaMensual = useMemo(() => {
|
const comparativaMensual = useMemo(() => {
|
||||||
|
if (!tablero) return []
|
||||||
const hoy = new Date()
|
const hoy = new Date()
|
||||||
const mesActual = hoy.getMonth()
|
const mesActual = hoy.getMonth()
|
||||||
const anioActual = hoy.getFullYear()
|
const anioActual = hoy.getFullYear()
|
||||||
@@ -145,6 +114,38 @@ export default function DashboardVendedor() {
|
|||||||
]
|
]
|
||||||
}, [tablero])
|
}, [tablero])
|
||||||
|
|
||||||
|
if (cargando && !tablero) return <SkeletonChart />
|
||||||
|
if (error) {
|
||||||
|
return (
|
||||||
|
<div className="rounded-xl border border-red-200 bg-red-50 p-6 text-center dark:border-red-900/50 dark:bg-red-950/30">
|
||||||
|
<p className="text-sm font-medium text-red-700 dark:text-red-400">{error}</p>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={() => void cargar()}
|
||||||
|
className="mt-3 rounded-lg bg-accent px-4 py-2 text-xs font-medium text-white transition-colors hover:bg-accent-hover"
|
||||||
|
>
|
||||||
|
Reintentar
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if (!tablero) return null
|
||||||
|
|
||||||
|
const totalFunnel = tablero.conversion.leads || 1
|
||||||
|
|
||||||
|
// Datos para gráfica de origen (solo top 6)
|
||||||
|
const datosOrigen = tablero.porOrigen.slice(0, 6)
|
||||||
|
|
||||||
|
// Datos para ranking de desarrollos
|
||||||
|
const datosDesarrollo = tablero.porDesarrollo.slice(0, 5)
|
||||||
|
|
||||||
|
// F2: KPIs adicionales
|
||||||
|
const tasaConversion = totalFunnel > 0
|
||||||
|
? ((tablero.conversion.oportunidades / totalFunnel) * 100).toFixed(1)
|
||||||
|
: '0'
|
||||||
|
|
||||||
|
// F1: Datos de comparativa mensual (calculados de leadsPorDia)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="space-y-6">
|
<div className="space-y-6">
|
||||||
{/* F2: KPIs mejorados */}
|
{/* F2: KPIs mejorados */}
|
||||||
|
|||||||
Reference in New Issue
Block a user