feat: animated SVG weather icons + dynamic gradient background by weather/time
Some checks failed
Deploy / deploy (push) Failing after 2m6s
Some checks failed
Deploy / deploy (push) Failing after 2m6s
This commit is contained in:
19
app/page.tsx
19
app/page.tsx
@@ -8,6 +8,7 @@ import TopBar from '@/components/TopBar'
|
||||
import RoomTabs from '@/components/RoomTabs'
|
||||
import DeviceCard from '@/components/DeviceCard'
|
||||
import CalendarTab from '@/components/CalendarTab'
|
||||
import WeatherAnimation from '@/components/WeatherAnimation'
|
||||
|
||||
type Tab = 'home' | 'devices' | 'calendar' | 'settings'
|
||||
|
||||
@@ -91,6 +92,18 @@ function formatEventTime(iso: string): string {
|
||||
return new Date(iso).toLocaleTimeString('ru-RU', { hour: '2-digit', minute: '2-digit' })
|
||||
}
|
||||
|
||||
function getWeatherBgClass(desc: string | null): string {
|
||||
if (!desc) return ''
|
||||
const d = desc.toLowerCase()
|
||||
const hour = new Date().getHours()
|
||||
if (hour >= 22 || hour < 5) return 'weather-bg-night'
|
||||
if (d.includes('гроз')) return 'weather-bg-thunder'
|
||||
if (d.includes('снег')) return 'weather-bg-snow'
|
||||
if (d.includes('дождь') || d.includes('ливен') || d.includes('морос')) return 'weather-bg-rain'
|
||||
if (d.includes('пасмурн') || d.includes('облач') || d.includes('туман')) return 'weather-bg-cloudy'
|
||||
return 'weather-bg-clear'
|
||||
}
|
||||
|
||||
function getGreeting(): string {
|
||||
const h = new Date().getHours()
|
||||
if (h >= 5 && h < 12) return 'Доброе утро'
|
||||
@@ -161,7 +174,7 @@ function Screensaver({ weather, onDismiss }: { weather: WeatherData | null; onDi
|
||||
display: 'flex', alignItems: 'center', gap: 12,
|
||||
marginTop: 16, color: 'rgba(255,255,255,0.3)',
|
||||
}}>
|
||||
<span style={{ fontSize: 28 }}>{getWeatherIcon(weather.desc)}</span>
|
||||
<WeatherAnimation condition={weather.desc} size={36} />
|
||||
<span style={{ fontSize: 24, fontWeight: 600 }}>{weather.temp}°</span>
|
||||
<span style={{ fontSize: 16 }}>{weather.desc}</span>
|
||||
</div>
|
||||
@@ -313,7 +326,7 @@ function HomeTab({ weather, sensors }: { weather: WeatherData | null; sensors: S
|
||||
<div style={{ position: 'absolute', top: -20, right: -10, fontSize: 80, opacity: 0.12, pointerEvents: 'none' }}>{getWeatherIcon(weather.desc)}</div>
|
||||
<div style={{ fontSize: 11, color: 'var(--text-secondary)', textTransform: 'uppercase', letterSpacing: '0.1em', fontWeight: 600, marginBottom: 16 }}>Погода</div>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: 16, marginBottom: 18, position: 'relative', zIndex: 1 }}>
|
||||
<span style={{ fontSize: 44 }}>{getWeatherIcon(weather.desc)}</span>
|
||||
<WeatherAnimation condition={weather.desc} size={56} />
|
||||
<div>
|
||||
<div style={{ fontSize: 36, fontWeight: 800, color: 'var(--text-primary)', lineHeight: 1, letterSpacing: '-2px' }}>{weather.temp}°</div>
|
||||
<div style={{ fontSize: 14, color: 'var(--text-secondary)', marginTop: 4, fontWeight: 500 }}>{weather.desc}</div>
|
||||
@@ -678,7 +691,7 @@ function HomePageInner() {
|
||||
}
|
||||
|
||||
return (
|
||||
<div style={{ display: 'flex', height: '100dvh', width: '100%', background: 'var(--bg)', overflow: 'hidden', position: 'relative' }}>
|
||||
<div className={getWeatherBgClass(weather?.desc || null)} style={{ display: 'flex', height: '100dvh', width: '100%', background: 'var(--bg)', overflow: 'hidden', position: 'relative' }}>
|
||||
<div className="bg-ambient" />
|
||||
|
||||
<AnimatePresence>
|
||||
|
||||
Reference in New Issue
Block a user