Style date time weather to fit in better
This commit is contained in:
@@ -122,35 +122,37 @@ const DateTimeWeatherDisplay = ({ scaleFactor = 1 }) => {
|
||||
if (!weatherCode) return <CircleAlert className="w-12 h-12 text-red-500" />;
|
||||
const code = parseInt(weatherCode, 10);
|
||||
const iconProps = small ? "w-8 h-8" : "w-12 h-12";
|
||||
const isNight = currentTime.getHours() >= 18 || currentTime.getHours() < 6;
|
||||
|
||||
switch (true) {
|
||||
case code >= 200 && code < 300:
|
||||
return <CloudLightning className={cn(iconProps, "text-gray-700")} />;
|
||||
return <CloudLightning className={cn(iconProps, "text-yellow-300")} />;
|
||||
case code >= 300 && code < 500:
|
||||
return <CloudDrizzle className={cn(iconProps, "text-blue-600")} />;
|
||||
return <CloudDrizzle className={cn(iconProps, "text-blue-300")} />;
|
||||
case code >= 500 && code < 600:
|
||||
return <CloudRain className={cn(iconProps, "text-blue-600")} />;
|
||||
return <CloudRain className={cn(iconProps, "text-blue-300")} />;
|
||||
case code >= 600 && code < 700:
|
||||
return <CloudSnow className={cn(iconProps, "text-blue-400")} />;
|
||||
return <CloudSnow className={cn(iconProps, "text-blue-200")} />;
|
||||
case code >= 700 && code < 721:
|
||||
return <CloudFog className={cn(iconProps, "text-gray-600")} />;
|
||||
return <CloudFog className={cn(iconProps, "text-gray-300")} />;
|
||||
case code === 721:
|
||||
return <Haze className={cn(iconProps, "text-gray-700")} />;
|
||||
return <Haze className={cn(iconProps, "text-gray-300")} />;
|
||||
case code >= 722 && code < 781:
|
||||
return <CloudFog className={cn(iconProps, "text-gray-600")} />;
|
||||
return <CloudFog className={cn(iconProps, "text-gray-300")} />;
|
||||
case code === 781:
|
||||
return <Tornado className={cn(iconProps, "text-gray-700")} />;
|
||||
return <Tornado className={cn(iconProps, "text-gray-300")} />;
|
||||
case code === 800:
|
||||
return currentTime.getHours() >= 6 && currentTime.getHours() < 18 ? (
|
||||
<Sun className={cn(iconProps, "text-yellow-700")} />
|
||||
<Sun className={cn(iconProps, "text-yellow-300")} />
|
||||
) : (
|
||||
<Moon className={cn(iconProps, "text-gray-500")} />
|
||||
<Moon className={cn(iconProps, "text-gray-300")} />
|
||||
);
|
||||
case code >= 800 && code < 803:
|
||||
return <CloudSun className={cn(iconProps, "text-gray-600")} />;
|
||||
return <CloudSun className={cn(iconProps, isNight ? "text-gray-300" : "text-gray-200")} />;
|
||||
case code >= 803:
|
||||
return <Cloud className={cn(iconProps, "text-gray-200")} />;
|
||||
return <Cloud className={cn(iconProps, "text-gray-300")} />;
|
||||
default:
|
||||
return <CircleAlert className={cn(iconProps, "text-red-700")} />;
|
||||
return <CircleAlert className={cn(iconProps, "text-red-500")} />;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -159,66 +161,68 @@ const DateTimeWeatherDisplay = ({ scaleFactor = 1 }) => {
|
||||
|
||||
// Thunderstorm (200-299)
|
||||
if (code >= 200 && code < 300) {
|
||||
return "bg-gradient-to-br from-slate-900 via-purple-900 to-slate-800";
|
||||
return "bg-gradient-to-br from-slate-900 to-purple-800";
|
||||
}
|
||||
|
||||
// Drizzle (300-399)
|
||||
if (code >= 300 && code < 400) {
|
||||
return "bg-gradient-to-br from-slate-700 via-blue-800 to-slate-700";
|
||||
return "bg-gradient-to-br from-slate-800 to-blue-800";
|
||||
}
|
||||
|
||||
// Rain (500-599)
|
||||
if (code >= 500 && code < 600) {
|
||||
return "bg-gradient-to-br from-slate-800 via-blue-900 to-slate-700";
|
||||
return "bg-gradient-to-br from-slate-800 to-blue-800";
|
||||
}
|
||||
|
||||
// Snow (600-699)
|
||||
if (code >= 600 && code < 700) {
|
||||
return "bg-gradient-to-br from-slate-200 via-blue-100 to-slate-100";
|
||||
return "bg-gradient-to-br from-slate-700 to-blue-800";
|
||||
}
|
||||
|
||||
// Atmosphere (700-799: mist, smoke, haze, fog, etc.)
|
||||
if (code >= 700 && code < 800) {
|
||||
return "bg-gradient-to-br from-slate-600 via-slate-500 to-slate-400";
|
||||
return "bg-gradient-to-br from-slate-700 to-slate-500";
|
||||
}
|
||||
|
||||
// Clear (800)
|
||||
if (code === 800) {
|
||||
if (isNight) {
|
||||
return "bg-gradient-to-br from-slate-900 via-blue-950 to-slate-800";
|
||||
return "bg-gradient-to-br from-slate-900 to-blue-900";
|
||||
}
|
||||
return "bg-gradient-to-br from-sky-400 via-blue-400 to-sky-500";
|
||||
return "bg-gradient-to-br from-blue-600 to-sky-400";
|
||||
}
|
||||
|
||||
// Clouds (801-804)
|
||||
if (code > 800) {
|
||||
if (isNight) {
|
||||
return "bg-gradient-to-br from-slate-800 via-slate-700 to-slate-600";
|
||||
return "bg-gradient-to-br from-slate-800 to-slate-600";
|
||||
}
|
||||
return "bg-gradient-to-br from-slate-400 via-slate-500 to-slate-400";
|
||||
return "bg-gradient-to-br from-slate-600 to-slate-400";
|
||||
}
|
||||
|
||||
// Default fallback
|
||||
return "bg-gradient-to-br from-slate-700 via-slate-600 to-slate-500";
|
||||
return "bg-gradient-to-br from-slate-700 to-slate-500";
|
||||
};
|
||||
|
||||
const getTemperatureColor = (weatherCode, isNight) => {
|
||||
const code = parseInt(weatherCode, 10);
|
||||
|
||||
// Use dark text for light backgrounds
|
||||
if (code >= 600 && code < 700) { // Snow
|
||||
return "text-slate-900";
|
||||
// Snow - dark background, light text
|
||||
if (code >= 600 && code < 700) {
|
||||
return "text-white";
|
||||
}
|
||||
|
||||
if (code === 800 && !isNight) { // Clear day
|
||||
return "text-slate-900";
|
||||
// Clear day - light background, dark text
|
||||
if (code === 800 && !isNight) {
|
||||
return "text-white";
|
||||
}
|
||||
|
||||
if (code > 800 && !isNight) { // Cloudy day
|
||||
return "text-slate-900";
|
||||
// Cloudy day - medium background, ensure contrast
|
||||
if (code > 800 && !isNight) {
|
||||
return "text-white";
|
||||
}
|
||||
|
||||
// Default to white text for all other (darker) backgrounds
|
||||
// All other cases (darker backgrounds)
|
||||
return "text-white";
|
||||
};
|
||||
|
||||
@@ -236,64 +240,64 @@ const DateTimeWeatherDisplay = ({ scaleFactor = 1 }) => {
|
||||
};
|
||||
|
||||
const WeatherDetails = () => (
|
||||
<div className="space-y-4 p-3">
|
||||
<div className="space-y-4 p-3 bg-gradient-to-br from-slate-800 to-slate-700">
|
||||
<div className="grid grid-cols-3 gap-2">
|
||||
<Card className="p-2">
|
||||
<Card className="bg-gradient-to-br from-slate-700 to-slate-600 backdrop-blur-sm p-2">
|
||||
<div className="flex items-center gap-1">
|
||||
<ThermometerSun className="w-5 h-5 text-orange-500" />
|
||||
<ThermometerSun className="w-5 h-5 text-yellow-300" />
|
||||
<div className="flex flex-col">
|
||||
<span className="text-xs text-muted-foreground">High</span>
|
||||
<span className="text-sm font-bold">{Math.round(weather.main.temp_max)}°F</span>
|
||||
<span className="text-xs text-slate-300">High</span>
|
||||
<span className="text-sm font-bold text-white">{Math.round(weather.main.temp_max)}°F</span>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
<Card className="p-2">
|
||||
<Card className="bg-gradient-to-br from-slate-700 to-slate-600 backdrop-blur-sm p-2">
|
||||
<div className="flex items-center gap-1">
|
||||
<ThermometerSnowflake className="w-5 h-5 text-blue-500" />
|
||||
<ThermometerSnowflake className="w-5 h-5 text-blue-300" />
|
||||
<div className="flex flex-col">
|
||||
<span className="text-xs text-muted-foreground">Low</span>
|
||||
<span className="text-sm font-bold">{Math.round(weather.main.temp_min)}°F</span>
|
||||
<span className="text-xs text-slate-300">Low</span>
|
||||
<span className="text-sm font-bold text-white">{Math.round(weather.main.temp_min)}°F</span>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
<Card className="p-2">
|
||||
<Card className="bg-gradient-to-br from-slate-700 to-slate-600 backdrop-blur-sm p-2">
|
||||
<div className="flex items-center gap-1">
|
||||
<Droplets className="w-5 h-5 text-blue-400" />
|
||||
<Droplets className="w-5 h-5 text-blue-300" />
|
||||
<div className="flex flex-col">
|
||||
<span className="text-xs text-muted-foreground">Humidity</span>
|
||||
<span className="text-sm font-bold">{weather.main.humidity}%</span>
|
||||
<span className="text-xs text-slate-300">Humidity</span>
|
||||
<span className="text-sm font-bold text-white">{weather.main.humidity}%</span>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
<Card className="p-2">
|
||||
<Card className="bg-gradient-to-br from-slate-700 to-slate-600 backdrop-blur-sm p-2">
|
||||
<div className="flex items-center gap-1">
|
||||
<Wind className="w-5 h-5 text-gray-500" />
|
||||
<Wind className="w-5 h-5 text-slate-300" />
|
||||
<div className="flex flex-col">
|
||||
<span className="text-xs text-muted-foreground">Wind</span>
|
||||
<span className="text-sm font-bold">{Math.round(weather.wind.speed)} mph</span>
|
||||
<span className="text-xs text-slate-300">Wind</span>
|
||||
<span className="text-sm font-bold text-white">{Math.round(weather.wind.speed)} mph</span>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
<Card className="p-2">
|
||||
<Card className="bg-gradient-to-br from-slate-700 to-slate-600 backdrop-blur-sm p-2">
|
||||
<div className="flex items-center gap-1">
|
||||
<Sunrise className="w-5 h-5 text-yellow-500" />
|
||||
<Sunrise className="w-5 h-5 text-yellow-300" />
|
||||
<div className="flex flex-col">
|
||||
<span className="text-xs text-muted-foreground">Sunrise</span>
|
||||
<span className="text-sm font-bold">{formatTime(weather.sys?.sunrise)}</span>
|
||||
<span className="text-xs text-slate-300">Sunrise</span>
|
||||
<span className="text-sm font-bold text-white">{formatTime(weather.sys?.sunrise)}</span>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
<Card className="p-2">
|
||||
<Card className="bg-gradient-to-br from-slate-700 to-slate-600 backdrop-blur-sm p-2">
|
||||
<div className="flex items-center gap-1">
|
||||
<Sunset className="w-5 h-5 text-orange-400" />
|
||||
<Sunset className="w-5 h-5 text-orange-300" />
|
||||
<div className="flex flex-col">
|
||||
<span className="text-xs text-muted-foreground">Sunset</span>
|
||||
<span className="text-sm font-bold">{formatTime(weather.sys?.sunset)}</span>
|
||||
<span className="text-xs text-slate-300">Sunset</span>
|
||||
<span className="text-sm font-bold text-white">{formatTime(weather.sys?.sunset)}</span>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
@@ -302,61 +306,71 @@ const DateTimeWeatherDisplay = ({ scaleFactor = 1 }) => {
|
||||
{forecast && (
|
||||
<div>
|
||||
<div className="grid grid-cols-5 gap-2">
|
||||
{forecast.map((day, index) => (
|
||||
<Card key={index} className="p-2">
|
||||
{forecast.map((day, index) => {
|
||||
const forecastTime = new Date(day.dt * 1000);
|
||||
const isNight = forecastTime.getHours() >= 18 || forecastTime.getHours() < 6;
|
||||
return (
|
||||
<Card
|
||||
key={index}
|
||||
className={cn(
|
||||
getWeatherBackground(day.weather[0].id, isNight),
|
||||
"p-2"
|
||||
)}
|
||||
>
|
||||
<div className="flex flex-col items-center gap-1">
|
||||
<span className="text-sm font-medium">
|
||||
{new Date(day.dt * 1000).toLocaleDateString('en-US', { weekday: 'short' })}
|
||||
<span className="text-sm font-medium text-white">
|
||||
{forecastTime.toLocaleDateString('en-US', { weekday: 'short' })}
|
||||
</span>
|
||||
{getWeatherIcon(day.weather[0].id, new Date(day.dt * 1000), true)}
|
||||
{getWeatherIcon(day.weather[0].id, forecastTime, true)}
|
||||
<div className="flex justify-center gap-1 items-baseline w-full">
|
||||
<span className="text-sm font-medium">
|
||||
<span className="text-sm font-medium text-white">
|
||||
{Math.round(day.main.temp_max)}°
|
||||
</span>
|
||||
<span className="text-xs text-muted-foreground">
|
||||
<span className="text-xs text-slate-300">
|
||||
{Math.round(day.main.temp_min)}°
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex flex-col items-center gap-1 w-full pt-1">
|
||||
{day.rain?.['3h'] > 0 && (
|
||||
<div className="flex items-center gap-1">
|
||||
<CloudRain className="w-3 h-3 text-blue-400" />
|
||||
<span className="text-xs">{day.rain['3h'].toFixed(2)}"</span>
|
||||
<CloudRain className="w-3 h-3 text-blue-300" />
|
||||
<span className="text-xs text-white">{day.rain['3h'].toFixed(2)}"</span>
|
||||
</div>
|
||||
)}
|
||||
{day.snow?.['3h'] > 0 && (
|
||||
<div className="flex items-center gap-1">
|
||||
<CloudSnow className="w-3 h-3 text-blue-400" />
|
||||
<span className="text-xs">{day.snow['3h'].toFixed(2)}"</span>
|
||||
<CloudSnow className="w-3 h-3 text-blue-300" />
|
||||
<span className="text-xs text-white">{day.snow['3h'].toFixed(2)}"</span>
|
||||
</div>
|
||||
)}
|
||||
{!day.rain?.['3h'] && !day.snow?.['3h'] && (
|
||||
<div className="flex items-center gap-1">
|
||||
<Umbrella className="w-3 h-3 text-gray-400" />
|
||||
<span className="text-xs">0"</span>
|
||||
<Umbrella className="w-3 h-3 text-slate-300" />
|
||||
<span className="text-xs text-white">0"</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
))}
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
);
|
||||
|
||||
return (
|
||||
return (
|
||||
<div className="flex flex-col items-center w-full transition-opacity duration-300 ${mounted ? 'opacity-100' : 'opacity-0'}">
|
||||
{/* Time Display */}
|
||||
<Card className="bg-gradient-to-br mb-[7px] from-slate-900 via-sky-800 to-cyan-800 dark:bg-slate-800 px-1 py-2 w-full hover:scale-[1.02] transition-transform duration-300">
|
||||
<Card className="bg-gradient-to-br mb-[7px] from-indigo-900 to-blue-800 backdrop-blur-sm dark:bg-slate-800 px-1 py-2 w-full hover:scale-[1.02] transition-transform duration-300">
|
||||
<CardContent className="p-3 h-[106px] flex items-center">
|
||||
<div className="flex justify-center items-baseline w-full">
|
||||
<div className={`transition-opacity duration-200 ${isTimeChanging ? 'opacity-60' : 'opacity-100'}`}>
|
||||
<span className="text-7xl font-bold text-white">{hours}</span>
|
||||
<span className="text-7xl font-bold text-white">:</span>
|
||||
<span className="text-7xl font-bold text-white">{minutes}</span>
|
||||
<span className="text-xl font-medium text-white/90 ml-1">{ampm}</span>
|
||||
<span className="text-6xl font-bold text-white">{hours}</span>
|
||||
<span className="text-6xl font-bold text-white">:</span>
|
||||
<span className="text-6xl font-bold text-white">{minutes}</span>
|
||||
<span className="text-lg font-medium text-white/90 ml-1">{ampm}</span>
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
@@ -364,10 +378,10 @@ return (
|
||||
|
||||
{/* Date and Weather Display */}
|
||||
<div className="h-[125px] mb-[6px] grid grid-cols-2 gap-2 w-full">
|
||||
<Card className="h-full bg-gradient-to-br from-slate-900 via-violet-800 to-purple-800 flex items-center justify-center">
|
||||
<Card className="h-full bg-gradient-to-br from-violet-900 to-purple-800 backdrop-blur-sm flex items-center justify-center">
|
||||
<CardContent className="h-full p-0">
|
||||
<div className="flex flex-col items-center justify-center h-full">
|
||||
<span className="text-7xl font-bold text-white">
|
||||
<span className="text-6xl font-bold text-white">
|
||||
{dateInfo.day}
|
||||
</span>
|
||||
<span className="text-sm font-bold text-white mt-2">
|
||||
@@ -385,18 +399,12 @@ return (
|
||||
weather.weather[0]?.id,
|
||||
datetime.getHours() >= 18 || datetime.getHours() < 6
|
||||
),
|
||||
"flex items-center justify-center cursor-pointer hover:brightness-110 transition-all relative"
|
||||
"flex items-center justify-center cursor-pointer hover:brightness-110 transition-all relative backdrop-blur-sm"
|
||||
)}>
|
||||
<CardContent className="h-full p-3">
|
||||
<div className="flex flex-col items-center">
|
||||
{getWeatherIcon(weather.weather[0]?.id, datetime)}
|
||||
<span className={cn(
|
||||
"text-3xl font-bold ml-1 mt-2",
|
||||
getTemperatureColor(
|
||||
weather.weather[0]?.id,
|
||||
datetime.getHours() >= 18 || datetime.getHours() < 6
|
||||
)
|
||||
)}>
|
||||
<span className="text-3xl font-bold ml-1 mt-2 text-white">
|
||||
{Math.round(weather.main.temp)}°
|
||||
</span>
|
||||
</div>
|
||||
@@ -409,7 +417,7 @@ return (
|
||||
</Card>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent
|
||||
className="w-[450px]"
|
||||
className="w-[450px] bg-gradient-to-br from-slate-800 to-slate-700 border-slate-600"
|
||||
align="start"
|
||||
side="right"
|
||||
sideOffset={10}
|
||||
@@ -419,9 +427,9 @@ return (
|
||||
}}
|
||||
>
|
||||
{weather.alerts && (
|
||||
<Alert variant="warning" className="mb-3">
|
||||
<AlertTriangle className="h-3 w-3" />
|
||||
<AlertDescription className="text-xs">
|
||||
<Alert variant="warning" className="mb-3 bg-amber-900/50 border-amber-700">
|
||||
<AlertTriangle className="h-3 w-3 text-amber-500" />
|
||||
<AlertDescription className="text-xs text-amber-200">
|
||||
{weather.alerts[0].event}
|
||||
</AlertDescription>
|
||||
</Alert>
|
||||
@@ -433,7 +441,7 @@ return (
|
||||
</div>
|
||||
|
||||
{/* Calendar Display */}
|
||||
<Card className="w-full">
|
||||
<Card className="w-full bg-white dark:bg-slate-800">
|
||||
<CardContent className="p-0">
|
||||
<CalendarComponent
|
||||
selected={datetime}
|
||||
@@ -442,7 +450,7 @@ return (
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
);
|
||||
};
|
||||
|
||||
export default DateTimeWeatherDisplay;
|
||||
Reference in New Issue
Block a user