163 lines
5.8 KiB
HTML
163 lines
5.8 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
<title>Log Entry — Bourbonacci</title>
|
|
<link rel="stylesheet" href="/css/style.css" />
|
|
</head>
|
|
<body>
|
|
|
|
<nav>
|
|
<a href="/index.html" class="nav-brand">🥃 Bourbonacci</a>
|
|
<div class="nav-links" id="nav-links"></div>
|
|
<div id="nav-user"></div>
|
|
</nav>
|
|
|
|
<main style="max-width:640px">
|
|
<h1 class="page-title">Log Entry</h1>
|
|
|
|
<div class="tabs">
|
|
<div class="tab active" id="tab-add" onclick="switchTab('add')">Add to Bottle</div>
|
|
<div class="tab" id="tab-remove" onclick="switchTab('remove')">Remove (Drink)</div>
|
|
</div>
|
|
|
|
<!-- ADD FORM -->
|
|
<div id="pane-add">
|
|
<div class="card">
|
|
<div id="alert-add"></div>
|
|
<form id="form-add">
|
|
<div class="form-group">
|
|
<label for="add-date">Date</label>
|
|
<input type="date" id="add-date" required />
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="bourbon-name">Bourbon Name</label>
|
|
<input type="text" id="bourbon-name" required placeholder="e.g. Buffalo Trace" />
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="proof">Proof</label>
|
|
<input type="number" id="proof" min="0" max="200" step="0.1" placeholder="e.g. 90" />
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="add-shots">Amount (shots)</label>
|
|
<input type="number" id="add-shots" min="0.25" step="0.25" value="1" required />
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="add-notes">Notes</label>
|
|
<textarea id="add-notes" placeholder="Tasting notes, batch info, anything worth remembering…"></textarea>
|
|
</div>
|
|
<div style="display:flex;gap:1rem;margin-top:.5rem">
|
|
<button type="submit" class="btn btn-primary" id="btn-add">Add to Bottle</button>
|
|
<a href="/dashboard.html" class="btn btn-ghost">Cancel</a>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- REMOVE FORM -->
|
|
<div id="pane-remove" style="display:none">
|
|
<div class="card">
|
|
<p style="color:var(--cream-dim);margin-bottom:1rem;font-size:.9rem">
|
|
Log shots you've poured and consumed from the infinity bottle.
|
|
</p>
|
|
<div id="alert-remove"></div>
|
|
<form id="form-remove">
|
|
<div class="form-group">
|
|
<label for="remove-date">Date</label>
|
|
<input type="date" id="remove-date" required />
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="remove-shots">Shots Consumed</label>
|
|
<input type="number" id="remove-shots" min="0.25" step="0.25" value="1" required />
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="remove-notes">Notes</label>
|
|
<textarea id="remove-notes" placeholder="Occasion, tasting notes…"></textarea>
|
|
</div>
|
|
<div style="display:flex;gap:1rem;margin-top:.5rem">
|
|
<button type="submit" class="btn btn-danger" id="btn-remove">Log Removal</button>
|
|
<a href="/dashboard.html" class="btn btn-ghost">Cancel</a>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</main>
|
|
|
|
<script src="/js/api.js"></script>
|
|
<script src="/js/auth.js"></script>
|
|
<script>
|
|
function today() {
|
|
return new Date().toISOString().split('T')[0];
|
|
}
|
|
|
|
document.addEventListener('DOMContentLoaded', () => {
|
|
if (!Auth.requireAuth()) return;
|
|
Auth.renderNav('log');
|
|
|
|
document.getElementById('add-date').value = today();
|
|
document.getElementById('remove-date').value = today();
|
|
});
|
|
|
|
function switchTab(tab) {
|
|
document.getElementById('pane-add').style.display = tab === 'add' ? '' : 'none';
|
|
document.getElementById('pane-remove').style.display = tab === 'remove' ? '' : 'none';
|
|
document.getElementById('tab-add').className = 'tab' + (tab === 'add' ? ' active' : '');
|
|
document.getElementById('tab-remove').className = 'tab' + (tab === 'remove' ? ' active' : '');
|
|
}
|
|
|
|
document.getElementById('form-add').addEventListener('submit', async (e) => {
|
|
e.preventDefault();
|
|
const alert = document.getElementById('alert-add');
|
|
const btn = document.getElementById('btn-add');
|
|
alert.innerHTML = '';
|
|
btn.disabled = true;
|
|
|
|
try {
|
|
await API.entries.create({
|
|
entry_type: 'add',
|
|
date: document.getElementById('add-date').value,
|
|
bourbon_name: document.getElementById('bourbon-name').value.trim(),
|
|
proof: parseFloat(document.getElementById('proof').value) || null,
|
|
amount_shots: parseFloat(document.getElementById('add-shots').value),
|
|
notes: document.getElementById('add-notes').value.trim() || null,
|
|
});
|
|
alert.innerHTML = `<div class="alert alert-success">Added to the bottle!</div>`;
|
|
e.target.reset();
|
|
document.getElementById('add-date').value = today();
|
|
document.getElementById('add-shots').value = '1';
|
|
} catch (err) {
|
|
alert.innerHTML = `<div class="alert alert-error">${err.message}</div>`;
|
|
} finally {
|
|
btn.disabled = false;
|
|
}
|
|
});
|
|
|
|
document.getElementById('form-remove').addEventListener('submit', async (e) => {
|
|
e.preventDefault();
|
|
const alert = document.getElementById('alert-remove');
|
|
const btn = document.getElementById('btn-remove');
|
|
alert.innerHTML = '';
|
|
btn.disabled = true;
|
|
|
|
try {
|
|
await API.entries.create({
|
|
entry_type: 'remove',
|
|
date: document.getElementById('remove-date').value,
|
|
amount_shots: parseFloat(document.getElementById('remove-shots').value),
|
|
notes: document.getElementById('remove-notes').value.trim() || null,
|
|
});
|
|
alert.innerHTML = `<div class="alert alert-success">Removal logged. Cheers!</div>`;
|
|
e.target.reset();
|
|
document.getElementById('remove-date').value = today();
|
|
document.getElementById('remove-shots').value = '1';
|
|
} catch (err) {
|
|
alert.innerHTML = `<div class="alert alert-error">${err.message}</div>`;
|
|
} finally {
|
|
btn.disabled = false;
|
|
}
|
|
});
|
|
</script>
|
|
</body>
|
|
</html>
|