add entry manually
This commit is contained in:
@@ -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(() => {
|
||||
|
||||
Reference in New Issue
Block a user