|
|
|
@ -1102,10 +1102,10 @@
|
|
|
|
const bands = ['80m', '40m', '30m', '20m', '17m', '15m', '12m', '10m'];
|
|
|
|
const bands = ['80m', '40m', '30m', '20m', '17m', '15m', '12m', '10m'];
|
|
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
return (
|
|
|
|
<div className="panel" style={{ cursor: 'pointer', padding: '6px' }} onClick={() => setViewMode(v => v === 'bars' ? 'chart' : 'bars')}>
|
|
|
|
<div className="panel" style={{ cursor: 'pointer' }} onClick={() => setViewMode(v => v === 'bars' ? 'chart' : 'bars')}>
|
|
|
|
<div className="panel-header" style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '4px', fontSize: '11px' }}>
|
|
|
|
<div className="panel-header" style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
|
|
|
|
<span>📡 VOACAP DE-DX</span>
|
|
|
|
<span>📡 VOACAP DE-DX</span>
|
|
|
|
<span style={{ fontSize: '9px', color: 'var(--text-muted)' }}>
|
|
|
|
<span style={{ fontSize: '11px', color: 'var(--text-muted)' }}>
|
|
|
|
{viewMode === 'bars' ? '▦ bars' : '▤ chart'} • click to toggle
|
|
|
|
{viewMode === 'bars' ? '▦ bars' : '▤ chart'} • click to toggle
|
|
|
|
</span>
|
|
|
|
</span>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
@ -1194,16 +1194,16 @@
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
) : (
|
|
|
|
) : (
|
|
|
|
/* Bar Chart View */
|
|
|
|
/* Bar Chart View */
|
|
|
|
<div style={{ fontSize: '11px' }}>
|
|
|
|
<div style={{ fontSize: '13px' }}>
|
|
|
|
{/* Solar quick stats */}
|
|
|
|
{/* Solar quick stats */}
|
|
|
|
<div style={{
|
|
|
|
<div style={{
|
|
|
|
display: 'flex',
|
|
|
|
display: 'flex',
|
|
|
|
justifyContent: 'space-around',
|
|
|
|
justifyContent: 'space-around',
|
|
|
|
padding: '2px',
|
|
|
|
padding: '4px',
|
|
|
|
marginBottom: '3px',
|
|
|
|
marginBottom: '4px',
|
|
|
|
background: 'var(--bg-tertiary)',
|
|
|
|
background: 'var(--bg-tertiary)',
|
|
|
|
borderRadius: '3px',
|
|
|
|
borderRadius: '4px',
|
|
|
|
fontSize: '10px'
|
|
|
|
fontSize: '12px'
|
|
|
|
}}>
|
|
|
|
}}>
|
|
|
|
<span><span style={{ color: 'var(--text-muted)' }}>SFI </span><span style={{ color: 'var(--accent-amber)' }}>{solarData.sfi}</span></span>
|
|
|
|
<span><span style={{ color: 'var(--text-muted)' }}>SFI </span><span style={{ color: 'var(--accent-amber)' }}>{solarData.sfi}</span></span>
|
|
|
|
<span><span style={{ color: 'var(--text-muted)' }}>SSN </span><span style={{ color: 'var(--accent-cyan)' }}>{solarData.ssn}</span></span>
|
|
|
|
<span><span style={{ color: 'var(--text-muted)' }}>SSN </span><span style={{ color: 'var(--accent-cyan)' }}>{solarData.ssn}</span></span>
|
|
|
|
@ -1213,19 +1213,19 @@
|
|
|
|
{currentBands.slice(0, 8).map((band, idx) => (
|
|
|
|
{currentBands.slice(0, 8).map((band, idx) => (
|
|
|
|
<div key={band.band} style={{
|
|
|
|
<div key={band.band} style={{
|
|
|
|
display: 'grid',
|
|
|
|
display: 'grid',
|
|
|
|
gridTemplateColumns: '28px 1fr 32px',
|
|
|
|
gridTemplateColumns: '32px 1fr 40px',
|
|
|
|
gap: '3px',
|
|
|
|
gap: '4px',
|
|
|
|
padding: '1px 0',
|
|
|
|
padding: '2px 0',
|
|
|
|
alignItems: 'center'
|
|
|
|
alignItems: 'center'
|
|
|
|
}}>
|
|
|
|
}}>
|
|
|
|
<span style={{
|
|
|
|
<span style={{
|
|
|
|
fontFamily: 'JetBrains Mono, monospace',
|
|
|
|
fontFamily: 'JetBrains Mono, monospace',
|
|
|
|
fontSize: '10px',
|
|
|
|
fontSize: '12px',
|
|
|
|
color: band.reliability >= 50 ? 'var(--accent-green)' : 'var(--text-muted)'
|
|
|
|
color: band.reliability >= 50 ? 'var(--accent-green)' : 'var(--text-muted)'
|
|
|
|
}}>
|
|
|
|
}}>
|
|
|
|
{band.band}
|
|
|
|
{band.band}
|
|
|
|
</span>
|
|
|
|
</span>
|
|
|
|
<div style={{ position: 'relative', height: '8px', background: 'var(--bg-tertiary)', borderRadius: '2px' }}>
|
|
|
|
<div style={{ position: 'relative', height: '10px', background: 'var(--bg-tertiary)', borderRadius: '2px' }}>
|
|
|
|
<div style={{
|
|
|
|
<div style={{
|
|
|
|
position: 'absolute',
|
|
|
|
position: 'absolute',
|
|
|
|
top: 0,
|
|
|
|
top: 0,
|
|
|
|
@ -1238,7 +1238,7 @@
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<span style={{
|
|
|
|
<span style={{
|
|
|
|
textAlign: 'right',
|
|
|
|
textAlign: 'right',
|
|
|
|
fontSize: '10px',
|
|
|
|
fontSize: '12px',
|
|
|
|
color: getStatusColor(band.status)
|
|
|
|
color: getStatusColor(band.status)
|
|
|
|
}}>
|
|
|
|
}}>
|
|
|
|
{band.reliability}%
|
|
|
|
{band.reliability}%
|
|
|
|
@ -1271,14 +1271,14 @@
|
|
|
|
const imageUrl = `https://sdo.gsfc.nasa.gov/assets/img/latest/latest_256_${imageType}.jpg?t=${timestamp}`;
|
|
|
|
const imageUrl = `https://sdo.gsfc.nasa.gov/assets/img/latest/latest_256_${imageType}.jpg?t=${timestamp}`;
|
|
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
return (
|
|
|
|
<div className="panel" style={{ padding: '6px' }}>
|
|
|
|
<div className="panel" style={{ padding: '8px' }}>
|
|
|
|
<div style={{
|
|
|
|
<div style={{
|
|
|
|
display: 'flex',
|
|
|
|
display: 'flex',
|
|
|
|
justifyContent: 'space-between',
|
|
|
|
justifyContent: 'space-between',
|
|
|
|
alignItems: 'center',
|
|
|
|
alignItems: 'center',
|
|
|
|
marginBottom: '4px'
|
|
|
|
marginBottom: '6px'
|
|
|
|
}}>
|
|
|
|
}}>
|
|
|
|
<span style={{ fontSize: '11px', color: 'var(--accent-amber)', fontWeight: '700' }}>☀ SOLAR</span>
|
|
|
|
<span style={{ fontSize: '12px', color: 'var(--accent-amber)', fontWeight: '700' }}>☀ SOLAR</span>
|
|
|
|
<select
|
|
|
|
<select
|
|
|
|
value={imageType}
|
|
|
|
value={imageType}
|
|
|
|
onChange={(e) => setImageType(e.target.value)}
|
|
|
|
onChange={(e) => setImageType(e.target.value)}
|
|
|
|
@ -1287,8 +1287,8 @@
|
|
|
|
background: 'var(--bg-tertiary)',
|
|
|
|
background: 'var(--bg-tertiary)',
|
|
|
|
border: '1px solid var(--border-color)',
|
|
|
|
border: '1px solid var(--border-color)',
|
|
|
|
color: 'var(--text-secondary)',
|
|
|
|
color: 'var(--text-secondary)',
|
|
|
|
fontSize: '10px',
|
|
|
|
fontSize: '11px',
|
|
|
|
padding: '1px 3px',
|
|
|
|
padding: '2px 4px',
|
|
|
|
borderRadius: '3px',
|
|
|
|
borderRadius: '3px',
|
|
|
|
cursor: 'pointer'
|
|
|
|
cursor: 'pointer'
|
|
|
|
}}
|
|
|
|
}}
|
|
|
|
@ -1300,9 +1300,8 @@
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div style={{
|
|
|
|
<div style={{
|
|
|
|
position: 'relative',
|
|
|
|
position: 'relative',
|
|
|
|
width: '65%',
|
|
|
|
width: '100%',
|
|
|
|
paddingBottom: '65%', // Smaller square
|
|
|
|
paddingBottom: '100%', // Square aspect ratio
|
|
|
|
margin: '0 auto',
|
|
|
|
|
|
|
|
background: '#000',
|
|
|
|
background: '#000',
|
|
|
|
borderRadius: '50%',
|
|
|
|
borderRadius: '50%',
|
|
|
|
overflow: 'hidden'
|
|
|
|
overflow: 'hidden'
|
|
|
|
@ -1326,11 +1325,11 @@
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div style={{
|
|
|
|
<div style={{
|
|
|
|
textAlign: 'center',
|
|
|
|
textAlign: 'center',
|
|
|
|
marginTop: '2px',
|
|
|
|
marginTop: '4px',
|
|
|
|
fontSize: '9px',
|
|
|
|
fontSize: '10px',
|
|
|
|
color: 'var(--text-muted)'
|
|
|
|
color: 'var(--text-muted)'
|
|
|
|
}}>
|
|
|
|
}}>
|
|
|
|
SDO/AIA • NASA
|
|
|
|
SDO/AIA • Live from NASA
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
);
|
|
|
|
@ -2704,8 +2703,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
useEffect(() => {
|
|
|
|
const calculateScale = () => {
|
|
|
|
const calculateScale = () => {
|
|
|
|
const minHeight = 750; // Design height (reduced for compact layout)
|
|
|
|
const minHeight = 900; // Design height
|
|
|
|
const minWidth = 1200; // Design width
|
|
|
|
const minWidth = 1400; // Design width
|
|
|
|
const vh = window.innerHeight;
|
|
|
|
const vh = window.innerHeight;
|
|
|
|
const vw = window.innerWidth;
|
|
|
|
const vw = window.innerWidth;
|
|
|
|
|
|
|
|
|
|
|
|
@ -2713,7 +2712,7 @@
|
|
|
|
const scaleW = vw / minWidth;
|
|
|
|
const scaleW = vw / minWidth;
|
|
|
|
const newScale = Math.min(scaleH, scaleW, 1); // Never scale above 1
|
|
|
|
const newScale = Math.min(scaleH, scaleW, 1); // Never scale above 1
|
|
|
|
|
|
|
|
|
|
|
|
setScale(Math.max(newScale, 0.6)); // Minimum 60% scale
|
|
|
|
setScale(Math.max(newScale, 0.5)); // Minimum 50% scale
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
calculateScale();
|
|
|
|
calculateScale();
|
|
|
|
@ -2737,10 +2736,10 @@
|
|
|
|
transform: `scale(${scale})`,
|
|
|
|
transform: `scale(${scale})`,
|
|
|
|
transformOrigin: 'center center',
|
|
|
|
transformOrigin: 'center center',
|
|
|
|
display: 'grid',
|
|
|
|
display: 'grid',
|
|
|
|
gridTemplateColumns: '220px 1fr 240px',
|
|
|
|
gridTemplateColumns: '280px 1fr 280px',
|
|
|
|
gridTemplateRows: '46px 1fr',
|
|
|
|
gridTemplateRows: '50px 1fr',
|
|
|
|
gap: '6px',
|
|
|
|
gap: '8px',
|
|
|
|
padding: '6px',
|
|
|
|
padding: '8px',
|
|
|
|
overflow: 'hidden',
|
|
|
|
overflow: 'hidden',
|
|
|
|
boxSizing: 'border-box'
|
|
|
|
boxSizing: 'border-box'
|
|
|
|
}}>
|
|
|
|
}}>
|
|
|
|
@ -2799,14 +2798,14 @@
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
{/* LEFT SIDEBAR */}
|
|
|
|
{/* LEFT SIDEBAR */}
|
|
|
|
<div style={{ display: 'flex', flexDirection: 'column', gap: '4px', overflow: 'hidden' }}>
|
|
|
|
<div style={{ display: 'flex', flexDirection: 'column', gap: '8px', overflowY: 'auto', overflowX: 'hidden' }}>
|
|
|
|
{/* DE Location */}
|
|
|
|
{/* DE Location */}
|
|
|
|
<div className="panel" style={{ padding: '8px', flex: '0 0 auto' }}>
|
|
|
|
<div className="panel" style={{ padding: '12px', flex: '0 0 auto' }}>
|
|
|
|
<div style={{ fontSize: '11px', color: 'var(--accent-cyan)', fontWeight: '700', marginBottom: '4px' }}>📍 DE - YOUR LOCATION</div>
|
|
|
|
<div style={{ fontSize: '13px', color: 'var(--accent-cyan)', fontWeight: '700', marginBottom: '8px' }}>📍 DE - YOUR LOCATION</div>
|
|
|
|
<div style={{ fontFamily: 'JetBrains Mono', fontSize: '11px' }}>
|
|
|
|
<div style={{ fontFamily: 'JetBrains Mono', fontSize: '13px' }}>
|
|
|
|
<div style={{ color: 'var(--accent-amber)', fontSize: '15px', fontWeight: '700' }}>{deGrid}</div>
|
|
|
|
<div style={{ color: 'var(--accent-amber)', fontSize: '18px', fontWeight: '700' }}>{deGrid}</div>
|
|
|
|
<div style={{ color: 'var(--text-secondary)', fontSize: '10px', marginTop: '1px' }}>{config.location.lat.toFixed(2)}°, {config.location.lon.toFixed(2)}°</div>
|
|
|
|
<div style={{ color: 'var(--text-secondary)', fontSize: '12px', marginTop: '2px' }}>{config.location.lat.toFixed(2)}°, {config.location.lon.toFixed(2)}°</div>
|
|
|
|
<div style={{ marginTop: '3px', fontSize: '10px' }}>
|
|
|
|
<div style={{ marginTop: '6px', fontSize: '12px' }}>
|
|
|
|
<span style={{ color: 'var(--text-secondary)' }}>☀ </span>
|
|
|
|
<span style={{ color: 'var(--text-secondary)' }}>☀ </span>
|
|
|
|
<span style={{ color: 'var(--accent-amber)' }}>{deSunTimes.sunrise}</span>
|
|
|
|
<span style={{ color: 'var(--accent-amber)' }}>{deSunTimes.sunrise}</span>
|
|
|
|
<span style={{ color: 'var(--text-secondary)' }}> → </span>
|
|
|
|
<span style={{ color: 'var(--text-secondary)' }}> → </span>
|
|
|
|
@ -2816,12 +2815,12 @@
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
{/* DX Location */}
|
|
|
|
{/* DX Location */}
|
|
|
|
<div className="panel" style={{ padding: '8px', flex: '0 0 auto' }}>
|
|
|
|
<div className="panel" style={{ padding: '12px', flex: '0 0 auto' }}>
|
|
|
|
<div style={{ fontSize: '11px', color: 'var(--accent-green)', fontWeight: '700', marginBottom: '4px' }}>🎯 DX - TARGET</div>
|
|
|
|
<div style={{ fontSize: '13px', color: 'var(--accent-green)', fontWeight: '700', marginBottom: '8px' }}>🎯 DX - TARGET</div>
|
|
|
|
<div style={{ fontFamily: 'JetBrains Mono', fontSize: '11px' }}>
|
|
|
|
<div style={{ fontFamily: 'JetBrains Mono', fontSize: '13px' }}>
|
|
|
|
<div style={{ color: 'var(--accent-amber)', fontSize: '15px', fontWeight: '700' }}>{dxGrid}</div>
|
|
|
|
<div style={{ color: 'var(--accent-amber)', fontSize: '18px', fontWeight: '700' }}>{dxGrid}</div>
|
|
|
|
<div style={{ color: 'var(--text-secondary)', fontSize: '10px', marginTop: '1px' }}>{dxLocation.lat.toFixed(2)}°, {dxLocation.lon.toFixed(2)}°</div>
|
|
|
|
<div style={{ color: 'var(--text-secondary)', fontSize: '12px', marginTop: '2px' }}>{dxLocation.lat.toFixed(2)}°, {dxLocation.lon.toFixed(2)}°</div>
|
|
|
|
<div style={{ marginTop: '3px', fontSize: '10px' }}>
|
|
|
|
<div style={{ marginTop: '6px', fontSize: '12px' }}>
|
|
|
|
<span style={{ color: 'var(--text-secondary)' }}>☀ </span>
|
|
|
|
<span style={{ color: 'var(--text-secondary)' }}>☀ </span>
|
|
|
|
<span style={{ color: 'var(--accent-amber)' }}>{dxSunTimes.sunrise}</span>
|
|
|
|
<span style={{ color: 'var(--accent-amber)' }}>{dxSunTimes.sunrise}</span>
|
|
|
|
<span style={{ color: 'var(--text-secondary)' }}> → </span>
|
|
|
|
<span style={{ color: 'var(--text-secondary)' }}> → </span>
|
|
|
|
@ -2831,9 +2830,9 @@
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
{/* Band Conditions - Compact with color coding */}
|
|
|
|
{/* Band Conditions - Compact with color coding */}
|
|
|
|
<div className="panel" style={{ padding: '6px', flex: '0 0 auto', overflow: 'hidden' }}>
|
|
|
|
<div className="panel" style={{ padding: '10px', flex: '0 0 auto', overflow: 'hidden' }}>
|
|
|
|
<div style={{ fontSize: '10px', color: 'var(--accent-purple)', fontWeight: '700', marginBottom: '4px' }}>📊 BAND CONDITIONS</div>
|
|
|
|
<div style={{ fontSize: '12px', color: 'var(--accent-purple)', fontWeight: '700', marginBottom: '6px' }}>📊 BAND CONDITIONS</div>
|
|
|
|
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: '2px', fontSize: '11px', fontFamily: 'JetBrains Mono' }}>
|
|
|
|
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: '3px', fontSize: '13px', fontFamily: 'JetBrains Mono' }}>
|
|
|
|
{bandConditions.data.slice(0, 12).map(band => {
|
|
|
|
{bandConditions.data.slice(0, 12).map(band => {
|
|
|
|
const colors = {
|
|
|
|
const colors = {
|
|
|
|
GOOD: { bg: 'rgba(0,255,136,0.2)', color: '#00ff88', border: 'rgba(0,255,136,0.4)' },
|
|
|
|
GOOD: { bg: 'rgba(0,255,136,0.2)', color: '#00ff88', border: 'rgba(0,255,136,0.4)' },
|
|
|
|
@ -2844,12 +2843,12 @@
|
|
|
|
return (
|
|
|
|
return (
|
|
|
|
<div key={band.band} style={{
|
|
|
|
<div key={band.band} style={{
|
|
|
|
textAlign: 'center',
|
|
|
|
textAlign: 'center',
|
|
|
|
padding: '2px 1px',
|
|
|
|
padding: '3px 1px',
|
|
|
|
background: style.bg,
|
|
|
|
background: style.bg,
|
|
|
|
border: `1px solid ${style.border}`,
|
|
|
|
border: `1px solid ${style.border}`,
|
|
|
|
borderRadius: '2px'
|
|
|
|
borderRadius: '2px'
|
|
|
|
}}>
|
|
|
|
}}>
|
|
|
|
<div style={{ fontWeight: '600', color: style.color, fontSize: '10px' }}>{band.band}</div>
|
|
|
|
<div style={{ fontWeight: '600', color: style.color, fontSize: '12px' }}>{band.band}</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
);
|
|
|
|
})}
|
|
|
|
})}
|
|
|
|
|