fix(awards): stack the reference validity dates, and prove the award fallback

Two dates side by side put each one in a half-width Field2, which spends 120px
on its label column — the second label overlapped the first input and the row
ran off the panel. The comment ten lines above says exactly this about the
group/subgroup fields; one per row, as everything else in this editor.

Also shows a far-future end date as open-ended. RDA carries 9999-12-31 as "no
end" and printing it back reads like a real deadline.

The claim that an empty per-reference window inherits the award's is now a
test rather than a comment: a QSO before the award's own ValidFrom does not
count for a reference that has no window of its own, and a narrower reference
window still applies on top.
This commit is contained in:
2026-08-12 10:51:12 +02:00
parent 8fc6673611
commit dd7b63c059
2 changed files with 47 additions and 11 deletions
+16 -11
View File
@@ -97,6 +97,13 @@ function Chips({ all, value, onToggle }: { all: string[]; value: string[]; onTog
);
}
// Awards use a far-future date as "no end" (RDA carries 9999-12-31). Printing it
// back at the operator reads like a real deadline, so show it as open-ended.
function openEnded(d?: string): string {
if (!d) return '—';
return /^9\d{3}-/.test(d) ? '—' : d;
}
function Field2({ label, children }: { label: string; children: React.ReactNode }) {
return (
<div className="grid grid-cols-[120px_1fr] items-center gap-2">
@@ -1064,19 +1071,17 @@ function ReferencesPanel({ code, presets, meta, awardValidFrom, awardValidTo, on
Left empty the award's own dates govern, which is why they show
as the placeholder: the operator can see what "empty" inherits
instead of having to remember. */}
<div className="grid grid-cols-2 gap-2">
<Field2 label={t('awed.refValidFrom')}>
<Input type="date" className="h-8" value={sel.valid_from ?? ''}
onChange={(e) => patchSel({ valid_from: e.target.value })} />
</Field2>
<Field2 label={t('awed.refValidTo')}>
<Input type="date" className="h-8" value={sel.valid_to ?? ''}
onChange={(e) => patchSel({ valid_to: e.target.value })} />
</Field2>
</div>
<Field2 label={t('awed.refValidFrom')}>
<Input type="date" className="h-8 w-44" value={sel.valid_from ?? ''}
onChange={(e) => patchSel({ valid_from: e.target.value })} />
</Field2>
<Field2 label={t('awed.refValidTo')}>
<Input type="date" className="h-8 w-44" value={sel.valid_to ?? ''}
onChange={(e) => patchSel({ valid_to: e.target.value })} />
</Field2>
<p className="text-xs text-muted-foreground">
{(awardValidFrom || awardValidTo)
? t('awed.refValidHintAward', { from: awardValidFrom || '—', to: awardValidTo || '—' })
? t('awed.refValidHintAward', { from: openEnded(awardValidFrom), to: openEnded(awardValidTo) })
: t('awed.refValidHint')}
</p>
<div className="flex justify-end pt-1"><Button size="sm" className="h-7" onClick={() => sel && saveRef(sel)}><Save className="size-3.5 mr-1" /> {t('awed.saveReference')}</Button></div>