From e5e0be57da4cce45f09058e2435d84f41f36ffa5 Mon Sep 17 00:00:00 2001 From: Tim Stollberg Date: Tue, 23 Jun 2026 17:33:39 +0700 Subject: [PATCH] feat(frontend): scaffold Nuxt 3 CSR SPA with full auth + client/history UI - Nuxt 3 CSR (ssr:false), @nuxtjs/tailwindcss, dev proxy to backend - useAuth composable: CSRF cookie, XSRF token, login/logout/fetchUser - auth middleware: redirects to /login if no session - Login page, client list with search + create modal - Client detail with editable name, dynamic notes (JSON), history feed - History form with type select, inline edit/delete per entry - Print layout at /clients/:id/print (calls window.print on mount) - TypeScript interfaces: User, Client, HistoryEntry, PaginatedResponse - German UI labels throughout Co-Authored-By: Claude Sonnet 4.6 --- .env.example | 6 +- CLAUDE.md | 5 + frontend/.gitignore | 24 + frontend/CLAUDE.md | 34 + frontend/README.md | 75 + frontend/app.vue | 3 + frontend/components/LogoutButton.vue | 7 + frontend/components/client/ClientCard.vue | 17 + frontend/components/client/ClientFields.vue | 52 + frontend/components/history/HistoryEntry.vue | 62 + frontend/components/history/HistoryForm.vue | 51 + frontend/composables/useAuth.ts | 48 + frontend/composables/useClient.ts | 59 + frontend/composables/useHistory.ts | 48 + frontend/middleware/auth.ts | 13 + frontend/nuxt.config.ts | 27 + frontend/package-lock.json | 12205 +++++++++++++++++ frontend/package.json | 19 + frontend/pages/clients/[id].vue | 99 + frontend/pages/clients/[id]/print.vue | 73 + frontend/pages/clients/index.vue | 92 + frontend/pages/index.vue | 8 + frontend/pages/login.vue | 61 + frontend/public/favicon.ico | Bin 0 -> 4286 bytes frontend/public/robots.txt | 2 + frontend/server/tsconfig.json | 3 + frontend/tailwind.config.ts | 15 + frontend/tsconfig.json | 4 + frontend/types/index.ts | 38 + 29 files changed, 13147 insertions(+), 3 deletions(-) create mode 100644 frontend/.gitignore create mode 100644 frontend/CLAUDE.md create mode 100644 frontend/README.md create mode 100644 frontend/app.vue create mode 100644 frontend/components/LogoutButton.vue create mode 100644 frontend/components/client/ClientCard.vue create mode 100644 frontend/components/client/ClientFields.vue create mode 100644 frontend/components/history/HistoryEntry.vue create mode 100644 frontend/components/history/HistoryForm.vue create mode 100644 frontend/composables/useAuth.ts create mode 100644 frontend/composables/useClient.ts create mode 100644 frontend/composables/useHistory.ts create mode 100644 frontend/middleware/auth.ts create mode 100644 frontend/nuxt.config.ts create mode 100644 frontend/package-lock.json create mode 100644 frontend/package.json create mode 100644 frontend/pages/clients/[id].vue create mode 100644 frontend/pages/clients/[id]/print.vue create mode 100644 frontend/pages/clients/index.vue create mode 100644 frontend/pages/index.vue create mode 100644 frontend/pages/login.vue create mode 100644 frontend/public/favicon.ico create mode 100644 frontend/public/robots.txt create mode 100644 frontend/server/tsconfig.json create mode 100644 frontend/tailwind.config.ts create mode 100644 frontend/tsconfig.json create mode 100644 frontend/types/index.ts diff --git a/.env.example b/.env.example index c6dc66d..d9590d9 100644 --- a/.env.example +++ b/.env.example @@ -1,12 +1,12 @@ APP_NAME=MandantCRM APP_ENV=local -APP_KEY=base64:PLACEHOLDER_KEY +APP_KEY= APP_URL=http://localhost DB_HOST=mysql DB_PORT=3306 DB_DATABASE=mandantcrm -DB_USERNAME=placeholder_user -DB_PASSWORD=placeholder_pass +DB_USERNAME=mandantcrm +DB_PASSWORD=secret SANCTUM_STATEFUL_DOMAINS=localhost,localhost:3000 SESSION_DOMAIN=localhost FRONTEND_URL=http://localhost:3000 \ No newline at end of file diff --git a/CLAUDE.md b/CLAUDE.md index ea00d7f..a442b1c 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -27,3 +27,8 @@ make shell-node # sh into frontend container ## Commit style feat/fix/chore/refactor/test/docs — conventional commits Examples: `feat(client): add search endpoint`, `fix(history): soft delete cascade` + +### Telegram Channel Guidelines +- Before calling any write_file, edit_file, or bash tools that trigger system permission prompts, you MUST send a Telegram text message summarizing exactly what you are about to modify and why. +- Never trigger a tool call blindly without explaining the context to the user first. + diff --git a/frontend/.gitignore b/frontend/.gitignore new file mode 100644 index 0000000..4a7f73a --- /dev/null +++ b/frontend/.gitignore @@ -0,0 +1,24 @@ +# Nuxt dev/build outputs +.output +.data +.nuxt +.nitro +.cache +dist + +# Node dependencies +node_modules + +# Logs +logs +*.log + +# Misc +.DS_Store +.fleet +.idea + +# Local env files +.env +.env.* +!.env.example diff --git a/frontend/CLAUDE.md b/frontend/CLAUDE.md new file mode 100644 index 0000000..4c3e0c5 --- /dev/null +++ b/frontend/CLAUDE.md @@ -0,0 +1,34 @@ +# Frontend — Nuxt 3 CSR + +## Structure +- `pages/` — file-based routing (CSR only, all behind auth middleware) +- `composables/useAuth.ts` — login/logout/user state (singleton via useState) +- `composables/useClient.ts` — CRUD + list +- `composables/useHistory.ts` — history entry CRUD per client +- `components/client/` — ClientCard, ClientFields +- `components/history/` — HistoryEntry, HistoryForm +- `middleware/auth.ts` — redirects to /login if no session +- `types/index.ts` — shared TypeScript interfaces + +## Auth flow +1. `GET /sanctum/csrf-cookie` sets XSRF-TOKEN cookie +2. `POST /api/login` with credentials — Laravel sets session cookie +3. All subsequent requests: include both cookies via `credentials: 'include'` +4. XSRF-TOKEN decoded and sent as `X-XSRF-TOKEN` header on mutating requests + +## API calls +Always use the `useApiFetch` composable pattern: +```ts +const data = await $fetch('/api/clients', { credentials: 'include' }) +``` + +## Tailwind +Desktop-first, no mobile breakpoints in MVP. +Dense, data-focused UI — think DATEV/Outlook aesthetics. + +## Commands +``` +npm run dev # dev server on :3000 +npm run build # production build +npm run typecheck +``` diff --git a/frontend/README.md b/frontend/README.md new file mode 100644 index 0000000..25b5821 --- /dev/null +++ b/frontend/README.md @@ -0,0 +1,75 @@ +# Nuxt Minimal Starter + +Look at the [Nuxt documentation](https://nuxt.com/docs/getting-started/introduction) to learn more. + +## Setup + +Make sure to install dependencies: + +```bash +# npm +npm install + +# pnpm +pnpm install + +# yarn +yarn install + +# bun +bun install +``` + +## Development Server + +Start the development server on `http://localhost:3000`: + +```bash +# npm +npm run dev + +# pnpm +pnpm dev + +# yarn +yarn dev + +# bun +bun run dev +``` + +## Production + +Build the application for production: + +```bash +# npm +npm run build + +# pnpm +pnpm build + +# yarn +yarn build + +# bun +bun run build +``` + +Locally preview production build: + +```bash +# npm +npm run preview + +# pnpm +pnpm preview + +# yarn +yarn preview + +# bun +bun run preview +``` + +Check out the [deployment documentation](https://nuxt.com/docs/getting-started/deployment) for more information. diff --git a/frontend/app.vue b/frontend/app.vue new file mode 100644 index 0000000..8f62b8b --- /dev/null +++ b/frontend/app.vue @@ -0,0 +1,3 @@ + diff --git a/frontend/components/LogoutButton.vue b/frontend/components/LogoutButton.vue new file mode 100644 index 0000000..47b73c4 --- /dev/null +++ b/frontend/components/LogoutButton.vue @@ -0,0 +1,7 @@ + + + diff --git a/frontend/components/client/ClientCard.vue b/frontend/components/client/ClientCard.vue new file mode 100644 index 0000000..6487382 --- /dev/null +++ b/frontend/components/client/ClientCard.vue @@ -0,0 +1,17 @@ + + + diff --git a/frontend/components/client/ClientFields.vue b/frontend/components/client/ClientFields.vue new file mode 100644 index 0000000..a47c713 --- /dev/null +++ b/frontend/components/client/ClientFields.vue @@ -0,0 +1,52 @@ + + + diff --git a/frontend/components/history/HistoryEntry.vue b/frontend/components/history/HistoryEntry.vue new file mode 100644 index 0000000..89331df --- /dev/null +++ b/frontend/components/history/HistoryEntry.vue @@ -0,0 +1,62 @@ + + +