refactor: replace date preview flow with single Create Season button

Remove two-step preview+add flow. One button now generates dates,
skips duplicates, and saves directly with a clear result message.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Greg 2026-03-08 14:04:53 +01:00
parent 7273b76c52
commit c66fefcc19

View File

@ -187,15 +187,10 @@
</select> </select>
</div> </div>
<div class="form-group" style="justify-content: flex-end;"> <div class="form-group" style="justify-content: flex-end;">
<button class="btn btn-secondary" onclick="previewDates()">Preview Dates</button> <button class="btn" onclick="createSeason()">Create Season</button>
</div> </div>
</div> </div>
<div class="msg" id="dates-msg"></div> <div class="msg" id="dates-msg"></div>
<div id="preview-box">
<div id="preview-summary"></div>
<div id="preview-dates"></div>
<button class="btn" id="add-dates-btn" onclick="addDates()" style="display:none;"></button>
</div>
</div> </div>
<!-- PLAYER MANAGEMENT --> <!-- PLAYER MANAGEMENT -->
@ -228,7 +223,6 @@
<script> <script>
let existingDates = []; let existingDates = [];
let allPlayers = []; let allPlayers = [];
let previewResult = null;
// Block XSS chars in text inputs // Block XSS chars in text inputs
document.querySelectorAll('input[type="text"]').forEach(inp => { document.querySelectorAll('input[type="text"]').forEach(inp => {
@ -310,16 +304,17 @@
return dates; return dates;
} }
function previewDates() { async function createSeason() {
const startStr = document.getElementById('start-date').value.trim(); const startStr = document.getElementById('start-date').value.trim();
const weeks = parseInt(document.getElementById('weeks').value); const weeks = parseInt(document.getElementById('weeks').value);
const dayOfWeek = parseInt(document.getElementById('day-of-week').value); const dayOfWeek = parseInt(document.getElementById('day-of-week').value);
const datesMsg = document.getElementById('dates-msg'); const datesMsg = document.getElementById('dates-msg');
datesMsg.textContent = ''; datesMsg.textContent = '';
datesMsg.className = 'msg';
if (!/^\d{2}\/\d{2}\/\d{2}$/.test(startStr)) { if (!/^\d{2}\/\d{2}\/\d{2}$/.test(startStr)) {
datesMsg.className = 'msg err'; datesMsg.className = 'msg err';
datesMsg.textContent = 'Invalid start date. Use DD/MM/YY format.'; datesMsg.textContent = 'Invalid start date. Use DD/MM/YY format (e.g. 02/04/26).';
return; return;
} }
if (!weeks || weeks < 1 || weeks > 104) { if (!weeks || weeks < 1 || weeks > 104) {
@ -335,42 +330,20 @@
return; return;
} }
const existingSet = new Set(existingDates); // Fetch current data and skip existing dates
const newDates = generated.filter(d => !existingSet.has(d));
const dupDates = generated.filter(d => existingSet.has(d));
previewResult = { generated, newDates };
const summaryEl = document.getElementById('preview-summary');
summaryEl.textContent = `${generated.length} dates total: ${newDates.length} new, ${dupDates.length} already in database (skipped).`;
const datesEl = document.getElementById('preview-dates');
datesEl.innerHTML = generated.map(d => {
const isNew = !existingSet.has(d);
return `<span class="date-chip ${isNew ? 'new' : 'dup'}">${d}</span>`;
}).join('');
const addBtn = document.getElementById('add-dates-btn');
if (newDates.length > 0) {
addBtn.style.display = '';
addBtn.textContent = `Add ${newDates.length} New Date${newDates.length !== 1 ? 's' : ''} to Database`;
} else {
addBtn.style.display = 'none';
}
document.getElementById('preview-box').style.display = '';
}
async function addDates() {
if (!previewResult || previewResult.newDates.length === 0) return;
const datesMsg = document.getElementById('dates-msg');
datesMsg.textContent = '';
// Fetch current full data, merge new dates, POST back
const res = await fetch('/api/data'); const res = await fetch('/api/data');
const data = await res.json(); const data = await res.json();
const mergedDates = [...(data.dates || []), ...previewResult.newDates]; const existingSet = new Set(data.dates || []);
const newDates = generated.filter(d => !existingSet.has(d));
const skipped = generated.length - newDates.length;
if (newDates.length === 0) {
datesMsg.className = 'msg ok';
datesMsg.textContent = `All ${generated.length} dates already exist in the database — nothing to add.`;
return;
}
const mergedDates = [...(data.dates || []), ...newDates];
const payload = { const payload = {
players: data.players || [], players: data.players || [],
guest: data.guest || 'Guest', guest: data.guest || 'Guest',
@ -387,16 +360,12 @@
const result = await postRes.json(); const result = await postRes.json();
if (result.status === 'success') { if (result.status === 'success') {
datesMsg.className = 'msg ok';
datesMsg.textContent = `${previewResult.newDates.length} date${previewResult.newDates.length !== 1 ? 's' : ''} added successfully.`;
existingDates = mergedDates; existingDates = mergedDates;
previewResult = null; datesMsg.className = 'msg ok';
document.getElementById('add-dates-btn').style.display = 'none'; datesMsg.textContent = `Done — ${newDates.length} date${newDates.length !== 1 ? 's' : ''} added${skipped ? `, ${skipped} already existed (skipped)` : ''}.`;
// Re-mark chips as duplicates
previewDates();
} else { } else {
datesMsg.className = 'msg err'; datesMsg.className = 'msg err';
datesMsg.textContent = result.message || 'Error adding dates.'; datesMsg.textContent = result.message || 'Error saving dates.';
} }
} }