diff --git a/src/App.css b/src/App.css index 4faacb1..4874604 100644 --- a/src/App.css +++ b/src/App.css @@ -129,6 +129,106 @@ body { color: var(--color-cyan); } +/* Navbar */ +.navbar { + display: flex; + align-items: center; + justify-content: space-between; + padding: 8px 16px; + background: var(--bg-card); + border: 1px solid var(--border-color); + border-radius: 12px; + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.4); +} + +.navbar-brand { + display: flex; + align-items: center; + gap: 10px; +} + +.navbar-logo { + font-size: 20px; + color: var(--color-cyan); + text-shadow: var(--glow-cyan); +} + +.navbar-title { + font-size: 16px; + font-weight: 700; + color: var(--color-text); + letter-spacing: 1px; +} + +.navbar-nav { + display: flex; + list-style: none; + gap: 4px; +} + +.nav-item { + display: flex; + align-items: center; + gap: 6px; + padding: 8px 14px; + background: transparent; + border: 1px solid transparent; + border-radius: 8px; + color: var(--color-text-dim); + font-family: var(--font-mono); + font-size: 12px; + cursor: pointer; + transition: all 0.2s ease; +} + +.nav-item:hover { + background: var(--bg-tertiary); + color: var(--color-text); + border-color: var(--border-color); +} + +.nav-item.active { + background: var(--bg-tertiary); + color: var(--color-cyan); + border-color: var(--color-cyan); + box-shadow: 0 0 10px rgba(34, 211, 238, 0.2); +} + +.nav-icon { + font-size: 14px; +} + +.nav-label { + font-weight: 500; +} + +.navbar-actions { + display: flex; + gap: 8px; +} + +.nav-action { + display: flex; + align-items: center; + justify-content: center; + width: 32px; + height: 32px; + background: transparent; + border: 1px solid var(--border-color); + border-radius: 8px; + color: var(--color-text-dim); + font-family: var(--font-mono); + font-size: 14px; + cursor: pointer; + transition: all 0.2s ease; +} + +.nav-action:hover { + background: var(--bg-tertiary); + color: var(--color-text); + border-color: var(--color-cyan); +} + /* Header */ .header { display: flex; @@ -470,6 +570,41 @@ body { gap: 10px; } +.pause-button { + background: rgba(0, 0, 0, 0.4); + border: 1px solid var(--border-color); + border-radius: 6px; + color: var(--color-text); + font-size: 12px; + padding: 4px 8px; + cursor: pointer; + transition: border-color 0.2s, box-shadow 0.2s, color 0.2s; +} + +.pause-button:hover { + border-color: var(--color-cyan); + box-shadow: 0 0 10px rgba(34, 211, 238, 0.2); +} + +.pause-button.paused { + color: var(--color-yellow); + border-color: var(--color-yellow); + box-shadow: 0 0 10px rgba(251, 191, 36, 0.3); +} + +.paused-indicator { + color: var(--color-yellow); + font-weight: bold; + font-size: 11px; + letter-spacing: 2px; + animation: blink 1s ease-in-out infinite; +} + +@keyframes blink { + 0%, 100% { opacity: 1; } + 50% { opacity: 0.4; } +} + .filter-label, .refresh-label { color: var(--color-text-dim); diff --git a/src/App.tsx b/src/App.tsx index 60c8dc0..c72e5f3 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,4 +1,5 @@ -import { useState } from 'react'; +import { useState, useEffect, useCallback } from 'react'; +import { Navbar } from './components/Navbar'; import { Header } from './components/Header'; import { CpuGraph } from './components/CpuGraph'; import { MemoryGraph } from './components/MemoryGraph'; @@ -11,7 +12,20 @@ import './App.css'; function App() { const [filter, setFilter] = useState(''); const [refreshRate, setRefreshRate] = useState(1000); - const { metrics, error, loading } = useSystemMetrics(refreshRate); + const [paused, setPaused] = useState(false); + const { metrics, error, loading } = useSystemMetrics(paused ? 0 : refreshRate); + + const handleKeyDown = useCallback((e: KeyboardEvent) => { + if (e.target instanceof HTMLInputElement || e.target instanceof HTMLSelectElement) return; + if (e.key === 'p' || e.key === 'P') { + setPaused(prev => !prev); + } + }, []); + + useEffect(() => { + window.addEventListener('keydown', handleKeyDown); + return () => window.removeEventListener('keydown', handleKeyDown); + }, [handleKeyDown]); if (loading && !metrics) { return ( @@ -43,6 +57,7 @@ function App() { return (