@knotpad/app 0.1.0 → 0.1.2

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.
Files changed (341) hide show
  1. package/bin/brief.js +165 -78
  2. package/package.json +6 -86
  3. package/app/(app)/calendar/page.tsx +0 -57
  4. package/app/(app)/error.tsx +0 -35
  5. package/app/(app)/graph/page.tsx +0 -32
  6. package/app/(app)/guide/page.tsx +0 -21
  7. package/app/(app)/kanban/loading.tsx +0 -24
  8. package/app/(app)/kanban/page.tsx +0 -59
  9. package/app/(app)/layout.tsx +0 -122
  10. package/app/(app)/list/loading.tsx +0 -21
  11. package/app/(app)/list/page.tsx +0 -137
  12. package/app/(app)/loading.tsx +0 -18
  13. package/app/(app)/notes/[noteId]/page.tsx +0 -84
  14. package/app/(app)/notes/layout.tsx +0 -30
  15. package/app/(app)/notes/page.tsx +0 -39
  16. package/app/(app)/page.tsx +0 -5
  17. package/app/(app)/settings/agent-token/page.tsx +0 -59
  18. package/app/(app)/settings/backup/page.tsx +0 -49
  19. package/app/(app)/settings/billing/page.tsx +0 -53
  20. package/app/(app)/settings/calendar/page.tsx +0 -41
  21. package/app/(app)/settings/layout.test.tsx +0 -39
  22. package/app/(app)/settings/layout.tsx +0 -71
  23. package/app/(app)/settings/page.tsx +0 -4
  24. package/app/(app)/settings/security/page.tsx +0 -43
  25. package/app/(app)/settings/team/page.tsx +0 -74
  26. package/app/(app)/settings/workspace/page.tsx +0 -27
  27. package/app/(app)/tasks/[taskId]/page.tsx +0 -79
  28. package/app/(auth)/forgot-password/page.tsx +0 -106
  29. package/app/(auth)/guest/page.tsx +0 -56
  30. package/app/(auth)/layout.tsx +0 -13
  31. package/app/(auth)/login/page.tsx +0 -14
  32. package/app/(auth)/register/page.tsx +0 -193
  33. package/app/(auth)/reset-password/page.tsx +0 -138
  34. package/app/api/account/claim/route.tsx +0 -135
  35. package/app/api/admin/backfill-encryption/route.tsx +0 -43
  36. package/app/api/admin/license/route.tsx +0 -42
  37. package/app/api/auth/2fa/route.tsx +0 -148
  38. package/app/api/auth/[...nextauth]/route.tsx +0 -3
  39. package/app/api/auth/change-password/route.tsx +0 -61
  40. package/app/api/auth/check-2fa/route.tsx +0 -19
  41. package/app/api/auth/forgot-password/route.tsx +0 -65
  42. package/app/api/auth/reset-password/route.tsx +0 -52
  43. package/app/api/auth/verify-2fa/route.tsx +0 -88
  44. package/app/api/backup/download/db/route.ts +0 -29
  45. package/app/api/backup/download/notes/route.ts +0 -25
  46. package/app/api/backup/settings/route.ts +0 -92
  47. package/app/api/billing/checkout/route.tsx +0 -81
  48. package/app/api/billing/migrate/route.tsx +0 -163
  49. package/app/api/billing/portal/route.tsx +0 -24
  50. package/app/api/billing/setup-intent/route.tsx +0 -55
  51. package/app/api/billing/status/route.tsx +0 -36
  52. package/app/api/billing/subscribe/route.tsx +0 -85
  53. package/app/api/billing/webhook/route.tsx +0 -199
  54. package/app/api/calendar-feeds/[feedId]/route.tsx +0 -67
  55. package/app/api/calendar-feeds/[feedId]/sync/route.tsx +0 -37
  56. package/app/api/calendar-feeds/events/route.tsx +0 -82
  57. package/app/api/calendar-feeds/route.tsx +0 -52
  58. package/app/api/calendar-feeds/sync-all/route.tsx +0 -34
  59. package/app/api/cron/calendar-feeds/route.tsx +0 -31
  60. package/app/api/cron/stale-tasks/route.tsx +0 -51
  61. package/app/api/cron/sync/route.tsx +0 -34
  62. package/app/api/devices/[deviceId]/route.tsx +0 -25
  63. package/app/api/devices/route.tsx +0 -41
  64. package/app/api/export/route.tsx +0 -40
  65. package/app/api/feedback/route.tsx +0 -54
  66. package/app/api/folders/[folderId]/route.tsx +0 -51
  67. package/app/api/folders/route.tsx +0 -37
  68. package/app/api/graph/route.tsx +0 -242
  69. package/app/api/guest/route.tsx +0 -58
  70. package/app/api/health/route.tsx +0 -10
  71. package/app/api/holidays/countries/route.tsx +0 -14
  72. package/app/api/holidays/route.tsx +0 -49
  73. package/app/api/holidays/states/route.tsx +0 -21
  74. package/app/api/invites/[token]/route.tsx +0 -131
  75. package/app/api/invites/route.tsx +0 -74
  76. package/app/api/mcp/generate-token/route.tsx +0 -55
  77. package/app/api/mcp/revoke-token/[tokenId]/route.tsx +0 -30
  78. package/app/api/mcp/update-alias/[tokenId]/route.tsx +0 -22
  79. package/app/api/notes/[noteId]/export/route.tsx +0 -45
  80. package/app/api/notes/[noteId]/route.tsx +0 -360
  81. package/app/api/notes/route.tsx +0 -112
  82. package/app/api/notifications/route.tsx +0 -44
  83. package/app/api/register/route.tsx +0 -67
  84. package/app/api/restore/route.tsx +0 -148
  85. package/app/api/sync/conflicts/[conflictId]/route.tsx +0 -134
  86. package/app/api/sync/conflicts/route.tsx +0 -48
  87. package/app/api/sync/status/route.tsx +0 -49
  88. package/app/api/sync/trigger/route.tsx +0 -15
  89. package/app/api/tasks/[taskId]/detail/route.tsx +0 -68
  90. package/app/api/tasks/[taskId]/route.tsx +0 -259
  91. package/app/api/tasks/bulk/route.tsx +0 -133
  92. package/app/api/tasks/route.tsx +0 -36
  93. package/app/api/workspace/active/route.tsx +0 -39
  94. package/app/api/workspace/create-team/route.tsx +0 -42
  95. package/app/api/workspace/kanban-statuses/route.tsx +0 -71
  96. package/app/api/workspace/members/[memberId]/route.tsx +0 -69
  97. package/app/api/workspace/route.tsx +0 -24
  98. package/app/download/page.tsx +0 -170
  99. package/app/favicon.ico +0 -0
  100. package/app/generated/prisma/client.d.ts +0 -1
  101. package/app/generated/prisma/client.js +0 -5
  102. package/app/generated/prisma/default.d.ts +0 -1
  103. package/app/generated/prisma/default.js +0 -5
  104. package/app/generated/prisma/edge.d.ts +0 -1
  105. package/app/generated/prisma/edge.js +0 -497
  106. package/app/generated/prisma/index-browser.js +0 -523
  107. package/app/generated/prisma/index.d.ts +0 -46376
  108. package/app/generated/prisma/index.js +0 -497
  109. package/app/generated/prisma/package.json +0 -144
  110. package/app/generated/prisma/query_compiler_fast_bg.js +0 -2
  111. package/app/generated/prisma/query_compiler_fast_bg.wasm +0 -0
  112. package/app/generated/prisma/query_compiler_fast_bg.wasm-base64.js +0 -2
  113. package/app/generated/prisma/runtime/client.d.ts +0 -3386
  114. package/app/generated/prisma/runtime/client.js +0 -86
  115. package/app/generated/prisma/runtime/index-browser.d.ts +0 -90
  116. package/app/generated/prisma/runtime/index-browser.js +0 -6
  117. package/app/generated/prisma/runtime/wasm-compiler-edge.js +0 -76
  118. package/app/generated/prisma/schema.prisma +0 -456
  119. package/app/generated/prisma/wasm-edge-light-loader.mjs +0 -5
  120. package/app/generated/prisma/wasm-worker-loader.mjs +0 -5
  121. package/app/globals.css +0 -54
  122. package/app/invite/[token]/page.tsx +0 -52
  123. package/app/layout.tsx +0 -90
  124. package/app/mcp/route.tsx +0 -430
  125. package/app/opengraph-image.tsx +0 -120
  126. package/app/page.tsx +0 -398
  127. package/app/privacy/page.tsx +0 -69
  128. package/app/robots.tsx +0 -25
  129. package/app/sitemap.tsx +0 -36
  130. package/app/terms/page.tsx +0 -69
  131. package/app/upgrade/page.tsx +0 -75
  132. package/auth.config.ts +0 -33
  133. package/auth.ts +0 -79
  134. package/components/auth/login-form.tsx +0 -302
  135. package/components/auth/password-checklist.tsx +0 -31
  136. package/components/auth/password-input.tsx +0 -36
  137. package/components/auth/switch-account-button.test.tsx +0 -22
  138. package/components/auth/switch-account-button.tsx +0 -19
  139. package/components/auth/two-factor-input.tsx +0 -116
  140. package/components/billing/billing-dashboard.tsx +0 -265
  141. package/components/billing/card-form.tsx +0 -210
  142. package/components/billing/claim-account-form.tsx +0 -99
  143. package/components/branding/app-logo.test.tsx +0 -20
  144. package/components/branding/app-logo.tsx +0 -25
  145. package/components/calendar/calendar-agenda.tsx +0 -150
  146. package/components/calendar/calendar-drag.test.tsx +0 -177
  147. package/components/calendar/calendar-grid.tsx +0 -357
  148. package/components/calendar/calendar-hooks.test.tsx +0 -27
  149. package/components/calendar/calendar-hooks.ts +0 -351
  150. package/components/calendar/calendar-toolbar.test.tsx +0 -68
  151. package/components/calendar/calendar-toolbar.tsx +0 -291
  152. package/components/calendar/calendar-types.ts +0 -148
  153. package/components/calendar/calendar-view.test.tsx +0 -295
  154. package/components/calendar/calendar-view.tsx +0 -307
  155. package/components/calendar/day-detail-popover.tsx +0 -174
  156. package/components/calendar/task-chip.tsx +0 -86
  157. package/components/command/command-palette.test.tsx +0 -33
  158. package/components/command/command-palette.tsx +0 -310
  159. package/components/download-cta.tsx +0 -87
  160. package/components/feedback/feedback-popup.tsx +0 -207
  161. package/components/graph/graph-draw.ts +0 -337
  162. package/components/graph/graph-overlays.tsx +0 -160
  163. package/components/graph/graph-page.test.tsx +0 -131
  164. package/components/graph/graph-page.tsx +0 -263
  165. package/components/graph/graph-types.ts +0 -47
  166. package/components/graph/graph-view.tsx +0 -322
  167. package/components/guide/guide-view.tsx +0 -522
  168. package/components/kanban/kanban-board.test.tsx +0 -128
  169. package/components/kanban/kanban-board.tsx +0 -361
  170. package/components/kanban/kanban-card-menu.tsx +0 -102
  171. package/components/kanban/kanban-card.tsx +0 -227
  172. package/components/kanban/kanban-column.tsx +0 -49
  173. package/components/kanban/kanban-status-context.tsx +0 -28
  174. package/components/landing/calendar-sandbox.test.tsx +0 -15
  175. package/components/landing/calendar-sandbox.tsx +0 -107
  176. package/components/landing/graph-sandbox.test.tsx +0 -27
  177. package/components/landing/graph-sandbox.tsx +0 -80
  178. package/components/landing/kanban-sandbox.test.tsx +0 -24
  179. package/components/landing/kanban-sandbox.tsx +0 -101
  180. package/components/landing/landing-showcase.test.tsx +0 -21
  181. package/components/landing/landing-showcase.tsx +0 -54
  182. package/components/landing/list-sandbox.tsx +0 -86
  183. package/components/landing/mock-workspace.ts +0 -168
  184. package/components/landing/notes-sandbox.test.tsx +0 -14
  185. package/components/landing/notes-sandbox.tsx +0 -88
  186. package/components/layout/app-shell.tsx +0 -83
  187. package/components/layout/backup-scheduler.tsx +0 -122
  188. package/components/layout/bottom-nav.tsx +0 -43
  189. package/components/layout/icon-bar.test.tsx +0 -29
  190. package/components/layout/icon-bar.tsx +0 -118
  191. package/components/layout/mobile-top-bar.tsx +0 -68
  192. package/components/layout/notes-panel-folder.tsx +0 -127
  193. package/components/layout/notes-panel-note-item.tsx +0 -140
  194. package/components/layout/notes-panel-task-tab.tsx +0 -63
  195. package/components/layout/notes-panel-types.ts +0 -44
  196. package/components/layout/notes-panel.tsx +0 -476
  197. package/components/layout/notification-bell.tsx +0 -251
  198. package/components/layout/paywall-screen.tsx +0 -41
  199. package/components/layout/pro-banner.tsx +0 -76
  200. package/components/layout/sw-register.tsx +0 -27
  201. package/components/layout/workspace-switcher.tsx +0 -90
  202. package/components/notes/mobile-bottom-sheet.tsx +0 -99
  203. package/components/notes/note-editor-context-menu.tsx +0 -47
  204. package/components/notes/note-editor-dom.ts +0 -33
  205. package/components/notes/note-editor-dropdowns.tsx +0 -484
  206. package/components/notes/note-editor-hooks.ts +0 -692
  207. package/components/notes/note-editor-keyboard.ts +0 -305
  208. package/components/notes/note-editor-overlay.tsx +0 -90
  209. package/components/notes/note-editor.test.tsx +0 -372
  210. package/components/notes/note-editor.tsx +0 -662
  211. package/components/notes/note-preview-pane.tsx +0 -156
  212. package/components/notes/note-tabs.tsx +0 -120
  213. package/components/notes/note-types.tsx +0 -157
  214. package/components/settings/accept-invite.tsx +0 -108
  215. package/components/settings/agent-token-settings.tsx +0 -369
  216. package/components/settings/backup-restore-settings.test.tsx +0 -25
  217. package/components/settings/backup-restore-settings.tsx +0 -327
  218. package/components/settings/calendar-feeds-settings.tsx +0 -489
  219. package/components/settings/calendar-general-settings.tsx +0 -174
  220. package/components/settings/confirm-danger-action.test.tsx +0 -215
  221. package/components/settings/confirm-danger-action.tsx +0 -65
  222. package/components/settings/security-settings.tsx +0 -252
  223. package/components/settings/settings-guidance.test.tsx +0 -98
  224. package/components/settings/team-settings.tsx +0 -319
  225. package/components/settings/two-factor-auth.tsx +0 -296
  226. package/components/settings/workspace-settings-client.tsx +0 -363
  227. package/components/settings/workspace-settings-form.tsx +0 -73
  228. package/components/sync/conflict-viewer.tsx +0 -247
  229. package/components/sync/sync-indicator.tsx +0 -171
  230. package/components/tasks/snippet-thread.tsx +0 -119
  231. package/components/tasks/status-dot.tsx +0 -47
  232. package/components/tasks/task-badge.tsx +0 -43
  233. package/components/tasks/task-detail.test.tsx +0 -187
  234. package/components/tasks/task-detail.tsx +0 -458
  235. package/components/tasks/task-list-filters.test.tsx +0 -75
  236. package/components/tasks/task-list-filters.tsx +0 -163
  237. package/components/tasks/task-list-types.ts +0 -20
  238. package/components/tasks/task-list.test.tsx +0 -175
  239. package/components/tasks/task-list.tsx +0 -481
  240. package/components/tasks/task-row.tsx +0 -85
  241. package/components/tasks/task-table-row.tsx +0 -259
  242. package/components/ui/skeleton.tsx +0 -3
  243. package/components/ui/toast.test.tsx +0 -42
  244. package/components/ui/toast.tsx +0 -70
  245. package/electron/main.ts +0 -251
  246. package/electron/preload.ts +0 -56
  247. package/instrumentation.tsx +0 -23
  248. package/lib/api-error.ts +0 -50
  249. package/lib/backup/backup-runner.test.ts +0 -32
  250. package/lib/backup/backup-runner.ts +0 -19
  251. package/lib/backup/backup-schedule.test.ts +0 -23
  252. package/lib/backup/backup-schedule.ts +0 -55
  253. package/lib/backup/backup-settings.test.ts +0 -30
  254. package/lib/backup/backup-settings.ts +0 -27
  255. package/lib/backup/export-notes-zip.test.ts +0 -26
  256. package/lib/backup/export-notes-zip.ts +0 -82
  257. package/lib/backup/export-workspace-backup.test.ts +0 -17
  258. package/lib/backup/export-workspace-backup.ts +0 -77
  259. package/lib/backup/restore-workspace-from-export.test.ts +0 -18
  260. package/lib/backup/restore-workspace-from-export.ts +0 -183
  261. package/lib/backup/types.ts +0 -14
  262. package/lib/brand-icons.ts +0 -1
  263. package/lib/calendar-feed-crypto.ts +0 -38
  264. package/lib/calendar-feed.ts +0 -239
  265. package/lib/client/online-status.ts +0 -47
  266. package/lib/conflict-resolver.test.ts +0 -57
  267. package/lib/conflict-resolver.ts +0 -240
  268. package/lib/db-init.ts +0 -79
  269. package/lib/email.ts +0 -159
  270. package/lib/encryption.test.ts +0 -41
  271. package/lib/encryption.ts +0 -98
  272. package/lib/extract-snippet.test.ts +0 -123
  273. package/lib/extract-snippet.ts +0 -69
  274. package/lib/kanban-status.ts +0 -55
  275. package/lib/license.ts +0 -21
  276. package/lib/limits.ts +0 -31
  277. package/lib/mcp-auth.test.ts +0 -58
  278. package/lib/mcp-auth.ts +0 -65
  279. package/lib/mcp-contract.test.ts +0 -25
  280. package/lib/mcp-contract.ts +0 -210
  281. package/lib/mcp-handler.ts +0 -31
  282. package/lib/mcp-url.test.ts +0 -12
  283. package/lib/mcp-url.ts +0 -7
  284. package/lib/mentions.test.ts +0 -45
  285. package/lib/mentions.ts +0 -73
  286. package/lib/note-crypto.ts +0 -108
  287. package/lib/note-sync.ts +0 -201
  288. package/lib/note-title.ts +0 -93
  289. package/lib/prisma.ts +0 -193
  290. package/lib/pro-flush.ts +0 -292
  291. package/lib/rate-limit.ts +0 -57
  292. package/lib/stripe.ts +0 -38
  293. package/lib/sync-worker.ts +0 -388
  294. package/lib/task-parser.test.ts +0 -91
  295. package/lib/task-parser.ts +0 -81
  296. package/lib/task-utils.ts +0 -52
  297. package/lib/use-is-electron.ts +0 -19
  298. package/lib/use-is-mobile.ts +0 -22
  299. package/lib/validation/calendar-feed.ts +0 -31
  300. package/lib/validation/note.ts +0 -27
  301. package/lib/validation/task.ts +0 -26
  302. package/lib/view-preferences.test.ts +0 -54
  303. package/lib/view-preferences.ts +0 -28
  304. package/lib/workspace.ts +0 -66
  305. package/next.config.ts +0 -21
  306. package/postcss.config.mjs +0 -7
  307. package/prisma/migrations/20260519021916_init/migration.sql +0 -388
  308. package/prisma/migrations/20260519061113_drop_sync_password/migration.sql +0 -8
  309. package/prisma/migrations/20260520065016_add_task_start_date/migration.sql +0 -2
  310. package/prisma/migrations/20260529010600_remove_encryption_fields/migration.sql +0 -12
  311. package/prisma/migrations/20260529020000_restore_encryption_salt/migration.sql +0 -3
  312. package/prisma/migrations/20260529030000_add_folders/migration.sql +0 -17
  313. package/prisma/migrations/20260605000000_deferred_fixes/migration.sql +0 -31
  314. package/prisma/migrations/20260605020806_add_pending_sync_to_note_and_task/migration.sql +0 -5
  315. package/prisma/migrations/20260605063634_add_stripe_webhook_event_sync_lock/migration.sql +0 -14
  316. package/prisma/migrations/20260605100000_add_prod_indexes/migration.sql +0 -26
  317. package/prisma/migrations/20260608081404_add_kanban_statuses/migration.sql +0 -23
  318. package/prisma/migrations/20260611032723_add_calendar_feeds/migration.sql +0 -43
  319. package/prisma/migrations/20260611040000_add_calendar_feed_color/migration.sql +0 -2
  320. package/prisma/migrations/20260611050000_add_task_priority/migration.sql +0 -14
  321. package/prisma/migrations/20260612060000_add_critical_priority/migration.sql +0 -2
  322. package/prisma/migrations/20260613090000_add_backup_settings/migration.sql +0 -25
  323. package/prisma/migrations/20260614160000_add_feedback/migration.sql +0 -20
  324. package/prisma/migrations/20260614210000_add_2fa/migration.sql +0 -4
  325. package/prisma/migrations/migration_lock.toml +0 -3
  326. package/prisma/schema.prisma +0 -457
  327. package/public/Logo_icon.svg +0 -1
  328. package/public/file.svg +0 -1
  329. package/public/globe.svg +0 -1
  330. package/public/icon-192.png +0 -0
  331. package/public/icon-512.png +0 -0
  332. package/public/icon.svg +0 -4
  333. package/public/icon_dark.svg +0 -1
  334. package/public/knotpad_icon.svg +0 -1
  335. package/public/knotpad_logo_full.svg +0 -1
  336. package/public/manifest.json +0 -14
  337. package/public/next.svg +0 -1
  338. package/public/sw.js +0 -137
  339. package/public/vercel.svg +0 -1
  340. package/public/window.svg +0 -1
  341. package/tsconfig.json +0 -35
