509b1a1320
Tasks can now have a start/end time on their deadline date. The new Calendar view shows a day as a timeline (with a week strip and projected repeats of recurring tasks), and the task form lists what is already planned that day and flags overlaps. Existing databases are migrated to schema v2 automatically, with a backup copy taken first. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
190 lines
7.4 KiB
HTML
190 lines
7.4 KiB
HTML
<!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">Categories</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>Category</span>
|
||
<select id="t-category"></select>
|
||
</label>
|
||
<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>
|
||
</div>
|
||
<div class="row">
|
||
<label class="field">
|
||
<span>Deadline</span>
|
||
<input id="t-due" type="date">
|
||
</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>
|
||
<div class="quick-dates">
|
||
<button type="button" class="chip-btn" data-days="0">Today</button>
|
||
<button type="button" class="chip-btn" data-days="1">Tomorrow</button>
|
||
<button type="button" class="chip-btn" data-days="7">Next week</button>
|
||
<button type="button" class="chip-btn" data-days="">No date</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>
|
||
<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="4" 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="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 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>
|