fix: offer refresh button when round history is empty
When a player has rating_history (graph) but no round_history (per-round detail), calculating a target produced a dead-end error. Now the modal detects the NO_ROUNDS case and shows a button that triggers the existing refresh-round-history endpoint and re-runs the calculation on success. Handles the 24h rate-limit and other refresh errors explicitly.
This commit is contained in:
@@ -353,3 +353,10 @@
|
|||||||
.target-rating-result .loading {
|
.target-rating-result .loading {
|
||||||
color: var(--text-muted);
|
color: var(--text-muted);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.target-rating-result .no-history-prompt {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 12px;
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
|||||||
@@ -615,6 +615,10 @@ async function calculateTargetRating(event) {
|
|||||||
clearResult();
|
clearResult();
|
||||||
|
|
||||||
if (!response.ok || !data.success) {
|
if (!response.ok || !data.success) {
|
||||||
|
if (response.status === 404 && data.errorType === 'NO_ROUNDS') {
|
||||||
|
renderNoHistoryPrompt(pdgaNumber, result);
|
||||||
|
return;
|
||||||
|
}
|
||||||
const msg = data.details ? data.error + ': ' + data.details : (data.error || 'Calculation failed');
|
const msg = data.details ? data.error + ': ' + data.details : (data.error || 'Calculation failed');
|
||||||
_targetResultMsg(result, 'error', msg);
|
_targetResultMsg(result, 'error', msg);
|
||||||
return;
|
return;
|
||||||
@@ -661,3 +665,61 @@ async function calculateTargetRating(event) {
|
|||||||
function closeTargetRatingModal(event) {
|
function closeTargetRatingModal(event) {
|
||||||
document.getElementById('target-rating-modal').style.display = 'none';
|
document.getElementById('target-rating-modal').style.display = 'none';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function renderNoHistoryPrompt(pdgaNumber, container) {
|
||||||
|
const wrapper = document.createElement('div');
|
||||||
|
wrapper.className = 'no-history-prompt';
|
||||||
|
|
||||||
|
const msg = document.createElement('div');
|
||||||
|
msg.textContent = 'No round-level history is stored for this player yet. Refresh from PDGA to enable the calculation.';
|
||||||
|
wrapper.appendChild(msg);
|
||||||
|
|
||||||
|
const btn = document.createElement('button');
|
||||||
|
btn.type = 'button';
|
||||||
|
btn.className = 'btn btn-confirm';
|
||||||
|
btn.textContent = 'Refresh round history & calculate';
|
||||||
|
btn.addEventListener('click', function () { refreshHistoryThenCalculate(pdgaNumber); });
|
||||||
|
wrapper.appendChild(btn);
|
||||||
|
|
||||||
|
container.appendChild(wrapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function refreshHistoryThenCalculate(pdgaNumber) {
|
||||||
|
const result = document.getElementById('target-rating-result');
|
||||||
|
while (result.firstChild) result.removeChild(result.firstChild);
|
||||||
|
_targetResultMsg(result, 'loading', 'Refreshing round history from PDGA — this may take up to 30 seconds...');
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetch('/api/refresh-round-history/' + pdgaNumber, { method: 'POST' });
|
||||||
|
const data = await response.json();
|
||||||
|
while (result.firstChild) result.removeChild(result.firstChild);
|
||||||
|
|
||||||
|
if (response.status === 429) {
|
||||||
|
const hours = data.hoursRemaining ? data.hoursRemaining + ' hour(s)' : 'a while';
|
||||||
|
_targetResultMsg(result, 'error', 'Round history was refreshed recently. Try again in ' + hours + '.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!response.ok || !data.success) {
|
||||||
|
const msg = data.details ? data.error + ': ' + data.details : (data.error || 'Refresh failed');
|
||||||
|
_targetResultMsg(result, 'error', msg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.debugLog) cachedDebugInfo[pdgaNumber] = data.debugLog;
|
||||||
|
const predictedCell = document.getElementById('predicted-' + pdgaNumber);
|
||||||
|
if (predictedCell) {
|
||||||
|
const predictedValue = predictedCell.querySelector('.predicted-value');
|
||||||
|
if (predictedValue) {
|
||||||
|
predictedValue.textContent = data.predictedRating || 'N/A';
|
||||||
|
predictedValue.dataset.stddev = data.stdDev || '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await calculateTargetRating(null);
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Error refreshing round history:', err);
|
||||||
|
while (result.firstChild) result.removeChild(result.firstChild);
|
||||||
|
_targetResultMsg(result, 'error', 'Network error during refresh. Please try again.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user