feat: add Admin layout

This commit is contained in:
2026-09-12 19:38:11 +07:00
parent 301063533a
commit 1c877de130
26 changed files with 742 additions and 1132 deletions
+18 -8
View File
@@ -20,19 +20,29 @@ No test runner, no linter configured. `vue-tsc -b` during `build` is the only st
## Layout & routing
Two nested layouts (`src/layouts/`):
Two sibling layout shells (`src/layouts/`) sharing the same sidebar + topbar chrome:
- `MainLayout`app shell with sidebar + topbar. Wraps all authenticated routes. Hosts the global `Toast` and `ConfirmDialog` (in `App.vue`).
- `ProjectLayout`header + tabs (Overview / Documents / Tasks / Members). Loads the project by `:id` route param on mount and renders `<router-view />` for the tab content.
- `AdminLayout`global/admin shell. Sidebar: **Projects** (`/projects`), **Users** (`/users`), **Settings** (`/settings/*`).
- `MainLayout`project-workspace shell. Sidebar: **Tasks / Documents / Members** for the current `:id` project; topbar has the project switcher.
Routes (`src/router/index.ts`) guard everything except `/login` via `meta.public`. Auth users hitting `/login` redirect to `/projects`. Unknown paths redirect to `/projects`.
`App.vue` hosts the global `Toast`, `ConfirmDialog`, and `LoadingOverlay`. `LoadingOverlay` is non-blocking (`pointer-events: none`) and driven by `useLoading`, a counter incremented/decremented by the axios interceptors.
Routes (`src/router/index.ts`):
- `/login` — public.
- `/select-project` — standalone, read-only project picker (no CRUD) for non-admin users.
- `/``AdminLayout`: `/projects` (admin-only project list with full CRUD), `/users`, `/settings/{masterdata,roles,permissions}`.
- `/projects/:id``MainLayout`: `tasks/board`, `documents`, `members`.
Role-based landing: `auth.isAdmin` (a user whose `roleName` contains `Admin`) lands on `/projects`; everyone else on `/select-project`. `meta.adminOnly` on `/projects` is enforced in the guard. Guards redirect unauthenticated users to `/login`; unknown paths redirect to the role landing page.
Domain areas (each is a folder under `views/`):
- `auth/``LoginView.vue`
- `projects/`list, overview, members
- `projects/``ProjectsListView.vue` (admin), `MembersView.vue`, `ProjectSelectView.vue`
- `documents/` — tree + editor
- `tasks/` list, kanban board, detail dialog
- `tasks/` — kanban board + detail dialog
- `users/`, `settings/` — admin management
## Service layer pattern
@@ -61,14 +71,14 @@ Generated types live in `src/auto-imports.d.ts` and `src/components.d.ts` — do
## Styling
- Tailwind v4 via `@tailwindcss/vite` plugin (no `tailwind.config.js` — theme is CSS-only).
- PrimeVue `Lara` preset wired in `main.ts`. Use PrimeVue components first; reach for raw HTML when PrimeVue has no equivalent.
- PrimeVue `Aura` preset (customized in `src/theme.ts`) wired in `main.ts`. Use PrimeVue components first; reach for raw HTML when PrimeVue has no equivalent.
- `src/style.css` defines a `.field` label helper used across forms.
## Adding a new view / feature
1. Add typed function(s) to `services/backend.ts` or `services/modules.ts`, types to `types/index.ts`.
2. Create the `.vue` under the matching `views/<area>/` folder.
3. Register the route in `router/index.ts` — pick the right layout (`MainLayout` for top-level, `ProjectLayout` for project-scoped tabs).
3. Register the route in `router/index.ts` — pick the right layout (`AdminLayout` for admin/top-level pages, `MainLayout` for project-scoped tabs).
4. Use auto-imported PrimeVue components and composables — no manual `import` for them.
## Container