/**
* 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;