Files
whattodo/app/static/index.html
T
goyban 39842c72d7 Add plan dates, postponing, backlog and projects
- Tasks get an optional plan date separate from the deadline. Unfinished
  plans roll over in Today; only missed deadlines count as overdue.
- Postpone sheet on every task (tomorrow, weekend, next week, ...) that
  can move either the plan date or the deadline, with undo.
- Backlog view for undated tasks, with suggestions in Today.
- Projects with deadline, notes, progress, next step and "falling
  behind" warnings, shown in Today and in their own view.
- Times and the calendar now follow the plan date (else the deadline).
- Schema v3 migration (backup taken first); export format v3 includes
  projects and still imports older files.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 14:26:32 +02:00

261 lines
10 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
<meta name="theme-color" content="#4f46e5">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-title" content="WhatToDo">
<title>WhatToDo</title>
<link rel="manifest" href="manifest.webmanifest">
<link rel="icon" href="icons/icon.svg" type="image/svg+xml">
<link rel="apple-touch-icon" href="icons/icon-180.png">
<link rel="stylesheet" href="style.css">
<script src="app.js" defer></script>
</head>
<body>
<div id="login" class="login" hidden>
<form id="login-form" class="login-card">
<img src="icons/icon.svg" alt="" width="56" height="56">
<h1>WhatToDo</h1>
<input type="password" id="login-password" placeholder="Password" autocomplete="current-password" required>
<button type="submit" class="btn primary">Log in</button>
<p id="login-error" class="error" hidden></p>
</form>
</div>
<div id="app" class="app" hidden>
<aside id="sidebar" class="sidebar">
<div class="brand"><img src="icons/icon.svg" alt="" width="28" height="28"> WhatToDo</div>
<nav id="views" class="nav"></nav>
<div class="nav-heading">
<span>Projects</span>
<button id="new-project" class="icon-btn small" type="button" aria-label="New project" title="New project">+</button>
</div>
<nav id="projects" class="nav"></nav>
<div class="nav-heading"><span>Categories</span></div>
<nav id="cats" class="nav"></nav>
<div class="sidebar-foot">
<button id="settings-btn" class="nav-item" type="button"><span class="nav-icon">⚙️</span> Settings</button>
</div>
</aside>
<div id="scrim" class="scrim"></div>
<main class="main">
<header class="topbar">
<button id="menu-btn" class="icon-btn menu-btn" type="button" aria-label="Open menu">☰</button>
<h2 id="view-title"></h2>
<input id="search" type="search" placeholder="Search or #tag" autocomplete="off">
</header>
<form id="quick-add" class="quick-add">
<input id="quick-title" placeholder="Add a task…" autocomplete="off" maxlength="500">
<button class="btn primary" type="submit">Add</button>
<button id="new-detailed" class="btn" type="button" title="New task with details">+ Details</button>
</form>
<div id="cal-nav" class="cal-nav" hidden>
<button id="cal-prev" class="btn" type="button" aria-label="Previous day">‹</button>
<input id="cal-date" type="date" aria-label="Day">
<button id="cal-next" class="btn" type="button" aria-label="Next day">›</button>
<button id="cal-today" class="btn" type="button">Today</button>
</div>
<div id="list" class="list"></div>
</main>
</div>
<dialog id="task-dialog">
<form id="task-form" class="dialog-body">
<h3 id="task-dialog-title">Task</h3>
<label class="field">
<span>Title</span>
<input id="t-title" required maxlength="500" autocomplete="off">
</label>
<div class="row">
<label class="field">
<span>Plan to do on</span>
<input id="t-planned" type="date">
</label>
<label class="field">
<span>Deadline</span>
<input id="t-due" type="date">
</label>
</div>
<div class="quick-dates">
<span class="muted small-label">Plan:</span>
<button type="button" class="chip-btn" data-plan="today">Today</button>
<button type="button" class="chip-btn" data-plan="tomorrow">Tomorrow</button>
<button type="button" class="chip-btn" data-plan="weekend">Weekend</button>
<button type="button" class="chip-btn" data-plan="nextweek">Next week</button>
<button type="button" class="chip-btn" data-plan="">No plan</button>
</div>
<div class="row">
<label class="field">
<span>From <small>(optional)</small></span>
<input id="t-start" type="time" step="300">
</label>
<label class="field">
<span>To</span>
<input id="t-end" type="time" step="300">
</label>
</div>
<div id="t-day" class="day-preview" hidden></div>
<div class="row">
<label class="field">
<span>Project</span>
<select id="t-project"></select>
</label>
<label class="field">
<span>Category</span>
<select id="t-category"></select>
</label>
</div>
<div class="row">
<label class="field">
<span>Priority</span>
<select id="t-priority">
<option value="0">None</option>
<option value="1">Low</option>
<option value="2">Medium</option>
<option value="3">High</option>
</select>
</label>
<label class="field">
<span>Repeat</span>
<select id="t-repeat">
<option value="none">Never</option>
<option value="daily">Daily</option>
<option value="weekly">Weekly</option>
<option value="monthly">Monthly</option>
<option value="yearly">Yearly</option>
</select>
</label>
<label class="field narrow" id="t-interval-wrap">
<span>Every</span>
<input id="t-interval" type="number" min="1" max="365" value="1">
</label>
</div>
<label class="field">
<span>Tags <small>(comma separated)</small></span>
<input id="t-tags" placeholder="e.g. editing, urgent" autocomplete="off">
</label>
<label class="field">
<span>Notes</span>
<textarea id="t-notes" rows="3" maxlength="20000"></textarea>
</label>
<div class="field">
<span>Checklist</span>
<ul id="t-subtasks" class="subtasks"></ul>
<div class="subtask-add">
<input id="t-subtask-new" placeholder="Add a step and press Enter" autocomplete="off" maxlength="500">
<button id="t-subtask-add" type="button" class="btn">Add</button>
</div>
</div>
<div class="dialog-actions">
<button id="t-delete" type="button" class="btn danger">Delete</button>
<span class="spacer"></span>
<button id="t-cancel" type="button" class="btn">Cancel</button>
<button type="submit" class="btn primary">Save</button>
</div>
</form>
</dialog>
<dialog id="plan-dialog" class="sheet">
<div class="dialog-body">
<h3 id="p-title">Postpone</h3>
<div id="p-mode" class="segmented" role="group" aria-label="What to move">
<button type="button" data-mode="plan">Plan date</button>
<button type="button" data-mode="due">Deadline</button>
</div>
<p id="p-current" class="muted"></p>
<div id="p-options" class="plan-options"></div>
<div class="row">
<input id="p-date" type="date" aria-label="Pick a date">
<button id="p-set" class="btn primary" type="button">Set</button>
</div>
<div class="dialog-actions">
<button id="p-clear" class="btn" type="button">Remove date</button>
<span class="spacer"></span>
<button id="p-cancel" class="btn" type="button">Cancel</button>
</div>
</div>
</dialog>
<dialog id="project-dialog">
<form id="project-form" class="dialog-body">
<h3 id="pr-dialog-title">Project</h3>
<label class="field">
<span>Name</span>
<input id="pr-name" required maxlength="100" autocomplete="off">
</label>
<div class="row">
<label class="field">
<span>Category</span>
<select id="pr-category"></select>
</label>
<label class="field">
<span>Deadline</span>
<input id="pr-due" type="date">
</label>
</div>
<label class="field">
<span>Goal / notes</span>
<textarea id="pr-notes" rows="4" maxlength="20000"></textarea>
</label>
<label class="check-field">
<input id="pr-done" type="checkbox"> Finished
</label>
<div class="dialog-actions">
<button id="pr-delete" type="button" class="btn danger">Delete</button>
<span class="spacer"></span>
<button id="pr-cancel" type="button" class="btn">Cancel</button>
<button type="submit" class="btn primary">Save</button>
</div>
</form>
</dialog>
<dialog id="settings-dialog">
<div class="dialog-body">
<h3>Settings</h3>
<section class="settings-section">
<h4>Categories</h4>
<ul id="s-cats" class="cat-edit-list"></ul>
<form id="s-cat-add" class="cat-add">
<input id="s-cat-color" type="color" value="#0ea5e9" aria-label="Color">
<input id="s-cat-name" placeholder="New category" maxlength="50" required autocomplete="off">
<button class="btn" type="submit">Add</button>
</form>
</section>
<section class="settings-section">
<h4>Export / import</h4>
<p class="muted">Export downloads all tasks, projects and categories as a JSON file. Import it on
another install, such as production, to move your data there.</p>
<div class="row wrap">
<a id="s-export" class="btn primary" href="api/export" download>Export data</a>
</div>
<div class="row wrap import-row">
<input id="s-import-file" type="file" accept="application/json,.json">
<select id="s-import-mode" aria-label="Import mode">
<option value="merge">Merge (add to current data)</option>
<option value="replace">Replace (delete current data first)</option>
</select>
<button id="s-import-btn" class="btn" type="button">Import</button>
</div>
</section>
<section class="settings-section">
<h4>Session</h4>
<button id="s-logout" class="btn" type="button">Log out</button>
</section>
<div class="dialog-actions">
<span class="spacer"></span>
<button id="s-close" class="btn primary" type="button">Done</button>
</div>
</div>
</dialog>
<div id="toast" class="toast" hidden></div>
</body>
</html>