79 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
		
		
			
		
	
	
			79 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
|  | import { Box, CircularProgress, Alert, Paper, Typography } from '@mui/material'; | ||
|  | import { PiCow } from "react-icons/pi"; // Un icono divertido para "cabezas"
 | ||
|  | import ScaleIcon from '@mui/icons-material/Scale'; // Para kilos
 | ||
|  | 
 | ||
|  | import type { CotizacionGanado } from '../models/mercadoModels'; | ||
|  | import { useApiData } from '../hooks/useApiData'; | ||
|  | import { formatCurrency, formatInteger } from '../utils/formatters'; | ||
|  | 
 | ||
|  | const AgroCard = ({ categoria }: { categoria: CotizacionGanado }) => { | ||
|  |     return ( | ||
|  |         <Paper elevation={2} sx={{ p: 2, flex: '1 1 250px', minWidth: '250px', maxWidth: '300px' }}> | ||
|  |             <Typography variant="h6" component="h3" sx={{ fontWeight: 'bold', borderBottom: 1, borderColor: 'divider', pb: 1, mb: 2 }}> | ||
|  |                 {categoria.categoria} | ||
|  |             </Typography> | ||
|  |             <Box sx={{ display: 'flex', justifyContent: 'space-between', mb: 1 }}> | ||
|  |                 <Typography variant="body2" color="text.secondary">Precio Máximo:</Typography> | ||
|  |                 <Typography variant="body2" sx={{ fontWeight: 'bold', color: 'success.main' }}>${formatCurrency(categoria.maximo)}</Typography> | ||
|  |             </Box> | ||
|  |             <Box sx={{ display: 'flex', justifyContent: 'space-between', mb: 1 }}> | ||
|  |                 <Typography variant="body2" color="text.secondary">Precio Mínimo:</Typography> | ||
|  |                 <Typography variant="body2" sx={{ fontWeight: 'bold', color: 'error.main' }}>${formatCurrency(categoria.minimo)}</Typography> | ||
|  |             </Box> | ||
|  |             <Box sx={{ display: 'flex', justifyContent: 'space-between', mb: 2 }}> | ||
|  |                 <Typography variant="body2" color="text.secondary">Precio Mediano:</Typography> | ||
|  |                 <Typography variant="body2" sx={{ fontWeight: 'bold' }}>${formatCurrency(categoria.mediano)}</Typography> | ||
|  |             </Box> | ||
|  |              | ||
|  |             <Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 3, pt: 1, borderTop: 1, borderColor: 'divider' }}> | ||
|  |                 <Box sx={{ textAlign: 'center' }}> | ||
|  |                     <PiCow size={28}/> | ||
|  |                     <Typography variant="body1" sx={{ fontWeight: 'bold' }}>{formatInteger(categoria.cabezas)}</Typography> | ||
|  |                     <Typography variant="caption" color="text.secondary">Cabezas</Typography> | ||
|  |                 </Box> | ||
|  |                  <Box sx={{ textAlign: 'center' }}> | ||
|  |                     <ScaleIcon color="action" /> | ||
|  |                     <Typography variant="body1" sx={{ fontWeight: 'bold' }}>{formatInteger(categoria.kilosTotales)}</Typography> | ||
|  |                     <Typography variant="caption" color="text.secondary">Kilos</Typography> | ||
|  |                 </Box> | ||
|  |             </Box> | ||
|  |         </Paper> | ||
|  |     ); | ||
|  | }; | ||
|  | 
 | ||
|  | // Este widget agrupa los datos por categoría para un resumen más limpio.
 | ||
|  | export const MercadoAgroCardWidget = () => { | ||
|  |     const { data, loading, error } = useApiData<CotizacionGanado[]>('/mercados/agroganadero'); | ||
|  | 
 | ||
|  |     if (loading) { | ||
|  |         return <Box sx={{ display: 'flex', justifyContent: 'center', p: 4 }}><CircularProgress /></Box>; | ||
|  |     } | ||
|  |     if (error) { | ||
|  |         return <Alert severity="error">{error}</Alert>; | ||
|  |     } | ||
|  |     if (!data || data.length === 0) { | ||
|  |         return <Alert severity="info">No hay datos del mercado agroganadero disponibles.</Alert>; | ||
|  |     } | ||
|  | 
 | ||
|  |     // Agrupamos y sumamos los datos por categoría principal
 | ||
|  |     const resumenPorCategoria = data.reduce((acc, item) => { | ||
|  |         if (!acc[item.categoria]) { | ||
|  |             acc[item.categoria] = { ...item }; | ||
|  |         } else { | ||
|  |             acc[item.categoria].cabezas += item.cabezas; | ||
|  |             acc[item.categoria].kilosTotales += item.kilosTotales; | ||
|  |             acc[item.categoria].importeTotal += item.importeTotal; | ||
|  |             acc[item.categoria].maximo = Math.max(acc[item.categoria].maximo, item.maximo); | ||
|  |             acc[item.categoria].minimo = Math.min(acc[item.categoria].minimo, item.minimo); | ||
|  |         } | ||
|  |         return acc; | ||
|  |     }, {} as Record<string, CotizacionGanado>); | ||
|  | 
 | ||
|  |     return ( | ||
|  |         <Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 2, justifyContent: 'center' }}> | ||
|  |             {Object.values(resumenPorCategoria).map(categoria => ( | ||
|  |                 <AgroCard key={categoria.categoria} categoria={categoria} /> | ||
|  |             ))} | ||
|  |         </Box> | ||
|  |     ); | ||
|  | }; |