fix(awards): band columns follow the contacts, not the permission
The columns took the award's declared band list when it had one, so every band the award PERMITS got a column whether or not anything had ever been worked on it. DDFM permits 6m and 70cm; a station that has never worked a French department on either was shown two empty columns, which reads as a gap in the log rather than as a band nobody tried. They now follow the bands this operator actually has contacts on for the award. The declared list is the fallback for an award with nothing worked yet — there, saying what the award is played on is the only honest answer available — and the classic HF set is the fallback for an award that declares nothing either. Together with taking the order from the full band list, this is what puts 23cm on DDFM: the column appears because there are contacts on it.
This commit is contained in:
@@ -196,18 +196,25 @@ export function AwardsPanel({ onEditQSO, onAwardsChanged, onPaperQSL }: {
|
||||
useEffect(() => { if (selected) compute(selected); /* eslint-disable-next-line react-hooks/exhaustive-deps */ }, [modeFilter]);
|
||||
|
||||
// Bands relevant to the selected award, used by BOTH the grid and the stats
|
||||
// matrix so neither is padded with bands the award doesn't use. Rule: the
|
||||
// award's explicit valid_bands if it has any (e.g. WAPC = 40/20/15/10m); else
|
||||
// the bands the operator actually has contacts on (so DXCC, which has no band
|
||||
// restriction, shows 160m–6m instead of empty VHF/UHF columns). Empty set =
|
||||
// no basis yet → callers fall back to all bands.
|
||||
// matrix so neither is padded with bands nothing was worked on. Rule: the
|
||||
// bands this operator HAS contacts on for this award; failing that, the
|
||||
// award's own list of permitted bands. Empty set = no basis at all → callers
|
||||
// fall back to the classic columns.
|
||||
const awardBands = useMemo(() => {
|
||||
const vb = (awardList.find((a) => a.code === selected)?.bands ?? []).map((b) => b.toLowerCase());
|
||||
if (vb.length > 0) return new Set(vb);
|
||||
const worked = (current?.bands ?? [])
|
||||
// The bands with CONTACTS on them come first, whatever the award declares.
|
||||
//
|
||||
// It used to take the declared list when there was one, which put up a
|
||||
// column for every band the award permits — DDFM allows 6m and 70cm, so
|
||||
// both stood there empty on a station that has never worked a French
|
||||
// department on either. An always-blank column reads as a gap in the log
|
||||
// rather than as a band the operator never tried.
|
||||
const worked = new Set((current?.bands ?? [])
|
||||
.filter((b) => (b.worked ?? 0) > 0)
|
||||
.map((b) => String(b.band).toLowerCase());
|
||||
return new Set(worked);
|
||||
.map((b) => String(b.band).toLowerCase()));
|
||||
if (worked.size > 0) return worked;
|
||||
// Nothing worked yet: the award's own list is the honest answer — it says
|
||||
// what this award is played on, which is the only thing there is to show.
|
||||
return new Set((awardList.find((a) => a.code === selected)?.bands ?? []).map((b) => b.toLowerCase()));
|
||||
}, [awardList, selected, current]);
|
||||
|
||||
const gridBands = useMemo(() => {
|
||||
|
||||
Reference in New Issue
Block a user