Todo/app.js

194 lines
7.2 KiB
JavaScript

// --- Basic Todo Model ---
const STORAGE_KEY = 'todos-v1';
const CATEGORY_KEY = 'todo-categories';
let todos = [];
let categories = [];
function loadTodos() {
todos = JSON.parse(localStorage.getItem(STORAGE_KEY) || '[]');
categories = JSON.parse(localStorage.getItem(CATEGORY_KEY) || '[]');
}
function saveTodos() {
localStorage.setItem(STORAGE_KEY, JSON.stringify(todos));
localStorage.setItem(CATEGORY_KEY, JSON.stringify(categories));
}
function getNextId() {
return todos.length ? Math.max(...todos.map(t => t.id)) + 1 : 1;
}
function renderForm() {
const form = document.getElementById('todo-form');
form.innerHTML = `
<div class="form-section">
<label for="task">Task Description</label>
<input type="text" id="task" placeholder="Task Description" required>
</div>
<div class="form-section grid-3">
<div>
<label for="creation-date">Creation Date</label>
<input type="date" id="creation-date" title="Creation Date">
</div>
<div>
<label for="next-date">Next Planned Work Date</label>
<input type="date" id="next-date" title="Next Planned Work Date">
</div>
<div>
<label for="due-date">Due Date</label>
<input type="date" id="due-date" title="Due Date">
</div>
</div>
<div class="form-section grid-3">
<div>
<label for="status">Status</label>
<select id="status">
<option value="">(Blank)</option>
<option value="Busy">Busy</option>
<option value="Done">Done</option>
<option value="W4A">W4A</option>
</select>
</div>
<div>
<label for="urgent">Urgent (1-7)</label>
<input type="number" id="urgent" min="1" max="7" placeholder="Urgent (1-7)">
</div>
<div>
<label for="importance">Importance (1-7)</label>
<input type="number" id="importance" min="1" max="7" placeholder="Importance (1-7)">
</div>
</div>
<div class="form-section grid-2">
<div>
<label for="time-estimation">Time Estimation (min)</label>
<input type="number" id="time-estimation" min="0" placeholder="Time Est. (min)">
</div>
<div>
<label for="actual-time">Actual Time Spent (min)</label>
<input type="number" id="actual-time" min="0" placeholder="Actual Time (min)">
</div>
</div>
<div class="form-section grid-2">
<div>
<label for="category">Category</label>
<input type="text" id="category" placeholder="Category" list="category-list">
<datalist id="category-list"></datalist>
</div>
<div>
<label for="linked-tasks">Link with other tasks (IDs, comma separated)</label>
<input type="text" id="linked-tasks" placeholder="Link with other tasks (IDs, comma separated)">
</div>
</div>
<div class="form-section grid-2">
<div>
<label for="coms">Coms URL</label>
<input type="url" id="coms" placeholder="Coms URL">
</div>
<div>
<label for="link">Link URL</label>
<input type="url" id="link" placeholder="Link URL">
</div>
</div>
<div class="form-section">
<label for="comments">Comments</label>
<textarea id="comments" placeholder="Comments"></textarea>
</div>
<button type="submit" class="add-todo-btn">Add Todo</button>
`;
// Autocomplete for categories
const datalist = document.getElementById('category-list');
datalist.innerHTML = categories.map(cat => `<option value="${cat}">`).join('');
}
function renderTodos() {
const list = document.getElementById('todos-list');
if (!todos.length) {
list.innerHTML = '<em>No todos yet.</em>';
return;
}
list.innerHTML = todos.map(todo => `
<div class="todo-item">
<div class="field"><b>ID:</b> ${todo.id}</div>
<div class="field"><b>Created:</b> ${todo.creationDate}</div>
<div class="field"><b>Next:</b> ${todo.nextDate || ''}</div>
<div class="field"><b>Due:</b> ${todo.dueDate || ''}</div>
<div class="field status-${todo.status || 'blank'}"><b>Status:</b> ${todo.status || ''}</div>
<div class="field urgent"><b>Urgent:</b> ${todo.urgent}</div>
<div class="field importance"><b>Importance:</b> ${todo.importance}</div>
<div class="field prio"><b>Prio:</b> ${todo.prio}</div>
<div class="field"><b>Est.:</b> ${todo.timeEstimation}m</div>
<div class="field"><b>Spent:</b> ${todo.actualTime}m</div>
<div class="field"><b>Category:</b> ${todo.category || ''}</div>
<div class="field"><b>Task:</b> ${todo.task}</div>
<div class="field"><b>Coms:</b> ${todo.coms ? `<a href="${todo.coms}" target="_blank">Link</a>` : ''}</div>
<div class="field"><b>Link:</b> ${todo.link ? `<a href="${todo.link}" target="_blank">Link</a>` : ''}</div>
<div class="field"><b>Comments:</b> ${todo.comments || ''}</div>
<div class="field"><b>Linked:</b> ${todo.linkedTasks || ''}</div>
</div>
`).join('');
}
function addTodo(e) {
e.preventDefault();
const task = document.getElementById('task').value.trim();
const creationDate = document.getElementById('creation-date').value || new Date().toISOString().slice(0,10);
const nextDate = document.getElementById('next-date').value;
const dueDate = document.getElementById('due-date').value;
const status = document.getElementById('status').value;
const urgent = parseInt(document.getElementById('urgent').value) || 1;
const importance = parseInt(document.getElementById('importance').value) || 1;
const prio = urgent * importance;
const timeEstimation = parseInt(document.getElementById('time-estimation').value) || 0;
const actualTime = parseInt(document.getElementById('actual-time').value) || 0;
let category = document.getElementById('category').value.trim();
if (category && !categories.includes(category)) {
categories.push(category);
}
const coms = document.getElementById('coms').value.trim();
const link = document.getElementById('link').value.trim();
const comments = document.getElementById('comments').value.trim();
const linkedTasks = document.getElementById('linked-tasks').value.trim();
const todo = {
id: getNextId(),
creationDate,
nextDate,
dueDate,
status,
urgent,
importance,
prio,
timeEstimation,
actualTime,
category,
task,
coms,
link,
comments,
linkedTasks
};
todos.push(todo);
saveTodos();
renderForm();
renderTodos();
document.getElementById('todo-form').reset();
}
function init() {
loadTodos();
renderForm();
renderTodos();
document.getElementById('todo-form').addEventListener('submit', addTodo);
}
document.addEventListener('DOMContentLoaded', init);
// Password protection placeholder (to be implemented if needed)
// If you want to enable password, set a flag in localStorage and show/hide #password-section accordingly.