Co-authored-by: aider (openrouter/thinkingmachines/inkling-small:free) <aider@aider.chat>
202 lines
8.0 KiB
JavaScript
202 lines
8.0 KiB
JavaScript
let currentUser = null;
|
|
let currentRound = null;
|
|
let currentData = null;
|
|
let currentIndex = 0;
|
|
|
|
async function signup() {
|
|
const name = document.getElementById('name').value;
|
|
const hcp = parseInt(document.getElementById('hcp').value) || 0;
|
|
const res = await fetch('/signup', {
|
|
method: 'POST',
|
|
headers: {'Content-Type': 'application/json'},
|
|
body: JSON.stringify({name, handicap: hcp})
|
|
});
|
|
currentUser = await res.json();
|
|
document.getElementById('signup-section').style.display = 'none';
|
|
document.getElementById('start-section').style.display = 'block';
|
|
loadCourse();
|
|
}
|
|
|
|
async function loadCourse() {
|
|
const res = await fetch('/course');
|
|
const course = await res.json();
|
|
document.getElementById('course-info').textContent = `${course.name} — ${course.holes.length} holes`;
|
|
}
|
|
|
|
async function startRound() {
|
|
const res = await fetch('/course');
|
|
const course = await res.json();
|
|
const tee = document.getElementById('tee-select').value;
|
|
const res2 = await fetch('/round', {
|
|
method: 'POST',
|
|
headers: {'Content-Type': 'application/json'},
|
|
body: JSON.stringify({user_id: currentUser.id, course_id: course.id, tee: tee})
|
|
});
|
|
currentRound = await res2.json();
|
|
document.getElementById('start-section').style.display = 'none';
|
|
document.getElementById('round-section').style.display = 'block';
|
|
document.getElementById('stats-section').style.display = 'block';
|
|
loadRound();
|
|
}
|
|
|
|
async function loadRound() {
|
|
const res = await fetch(`/round/${currentRound.id}`);
|
|
currentData = await res.json();
|
|
const holes = currentData.holes.sort((a,b) => a.hole_number - b.hole_number);
|
|
if (holes.length === 0) return;
|
|
if (currentIndex >= holes.length) currentIndex = 0;
|
|
renderHole(holes[currentIndex]);
|
|
renderNav(holes);
|
|
loadStats();
|
|
}
|
|
|
|
function saveDraft() {
|
|
const id = document.getElementById('hole-score-id').value;
|
|
if (!id) return;
|
|
const draft = {
|
|
strokes: document.getElementById('strokes').value,
|
|
unfinished: document.getElementById('unfinished').checked,
|
|
fairway: document.getElementById('fairway').checked,
|
|
putts_green: document.getElementById('putts-green').value,
|
|
putts_off_green: document.getElementById('putts-off-green').value,
|
|
pen_water: document.getElementById('pen-water').checked,
|
|
pen_ob: document.getElementById('pen-ob').checked,
|
|
pen_lost: document.getElementById('pen-lost').checked,
|
|
bunker_greenside: document.getElementById('bunker-greenside').checked,
|
|
bunker_fairway: document.getElementById('bunker-fairway').checked
|
|
};
|
|
localStorage.setItem('draft_' + id, JSON.stringify(draft));
|
|
}
|
|
|
|
function applyDraft(hole) {
|
|
const draftRaw = localStorage.getItem('draft_' + hole.hole_score_id);
|
|
if (!draftRaw) return;
|
|
const d = JSON.parse(draftRaw);
|
|
document.getElementById('strokes').value = d.strokes !== undefined ? d.strokes : (hole.strokes || 1);
|
|
document.getElementById('unfinished').checked = d.unfinished || false;
|
|
document.getElementById('fairway').checked = d.fairway || false;
|
|
document.getElementById('putts-green').value = d.putts_green !== undefined ? d.putts_green : (hole.putts_green || 0);
|
|
document.getElementById('putts-off-green').value = d.putts_off_green !== undefined ? d.putts_off_green : (hole.putts_off_green || 0);
|
|
document.getElementById('pen-water').checked = d.pen_water || false;
|
|
document.getElementById('pen-ob').checked = d.pen_ob || false;
|
|
document.getElementById('pen-lost').checked = d.pen_lost || false;
|
|
document.getElementById('bunker-greenside').checked = d.bunker_greenside || false;
|
|
document.getElementById('bunker-fairway').checked = d.bunker_fairway || false;
|
|
}
|
|
|
|
function renderHole(hole) {
|
|
document.getElementById('hole-score-id').value = hole.hole_score_id;
|
|
document.getElementById('hole-label').textContent = `Hole ${hole.hole_number}`;
|
|
document.getElementById('strokes').value = hole.strokes || 1;
|
|
document.getElementById('unfinished').checked = hole.unfinished || false;
|
|
document.getElementById('fairway').checked = hole.fairway_hit || false;
|
|
document.getElementById('gir-display').textContent = hole.gir ? 'Yes' : 'No';
|
|
|
|
document.getElementById('putts-green').value = hole.putts_green || 0;
|
|
document.getElementById('putts-off-green').value = hole.putts_off_green || 0;
|
|
|
|
document.getElementById('pen-water').checked = hole.penalty_water || false;
|
|
document.getElementById('pen-ob').checked = hole.penalty_ob || false;
|
|
document.getElementById('pen-lost').checked = hole.penalty_lost || false;
|
|
|
|
document.getElementById('bunker-greenside').checked = hole.bunker_greenside || false;
|
|
document.getElementById('bunker-fairway').checked = hole.bunker_fairway || false;
|
|
|
|
applyDraft(hole);
|
|
|
|
const info = hole.hole_info || {};
|
|
document.getElementById('hole-info').innerHTML = `
|
|
<strong>Par ${info.par}</strong> | Tee: ${info.tee} | ${info.yardage_meters}m
|
|
`;
|
|
}
|
|
|
|
function renderNav(holes) {
|
|
document.getElementById('prev-btn').disabled = currentIndex <= 0;
|
|
document.getElementById('next-btn').disabled = currentIndex >= holes.length - 1;
|
|
}
|
|
|
|
function prevHole() {
|
|
if (currentIndex > 0) {
|
|
saveHole().then(() => {
|
|
currentIndex--;
|
|
loadRound();
|
|
});
|
|
}
|
|
}
|
|
|
|
function nextHole() {
|
|
saveHole().then(() => {
|
|
currentIndex++;
|
|
loadRound();
|
|
});
|
|
}
|
|
|
|
async function saveHole() {
|
|
const id = document.getElementById('hole-score-id').value;
|
|
if (!id) return Promise.resolve();
|
|
const strokes = parseInt(document.getElementById('strokes').value) || 1;
|
|
const unfinished = document.getElementById('unfinished').checked;
|
|
const fairway = document.getElementById('fairway').checked;
|
|
|
|
const puttsGreen = parseInt(document.getElementById('putts-green').value) || 0;
|
|
const puttsOffGreen = parseInt(document.getElementById('putts-off-green').value) || 0;
|
|
|
|
const penWater = document.getElementById('pen-water').checked;
|
|
const penOb = document.getElementById('pen-ob').checked;
|
|
const penLost = document.getElementById('pen-lost').checked;
|
|
|
|
const bunkerGreenside = document.getElementById('bunker-greenside').checked;
|
|
const bunkerFairway = document.getElementById('bunker-fairway').checked;
|
|
|
|
const res = await fetch(`/hole/${id}`, {
|
|
method: 'POST',
|
|
headers: {'Content-Type': 'application/json'},
|
|
body: JSON.stringify({
|
|
strokes, skipped: false, completed: false, fairway_hit: fairway, unfinished,
|
|
putts_green: puttsGreen, putts_off_green: puttsOffGreen,
|
|
penalty_water: penWater, penalty_ob: penOb, penalty_lost: penLost,
|
|
bunker_greenside: bunkerGreenside, bunker_fairway: bunkerFairway
|
|
})
|
|
});
|
|
const result = await res.json();
|
|
document.getElementById('gir-display').textContent = result.gir ? 'Yes' : 'No';
|
|
localStorage.removeItem('draft_' + id);
|
|
loadStats();
|
|
return result;
|
|
}
|
|
|
|
async function skipHole() {
|
|
const id = document.getElementById('hole-score-id').value;
|
|
await fetch(`/hole/${id}`, {
|
|
method: 'POST',
|
|
headers: {'Content-Type': 'application/json'},
|
|
body: JSON.stringify({
|
|
strokes: 0, skipped: true, completed: false, fairway_hit: false, unfinished: false,
|
|
putts_green: 0, putts_off_green: 0,
|
|
penalty_water: false, penalty_ob: false, penalty_lost: false,
|
|
bunker_greenside: false, bunker_fairway: false
|
|
})
|
|
});
|
|
localStorage.removeItem('draft_' + id);
|
|
const holes = currentData.holes.sort((a,b) => a.hole_number - b.hole_number);
|
|
if (currentIndex < holes.length - 1) {
|
|
currentIndex++;
|
|
loadRound();
|
|
}
|
|
}
|
|
|
|
async function loadStats() {
|
|
const res = await fetch(`/stats/${currentRound.id}`);
|
|
const stats = await res.json();
|
|
document.getElementById('stats-display').innerHTML = `
|
|
<p><strong>Total Strokes:</strong> ${stats.total_strokes}</p>
|
|
<p><strong>Total Putts:</strong> ${stats.total_putts}</p>
|
|
<p><strong>Fairways Hit:</strong> ${stats.fairways_hit}</p>
|
|
<p><strong>GIR:</strong> ${stats.gir}</p>
|
|
<p><strong>Penalty Strokes:</strong> ${stats.penalty_strokes}</p>
|
|
<p><strong>Bunker Greenside:</strong> ${stats.bunker_greenside}</p>
|
|
<p><strong>Bunker Fairway:</strong> ${stats.bunker_fairway}</p>
|
|
<p><strong>Holes Played:</strong> ${stats.holes_played}</p>
|
|
`;
|
|
}
|