| 
									
										
										
										
											2025-07-01 13:42:16 -03:00
										 |  |  | import { | 
					
						
							|  |  |  |   Box, CircularProgress, Alert, Table, TableBody, TableCell, | 
					
						
							|  |  |  |   TableContainer, TableHead, TableRow, Paper, Typography, Tooltip | 
					
						
							|  |  |  | } from '@mui/material'; | 
					
						
							|  |  |  | import ArrowUpwardIcon from '@mui/icons-material/ArrowUpward'; | 
					
						
							|  |  |  | import ArrowDownwardIcon from '@mui/icons-material/ArrowDownward'; | 
					
						
							|  |  |  | import RemoveIcon from '@mui/icons-material/Remove'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-15 15:20:36 -03:00
										 |  |  | // Importaciones de nuestro proyecto
 | 
					
						
							|  |  |  | import type { CotizacionGrano } from '../models/mercadoModels'; | 
					
						
							|  |  |  | import { useApiData } from '../hooks/useApiData'; | 
					
						
							|  |  |  | import { useIsHoliday } from '../hooks/useIsHoliday'; | 
					
						
							|  |  |  | import { formatInteger, formatDateOnly, formatFullDateTime } from '../utils/formatters'; | 
					
						
							|  |  |  | import { HolidayAlert } from './common/HolidayAlert'; | 
					
						
							| 
									
										
										
										
											2025-07-01 13:42:16 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-15 15:20:36 -03:00
										 |  |  | /** | 
					
						
							|  |  |  |  * Sub-componente para mostrar la variación con icono y color. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2025-07-01 13:42:16 -03:00
										 |  |  | const Variacion = ({ value }: { value: number }) => { | 
					
						
							|  |  |  |   const color = value > 0 ? 'success.main' : value < 0 ? 'error.main' : 'text.secondary'; | 
					
						
							|  |  |  |   const Icon = value > 0 ? ArrowUpwardIcon : value < 0 ? ArrowDownwardIcon : RemoveIcon; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return ( | 
					
						
							|  |  |  |     <Box component="span" sx={{ display: 'flex', alignItems: 'center', justifyContent: 'center', color }}> | 
					
						
							|  |  |  |       <Icon sx={{ fontSize: '1rem', mr: 0.5 }} /> | 
					
						
							|  |  |  |       <Typography variant="body2" component="span" sx={{ fontWeight: 'bold' }}> | 
					
						
							| 
									
										
										
										
											2025-07-15 15:20:36 -03:00
										 |  |  |         {formatInteger(value)} | 
					
						
							| 
									
										
										
										
											2025-07-01 13:42:16 -03:00
										 |  |  |       </Typography> | 
					
						
							|  |  |  |     </Box> | 
					
						
							|  |  |  |   ); | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-15 15:20:36 -03:00
										 |  |  | /** | 
					
						
							|  |  |  |  * Widget autónomo para la tabla detallada del mercado de granos. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2025-07-01 13:42:16 -03:00
										 |  |  | export const GranosWidget = () => { | 
					
						
							| 
									
										
										
										
											2025-07-15 15:20:36 -03:00
										 |  |  |   // Hooks para obtener los datos y el estado de feriado para el mercado argentino.
 | 
					
						
							|  |  |  |   const { data, loading: dataLoading, error: dataError } = useApiData<CotizacionGrano[]>('/mercados/granos'); | 
					
						
							|  |  |  |   const isHoliday = useIsHoliday('BA'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Estado de carga unificado.
 | 
					
						
							|  |  |  |   const isLoading = dataLoading || isHoliday === null; | 
					
						
							| 
									
										
										
										
											2025-07-01 13:42:16 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-15 15:20:36 -03:00
										 |  |  |   if (isLoading) { | 
					
						
							| 
									
										
										
										
											2025-07-01 13:42:16 -03:00
										 |  |  |     return <Box sx={{ display: 'flex', justifyContent: 'center', p: 4 }}><CircularProgress /></Box>; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-15 15:20:36 -03:00
										 |  |  |   if (dataError) { | 
					
						
							|  |  |  |     return <Alert severity="error">{dataError}</Alert>; | 
					
						
							| 
									
										
										
										
											2025-07-01 13:42:16 -03:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-15 15:20:36 -03:00
										 |  |  |   // Si no hay ningún dato que mostrar.
 | 
					
						
							| 
									
										
										
										
											2025-07-01 13:42:16 -03:00
										 |  |  |   if (!data || data.length === 0) { | 
					
						
							| 
									
										
										
										
											2025-07-15 15:20:36 -03:00
										 |  |  |     if (isHoliday) { | 
					
						
							|  |  |  |       return <HolidayAlert />; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2025-07-01 13:42:16 -03:00
										 |  |  |     return <Alert severity="info">No hay datos de granos disponibles en este momento.</Alert>; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return ( | 
					
						
							| 
									
										
										
										
											2025-07-15 15:20:36 -03:00
										 |  |  |     <Box> | 
					
						
							|  |  |  |       {/* Si es feriado, mostramos la alerta como un aviso encima del contenido. */} | 
					
						
							|  |  |  |       {isHoliday && ( | 
					
						
							|  |  |  |         <Box sx={{ mb: 2 }}> | 
					
						
							|  |  |  |           <HolidayAlert /> | 
					
						
							|  |  |  |         </Box> | 
					
						
							|  |  |  |       )} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       <TableContainer component={Paper}> | 
					
						
							|  |  |  |         <Table size="small" aria-label="tabla granos"> | 
					
						
							|  |  |  |           <TableHead> | 
					
						
							|  |  |  |             <TableRow> | 
					
						
							|  |  |  |               <TableCell>Grano</TableCell> | 
					
						
							|  |  |  |               <TableCell align="right">Precio ($/Tn)</TableCell> | 
					
						
							|  |  |  |               <TableCell align="center">Variación</TableCell> | 
					
						
							|  |  |  |               <TableCell align="right">Fecha Operación</TableCell> | 
					
						
							| 
									
										
										
										
											2025-07-01 13:42:16 -03:00
										 |  |  |             </TableRow> | 
					
						
							| 
									
										
										
										
											2025-07-15 15:20:36 -03:00
										 |  |  |           </TableHead> | 
					
						
							|  |  |  |           <TableBody> | 
					
						
							|  |  |  |             {data.map((row) => ( | 
					
						
							|  |  |  |               <TableRow key={row.nombre} hover> | 
					
						
							|  |  |  |                 <TableCell component="th" scope="row"> | 
					
						
							|  |  |  |                   <Typography variant="body2" sx={{ fontWeight: 'bold' }}>{row.nombre}</Typography> | 
					
						
							|  |  |  |                 </TableCell> | 
					
						
							|  |  |  |                 <TableCell align="right">${formatInteger(row.precio)}</TableCell> | 
					
						
							|  |  |  |                 <TableCell align="center"> | 
					
						
							|  |  |  |                   <Variacion value={row.variacionPrecio} /> | 
					
						
							|  |  |  |                 </TableCell> | 
					
						
							|  |  |  |                 <TableCell align="right">{formatDateOnly(row.fechaOperacion)}</TableCell> | 
					
						
							|  |  |  |               </TableRow> | 
					
						
							|  |  |  |             ))} | 
					
						
							|  |  |  |           </TableBody> | 
					
						
							|  |  |  |         </Table> | 
					
						
							|  |  |  |         <Tooltip title={`Última actualización: ${formatFullDateTime(data[0].fechaRegistro)}`}> | 
					
						
							|  |  |  |           <Typography variant="caption" sx={{ p: 1, display: 'block', textAlign: 'right', color: 'text.secondary' }}> | 
					
						
							|  |  |  |             Fuente: Bolsa de Comercio de Rosario | 
					
						
							|  |  |  |           </Typography> | 
					
						
							|  |  |  |         </Tooltip> | 
					
						
							|  |  |  |       </TableContainer> | 
					
						
							|  |  |  |     </Box> | 
					
						
							| 
									
										
										
										
											2025-07-01 13:42:16 -03:00
										 |  |  |   ); | 
					
						
							|  |  |  | }; |