Update index.html

pull/1/head
accius 6 days ago
parent 6281a1c81e
commit 7a36dae9e2

@ -1162,7 +1162,7 @@
}, [potaSpots]); }, [potaSpots]);
return ( return (
<div style={{ position: 'relative', height: '100%', minHeight: '350px' }}> <div style={{ position: 'relative', height: '100%', minHeight: '200px' }}>
<div ref={mapRef} style={{ height: '100%', width: '100%', borderRadius: '8px' }} /> <div ref={mapRef} style={{ height: '100%', width: '100%', borderRadius: '8px' }} />
{/* Map style selector */} {/* Map style selector */}
@ -2147,40 +2147,207 @@
); );
} }
// Modern Layout (default) // Modern Layout (default) - Compact single-screen design
return ( return (
<div style={{ minHeight: '100vh', background: 'var(--bg-primary)' }}> <div style={{
<Header callsign={config.callsign} uptime={uptime} version="3.3.0" onSettingsClick={() => setShowSettings(true)} /> height: '100vh',
background: 'var(--bg-primary)',
display: 'grid',
gridTemplateColumns: '280px 1fr 280px',
gridTemplateRows: '50px 1fr',
gap: '8px',
padding: '8px',
overflow: 'hidden'
}}>
{/* TOP BAR - spans full width */}
<div style={{
gridColumn: '1 / -1',
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
background: 'var(--bg-panel)',
border: '1px solid var(--border-color)',
borderRadius: '6px',
padding: '0 16px',
fontFamily: 'JetBrains Mono, monospace'
}}>
{/* Callsign & Settings */}
<div style={{ display: 'flex', alignItems: 'center', gap: '16px' }}>
<span
style={{ fontSize: '20px', fontWeight: '900', color: 'var(--accent-amber)', cursor: 'pointer', fontFamily: 'Orbitron, monospace' }}
onClick={() => setShowSettings(true)}
title="Click for settings"
>
{config.callsign}
</span>
<span style={{ fontSize: '10px', color: 'var(--text-muted)' }}>v3.3.0</span>
</div>
{/* UTC Clock */}
<div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
<span style={{ fontSize: '10px', color: 'var(--accent-cyan)' }}>UTC</span>
<span style={{ fontSize: '22px', fontWeight: '700', color: 'var(--accent-cyan)', fontFamily: 'Orbitron, monospace' }}>{utcTime}</span>
<span style={{ fontSize: '10px', color: 'var(--text-muted)' }}>{utcDate}</span>
</div>
{/* Local Clock */}
<div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
<span style={{ fontSize: '10px', color: 'var(--accent-amber)' }}>LOCAL</span>
<span style={{ fontSize: '22px', fontWeight: '700', color: 'var(--accent-amber)', fontFamily: 'Orbitron, monospace' }}>{localTime}</span>
<span style={{ fontSize: '10px', color: 'var(--text-muted)' }}>{localDate}</span>
</div>
{/* Solar Quick Stats */}
<div style={{ display: 'flex', gap: '16px', fontSize: '11px' }}>
<div><span style={{ color: 'var(--text-muted)' }}>SFI </span><span style={{ color: 'var(--accent-amber)', fontWeight: '600' }}>{spaceWeather.data?.solarFlux || '--'}</span></div>
<div><span style={{ color: 'var(--text-muted)' }}>K </span><span style={{ color: spaceWeather.data?.kIndex >= 4 ? 'var(--accent-red)' : 'var(--accent-green)', fontWeight: '600' }}>{spaceWeather.data?.kIndex ?? '--'}</span></div>
<div><span style={{ color: 'var(--text-muted)' }}>SSN </span><span style={{ color: 'var(--accent-cyan)', fontWeight: '600' }}>{spaceWeather.data?.sunspotNumber || '--'}</span></div>
</div>
{/* Settings Button */}
<button
onClick={() => setShowSettings(true)}
style={{ background: 'var(--bg-tertiary)', border: '1px solid var(--border-color)', padding: '6px 12px', borderRadius: '4px', color: 'var(--text-secondary)', fontSize: '11px', cursor: 'pointer' }}
>
⚙ Settings
</button>
</div>
<main style={{ padding: '20px', display: 'grid', gridTemplateColumns: '1fr 1fr 1fr 1fr', gridTemplateRows: 'auto 1fr auto', gap: '16px', maxWidth: '1920px', margin: '0 auto', minHeight: 'calc(100vh - 120px)' }}> {/* LEFT SIDEBAR */}
{/* Row 1 */} <div style={{ display: 'flex', flexDirection: 'column', gap: '8px', overflow: 'hidden' }}>
<ClockPanel label="UTC Time" time={utcTime} date={utcDate} isUtc={true} /> {/* DE Location */}
<ClockPanel label="Local Time" time={localTime} date={localDate} isUtc={false} /> <div className="panel" style={{ padding: '10px', flex: '0 0 auto' }}>
<LocationPanel type="DE" location={config.location} gridSquare={deGrid} sunTimes={deSunTimes} otherLocation={dxLocation} /> <div style={{ fontSize: '10px', color: 'var(--accent-cyan)', fontWeight: '700', marginBottom: '6px' }}>📍 DE - YOUR LOCATION</div>
<LocationPanel type="DX" location={dxLocation} gridSquare={dxGrid} sunTimes={dxSunTimes} otherLocation={config.location} /> <div style={{ fontFamily: 'JetBrains Mono', fontSize: '11px' }}>
<div style={{ color: 'var(--accent-amber)', fontSize: '14px', fontWeight: '700' }}>{deGrid}</div>
<div style={{ color: 'var(--text-muted)', fontSize: '10px' }}>{config.location.lat.toFixed(2)}°, {config.location.lon.toFixed(2)}°</div>
<div style={{ marginTop: '4px', fontSize: '10px' }}>
<span style={{ color: 'var(--text-muted)' }}></span>
<span style={{ color: 'var(--accent-amber)' }}>{deSunTimes.sunrise}</span>
<span style={{ color: 'var(--text-muted)' }}></span>
<span style={{ color: 'var(--accent-purple)' }}>{deSunTimes.sunset}</span>
</div>
</div>
</div>
{/* Row 2: Map + Side Panel */} {/* DX Location */}
<div style={{ gridColumn: 'span 3', minHeight: '400px' }}> <div className="panel" style={{ padding: '10px', flex: '0 0 auto' }}>
<WorldMap deLocation={config.location} dxLocation={dxLocation} onDXChange={handleDXChange} potaSpots={potaSpots.data} /> <div style={{ fontSize: '10px', color: 'var(--accent-green)', fontWeight: '700', marginBottom: '6px' }}>🎯 DX - TARGET</div>
<div style={{ fontSize: '10px', color: 'var(--text-muted)', marginTop: '8px', fontFamily: 'JetBrains Mono', textAlign: 'center' }}> <div style={{ fontFamily: 'JetBrains Mono', fontSize: '11px' }}>
Click anywhere on map to set DX location • Use buttons to change map style <div style={{ color: 'var(--accent-amber)', fontSize: '14px', fontWeight: '700' }}>{dxGrid}</div>
<div style={{ color: 'var(--text-muted)', fontSize: '10px' }}>{dxLocation.lat.toFixed(2)}°, {dxLocation.lon.toFixed(2)}°</div>
<div style={{ marginTop: '4px', fontSize: '10px' }}>
<span style={{ color: 'var(--text-muted)' }}></span>
<span style={{ color: 'var(--accent-amber)' }}>{dxSunTimes.sunrise}</span>
<span style={{ color: 'var(--text-muted)' }}></span>
<span style={{ color: 'var(--accent-purple)' }}>{dxSunTimes.sunset}</span>
</div>
</div> </div>
</div> </div>
<div style={{ display: 'flex', flexDirection: 'column', gap: '16px' }}>
<SpaceWeatherPanel data={spaceWeather.data} loading={spaceWeather.loading} /> {/* Band Conditions - Compact */}
<ContestPanel contests={contests.data} loading={contests.loading} /> <div className="panel" style={{ padding: '10px', flex: '1 1 auto', overflow: 'hidden', minHeight: 0 }}>
<div style={{ fontSize: '10px', color: 'var(--accent-purple)', fontWeight: '700', marginBottom: '6px' }}>📊 BAND CONDITIONS</div>
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: '4px', fontSize: '10px', fontFamily: 'JetBrains Mono' }}>
{bandConditions.data.map(band => (
<div key={band.band} style={{
textAlign: 'center',
padding: '4px 2px',
background: 'var(--bg-tertiary)',
borderRadius: '3px'
}}>
<div style={{ fontWeight: '600', color: band.status === 'GOOD' ? 'var(--accent-green)' : band.status === 'FAIR' ? 'var(--accent-amber)' : 'var(--text-muted)' }}>{band.band}</div>
<div style={{ fontSize: '8px', color: 'var(--text-muted)' }}>{band.status?.substring(0,4)}</div>
</div>
))}
</div>
</div> </div>
{/* Row 3 */} {/* Propagation Compact */}
<BandConditionsPanel bands={bandConditions.data} loading={bandConditions.loading} /> <div className="panel" style={{ padding: '10px', flex: '1 1 auto', overflow: 'hidden', minHeight: 0 }}>
<DXClusterPanel spots={dxCluster.data} loading={dxCluster.loading} /> <div style={{ fontSize: '10px', color: 'var(--accent-cyan)', fontWeight: '700', marginBottom: '6px' }}>📡 PROPAGATION TO DX</div>
<POTAPanel activities={potaSpots.data} loading={potaSpots.loading} /> {propagation.data ? (
<PropagationPanel propagation={propagation.data} loading={propagation.loading} /> <div style={{ fontSize: '10px', fontFamily: 'JetBrains Mono' }}>
</main> <div style={{ marginBottom: '6px', color: 'var(--text-muted)', fontSize: '9px' }}>
{Math.round(propagation.data.distance).toLocaleString()} km path
<footer style={{ textAlign: 'center', padding: '20px', color: 'var(--text-muted)', fontSize: '11px', fontFamily: 'JetBrains Mono, monospace' }}> </div>
OpenHamClock v3.3.0 | In memory of Elwood Downey WB0OEW | Map tiles © OpenStreetMap, ESRI, CARTO | 73 de {config.callsign} {propagation.data.currentBands.slice(0, 6).map(b => (
</footer> <div key={b.band} style={{ display: 'flex', alignItems: 'center', gap: '6px', marginBottom: '3px' }}>
<span style={{ width: '32px', color: b.reliability >= 50 ? 'var(--accent-green)' : 'var(--text-muted)' }}>{b.band}</span>
<div style={{ flex: 1, height: '8px', background: 'var(--bg-tertiary)', borderRadius: '2px', overflow: 'hidden' }}>
<div style={{ width: `${b.reliability}%`, height: '100%', background: b.reliability >= 70 ? '#00ff88' : b.reliability >= 50 ? '#88ff00' : b.reliability >= 30 ? '#ffcc00' : '#ff4444', borderRadius: '2px' }} />
</div>
<span style={{ width: '28px', fontSize: '9px', color: b.reliability >= 50 ? 'var(--accent-green)' : 'var(--text-muted)' }}>{b.reliability}%</span>
</div>
))}
</div>
) : (
<div style={{ color: 'var(--text-muted)', fontSize: '10px' }}>Loading...</div>
)}
</div>
</div>
{/* CENTER - MAP */}
<div style={{ position: 'relative', borderRadius: '6px', overflow: 'hidden' }}>
<WorldMap deLocation={config.location} dxLocation={dxLocation} onDXChange={handleDXChange} potaSpots={potaSpots.data} />
<div style={{ position: 'absolute', bottom: '8px', left: '50%', transform: 'translateX(-50%)', fontSize: '9px', color: 'var(--text-muted)', background: 'rgba(0,0,0,0.7)', padding: '2px 8px', borderRadius: '4px' }}>
Click map to set DX • 73 de {config.callsign}
</div>
</div>
{/* RIGHT SIDEBAR */}
<div style={{ display: 'flex', flexDirection: 'column', gap: '8px', overflow: 'hidden' }}>
{/* DX Cluster - Compact */}
<div className="panel" style={{ padding: '10px', flex: '1 1 auto', overflow: 'hidden', minHeight: 0 }}>
<div style={{ fontSize: '10px', color: 'var(--accent-green)', fontWeight: '700', marginBottom: '6px' }}>
🌐 DX CLUSTER <span style={{ color: 'var(--accent-green)', fontSize: '8px' }}>● LIVE</span>
</div>
<div style={{ overflow: 'auto', maxHeight: 'calc(100% - 20px)' }}>
{dxCluster.data.slice(0, 8).map((s, i) => (
<div key={i} style={{ padding: '3px 0', borderBottom: '1px solid rgba(255,255,255,0.05)', fontSize: '10px', fontFamily: 'JetBrains Mono' }}>
<div style={{ display: 'flex', justifyContent: 'space-between' }}>
<span style={{ color: 'var(--accent-cyan)' }}>{s.freq}</span>
<span style={{ color: 'var(--accent-amber)', fontWeight: '600' }}>{s.call}</span>
<span style={{ color: 'var(--text-muted)', fontSize: '9px' }}>{s.time}</span>
</div>
</div>
))}
{dxCluster.data.length === 0 && <div style={{ color: 'var(--text-muted)', fontSize: '10px' }}>No spots</div>}
</div>
</div>
{/* POTA - Compact */}
<div className="panel" style={{ padding: '10px', flex: '0 0 auto' }}>
<div style={{ fontSize: '10px', color: 'var(--accent-amber)', fontWeight: '700', marginBottom: '6px' }}>🏕 POTA ACTIVATORS</div>
<div style={{ fontSize: '10px', fontFamily: 'JetBrains Mono' }}>
{potaSpots.data.slice(0, 5).map((a, i) => (
<div key={i} style={{ padding: '2px 0', display: 'flex', justifyContent: 'space-between' }}>
<span style={{ color: 'var(--accent-amber)' }}>{a.call}</span>
<span style={{ color: 'var(--accent-purple)' }}>{a.ref}</span>
<span style={{ color: 'var(--accent-green)' }}>{a.freq}</span>
</div>
))}
{potaSpots.data.length === 0 && <div style={{ color: 'var(--text-muted)' }}>No activators</div>}
</div>
</div>
{/* Contests - Compact */}
<div className="panel" style={{ padding: '10px', flex: '1 1 auto', overflow: 'hidden', minHeight: 0 }}>
<div style={{ fontSize: '10px', color: 'var(--accent-purple)', fontWeight: '700', marginBottom: '6px' }}>🏆 CONTESTS</div>
<div style={{ overflow: 'auto', maxHeight: 'calc(100% - 20px)', fontSize: '10px', fontFamily: 'JetBrains Mono' }}>
{contests.data.slice(0, 6).map((c, i) => (
<div key={i} style={{ padding: '3px 0', borderBottom: '1px solid rgba(255,255,255,0.05)' }}>
<div style={{ color: c.status === 'active' ? 'var(--accent-green)' : 'var(--text-secondary)', fontWeight: c.status === 'active' ? '700' : '400' }}>
{c.name} {c.status === 'active' && <span style={{ animation: 'blink 1s infinite' }}></span>}
</div>
<div style={{ color: 'var(--text-muted)', fontSize: '9px' }}>
{c.mode} • {new Date(c.start).toLocaleDateString('en-US', { month: 'short', day: 'numeric' })}
</div>
</div>
))}
</div>
</div>
</div>
{/* Settings Panel */} {/* Settings Panel */}
<SettingsPanel <SettingsPanel

Loading…
Cancel
Save

Powered by TurnKey Linux.