Add a persistent left sidebar to the signed-in layout

App.vue now renders a left AppSidebar beside the routed view for any
requiresAuth page, staying mounted as you move between the dashboard and
projects. The sidebar has a Dashboard link (icon), a divider, the project list
(each an icon link, current page highlighted via RouterLink active-class), and a
compact new-project form that jumps to the created project.

- New /dashboard route + DashboardView ("under construction"); / and unknown
  paths redirect there. HomeView removed -- its project list and form moved into
  the sidebar.
- <RouterView :key="route.path"> so navigating project -> project via the
  sidebar remounts and reloads instead of reusing the instance.
- Signed-out routes (login/register/verify-email) render without the sidebar.

Icons are inline SVG -- no new dependency.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-04 13:55:31 +01:00
co-authored by Claude Sonnet 5
parent 9c1768ddb2
commit cd54b41ab7
8 changed files with 303 additions and 149 deletions
+17 -2
View File
@@ -35,12 +35,27 @@ src/stores/auth.ts Pinia store: token in localStorage, register/login/fetch
src/stores/projects.ts Pinia store: the user's projects (fetch + create)
src/stores/cards.ts Pinia store: one project's cards (CRUD + reorderColumn)
src/lib/api.ts fetch wrapper, bearer token, typed ApiError
src/components/AppSidebar.vue left nav: Dashboard link, divider, project list + new-project form
src/components/CardRow.vue editable text + status chip + delete, one card
src/components/KanbanCard.vue small draggable card for the board columns
src/views/ HomeView, ProjectView, LoginView, RegisterView,
src/views/ DashboardView, ProjectView, LoginView, RegisterView,
ProfileView, VerifyEmailView
```
## Layout
Signed-in "app" routes (`meta.requiresAuth`) render inside a persistent shell:
the top bar, then a left **sidebar** (`AppSidebar.vue`) beside the routed view.
The sidebar stays mounted across navigation — it holds a **Dashboard** link, a
divider, the project list, and a compact new-project form (creating one jumps to
it). The current page is highlighted via RouterLink's `active-class`.
`<RouterView :key="route.path">` remounts the view on every path change so
sidebar → project → project navigation always does a fresh load.
`/` redirects to `/dashboard` (`DashboardView.vue`, an "under construction"
placeholder). Signed-out routes (`/login`, `/register`, `/verify-email`) render
without the sidebar.
## Project detail
`/projects/:id` shows one project. It renders on a **full-width** layout (the
@@ -48,7 +63,7 @@ route sets `meta.wide`, which widens `.app__main` in `App.vue`). The title and
description are inline-editable (saved on blur via `PATCH /api/projects/:id`; the
description shows an "Add a description" placeholder when empty). A **Manage**
menu (top right) has a **Delete project** action that opens a confirmation modal;
confirming calls `DELETE /api/projects/:id` and returns to the all-projects view.
confirming calls `DELETE /api/projects/:id` and returns to the dashboard.
Below the header are two tabs (local `activeTab` state, `v-show` so both stay
mounted):