92 lines
No EOL
3.2 KiB
JavaScript
92 lines
No EOL
3.2 KiB
JavaScript
import { Typography, Box, Chip, Stack } from '@mui/material';
|
|
import { Cloud, WbSunny, Thunderstorm, AcUnit } from '@mui/icons-material';
|
|
import GenericWidget from './GenericWidget';
|
|
|
|
function WeatherWidget({ data, sx }) {
|
|
const getWeatherIcon = (description) => {
|
|
const desc = description?.toLowerCase() || '';
|
|
if (desc.includes('sun') || desc.includes('clear')) return <WbSunny />;
|
|
if (desc.includes('cloud') || desc.includes('overcast')) return <Cloud />;
|
|
if (desc.includes('rain') || desc.includes('storm')) return <Thunderstorm />;
|
|
if (desc.includes('snow') || desc.includes('ice')) return <AcUnit />;
|
|
return <Cloud />;
|
|
};
|
|
|
|
if (!data || data.error) {
|
|
return (
|
|
<GenericWidget title="Weather" sx={{ opacity: 0.5, ...sx }}>
|
|
<Typography color="text.secondary">
|
|
{data?.message || 'Weather data unavailable'}
|
|
</Typography>
|
|
</GenericWidget>
|
|
);
|
|
}
|
|
|
|
const current = data.current || {};
|
|
const location = data.nearestArea?.areaName?.[0]?.value || data.location || 'Unknown';
|
|
const temp = current.temp_F || current.temp_C || '?';
|
|
const tempUnit = current.temp_F ? '°F' : '°C';
|
|
const description = current.weatherDesc?.[0]?.value || 'No description';
|
|
const humidity = current.humidity || '?';
|
|
const windSpeed = current.windspeedMiles || current.windspeedKmph || '?';
|
|
const windUnit = current.windspeedMiles ? 'mph' : 'km/h';
|
|
|
|
return (
|
|
<GenericWidget title={`Weather - ${location}`} sx={{ ...sx }}>
|
|
<Box sx={{ mt: 1 }}>
|
|
<Box sx={{ display: 'flex', alignItems: 'center', mb: 2 }}>
|
|
<Box sx={{ mr: 2 }}>
|
|
{getWeatherIcon(description)}
|
|
</Box>
|
|
<Box>
|
|
<Typography variant="h3" component="span">
|
|
{temp}
|
|
</Typography>
|
|
<Typography variant="h5" component="span" color="text.secondary">
|
|
{tempUnit}
|
|
</Typography>
|
|
</Box>
|
|
</Box>
|
|
|
|
<Typography variant="body1" sx={{ mb: 2 }}>
|
|
{description}
|
|
</Typography>
|
|
|
|
<Stack direction="row" spacing={1}>
|
|
<Chip
|
|
label={`Humidity: ${humidity}%`}
|
|
size="small"
|
|
variant="outlined"
|
|
/>
|
|
<Chip
|
|
label={`Wind: ${windSpeed} ${windUnit}`}
|
|
size="small"
|
|
variant="outlined"
|
|
/>
|
|
</Stack>
|
|
|
|
{data.forecast && data.forecast.length > 0 && (
|
|
<Box sx={{ mt: 2 }}>
|
|
<Typography variant="subtitle2" color="text.secondary" gutterBottom>
|
|
Forecast
|
|
</Typography>
|
|
<Stack direction="row" spacing={1}>
|
|
{data.forecast.slice(0, 3).map((day, index) => (
|
|
<Box key={index} sx={{ textAlign: 'center' }}>
|
|
<Typography variant="caption" display="block">
|
|
Day {index + 1}
|
|
</Typography>
|
|
<Typography variant="body2">
|
|
{day.maxtempF || day.maxtempC}° / {day.mintempF || day.mintempC}°
|
|
</Typography>
|
|
</Box>
|
|
))}
|
|
</Stack>
|
|
</Box>
|
|
)}
|
|
</Box>
|
|
</GenericWidget>
|
|
);
|
|
}
|
|
|
|
export default WeatherWidget; |