/** * PSKFilterManager Component * Filter modal for PSKReporter spots - Bands, Grids, Modes */ import React, { useState } from 'react'; const BANDS = ['160m', '80m', '60m', '40m', '30m', '20m', '17m', '15m', '12m', '10m', '6m', '2m', '70cm']; const MODES = ['FT8', 'FT4', 'JS8', 'WSPR', 'JT65', 'JT9', 'MSK144', 'Q65', 'FST4', 'FST4W']; // Common grid field prefixes by region const GRID_REGIONS = [ { name: 'North America East', grids: ['FN', 'FM', 'EN', 'EM', 'DN', 'DM'] }, { name: 'North America West', grids: ['CN', 'CM', 'DM', 'DN', 'BN', 'BM'] }, { name: 'Europe', grids: ['JO', 'JN', 'IO', 'IN', 'KO', 'KN', 'LO', 'LN'] }, { name: 'South America', grids: ['GG', 'GH', 'GI', 'FG', 'FH', 'FI', 'FF', 'FE'] }, { name: 'Asia', grids: ['PM', 'PL', 'OM', 'OL', 'QL', 'QM', 'NM', 'NL'] }, { name: 'Oceania', grids: ['QF', 'QG', 'PF', 'PG', 'RF', 'RG', 'OF', 'OG'] }, { name: 'Africa', grids: ['KH', 'KG', 'JH', 'JG', 'IH', 'IG'] }, ]; export const PSKFilterManager = ({ filters, onFilterChange, isOpen, onClose }) => { const [activeTab, setActiveTab] = useState('bands'); const [customGrid, setCustomGrid] = useState(''); if (!isOpen) return null; const toggleArrayItem = (key, item) => { const current = filters[key] || []; const newArray = current.includes(item) ? current.filter(x => x !== item) : [...current, item]; onFilterChange({ ...filters, [key]: newArray.length ? newArray : undefined }); }; const selectAll = (key, items) => { onFilterChange({ ...filters, [key]: [...items] }); }; const clearFilter = (key) => { const newFilters = { ...filters }; delete newFilters[key]; onFilterChange(newFilters); }; const clearAllFilters = () => { onFilterChange({}); }; const addCustomGrid = () => { if (customGrid.trim() && customGrid.length >= 2) { const grid = customGrid.toUpperCase().substring(0, 2); const current = filters?.grids || []; if (!current.includes(grid)) { onFilterChange({ ...filters, grids: [...current, grid] }); } setCustomGrid(''); } }; const getActiveFilterCount = () => { let count = 0; if (filters?.bands?.length) count += filters.bands.length; if (filters?.grids?.length) count += filters.grids.length; if (filters?.modes?.length) count += filters.modes.length; return count; }; const tabStyle = (active) => ({ padding: '8px 16px', background: active ? 'var(--bg-tertiary)' : 'transparent', border: 'none', borderBottom: active ? '2px solid var(--accent-cyan)' : '2px solid transparent', color: active ? 'var(--accent-cyan)' : 'var(--text-muted)', fontSize: '13px', cursor: 'pointer', fontFamily: 'inherit' }); const chipStyle = (selected) => ({ padding: '6px 12px', background: selected ? 'rgba(0, 221, 255, 0.2)' : 'var(--bg-tertiary)', border: `1px solid ${selected ? 'var(--accent-cyan)' : 'var(--border-color)'}`, borderRadius: '4px', color: selected ? 'var(--accent-cyan)' : 'var(--text-secondary)', fontSize: '12px', cursor: 'pointer', fontFamily: 'JetBrains Mono, monospace' }); const renderBandsTab = () => (
Filter by Band
{BANDS.map(band => ( ))}
{filters?.bands?.length ? `Showing only: ${filters.bands.join(', ')}` : 'Showing all bands (no filter)'}
); const renderGridsTab = () => (
Filter by Grid Square
{/* Custom grid input */}
setCustomGrid(e.target.value.toUpperCase())} maxLength={2} onKeyPress={(e) => e.key === 'Enter' && addCustomGrid()} style={{ flex: 1, padding: '8px 12px', background: 'var(--bg-tertiary)', border: '1px solid var(--border-color)', borderRadius: '4px', color: 'var(--text-primary)', fontSize: '13px', fontFamily: 'JetBrains Mono' }} />
{/* Selected grids */} {filters?.grids?.length > 0 && (
Active Grid Filters:
{filters.grids.map(grid => ( ))}
)} {/* Quick select by region */}
Quick Select by Region:
{GRID_REGIONS.map(region => (
{region.name}
{region.grids.map(grid => ( ))}
))}
); const renderModesTab = () => (
Filter by Mode
{MODES.map(mode => ( ))}
{filters?.modes?.length ? `Showing only: ${filters.modes.join(', ')}` : 'Showing all modes (no filter)'}
); return (
e.target === e.currentTarget && onClose()} >
{/* Header */}

📡 PSKReporter Filters

{getActiveFilterCount()} filter{getActiveFilterCount() !== 1 ? 's' : ''} active
{/* Tabs */}
{/* Tab Content */}
{activeTab === 'bands' && renderBandsTab()} {activeTab === 'grids' && renderGridsTab()} {activeTab === 'modes' && renderModesTab()}
{/* Footer */}
); }; export default PSKFilterManager;