119 lines
4.0 KiB
JavaScript
119 lines
4.0 KiB
JavaScript
let currentData = [];
|
|
|
|
async function loadHistory() {
|
|
const tbody = document.getElementById('history-body');
|
|
const tfoot = document.getElementById('history-foot');
|
|
const msg = document.getElementById('msg');
|
|
const start = document.getElementById('filter-start').value;
|
|
const end = document.getElementById('filter-end').value;
|
|
|
|
let url = '/api/eggs';
|
|
const params = new URLSearchParams();
|
|
if (start) params.set('start', start);
|
|
if (end) params.set('end', end);
|
|
if ([...params].length) url += '?' + params.toString();
|
|
|
|
try {
|
|
currentData = await API.get(url);
|
|
|
|
if (currentData.length === 0) {
|
|
tbody.innerHTML = '<tr class="empty-row"><td colspan="4">No entries found.</td></tr>';
|
|
tfoot.innerHTML = '';
|
|
return;
|
|
}
|
|
|
|
renderTable();
|
|
} catch (err) {
|
|
showMessage(msg, `Failed to load history: ${err.message}`, 'error');
|
|
}
|
|
}
|
|
|
|
|
|
function renderTable() {
|
|
const tbody = document.getElementById('history-body');
|
|
const tfoot = document.getElementById('history-foot');
|
|
|
|
// Update result count label
|
|
const total = currentData.reduce((sum, e) => sum + e.eggs, 0);
|
|
const countEl = document.getElementById('result-count');
|
|
if (countEl) countEl.textContent = `${currentData.length} entries · ${total} eggs`;
|
|
|
|
tbody.innerHTML = currentData.map(e => `
|
|
<tr data-id="${e.id}">
|
|
<td>${fmtDate(e.date)}</td>
|
|
<td>${e.eggs}</td>
|
|
<td class="notes">${e.notes || ''}</td>
|
|
<td class="actions">
|
|
<button class="btn btn-ghost btn-sm" onclick="startEdit(${e.id})">Edit</button>
|
|
<button class="btn btn-danger btn-sm" onclick="deleteEntry(${e.id})">Delete</button>
|
|
</td>
|
|
</tr>
|
|
`).join('');
|
|
|
|
// Total row in footer
|
|
tfoot.innerHTML = `
|
|
<tr class="total-row">
|
|
<td colspan="1">Total</td>
|
|
<td>${total}</td>
|
|
<td colspan="2">${currentData.length} entries</td>
|
|
</tr>
|
|
`;
|
|
}
|
|
|
|
function startEdit(id) {
|
|
const entry = currentData.find(e => e.id === id);
|
|
const row = document.querySelector(`tr[data-id="${id}"]`);
|
|
|
|
row.innerHTML = `
|
|
<td><input type="date" value="${entry.date}"></td>
|
|
<td><input type="number" min="0" value="${entry.eggs}" style="width:80px;"></td>
|
|
<td><input type="text" value="${entry.notes || ''}" placeholder="Notes"></td>
|
|
<td class="actions">
|
|
<button class="btn btn-primary btn-sm" onclick="saveEdit(${id})">Save</button>
|
|
<button class="btn btn-ghost btn-sm" onclick="renderTable()">Cancel</button>
|
|
</td>
|
|
`;
|
|
}
|
|
|
|
async function saveEdit(id) {
|
|
const msg = document.getElementById('msg');
|
|
const row = document.querySelector(`tr[data-id="${id}"]`);
|
|
const [dateInput, eggsInput, notesInput] = row.querySelectorAll('input');
|
|
|
|
try {
|
|
const updated = await API.put(`/api/eggs/${id}`, {
|
|
date: dateInput.value,
|
|
eggs: parseInt(eggsInput.value, 10),
|
|
notes: notesInput.value.trim() || null,
|
|
});
|
|
// Update local data and re-render
|
|
const idx = currentData.findIndex(e => e.id === id);
|
|
currentData[idx] = updated;
|
|
renderTable();
|
|
showMessage(msg, 'Entry updated.');
|
|
} catch (err) {
|
|
showMessage(msg, `Error: ${err.message}`, 'error');
|
|
}
|
|
}
|
|
|
|
async function deleteEntry(id) {
|
|
if (!confirm('Delete this entry?')) return;
|
|
const msg = document.getElementById('msg');
|
|
try {
|
|
await API.del(`/api/eggs/${id}`);
|
|
currentData = currentData.filter(e => e.id !== id);
|
|
renderTable();
|
|
showMessage(msg, 'Entry deleted.');
|
|
} catch (err) {
|
|
showMessage(msg, `Error: ${err.message}`, 'error');
|
|
}
|
|
}
|
|
|
|
function clearFilter() {
|
|
document.getElementById('filter-start').value = '';
|
|
document.getElementById('filter-end').value = '';
|
|
loadHistory();
|
|
}
|
|
|
|
document.addEventListener('DOMContentLoaded', loadHistory);
|