diff --git a/src/frontend/src/routes/awards/[id]/+page.svelte b/src/frontend/src/routes/awards/[id]/+page.svelte index e6ffb01..a8b4edc 100644 --- a/src/frontend/src/routes/awards/[id]/+page.svelte +++ b/src/frontend/src/routes/awards/[id]/+page.svelte @@ -9,6 +9,8 @@ let error = null; let filter = 'all'; // all, worked, confirmed, unworked let sort = 'name'; // name, status + let groupedData = []; + let bands = []; onMount(async () => { await loadAwardData(); @@ -40,6 +42,9 @@ award = data.award; entities = data.entities || []; + + // Group data for table display + groupDataForTable(); } catch (e) { error = e.message; } finally { @@ -47,6 +52,93 @@ } } + function groupDataForTable() { + // Group by entity name, then create band columns + const entityMap = new Map(); + const bandsSet = new Set(); + + entities.forEach((entity) => { + const entityName = entity.entityName || entity.entity || 'Unknown'; + + if (!entityMap.has(entityName)) { + entityMap.set(entityName, { + entityName, + bands: new Map(), + worked: entity.worked, + confirmed: entity.confirmed, + }); + } + + const entityData = entityMap.get(entityName); + + if (entity.band) { + bandsSet.add(entity.band); + + if (!entityData.bands.has(entity.band)) { + entityData.bands.set(entity.band, []); + } + + // Add QSO info to this band + entityData.bands.get(entity.band).push({ + callsign: entity.callsign, + mode: entity.mode, + confirmed: entity.confirmed, + qsoDate: entity.qsoDate, + }); + } + }); + + // Convert bands Set to sorted array + bands = Array.from(bandsSet).sort(); + + // Convert Map to array + groupedData = Array.from(entityMap.values()); + + // Apply filtering + applyFilter(); + } + + function applyFilter() { + // Re-group from original entities with filter applied + const filteredEntities = getFilteredEntities(); + + const entityMap = new Map(); + const bandsSet = new Set(); + + filteredEntities.forEach((entity) => { + const entityName = entity.entityName || entity.entity || 'Unknown'; + + if (!entityMap.has(entityName)) { + entityMap.set(entityName, { + entityName, + bands: new Map(), + worked: entity.worked, + confirmed: entity.confirmed, + }); + } + + const entityData = entityMap.get(entityName); + + if (entity.band) { + bandsSet.add(entity.band); + + if (!entityData.bands.has(entity.band)) { + entityData.bands.set(entity.band, []); + } + + entityData.bands.get(entity.band).push({ + callsign: entity.callsign, + mode: entity.mode, + confirmed: entity.confirmed, + qsoDate: entity.qsoDate, + }); + } + }); + + bands = Array.from(bandsSet).sort(); + groupedData = Array.from(entityMap.values()); + } + function getFilteredEntities() { let filtered = [...entities]; @@ -88,16 +180,9 @@ return filtered; } - function getStatusClass(entity) { - if (entity.confirmed) return 'confirmed'; - if (entity.worked) return 'worked'; - return 'unworked'; - } - - function getStatusText(entity) { - if (entity.confirmed) return 'Confirmed'; - if (entity.worked) return 'Worked'; - return 'Not Worked'; + // Re-apply filter when filter/sort changes + $: if (entities.length > 0) { + applyFilter(); } @@ -187,44 +272,46 @@ {/if} -
| Entity | + {#each bands as band} +{band} | + {/each} +
|---|---|
|
+ {row.entityName}
+ |
+ {#each bands as band}
+ {@const qsos = row.bands.get(band) || []}
+
+ {#if qsos.length > 0}
+
+ {#each qsos as qso}
+
+ {:else}
+
+ {qso.callsign}
+ {qso.mode}
+
+ {/each}
+ -
+ {/if}
+ |
+ {/each}
+