// api.js — shared fetch helpers and utilities used by every page const API = { async _fetch(url, options = {}) { const res = await fetch(url, { headers: { 'Content-Type': 'application/json' }, ...options, }); if (!res.ok) { const err = await res.json().catch(() => ({ detail: res.statusText })); throw new Error(err.detail || `Request failed (${res.status})`); } if (res.status === 204) return null; // DELETE returns No Content return res.json(); }, get: (url) => API._fetch(url), post: (url, data) => API._fetch(url, { method: 'POST', body: JSON.stringify(data) }), put: (url, data) => API._fetch(url, { method: 'PUT', body: JSON.stringify(data) }), del: (url) => API._fetch(url, { method: 'DELETE' }), }; // Show a timed success or error message inside a .message element function showMessage(el, text, type = 'success') { el.textContent = text; el.className = `message ${type} visible`; setTimeout(() => { el.className = 'message'; }, 4000); } // Set an input[type=date] to today's date (using local time, not UTC) function setToday(inputEl) { const now = new Date(); const y = now.getFullYear(); const m = String(now.getMonth() + 1).padStart(2, '0'); const d = String(now.getDate()).padStart(2, '0'); inputEl.value = `${y}-${m}-${d}`; } // Format YYYY-MM-DD → MM/DD/YYYY for display function fmtDate(str) { if (!str) return '—'; const [y, m, d] = str.split('-'); return `${m}/${d}/${y}`; } // Format a number as a dollar amount function fmtMoney(val) { if (val == null || val === '' || isNaN(Number(val))) return '—'; return '$' + Number(val).toFixed(2); } // Format a small decimal (cost per egg) with 4 decimal places function fmtMoneyFull(val) { if (val == null || val === '' || isNaN(Number(val))) return '—'; return '$' + Number(val).toFixed(4); } // Highlight the nav link that matches the current page function highlightNav() { const path = window.location.pathname.replace(/\.html$/, '').replace(/\/$/, '') || '/'; document.querySelectorAll('.nav-links a').forEach(a => { const href = a.getAttribute('href').replace(/\/$/, '') || '/'; if (href === path) a.classList.add('active'); }); } document.addEventListener('DOMContentLoaded', highlightNav);