UI fix + Data Export + Weekly Report + WebSocket

- Header: groups+status on one row
- GET /auth/export-data (GDPR data download)
- Weekly AI report cron (Monday 8:00)
- WebSocket /ws endpoint (real-time notifications)
- @fastify/websocket installed

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-30 00:17:57 +00:00
parent 03d7bd8de6
commit 5751ab832f
14 changed files with 182 additions and 42 deletions

View File

@@ -130,30 +130,30 @@ export default function TasksPage() {
return (
<div className="space-y-2 pb-24 sm:pb-8 px-4 sm:px-0">
{/* Group dropdown + Status pills row */}
<div className="flex items-center gap-3 flex-wrap">
<GroupSelector
groups={groups}
selected={selectedGroup}
onSelect={setSelectedGroup}
/>
</div>
{/* Status filter pills - compact */}
<div className="flex gap-1 overflow-x-auto scrollbar-hide px-4">
{statusOptions.map((opt) => (
<button
key={opt.value}
onClick={() => setStatusFilter(opt.value)}
className={`flex-shrink-0 px-2.5 py-1 rounded-full text-[11px] font-medium transition-all ${
statusFilter === opt.value
? "bg-gray-800 text-white dark:bg-white dark:text-gray-900"
: "bg-gray-100 dark:bg-gray-800 text-gray-500 dark:text-gray-400 hover:bg-gray-200 dark:hover:bg-gray-700"
}`}
>
{opt.label}
</button>
))}
{/* Group dropdown + Status pills — single compact row */}
<div className="flex items-center gap-3 flex-nowrap">
<div className="flex-shrink-0">
<GroupSelector
groups={groups}
selected={selectedGroup}
onSelect={setSelectedGroup}
/>
</div>
<div className="flex gap-1 overflow-x-auto scrollbar-hide flex-1 min-w-0">
{statusOptions.map((opt) => (
<button
key={opt.value}
onClick={() => setStatusFilter(opt.value)}
className={`flex-shrink-0 px-2.5 py-1 rounded-full text-[11px] font-medium transition-all ${
statusFilter === opt.value
? "bg-gray-800 text-white dark:bg-white dark:text-gray-900"
: "bg-gray-100 dark:bg-gray-800 text-gray-500 dark:text-gray-400 hover:bg-gray-200 dark:hover:bg-gray-700"
}`}
>
{opt.label}
</button>
))}
</div>
</div>
{/* Swipeable task list area */}