@walknpm/todo-cli 1.1.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +208 -141
- package/README.zh-CN.md +158 -150
- package/package.json +20 -6
- package/skill/CHANGELOG.md +8 -0
- package/skill/README.md +48 -0
- package/skill/SKILL.md +224 -0
- package/src/cli.js +396 -24
- package/src/server.js +422 -0
- package/src/todo.js +544 -35
- package/web/css/style.css +804 -0
- package/web/index.html +216 -0
- package/web/js/app.js +934 -0
package/web/index.html
ADDED
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en" data-theme="dark">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>Todo CLI — Web UI</title>
|
|
7
|
+
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>✓</text></svg>">
|
|
8
|
+
<link rel="stylesheet" href="/css/style.css">
|
|
9
|
+
</head>
|
|
10
|
+
<body>
|
|
11
|
+
<!-- ─── Sidebar ─────────────────────────────────────────────── -->
|
|
12
|
+
<aside id="sidebar">
|
|
13
|
+
<div class="sidebar-header">
|
|
14
|
+
<span class="logo">✓</span>
|
|
15
|
+
<span class="app-name">Todo CLI</span>
|
|
16
|
+
<button id="sidebar-close" class="icon-btn mobile-only" aria-label="Close sidebar">✕</button>
|
|
17
|
+
</div>
|
|
18
|
+
|
|
19
|
+
<nav class="sidebar-nav">
|
|
20
|
+
<button class="nav-item active" data-view="dashboard">
|
|
21
|
+
<svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="3" width="7" height="7" rx="1"/><rect x="14" y="3" width="7" height="7" rx="1"/><rect x="3" y="14" width="7" height="7" rx="1"/><rect x="14" y="14" width="7" height="7" rx="1"/></svg>
|
|
22
|
+
<span>Dashboard</span>
|
|
23
|
+
</button>
|
|
24
|
+
<button class="nav-item" data-view="list">
|
|
25
|
+
<svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="8" y1="6" x2="21" y2="6"/><line x1="8" y1="12" x2="21" y2="12"/><line x1="8" y1="18" x2="21" y2="18"/><circle cx="3.5" cy="6" r="1.5"/><circle cx="3.5" cy="12" r="1.5"/><circle cx="3.5" cy="18" r="1.5"/></svg>
|
|
26
|
+
<span>All Todos</span>
|
|
27
|
+
</button>
|
|
28
|
+
<button class="nav-item" data-view="kanban">
|
|
29
|
+
<svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="3" width="6" height="18" rx="1"/><rect x="10" y="3" width="6" height="12" rx="1"/><rect x="17" y="3" width="4" height="8" rx="1"/></svg>
|
|
30
|
+
<span>Kanban Board</span>
|
|
31
|
+
</button>
|
|
32
|
+
<button class="nav-item" data-view="calendar">
|
|
33
|
+
<svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="4" width="18" height="18" rx="2"/><line x1="16" y1="2" x2="16" y2="6"/><line x1="8" y1="2" x2="8" y2="6"/><line x1="3" y1="10" x2="21" y2="10"/></svg>
|
|
34
|
+
<span>Calendar</span>
|
|
35
|
+
</button>
|
|
36
|
+
<button class="nav-item" data-view="timeline">
|
|
37
|
+
<svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><polyline points="12,6 12,12 16,14"/></svg>
|
|
38
|
+
<span>Timeline</span>
|
|
39
|
+
</button>
|
|
40
|
+
</nav>
|
|
41
|
+
|
|
42
|
+
<div class="sidebar-section">
|
|
43
|
+
<div class="section-title">Quick Filters</div>
|
|
44
|
+
<button class="nav-item" data-filter="pending">
|
|
45
|
+
<span class="dot dot-pending"></span>
|
|
46
|
+
<span>Pending</span>
|
|
47
|
+
<span class="badge" id="count-pending">0</span>
|
|
48
|
+
</button>
|
|
49
|
+
<button class="nav-item" data-filter="done">
|
|
50
|
+
<span class="dot dot-done"></span>
|
|
51
|
+
<span>Completed</span>
|
|
52
|
+
<span class="badge" id="count-done">0</span>
|
|
53
|
+
</button>
|
|
54
|
+
<button class="nav-item" data-filter="overdue">
|
|
55
|
+
<span class="dot dot-overdue"></span>
|
|
56
|
+
<span>Overdue</span>
|
|
57
|
+
<span class="badge" id="count-overdue">0</span>
|
|
58
|
+
</button>
|
|
59
|
+
<button class="nav-item" data-filter="today">
|
|
60
|
+
<span class="dot dot-today"></span>
|
|
61
|
+
<span>Due Today</span>
|
|
62
|
+
<span class="badge" id="count-today">0</span>
|
|
63
|
+
</button>
|
|
64
|
+
<button class="nav-item" data-filter="pinned">
|
|
65
|
+
<span>📌</span>
|
|
66
|
+
<span>Pinned</span>
|
|
67
|
+
<span class="badge" id="count-pinned">0</span>
|
|
68
|
+
</button>
|
|
69
|
+
</div>
|
|
70
|
+
|
|
71
|
+
<div class="sidebar-section" id="category-section">
|
|
72
|
+
<div class="section-title">Categories</div>
|
|
73
|
+
<div id="category-list" class="category-list"></div>
|
|
74
|
+
</div>
|
|
75
|
+
|
|
76
|
+
<div class="sidebar-footer">
|
|
77
|
+
<button id="theme-toggle" class="icon-btn" title="Toggle theme">
|
|
78
|
+
<svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/></svg>
|
|
79
|
+
</button>
|
|
80
|
+
<span class="version" id="app-version">v2.0.0</span>
|
|
81
|
+
</div>
|
|
82
|
+
</aside>
|
|
83
|
+
|
|
84
|
+
<!-- ─── Main Content ───────────────────────────────────────── -->
|
|
85
|
+
<main id="main">
|
|
86
|
+
<header id="topbar">
|
|
87
|
+
<button id="sidebar-toggle" class="icon-btn mobile-only" aria-label="Open sidebar">
|
|
88
|
+
<svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="3" y1="12" x2="21" y2="12"/><line x1="3" y1="6" x2="21" y2="6"/><line x1="3" y1="18" x2="21" y2="18"/></svg>
|
|
89
|
+
</button>
|
|
90
|
+
<h1 id="page-title">Dashboard</h1>
|
|
91
|
+
<div class="topbar-actions">
|
|
92
|
+
<div class="search-box">
|
|
93
|
+
<svg class="icon search-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>
|
|
94
|
+
<input type="text" id="search-input" placeholder="Search todos..." autocomplete="off">
|
|
95
|
+
</div>
|
|
96
|
+
<button id="add-btn" class="btn btn-primary">
|
|
97
|
+
<svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg>
|
|
98
|
+
<span>New Todo</span>
|
|
99
|
+
</button>
|
|
100
|
+
</div>
|
|
101
|
+
</header>
|
|
102
|
+
|
|
103
|
+
<div id="content">
|
|
104
|
+
<!-- Views rendered here by JS -->
|
|
105
|
+
</div>
|
|
106
|
+
</main>
|
|
107
|
+
|
|
108
|
+
<!-- ─── Modal: Add/Edit Todo ───────────────────────────────── -->
|
|
109
|
+
<div id="modal-overlay" class="modal-overlay hidden">
|
|
110
|
+
<div id="todo-modal" class="modal">
|
|
111
|
+
<div class="modal-header">
|
|
112
|
+
<h2 id="modal-title">New Todo</h2>
|
|
113
|
+
<button class="icon-btn modal-close" aria-label="Close">✕</button>
|
|
114
|
+
</div>
|
|
115
|
+
<form id="todo-form" class="modal-body">
|
|
116
|
+
<input type="hidden" id="todo-id">
|
|
117
|
+
<div class="form-group">
|
|
118
|
+
<label for="f-title">Title <span class="required">*</span></label>
|
|
119
|
+
<input type="text" id="f-title" required placeholder="What needs to be done?">
|
|
120
|
+
</div>
|
|
121
|
+
<div class="form-row">
|
|
122
|
+
<div class="form-group">
|
|
123
|
+
<label for="f-priority">Priority</label>
|
|
124
|
+
<select id="f-priority">
|
|
125
|
+
<option value="high">🔴 High</option>
|
|
126
|
+
<option value="medium" selected>🟡 Medium</option>
|
|
127
|
+
<option value="low">🟢 Low</option>
|
|
128
|
+
</select>
|
|
129
|
+
</div>
|
|
130
|
+
<div class="form-group">
|
|
131
|
+
<label for="f-category">Category</label>
|
|
132
|
+
<input type="text" id="f-category" placeholder="e.g. work, personal" list="category-datalist">
|
|
133
|
+
<datalist id="category-datalist"></datalist>
|
|
134
|
+
</div>
|
|
135
|
+
</div>
|
|
136
|
+
<div class="form-row">
|
|
137
|
+
<div class="form-group">
|
|
138
|
+
<label for="f-due">Due Date</label>
|
|
139
|
+
<input type="date" id="f-due">
|
|
140
|
+
</div>
|
|
141
|
+
<div class="form-group">
|
|
142
|
+
<label for="f-assignee">Assignee</label>
|
|
143
|
+
<input type="text" id="f-assignee" placeholder="Who's doing it?" list="assignee-datalist">
|
|
144
|
+
<datalist id="assignee-datalist"></datalist>
|
|
145
|
+
</div>
|
|
146
|
+
</div>
|
|
147
|
+
<div class="form-row">
|
|
148
|
+
<div class="form-group">
|
|
149
|
+
<label for="f-estimate">Estimate (minutes)</label>
|
|
150
|
+
<input type="number" id="f-estimate" min="0" placeholder="e.g. 60">
|
|
151
|
+
</div>
|
|
152
|
+
<div class="form-group">
|
|
153
|
+
<label for="f-tags">Tags (comma-separated)</label>
|
|
154
|
+
<input type="text" id="f-tags" placeholder="e.g. urgent, backend">
|
|
155
|
+
</div>
|
|
156
|
+
</div>
|
|
157
|
+
<div class="form-group">
|
|
158
|
+
<label for="f-note">Note</label>
|
|
159
|
+
<textarea id="f-note" rows="3" placeholder="Additional details..."></textarea>
|
|
160
|
+
</div>
|
|
161
|
+
<div class="form-row">
|
|
162
|
+
<div class="form-group">
|
|
163
|
+
<label for="f-recur">Recurrence</label>
|
|
164
|
+
<select id="f-recur">
|
|
165
|
+
<option value="">None</option>
|
|
166
|
+
<option value="daily">Daily</option>
|
|
167
|
+
<option value="weekly">Weekly</option>
|
|
168
|
+
<option value="monthly">Monthly</option>
|
|
169
|
+
<option value="yearly">Yearly</option>
|
|
170
|
+
</select>
|
|
171
|
+
</div>
|
|
172
|
+
<div class="form-group">
|
|
173
|
+
<label for="f-recur-interval">Interval</label>
|
|
174
|
+
<input type="number" id="f-recur-interval" min="1" value="1">
|
|
175
|
+
</div>
|
|
176
|
+
</div>
|
|
177
|
+
<div class="form-check">
|
|
178
|
+
<input type="checkbox" id="f-pinned">
|
|
179
|
+
<label for="f-pinned">📌 Pin to top</label>
|
|
180
|
+
</div>
|
|
181
|
+
<div class="modal-footer">
|
|
182
|
+
<button type="button" class="btn btn-danger hidden" id="delete-btn">Delete</button>
|
|
183
|
+
<button type="button" class="btn btn-secondary modal-close">Cancel</button>
|
|
184
|
+
<button type="submit" class="btn btn-primary">Save</button>
|
|
185
|
+
</div>
|
|
186
|
+
</form>
|
|
187
|
+
</div>
|
|
188
|
+
</div>
|
|
189
|
+
|
|
190
|
+
<!-- ─── Modal: Detail View ─────────────────────────────────── -->
|
|
191
|
+
<div id="detail-overlay" class="modal-overlay hidden">
|
|
192
|
+
<div id="detail-modal" class="modal modal-lg">
|
|
193
|
+
<div class="modal-header">
|
|
194
|
+
<h2 id="detail-title-text">Todo Details</h2>
|
|
195
|
+
<button class="icon-btn modal-close-detail" aria-label="Close">✕</button>
|
|
196
|
+
</div>
|
|
197
|
+
<div id="detail-body" class="modal-body">
|
|
198
|
+
<!-- Filled by JS -->
|
|
199
|
+
</div>
|
|
200
|
+
</div>
|
|
201
|
+
</div>
|
|
202
|
+
|
|
203
|
+
<!-- ─── Toast Container ────────────────────────────────────── -->
|
|
204
|
+
<div id="toast-container"></div>
|
|
205
|
+
|
|
206
|
+
<!-- ─── Floating Timer ─────────────────────────────────────── -->
|
|
207
|
+
<div id="floating-timer" class="floating-timer hidden">
|
|
208
|
+
<span class="timer-icon">⏱</span>
|
|
209
|
+
<span id="timer-label">--</span>
|
|
210
|
+
<span id="timer-time">00:00</span>
|
|
211
|
+
<button id="timer-stop" class="btn btn-sm btn-danger">Stop</button>
|
|
212
|
+
</div>
|
|
213
|
+
|
|
214
|
+
<script type="module" src="/js/app.js"></script>
|
|
215
|
+
</body>
|
|
216
|
+
</html>
|