Style date time weather to fit in better

This commit is contained in:
2025-01-04 00:37:29 -05:00
parent a2eb5bfcd7
commit 194ac96732

View File

@@ -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,44 +306,54 @@ 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>
)}
@@ -349,14 +363,14 @@ const DateTimeWeatherDisplay = ({ scaleFactor = 1 }) => {
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}