@@ -1,522 +0,0 @@
1
- "use client";
2
-
3
- import { useState } from "react";
4
- import {
5
- FileText,
6
- Kanban,
7
- List,
8
- Calendar,
9
- Network,
10
- Settings,
11
- Bell,
12
- Search,
13
- Users,
14
- Shield,
15
- Zap,
16
- BookOpen,
17
- } from "lucide-react";
18
-
19
- type Section = {
20
- id: string;
21
- icon: typeof FileText;
22
- title: string;
23
- content: React.ReactNode;
24
- };
25
-
26
- const sections: Section[] = [
27
- {
28
- id: "overview",
29
- icon: BookOpen,
30
- title: "Overview",
31
- content: (
32
- <div className="space-y-4">
33
- <p className="text-sm text-zinc-300 leading-relaxed">
34
- <strong className="text-zinc-100">Knotpad</strong> is a note-first project management tool designed for
35
- individuals and teams who want to organize their work around written context rather than just task lists.
36
- </p>
37
- <p className="text-sm text-zinc-300 leading-relaxed">
38
- Unlike traditional project management tools that start with tasks, Knotpad starts with <strong className="text-zinc-100">notes</strong>.
39
- Each note can contain multiple tasks, and tasks can be viewed across different perspectives: Kanban boards,
40
- list views, calendar timelines, and relationship graphs.
41
- </p>
42
- <div className="rounded-lg border border-zinc-800 bg-zinc-900/50 p-4">
43
- <h4 className="text-xs font-semibold text-zinc-400 uppercase tracking-wider mb-2">Core Concepts</h4>
44
- <ul className="space-y-2 text-sm text-zinc-300">
45
- <li className="flex items-start gap-2">
46
- <span className="text-zinc-500">•</span>
47
- <span><strong>Notes:</strong> Your primary documents - project specs, meeting notes, ideas, or any written context</span>
48
- </li>
49
- <li className="flex items-start gap-2">
50
- <span className="text-zinc-500">•</span>
51
- <span><strong>Tasks:</strong> Action items extracted from notes with status, priority, and assignment</span>
52
- </li>
53
- <li className="flex items-start gap-2">
54
- <span className="text-zinc-500">•</span>
55
- <span><strong>Folders:</strong> Organize notes into collections for better navigation</span>
56
- </li>
57
- <li className="flex items-start gap-2">
58
- <span className="text-zinc-500">•</span>
59
- <span><strong>Workspaces:</strong> Separate environments for different teams or projects</span>
60
- </li>
61
- </ul>
62
- </div>
63
- </div>
64
- ),
65
- },
66
- {
67
- id: "notes",
68
- icon: FileText,
69
- title: "Notes & Editor",
70
- content: (
71
- <div className="space-y-4">
72
- <p className="text-sm text-zinc-300 leading-relaxed">
73
- The <strong className="text-zinc-100">Notes</strong> module is your main workspace for writing and editing.
74
- Notes support rich formatting and can contain tasks that appear across all views.
75
- </p>
76
- <div className="grid gap-3">
77
- <div className="rounded-lg border border-zinc-800 bg-zinc-900/50 p-3">
78
- <h4 className="text-xs font-medium text-zinc-200 mb-1">Creating Notes</h4>
79
- <p className="text-xs text-zinc-400">
80
- Click the "+" button in the notes panel or press ⌘+N (Ctrl+N on Windows) to create a new note.
81
- Notes are auto-saved as you type.
82
- </p>
83
- </div>
84
- <div className="rounded-lg border border-zinc-800 bg-zinc-900/50 p-3">
85
- <h4 className="text-xs font-medium text-zinc-200 mb-1">Task Extraction</h4>
86
- <p className="text-xs text-zinc-400">
87
- Type "- [ ]" or "1. [ ]" at the start of a line to create a task checkbox.
88
- These tasks automatically appear in your Kanban, List, and Calendar views.
89
- </p>
90
- </div>
91
- <div className="rounded-lg border border-zinc-800 bg-zinc-900/50 p-3">
92
- <h4 className="text-xs font-medium text-zinc-200 mb-1">Folders</h4>
93
- <p className="text-xs text-zinc-400">
94
- Organize notes by dragging them into folders. Create folders from the sidebar menu.
95
- Folders help group related projects or contexts together.
96
- </p>
97
- </div>
98
- </div>
99
- </div>
100
- ),
101
- },
102
- {
103
- id: "kanban",
104
- icon: Kanban,
105
- title: "Kanban Board",
106
- content: (
107
- <div className="space-y-4">
108
- <p className="text-sm text-zinc-300 leading-relaxed">
109
- The <strong className="text-zinc-100">Kanban</strong> view displays tasks as cards organized by status columns.
110
- Drag and drop tasks between columns to update their status.
111
- </p>
112
- <div className="grid gap-3">
113
- <div className="rounded-lg border border-zinc-800 bg-zinc-900/50 p-3">
114
- <h4 className="text-xs font-medium text-zinc-200 mb-1">Status Columns</h4>
115
- <p className="text-xs text-zinc-400">
116
- Default columns: Open, Claimed, In Progress, Review, Done.
117
- Admins can customize columns in Settings → Kanban Statuses.
118
- </p>
119
- </div>
120
- <div className="rounded-lg border border-zinc-800 bg-zinc-900/50 p-3">
121
- <h4 className="text-xs font-medium text-zinc-200 mb-1">Task Cards</h4>
122
- <p className="text-xs text-zinc-400">
123
- Each card shows the task title, priority indicator, assignee, and linked note.
124
- Click any card to open its note in the editor.
125
- </p>
126
- </div>
127
- <div className="rounded-lg border border-zinc-800 bg-zinc-900/50 p-3">
128
- <h4 className="text-xs font-medium text-zinc-200 mb-1">Claiming Tasks</h4>
129
- <p className="text-xs text-zinc-400">
130
- Click "Claim" on a task to take ownership and start working on it.
131
- Tasks auto-release if you go offline for too long, allowing others to pick them up.
132
- </p>
133
- </div>
134
- </div>
135
- </div>
136
- ),
137
- },
138
- {
139
- id: "list",
140
- icon: List,
141
- title: "List View",
142
- content: (
143
- <div className="space-y-4">
144
- <p className="text-sm text-zinc-300 leading-relaxed">
145
- The <strong className="text-zinc-100">List</strong> view provides a compact, filterable table of all tasks.
146
- Great for quick scanning and bulk operations.
147
- </p>
148
- <div className="grid gap-3">
149
- <div className="rounded-lg border border-zinc-800 bg-zinc-900/50 p-3">
150
- <h4 className="text-xs font-medium text-zinc-200 mb-1">Sorting & Filtering</h4>
151
- <p className="text-xs text-zinc-400">
152
- Click column headers to sort. Use the search bar to filter by task title,
153
- note name, or assignee. Filter by status using the dropdown.
154
- </p>
155
- </div>
156
- <div className="rounded-lg border border-zinc-800 bg-zinc-900/50 p-3">
157
- <h4 className="text-xs font-medium text-zinc-200 mb-1">Inline Editing</h4>
158
- <p className="text-xs text-zinc-400">
159
- Click any task title to edit it inline. Status and priority can be changed
160
- via dropdown menus on each row.
161
- </p>
162
- </div>
163
- <div className="rounded-lg border border-zinc-800 bg-zinc-900/50 p-3">
164
- <h4 className="text-xs font-medium text-zinc-200 mb-1">Bulk Selection</h4>
165
- <p className="text-xs text-zinc-400">
166
- Select multiple tasks using checkboxes to perform bulk actions like
167
- changing status or priority for several tasks at once.
168
- </p>
169
- </div>
170
- </div>
171
- </div>
172
- ),
173
- },
174
- {
175
- id: "calendar",
176
- icon: Calendar,
177
- title: "Calendar",
178
- content: (
179
- <div className="space-y-4">
180
- <p className="text-sm text-zinc-300 leading-relaxed">
181
- The <strong className="text-zinc-100">Calendar</strong> view shows tasks with due dates across a monthly timeline.
182
- External calendar feeds (Google/Apple) can be overlaid for context.
183
- </p>
184
- <div className="grid gap-3">
185
- <div className="rounded-lg border border-zinc-800 bg-zinc-900/50 p-3">
186
- <h4 className="text-xs font-medium text-zinc-200 mb-1">Setting Due Dates</h4>
187
- <p className="text-xs text-zinc-400">
188
- Click the "+" button next to a task or use the date picker in task details
189
- to set start and due dates. Tasks with dates appear on the calendar.
190
- </p>
191
- </div>
192
- <div className="rounded-lg border border-zinc-800 bg-zinc-900/50 p-3">
193
- <h4 className="text-xs font-medium text-zinc-200 mb-1">Calendar Feeds</h4>
194
- <p className="text-xs text-zinc-400">
195
- Add external calendars in Settings → Calendar Feeds. Paste your Google/Apple
196
- calendar's "secret iCal URL" to overlay meetings alongside tasks.
197
- </p>
198
- </div>
199
- <div className="rounded-lg border border-zinc-800 bg-zinc-900/50 p-3">
200
- <h4 className="text-xs font-medium text-zinc-200 mb-1">Day Detail</h4>
201
- <p className="text-xs text-zinc-400">
202
- Click any date to see all tasks and events for that day.
203
- Drag tasks between days to reschedule their due dates.
204
- </p>
205
- </div>
206
- </div>
207
- </div>
208
- ),
209
- },
210
- {
211
- id: "graph",
212
- icon: Network,
213
- title: "Graph View",
214
- content: (
215
- <div className="space-y-4">
216
- <p className="text-sm text-zinc-300 leading-relaxed">
217
- The <strong className="text-zinc-100">Graph</strong> view visualizes relationships between notes and tasks
218
- as a network diagram. Useful for understanding connections in complex projects.
219
- </p>
220
- <div className="grid gap-3">
221
- <div className="rounded-lg border border-zinc-800 bg-zinc-900/50 p-3">
222
- <h4 className="text-xs font-medium text-zinc-200 mb-1">Node Types</h4>
223
- <p className="text-xs text-zinc-400">
224
- Notes appear as larger nodes, tasks as smaller nodes.
225
- Lines show relationships between notes and their tasks.
226
- </p>
227
- </div>
228
- <div className="rounded-lg border border-zinc-800 bg-zinc-900/50 p-3">
229
- <h4 className="text-xs font-medium text-zinc-200 mb-1">Navigation</h4>
230
- <p className="text-xs text-zinc-400">
231
- Click and drag to pan, scroll to zoom. Click a node to focus on it
232
- and see only its connected items. Double-click to open the note.
233
- </p>
234
- </div>
235
- <div className="rounded-lg border border-zinc-800 bg-zinc-900/50 p-3">
236
- <h4 className="text-xs font-medium text-zinc-200 mb-1">Task References</h4>
237
- <p className="text-xs text-zinc-400">
238
- When you mention a task ID in another note, a reference link is created.
239
- These references appear as connections in the graph view.
240
- </p>
241
- </div>
242
- </div>
243
- </div>
244
- ),
245
- },
246
- {
247
- id: "search",
248
- icon: Search,
249
- title: "Search & Command",
250
- content: (
251
- <div className="space-y-4">
252
- <p className="text-sm text-zinc-300 leading-relaxed">
253
- <strong className="text-zinc-100">Command Palette</strong> (⌘K) is your quick access tool
254
- for finding notes, tasks, and actions without leaving the keyboard.
255
- </p>
256
- <div className="grid gap-3">
257
- <div className="rounded-lg border border-zinc-800 bg-zinc-900/50 p-3">
258
- <h4 className="text-xs font-medium text-zinc-200 mb-1">Opening the Palette</h4>
259
- <p className="text-xs text-zinc-400">
260
- Press ⌘+K (Ctrl+K) or click the search icon in the sidebar.
261
- Type to filter results instantly across notes and tasks.
262
- </p>
263
- </div>
264
- <div className="rounded-lg border border-zinc-800 bg-zinc-900/50 p-3">
265
- <h4 className="text-xs font-medium text-zinc-200 mb-1">Quick Actions</h4>
266
- <p className="text-xs text-zinc-400">
267
- Type "/" to see available commands like "Create note", "Go to Kanban",
268
- or "Toggle theme". Navigate with arrow keys, confirm with Enter.
269
- </p>
270
- </div>
271
- </div>
272
- </div>
273
- ),
274
- },
275
- {
276
- id: "notifications",
277
- icon: Bell,
278
- title: "Notifications",
279
- content: (
280
- <div className="space-y-4">
281
- <p className="text-sm text-zinc-300 leading-relaxed">
282
- Stay informed about task assignments, status changes, and team activity
283
- through the notification system.
284
- </p>
285
- <div className="grid gap-3">
286
- <div className="rounded-lg border border-zinc-800 bg-zinc-900/50 p-3">
287
- <h4 className="text-xs font-medium text-zinc-200 mb-1">Notification Types</h4>
288
- <p className="text-xs text-zinc-400">
289
- • <strong>Task Assigned:</strong> Someone assigned you a task<br />
290
- • <strong>Status Change:</strong> A task you own changed status<br />
291
- • <strong>Invite Accepted:</strong> Someone joined your workspace<br />
292
- • <strong>Takeover:</strong> Your stale claim was released
293
- </p>
294
- </div>
295
- <div className="rounded-lg border border-zinc-800 bg-zinc-900/50 p-3">
296
- <h4 className="text-xs font-medium text-zinc-200 mb-1">Managing Notifications</h4>
297
- <p className="text-xs text-zinc-400">
298
- Click the bell icon to open the notification panel.
299
- Mark individual items read or "Mark all read" to clear the list.
300
- </p>
301
- </div>
302
- </div>
303
- </div>
304
- ),
305
- },
306
- {
307
- id: "team",
308
- icon: Users,
309
- title: "Team & Collaboration",
310
- content: (
311
- <div className="space-y-4">
312
- <p className="text-sm text-zinc-300 leading-relaxed">
313
- <strong className="text-zinc-100">Workspaces</strong> are collaborative environments where teams
314
- share notes and tasks. Personal workspaces are private by default.
315
- </p>
316
- <div className="grid gap-3">
317
- <div className="rounded-lg border border-zinc-800 bg-zinc-900/50 p-3">
318
- <h4 className="text-xs font-medium text-zinc-200 mb-1">Inviting Members</h4>
319
- <p className="text-xs text-zinc-400">
320
- Go to Settings → Team Members. Enter email addresses to send invites.
321
- New members can be Admins (full access) or Members (can edit, can't manage).
322
- </p>
323
- </div>
324
- <div className="rounded-lg border border-zinc-800 bg-zinc-900/50 p-3">
325
- <h4 className="text-xs font-medium text-zinc-200 mb-1">Task Assignment</h4>
326
- <p className="text-xs text-zinc-400">
327
- Click the assignee area on any task to assign it to a team member.
328
- Assigned tasks appear in their personal views and notifications.
329
- </p>
330
- </div>
331
- <div className="rounded-lg border border-zinc-800 bg-zinc-900/50 p-3">
332
- <h4 className="text-xs font-medium text-zinc-200 mb-1">Workspace Switcher</h4>
333
- <p className="text-xs text-zinc-400">
334
- Use the workspace dropdown in the sidebar to switch between personal
335
- and team workspaces. Each workspace has isolated notes and tasks.
336
- </p>
337
- </div>
338
- </div>
339
- </div>
340
- ),
341
- },
342
- {
343
- id: "settings",
344
- icon: Settings,
345
- title: "Settings",
346
- content: (
347
- <div className="space-y-4">
348
- <p className="text-sm text-zinc-300 leading-relaxed">
349
- Customize your Knotpad experience through the various settings panels.
350
- </p>
351
- <div className="grid gap-3">
352
- <div className="rounded-lg border border-zinc-800 bg-zinc-900/50 p-3">
353
- <h4 className="text-xs font-medium text-zinc-200 mb-1">Workspace Settings</h4>
354
- <p className="text-xs text-zinc-400">
355
- Rename workspace, update slug (URL identifier), manage cloud sync preferences.
356
- Only owners and admins can change workspace settings.
357
- </p>
358
- </div>
359
- <div className="rounded-lg border border-zinc-800 bg-zinc-900/50 p-3">
360
- <h4 className="text-xs font-medium text-zinc-200 mb-1">Kanban Statuses</h4>
361
- <p className="text-xs text-zinc-400">
362
- Customize the columns in your Kanban board. Add, rename, reorder, or hide statuses.
363
- Each status has a color for visual organization.
364
- </p>
365
- </div>
366
- <div className="rounded-lg border border-zinc-800 bg-zinc-900/50 p-3">
367
- <h4 className="text-xs font-medium text-zinc-200 mb-1">Calendar Feeds</h4>
368
- <p className="text-xs text-zinc-400">
369
- Add external calendar URLs (Google, Apple, Outlook) to overlay on your task calendar.
370
- Feeds are personal - other members don't see your calendar events.
371
- </p>
372
- </div>
373
- <div className="rounded-lg border border-zinc-800 bg-zinc-900/50 p-3">
374
- <h4 className="text-xs font-medium text-zinc-200 mb-1">Backup & Export</h4>
375
- <p className="text-xs text-zinc-400">
376
- Schedule automatic backups or export your workspace data as JSON or Markdown ZIP.
377
- Backups include all notes, tasks, and folder structure.
378
- </p>
379
- </div>
380
- </div>
381
- </div>
382
- ),
383
- },
384
- {
385
- id: "security",
386
- icon: Shield,
387
- title: "Security & Privacy",
388
- content: (
389
- <div className="space-y-4">
390
- <p className="text-sm text-zinc-300 leading-relaxed">
391
- Knotpad is designed with security in mind for both personal and team use.
392
- </p>
393
- <div className="grid gap-3">
394
- <div className="rounded-lg border border-zinc-800 bg-zinc-900/50 p-3">
395
- <h4 className="text-xs font-medium text-zinc-200 mb-1">Authentication</h4>
396
- <p className="text-xs text-zinc-400">
397
- Secure password-based login with session management.
398
- All passwords are hashed using bcrypt before storage.
399
- </p>
400
- </div>
401
- <div className="rounded-lg border border-zinc-800 bg-zinc-900/50 p-3">
402
- <h4 className="text-xs font-medium text-zinc-200 mb-1">Data Encryption</h4>
403
- <p className="text-xs text-zinc-400">
404
- Calendar feed URLs are encrypted at rest using per-row salts.
405
- All data is served over HTTPS. Notes are stored securely with workspace-level isolation.
406
- </p>
407
- </div>
408
- <div className="rounded-lg border border-zinc-800 bg-zinc-900/50 p-3">
409
- <h4 className="text-xs font-medium text-zinc-200 mb-1">Device Sessions</h4>
410
- <p className="text-xs text-zinc-400">
411
- View and manage active logins from Settings → Security.
412
- Revoke access from devices you no longer use.
413
- </p>
414
- </div>
415
- </div>
416
- </div>
417
- ),
418
- },
419
- {
420
- id: "pro",
421
- icon: Zap,
422
- title: "Pro Features",
423
- content: (
424
- <div className="space-y-4">
425
- <p className="text-sm text-zinc-300 leading-relaxed">
426
- Upgrade to Pro to unlock additional capabilities for power users and teams.
427
- </p>
428
- <div className="grid gap-3">
429
- <div className="rounded-lg border border-zinc-800 bg-zinc-900/50 p-3">
430
- <h4 className="text-xs font-medium text-zinc-200 mb-1">Cloud Sync</h4>
431
- <p className="text-xs text-zinc-400">
432
- Pro workspaces sync across all your devices in real-time.
433
- Access your notes and tasks from desktop, web, and mobile apps.
434
- </p>
435
- </div>
436
- <div className="rounded-lg border border-zinc-800 bg-zinc-900/50 p-3">
437
- <h4 className="text-xs font-medium text-zinc-200 mb-1">Team Workspaces</h4>
438
- <p className="text-xs text-zinc-400">
439
- Create unlimited team workspaces with multiple members.
440
- Perfect for agencies, departments, or project teams.
441
- </p>
442
- </div>
443
- <div className="rounded-lg border border-zinc-800 bg-zinc-900/50 p-3">
444
- <h4 className="text-xs font-medium text-zinc-200 mb-1">Priority Support</h4>
445
- <p className="text-xs text-zinc-400">
446
- Pro users get priority response on feedback and support requests.
447
- Direct access to the product team for feature requests.
448
- </p>
449
- </div>
450
- </div>
451
- </div>
452
- ),
453
- },
454
- ];
455
-
456
- export function GuideView() {
457
- const [activeSection, setActiveSection] = useState<string>("overview");
458
- const [sidebarOpen, setSidebarOpen] = useState(false);
459
-
460
- const activeContent = sections.find((s) => s.id === activeSection);
461
-
462
- return (
463
- <div className="flex flex-1 overflow-hidden relative">
464
- {/* Mobile sidebar toggle */}
465
- <button
466
- onClick={() => setSidebarOpen(!sidebarOpen)}
467
- className="lg:hidden absolute top-4 left-4 z-20 p-2 rounded-md bg-zinc-900 border border-zinc-800 text-zinc-400 hover:text-zinc-200"
468
- aria-label="Toggle menu"
469
- >
470
- <BookOpen size={16} />
471
- </button>
472
-
473
- {/* Sidebar */}
474
- <aside className={`fixed inset-y-0 left-0 z-10 w-64 border-r border-zinc-800 bg-zinc-950 overflow-y-auto transform transition-transform duration-200 lg:relative lg:transform-none ${sidebarOpen ? 'translate-x-0' : '-translate-x-full lg:translate-x-0'}`}>
475
- <nav className="p-2 space-y-0.5">
476
- {sections.map((section) => {
477
- const Icon = section.icon;
478
- const isActive = section.id === activeSection;
479
- return (
480
- <button
481
- key={section.id}
482
- onClick={() => {
483
- setActiveSection(section.id);
484
- setSidebarOpen(false);
485
- }}
486
- className={`w-full flex items-center gap-2.5 rounded-md px-3 py-2 text-left text-xs transition-colors ${
487
- isActive
488
- ? "bg-zinc-800 text-zinc-200"
489
- : "text-zinc-400 hover:bg-zinc-800/50 hover:text-zinc-300"
490
- }`}
491
- >
492
- <Icon size={14} className={isActive ? "text-zinc-200" : "text-zinc-500"} />
493
- <span className="font-medium">{section.title}</span>
494
- </button>
495
- );
496
- })}
497
- </nav>
498
- </aside>
499
-
500
- {/* Mobile overlay */}
501
- {sidebarOpen && (
502
- <div
503
- className="fixed inset-0 bg-black/50 z-0 lg:hidden"
504
- onClick={() => setSidebarOpen(false)}
505
- />
506
- )}
507
-
508
- {/* Content */}
509
- <main className="flex-1 overflow-y-auto p-4 lg:p-6 lg:ml-0">
510
- {activeContent && (
511
- <div className="max-w-2xl mt-12 lg:mt-0">
512
- <div className="flex items-center gap-3 mb-6">
513
- <activeContent.icon size={20} className="text-zinc-400" />
514
- <h2 className="text-lg font-semibold text-zinc-100">{activeContent.title}</h2>
515
- </div>
516
- {activeContent.content}
517
- </div>
518
- )}
519
- </main>
520
- </div>
521
- );
522
- }
@@ -1,128 +0,0 @@
1
- // @vitest-environment jsdom
2
- import { cleanup, render, screen } from "@testing-library/react";
3
- import userEvent from "@testing-library/user-event";
4
- import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
5
- import { KanbanBoard } from "@/components/kanban/kanban-board";
6
- import type { KanbanTask } from "@/components/kanban/kanban-board";
7
-
8
- vi.mock("next/navigation", () => ({
9
- useRouter: () => ({ push: vi.fn(), refresh: vi.fn() }),
10
- }));
11
-
12
- vi.mock("@/components/kanban/kanban-status-context", () => ({
13
- useKanbanStatuses: () => [
14
- { key: "OPEN", label: "Open", color: "border-zinc-700", isVisible: true },
15
- { key: "DONE", label: "Done", color: "border-zinc-700", isVisible: true },
16
- ],
17
- }));
18
-
19
- vi.mock("@/components/kanban/kanban-card", () => ({
20
- KanbanCard: ({ task }: { task: KanbanTask }) => <div data-testid="kanban-card">{task.title}</div>,
21
- }));
22
-
23
- function makeTask(overrides: Partial<KanbanTask> = {}): KanbanTask {
24
- return {
25
- id: overrides.id ?? "t1",
26
- title: overrides.title ?? "Ship notes polish",
27
- status: overrides.status ?? "OPEN",
28
- claimedBy: overrides.claimedBy ?? null,
29
- claimedByAlias: overrides.claimedByAlias ?? null,
30
- lastHeartbeat: overrides.lastHeartbeat ?? null,
31
- assigneeType: overrides.assigneeType ?? "HUMAN",
32
- assignee: overrides.assignee ?? null,
33
- note: overrides.note ?? { id: "n1", title: "Launch" },
34
- dueDate: overrides.dueDate ?? null,
35
- };
36
- }
37
-
38
- function getColumnBody(label: string) {
39
- const header = screen.getByText(label).closest("header");
40
-
41
- if (!(header instanceof HTMLElement) || !(header.nextElementSibling instanceof HTMLElement)) {
42
- throw new Error(`Could not find column body for ${label}`);
43
- }
44
-
45
- return { header, body: header.nextElementSibling };
46
- }
47
-
48
- beforeEach(() => {
49
- window.localStorage.clear();
50
- });
51
-
52
- afterEach(() => {
53
- cleanup();
54
- });
55
-
56
- describe("KanbanBoard", () => {
57
- it("shows density controls, makes headers sticky, and saves compact mode", async () => {
58
- const user = userEvent.setup();
59
-
60
- render(<KanbanBoard tasks={[makeTask()]} />);
61
-
62
- expect(screen.getByRole("button", { name: "Comfortable" })).toBeInTheDocument();
63
- expect(screen.getByRole("button", { name: "Compact" })).toBeInTheDocument();
64
-
65
- const { header, body } = getColumnBody("Open");
66
- expect(header.className).toContain("sticky");
67
- expect(header.className).toContain("top-0");
68
- expect(body.className).toContain("gap-3");
69
- expect(body.className).toContain("p-3");
70
-
71
- await user.click(screen.getByRole("button", { name: "Compact" }));
72
-
73
- expect(body.className).toContain("gap-2");
74
- expect(body.className).toContain("p-2");
75
- expect(window.localStorage.getItem("brief:kanban-density")).toBe(JSON.stringify("compact"));
76
- });
77
-
78
- it("loads the saved density preference on first render", () => {
79
- window.localStorage.setItem("brief:kanban-density", JSON.stringify("compact"));
80
-
81
- render(<KanbanBoard tasks={[makeTask()]} />);
82
-
83
- const { body } = getColumnBody("Open");
84
- expect(body.className).toContain("gap-2");
85
- expect(body.className).toContain("p-2");
86
- expect(screen.getByRole("button", { name: "Compact" })).toHaveAttribute("aria-pressed", "true");
87
- });
88
-
89
- it("filters the board down to overdue tasks", async () => {
90
- const user = userEvent.setup();
91
- const yesterday = new Date();
92
- yesterday.setDate(yesterday.getDate() - 1);
93
- const tomorrow = new Date();
94
- tomorrow.setDate(tomorrow.getDate() + 1);
95
-
96
- const overdueTask = makeTask({
97
- id: "overdue-task",
98
- title: "Past due follow-up",
99
- dueDate: yesterday.toISOString(),
100
- });
101
- const futureTask = makeTask({
102
- id: "future-task",
103
- title: "Upcoming review",
104
- dueDate: tomorrow.toISOString(),
105
- });
106
-
107
- render(<KanbanBoard tasks={[overdueTask, futureTask]} />);
108
-
109
- await user.click(screen.getByRole("button", { name: "Overdue" }));
110
-
111
- expect(screen.getByText(overdueTask.title)).toBeInTheDocument();
112
- expect(screen.queryByText(futureTask.title)).not.toBeInTheDocument();
113
- });
114
-
115
- it("shows filtered-empty column messaging when quick filters hide cards", async () => {
116
- const user = userEvent.setup();
117
- const futureHumanTask = makeTask({
118
- id: "future-human-task",
119
- title: "Upcoming human review",
120
- });
121
-
122
- render(<KanbanBoard tasks={[futureHumanTask]} />);
123
-
124
- await user.click(screen.getByRole("button", { name: "Agent" }));
125
-
126
- expect(screen.getAllByText("No matching tasks in this column")).toHaveLength(2);
127
- });
128
- });