feat(frontend): settings window, i18n, admin UI, books, tasks, calendar, timer
ci / backend (push) Canceled after 0s
ci / frontend (push) Canceled after 0s

- Settings window with tabs: profile (name, email, avatar, password),
  appearance (light/dark/system), language (de/en/zh), background
  (gradient presets, custom URL, blur toggle); persisted server-side
- i18n dictionaries (de/en/zh) applied across nav, sidebar, tasks,
  calendar, time tracking, admin, invites and comments
- Greeting header with time-of-day message, live clock and date; cooler
  theme, cards, kanban, calendar grid and data-table styling
- Shared sidebar: nav, collapsible books with per-book pages, top-level
  pages, search; user chip opens settings
- Tasks kanban with priorities, overdue flags and book/page links;
  calendar month view fed by task deadlines; time view with entries,
  durations and totals; top-right live timer with optional book link
- User discovery autocomplete in the invite card; editor gains tables
  and checklists; standalone theme buttons removed
This commit is contained in:
x3
2026-09-22 13:56:26 +02:00
parent b852583499
commit fb396d313a
30 changed files with 1698 additions and 190 deletions
+26
View File
@@ -59,6 +59,32 @@ Content fields: `content_json` (TipTap JSON), `content_html` (rendered HTML).
## Users
- `GET /users/search?email=` — lookup for invites (auth required).
- `GET /users/discover?q=` — fuzzy discovery (min 2 chars, max 10 hits, no hashes).
- `PATCH /users/me` — profile/appearance (`name, email, avatar, locale, theme, bg_image, bg_blur`).
- `PATCH /users/me/password` — `{ currentPassword, newPassword }`.
## Books
- `GET /books/by-workspace/:workspaceId`, `POST /books {workspace_id,title?,icon?}`
- `PATCH /books/:id`, `DELETE /books/:id` (pages inside cascade).
## Tasks
- `GET /tasks/by-workspace/:workspaceId?status=&from=&to=` (calendar range on `due_at`)
- `POST /tasks {workspace_id, book_id?, page_id?, title, status?, priority?, due_at?}`
- `PATCH /tasks/:id`, `DELETE /tasks/:id`
## Time tracking
- `GET /time/by-workspace/:workspaceId` → `{ entries, open }`
- `POST /time/start {workspace_id, book_id?, page_id?, description?}` (409 if running)
- `POST /time/stop {workspace_id}` → sets `ended_at` + `duration_seconds`
- `PATCH /time/:id`, `DELETE /time/:id` (own or admin+)
## Admin (requires `is_admin`)
- `GET /admin/overview` → counts + recent users
- `GET /admin/users`, `PATCH /admin/users/:id {is_admin}`, `DELETE /admin/users/:id`
## Health