feat: add import log showing synced QSOs
Add import log display that shows QSOs imported via LoTW/DCL sync. Backend now tracks added/updated QSOs (callsign, date, band, mode) and returns them in sync result. Frontend displays tables showing new and updated QSOs after sync completes. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -193,6 +193,8 @@ export async function syncQSOs(userId, dclApiKey, sinceDate = null, jobId = null
|
||||
let addedCount = 0;
|
||||
let updatedCount = 0;
|
||||
const errors = [];
|
||||
const addedQSOs = [];
|
||||
const updatedQSOs = [];
|
||||
|
||||
for (let i = 0; i < adifQSOs.length; i++) {
|
||||
const adifQSO = adifQSOs[i];
|
||||
@@ -230,10 +232,24 @@ export async function syncQSOs(userId, dclApiKey, sinceDate = null, jobId = null
|
||||
})
|
||||
.where(eq(qsos.id, existing[0].id));
|
||||
updatedCount++;
|
||||
// Track updated QSO (CALL and DATE)
|
||||
updatedQSOs.push({
|
||||
callsign: dbQSO.callsign,
|
||||
date: dbQSO.qsoDate,
|
||||
band: dbQSO.band,
|
||||
mode: dbQSO.mode,
|
||||
});
|
||||
} else {
|
||||
// Insert new QSO
|
||||
await db.insert(qsos).values(dbQSO);
|
||||
addedCount++;
|
||||
// Track added QSO (CALL and DATE)
|
||||
addedQSOs.push({
|
||||
callsign: dbQSO.callsign,
|
||||
date: dbQSO.qsoDate,
|
||||
band: dbQSO.band,
|
||||
mode: dbQSO.mode,
|
||||
});
|
||||
}
|
||||
|
||||
// Update job progress every 10 QSOs
|
||||
@@ -258,6 +274,8 @@ export async function syncQSOs(userId, dclApiKey, sinceDate = null, jobId = null
|
||||
total: adifQSOs.length,
|
||||
added: addedCount,
|
||||
updated: updatedCount,
|
||||
addedQSOs,
|
||||
updatedQSOs,
|
||||
confirmed: adifQSOs.filter(q => q.dcl_qsl_rcvd === 'Y').length,
|
||||
errors: errors.length > 0 ? errors : undefined,
|
||||
};
|
||||
|
||||
@@ -223,6 +223,8 @@ export async function syncQSOs(userId, lotwUsername, lotwPassword, sinceDate = n
|
||||
let addedCount = 0;
|
||||
let updatedCount = 0;
|
||||
const errors = [];
|
||||
const addedQSOs = [];
|
||||
const updatedQSOs = [];
|
||||
|
||||
for (let i = 0; i < adifQSOs.length; i++) {
|
||||
const qsoData = adifQSOs[i];
|
||||
@@ -254,9 +256,23 @@ export async function syncQSOs(userId, lotwUsername, lotwPassword, sinceDate = n
|
||||
})
|
||||
.where(eq(qsos.id, existing[0].id));
|
||||
updatedCount++;
|
||||
// Track updated QSO (CALL and DATE)
|
||||
updatedQSOs.push({
|
||||
callsign: dbQSO.callsign,
|
||||
date: dbQSO.qsoDate,
|
||||
band: dbQSO.band,
|
||||
mode: dbQSO.mode,
|
||||
});
|
||||
} else {
|
||||
await db.insert(qsos).values(dbQSO);
|
||||
addedCount++;
|
||||
// Track added QSO (CALL and DATE)
|
||||
addedQSOs.push({
|
||||
callsign: dbQSO.callsign,
|
||||
date: dbQSO.qsoDate,
|
||||
band: dbQSO.band,
|
||||
mode: dbQSO.mode,
|
||||
});
|
||||
}
|
||||
|
||||
// Update job progress every 10 QSOs
|
||||
@@ -279,6 +295,8 @@ export async function syncQSOs(userId, lotwUsername, lotwPassword, sinceDate = n
|
||||
total: adifQSOs.length,
|
||||
added: addedCount,
|
||||
updated: updatedCount,
|
||||
addedQSOs,
|
||||
updatedQSOs,
|
||||
errors: errors.length > 0 ? errors : undefined,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -306,6 +306,68 @@
|
||||
{/if}
|
||||
<button on:click={() => syncResult = null} class="btn-small">Dismiss</button>
|
||||
</div>
|
||||
|
||||
{#if syncResult.success && (syncResult.addedQSOs?.length > 0 || syncResult.updatedQSOs?.length > 0)}
|
||||
<div class="import-log">
|
||||
<h3>Import Log</h3>
|
||||
|
||||
{#if syncResult.addedQSOs && syncResult.addedQSOs.length > 0}
|
||||
<div class="log-section">
|
||||
<h4>New QSOs ({syncResult.addedQSOs.length})</h4>
|
||||
<div class="log-table-container">
|
||||
<table class="log-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Callsign</th>
|
||||
<th>Date</th>
|
||||
<th>Band</th>
|
||||
<th>Mode</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each syncResult.addedQSOs as qso}
|
||||
<tr>
|
||||
<td class="callsign">{qso.callsign}</td>
|
||||
<td>{formatDate(qso.date)}</td>
|
||||
<td>{qso.band || '-'}</td>
|
||||
<td>{qso.mode || '-'}</td>
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{#if syncResult.updatedQSOs && syncResult.updatedQSOs.length > 0}
|
||||
<div class="log-section">
|
||||
<h4>Updated QSOs ({syncResult.updatedQSOs.length})</h4>
|
||||
<div class="log-table-container">
|
||||
<table class="log-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Callsign</th>
|
||||
<th>Date</th>
|
||||
<th>Band</th>
|
||||
<th>Mode</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each syncResult.updatedQSOs as qso}
|
||||
<tr>
|
||||
<td class="callsign">{qso.callsign}</td>
|
||||
<td>{formatDate(qso.date)}</td>
|
||||
<td>{qso.band || '-'}</td>
|
||||
<td>{qso.mode || '-'}</td>
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
{/if}
|
||||
|
||||
{#if showDeleteConfirm}
|
||||
@@ -845,4 +907,72 @@
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.import-log {
|
||||
background: white;
|
||||
border: 1px solid #e0e0e0;
|
||||
border-radius: 8px;
|
||||
padding: 1.5rem;
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
.import-log h3 {
|
||||
margin: 0 0 1rem 0;
|
||||
color: #333;
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
|
||||
.log-section {
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.log-section:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.log-section h4 {
|
||||
margin: 0 0 0.75rem 0;
|
||||
color: #555;
|
||||
font-size: 1rem;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.log-table-container {
|
||||
overflow-x: auto;
|
||||
border: 1px solid #e0e0e0;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.log-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.log-table th,
|
||||
.log-table td {
|
||||
padding: 0.5rem 0.75rem;
|
||||
text-align: left;
|
||||
border-bottom: 1px solid #e0e0e0;
|
||||
}
|
||||
|
||||
.log-table th {
|
||||
background-color: #f8f9fa;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
|
||||
.log-table tr:last-child td {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.log-table tr:hover {
|
||||
background-color: #f8f9fa;
|
||||
}
|
||||
|
||||
.log-table .callsign {
|
||||
font-weight: 600;
|
||||
color: #4a90e2;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user