add entry manually

This commit is contained in:
2026-02-12 10:33:32 +01:00
parent ef9b54b4be
commit 0a18e08581
2 changed files with 156 additions and 1 deletions

View File

@@ -6,6 +6,59 @@
<div style="flex: 1; min-width: 300px;">
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 2rem;">
<h2 style="margin: 0;">Logbook</h2>
<button onclick="document.getElementById('manualEntryForm').style.display = document.getElementById('manualEntryForm').style.display === 'none' ? 'block' : 'none'"
class="btn" style="padding: 5px 12px; font-weight: bold;">
+ Add Entry
</button>
</div>
<!-- Manual Entry Form (Hidden by default) -->
<div id="manualEntryForm" style="display: none; margin-bottom: 2rem; background: #fff; padding: 1.5rem; border: 1px solid var(--border-dim); border-radius: var(--radius-md); box-shadow: 0 4px 6px rgba(0,0,0,0.05);">
<h3 style="margin-top: 0; margin-bottom: 1rem; font-size: 1.1rem;">Add Log Entry Retrospectively</h3>
<form action="{{ url_for('add_manual_entry') }}" method="POST">
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; margin-bottom: 1rem;">
<div>
<label style="display: block; margin-bottom: 0.5rem; font-size: 0.9rem;">Activity</label>
<select name="activity_id" id="activitySelect" onchange="updateSubcategories()" required style="width: 100%; padding: 8px; border: 1px solid var(--border-dim); border-radius: 4px;">
<option value="" disabled selected>Select Activity</option>
{% for activity in activities %}
<option value="{{ activity._id }}" data-subcategories='{{ activity.get("subcategories", [])|tojson }}'>{{ activity.name }}</option>
{% endfor %}
</select>
</div>
<div>
<label style="display: block; margin-bottom: 0.5rem; font-size: 0.9rem;">Subcategory</label>
<!-- Text Input (Default / Fallback) -->
<input type="text" id="subcatInput" name="subcategory" placeholder="e.g. Development" style="width: 100%; padding: 8px; border: 1px solid var(--border-dim); border-radius: 4px;">
<!-- Select Input (Hidden by default) -->
<select id="subcatSelect" name="subcategory_select" disabled style="display: none; width: 100%; padding: 8px; border: 1px solid var(--border-dim); border-radius: 4px;">
<option value="">-- Select Subcategory --</option>
</select>
</div>
</div>
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; margin-bottom: 1rem;">
<div>
<label style="display: block; margin-bottom: 0.5rem; font-size: 0.9rem;">Start Time</label>
<input type="datetime-local" name="start_time" required class="date-input" style="width: 100%; padding: 8px; border: 1px solid var(--border-dim); border-radius: 4px;">
</div>
<div>
<label style="display: block; margin-bottom: 0.5rem; font-size: 0.9rem;">End Time</label>
<input type="datetime-local" name="end_time" required class="date-input" style="width: 100%; padding: 8px; border: 1px solid var(--border-dim); border-radius: 4px;">
</div>
</div>
<div style="margin-bottom: 1rem;">
<label style="display: block; margin-bottom: 0.5rem; font-size: 0.9rem;">Note</label>
<textarea name="note" rows="2" style="width: 100%; padding: 8px; border: 1px solid var(--border-dim); border-radius: 4px; resize: vertical;"></textarea>
</div>
<div style="text-align: right;">
<button type="button" onclick="document.getElementById('manualEntryForm').style.display = 'none'" class="btn" style="background: transparent; color: #666; margin-right: 0.5rem;">Cancel</button>
<button type="submit" class="btn">Save Entry</button>
</div>
</form>
</div>
<!-- Search Bar -->
@@ -139,6 +192,63 @@
});
}, 1000);
// Initialize datetime inputs with safe defaults if needed
window.addEventListener('load', () => {
const now = new Date();
now.setMinutes(now.getMinutes() - now.getTimezoneOffset());
const nowStr = now.toISOString().slice(0, 16);
// Optionally set default values for inputs that are empty
document.querySelectorAll('input[type="datetime-local"].date-input').forEach(input => {
if (!input.value) input.value = nowStr;
});
// Initialize subcategories check
updateSubcategories();
});
function updateSubcategories() {
const activitySelect = document.getElementById('activitySelect');
const subcatInput = document.getElementById('subcatInput');
const subcatSelect = document.getElementById('subcatSelect');
const selectedOption = activitySelect.options[activitySelect.selectedIndex];
let subcats = [];
try {
if (selectedOption && selectedOption.dataset.subcategories) {
subcats = JSON.parse(selectedOption.dataset.subcategories);
}
} catch (e) {
console.error("Error parsing subcategories", e);
}
if (subcats && subcats.length > 0) {
// Show Dropdown
subcatInput.style.display = 'none';
subcatInput.disabled = true; // Disable so it's not sent
subcatSelect.style.display = 'block';
subcatSelect.disabled = false;
// Clear and populate
subcatSelect.innerHTML = '<option value="">-- Select Subcategory --</option>';
subcats.forEach(sc => {
const opt = document.createElement('option');
opt.value = sc;
opt.textContent = sc;
subcatSelect.appendChild(opt);
});
} else {
// Show Text Input
subcatInput.style.display = 'block';
subcatInput.disabled = false;
subcatSelect.style.display = 'none';
subcatSelect.disabled = true;
}
}
// Background Sync (Polls for new tasks or status changes)
let lastContentHash = "";
setInterval(() => {