diff --git a/app/page.tsx b/app/page.tsx index 07d0e3a..cb17012 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -15,6 +15,7 @@ import VoiceOverlay from '@/components/VoiceOverlay' import VoiceController from '@/components/VoiceController' import TimerWidget from '@/components/TimerWidget' import TimerHomeWidget from '@/components/TimerHomeWidget' +import SpotifyWidget from '@/components/SpotifyWidget' type Tab = 'home' | 'devices' | 'calendar' | 'notes' | 'settings' @@ -712,6 +713,9 @@ function HomeTab({ weather, sensors }: { weather: WeatherData | null; sensors: S + {/* ───── Spotify ───── */} + + {/* Weather day detail modal */} {selectedDay && ( (null) + const [loading, setLoading] = useState(true) + const [actionLoading, setActionLoading] = useState(false) + + const fetchState = useCallback(async () => { + try { + const r = await fetch('/api/voice/tools/spotify', { + headers: { + 'x-voice-internal': process.env.NEXT_PUBLIC_VOICE_API_KEY || '', + }, + }) + if (r.ok) { + const d = await r.json() + setState(d) + } + } catch {} + finally { setLoading(false) } + }, []) + + useEffect(() => { + fetchState() + const t = setInterval(fetchState, 15_000) + return () => clearInterval(t) + }, [fetchState]) + + const control = async (action: string) => { + setActionLoading(true) + try { + await fetch('/api/voice/tools/spotify', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'x-voice-internal': process.env.NEXT_PUBLIC_VOICE_API_KEY || '', + }, + body: JSON.stringify({ action }), + }) + setTimeout(fetchState, 500) + } catch {} + finally { setActionLoading(false) } + } + + const btnStyle = (active?: boolean): React.CSSProperties => ({ + width: 40, height: 40, borderRadius: 12, + display: 'flex', alignItems: 'center', justifyContent: 'center', + background: active ? 'rgba(30,215,96,0.15)' : 'rgba(255,255,255,0.04)', + border: `1px solid ${active ? 'rgba(30,215,96,0.3)' : 'rgba(255,255,255,0.07)'}`, + color: active ? '#1ED760' : 'var(--text-secondary)', + transition: 'all 0.2s ease', + cursor: actionLoading ? 'not-allowed' : 'pointer', + opacity: actionLoading ? 0.6 : 1, + }) + + return ( +
+ {/* Header */} +
+
+ +
+ Spotify + {state?.device && ( + + {state.device} + + )} +
+ + {/* Track info */} + {loading ? ( +
Загрузка...
+ ) : !state?.track ? ( +
Ничего не играет
+ ) : ( +
+
{state.track}
+
{state.artist}
+
+ )} + + {/* Controls */} +
+ + + +
+
+ ) +}