feat: event editing, light/dark theme, device animations, 7-day forecast
Some checks failed
Deploy / deploy (push) Has been cancelled
Some checks failed
Deploy / deploy (push) Has been cancelled
This commit is contained in:
45
app/page.tsx
45
app/page.tsx
@@ -391,7 +391,7 @@ function HomeTab({ weather, sensors }: { weather: WeatherData | null; sensors: S
|
||||
}
|
||||
|
||||
// ————— Settings Tab —————
|
||||
function SettingsTab({ city, onCityChange, onLogout }: { city: string; onCityChange: (id: string) => void; onLogout: () => void }) {
|
||||
function SettingsTab({ city, onCityChange, onLogout, theme, onThemeChange }: { city: string; onCityChange: (id: string) => void; onLogout: () => void; theme: string; onThemeChange: (t: string) => void }) {
|
||||
const [showPinChange, setShowPinChange] = useState(false)
|
||||
const [oldPin, setOldPin] = useState('')
|
||||
const [newPin, setNewPin] = useState('')
|
||||
@@ -431,7 +431,7 @@ function SettingsTab({ city, onCityChange, onLogout }: { city: string; onCityCha
|
||||
<h2 style={{ fontSize: 24, fontWeight: 800, color: 'var(--text-primary)', margin: '0 0 8px', letterSpacing: '-0.5px' }}>Настройки</h2>
|
||||
|
||||
{/* City selector */}
|
||||
<div style={{ background: 'rgba(255,255,255,0.03)', border: '1px solid rgba(255,255,255,0.06)', borderRadius: 22, padding: '22px 24px' }}>
|
||||
<div style={{ background: 'var(--card-bg)', border: '1px solid var(--card-border)', borderRadius: 22, padding: '22px 24px' }}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 16 }}>
|
||||
<MapPin size={18} color="#818cf8" />
|
||||
<span style={{ fontSize: 15, fontWeight: 600, color: 'var(--text-primary)' }}>Город</span>
|
||||
@@ -457,8 +457,35 @@ function SettingsTab({ city, onCityChange, onLogout }: { city: string; onCityCha
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Theme */}
|
||||
<div style={{ background: 'var(--card-bg)', border: '1px solid var(--card-border)', borderRadius: 22, padding: '22px 24px' }}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
|
||||
<span style={{ fontSize: 18 }}>{theme === 'dark' ? '🌙' : '☀️'}</span>
|
||||
<span style={{ fontSize: 15, fontWeight: 600, color: 'var(--text-primary)' }}>Тема</span>
|
||||
</div>
|
||||
<div style={{ display: 'flex', gap: 6 }}>
|
||||
{[
|
||||
{ id: 'dark', label: 'Тёмная' },
|
||||
{ id: 'light', label: 'Светлая' },
|
||||
].map(t => (
|
||||
<button key={t.id} onClick={() => onThemeChange(t.id)} style={{
|
||||
padding: '8px 16px', borderRadius: 12,
|
||||
background: theme === t.id ? 'rgba(99,102,241,0.12)' : 'rgba(255,255,255,0.02)',
|
||||
border: theme === t.id ? '1px solid rgba(129,140,248,0.25)' : '1px solid var(--card-border)',
|
||||
color: theme === t.id ? '#a5b4fc' : 'var(--text-secondary)',
|
||||
fontSize: 13, fontWeight: theme === t.id ? 600 : 500,
|
||||
transition: 'all 0.25s ease',
|
||||
}}>
|
||||
{t.label}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* PIN change */}
|
||||
<div style={{ background: 'rgba(255,255,255,0.03)', border: '1px solid rgba(255,255,255,0.06)', borderRadius: 22, padding: '22px 24px' }}>
|
||||
<div style={{ background: 'var(--card-bg)', border: '1px solid var(--card-border)', borderRadius: 22, padding: '22px 24px' }}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
|
||||
<KeyRound size={18} color="#818cf8" />
|
||||
@@ -551,8 +578,18 @@ function HomePageInner() {
|
||||
return 'spb'
|
||||
})
|
||||
const [screensaverActive, setScreensaverActive] = useState(false)
|
||||
const [theme, setTheme] = useState(() => {
|
||||
if (typeof window !== 'undefined') return localStorage.getItem('tablet-theme') || 'dark'
|
||||
return 'dark'
|
||||
})
|
||||
const idleTimer = useRef<ReturnType<typeof setTimeout> | null>(null)
|
||||
|
||||
// Theme
|
||||
useEffect(() => {
|
||||
document.documentElement.className = theme
|
||||
localStorage.setItem('tablet-theme', theme)
|
||||
}, [theme])
|
||||
|
||||
// Auth check
|
||||
useEffect(() => {
|
||||
fetch('/api/auth')
|
||||
@@ -690,7 +727,7 @@ function HomePageInner() {
|
||||
|
||||
{tab === 'settings' && (
|
||||
<motion.div key="settings" variants={tabVariants} initial="enter" animate="center" exit="exit" transition={{ duration: 0.2 }} style={{ flex: 1, display: 'flex', flexDirection: 'column', overflow: 'hidden' }}>
|
||||
<SettingsTab city={city} onCityChange={handleCityChange} onLogout={handleLogout} />
|
||||
<SettingsTab city={city} onCityChange={handleCityChange} onLogout={handleLogout} theme={theme} onThemeChange={setTheme} />
|
||||
</motion.div>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
|
||||
Reference in New Issue
Block a user