diff --git a/.phase12-state.json b/.phase12-state.json index 91ffd0a..80e8774 100644 --- a/.phase12-state.json +++ b/.phase12-state.json @@ -1,11 +1,12 @@ { "completed_features": [], - "current_feature": "api-client-phase12", + "current_feature": "router-phase12", "started_at": "2026-05-23T06:33:48.406343", "attempted_features": [ "invoicing-stub", "time-rounding-rules", "user-avatars", - "app-version-display" + "app-version-display", + "api-client-phase12" ] } \ No newline at end of file diff --git a/GENERATION_LOG.md b/GENERATION_LOG.md index 4fb8ab7..be6ddbe 100644 --- a/GENERATION_LOG.md +++ b/GENERATION_LOG.md @@ -1533,3 +1533,24 @@ src/index.ts(27,25): error TS2769: No overload matches this call. Overload 2 of 3, '(plugin: FastifyPluginAsync<{ limits: { fileSize: number; }; }, RawServerDefault, FastifyTypeProvider, FastifyBaseLogger>, opts?: FastifyRegisterOptions<...> | undefined): FastifyInstance<...> & PromiseLike<...>', gave the following error. Argument of type 'Promise' is not assignable to parameter of type 'FastifyPluginAsync<{ limits: { fileSize: number; }; }, RawServerDefault, FastifyTypeProvider, FastifyBaseLogger>'. Type 'Promise' provides no match for the signature '(instance: FastifyInstance, FastifyBaseLogger, FastifyTy +- `06:39:11` **INFO** Committed feature api-client-phase12 +- `06:39:12` **INFO** Pushed: rc=0 + +## Phase-3 Feature: router-phase12 (2026-05-23 06:39:12) + +- `06:39:12` **INFO** Description: App + routes/index für /invoices +- `06:39:12` **INFO** Generating apps/api/src/routes/index.ts (ERWEITERT — füge invoiceRoutes ('/api/invoices').…) +- `06:39:23` **INFO** wrote 1446 chars in 11.4s (attempt 1) +- `06:39:23` **INFO** Generating apps/web/src/App.tsx (ERWEITERT — füge /invoices Route. Behalte alles.…) +- `06:40:11` **INFO** wrote 5744 chars in 47.7s (attempt 1) +- `06:40:11` **INFO** Generating apps/web/src/components/Nav.tsx (ERWEITERT — füge Invoices-Link in Nav (alle User). Behalte alles.…) +- `06:41:09` **INFO** wrote 6049 chars in 58.4s (attempt 1) +- `06:41:09` **INFO** Running tsc --noEmit on api… +- `06:41:11` **WARN** tsc errors: +src/index.ts(27,25): error TS2769: No overload matches this call. + Overload 1 of 3, '(plugin: FastifyPluginCallback<{ limits: { fileSize: number; }; }, RawServerDefault, FastifyTypeProvider, FastifyBaseLogger>, opts?: FastifyRegisterOptions<...> | undefined): FastifyInstance<...> & PromiseLike<...>', gave the following error. + Argument of type 'Promise' is not assignable to parameter of type 'FastifyPluginCallback<{ limits: { fileSize: number; }; }, RawServerDefault, FastifyTypeProvider, FastifyBaseLogger>'. + Type 'Promise' provides no match for the signature '(instance: FastifyInstance, FastifyBaseLogger, FastifyTypeProvider>, opts: { ...; }, done: (err?: Error | undefined) => void): void'. + Overload 2 of 3, '(plugin: FastifyPluginAsync<{ limits: { fileSize: number; }; }, RawServerDefault, FastifyTypeProvider, FastifyBaseLogger>, opts?: FastifyRegisterOptions<...> | undefined): FastifyInstance<...> & PromiseLike<...>', gave the following error. + Argument of type 'Promise' is not assignable to parameter of type 'FastifyPluginAsync<{ limits: { fileSize: number; }; }, RawServerDefault, FastifyTypeProvider, FastifyBaseLogger>'. + Type 'Promise' provides no match for the signature '(instance: FastifyInstance, FastifyBaseLogger, FastifyTy diff --git a/apps/api/src/routes/index.ts b/apps/api/src/routes/index.ts index 23b0257..ef5f5f1 100644 --- a/apps/api/src/routes/index.ts +++ b/apps/api/src/routes/index.ts @@ -11,6 +11,7 @@ import documentsRoutes from "./documents" import searchRoutes from "./search" import webhookRoutes from "./webhooks" import reportsRoutes from "./reports" +import invoiceRoutes from "./invoices" export async function setupRoutes(server: FastifyInstance) { server.register(authRoutes, { prefix: "/api/auth" }) @@ -25,4 +26,5 @@ export async function setupRoutes(server: FastifyInstance) { server.register(searchRoutes, { prefix: "/api/search" }) server.register(webhookRoutes, { prefix: "/api/webhooks" }) server.register(reportsRoutes, { prefix: "/api/reports" }) + server.register(invoiceRoutes, { prefix: "/api/invoices" }) } \ No newline at end of file diff --git a/apps/web/src/App.tsx b/apps/web/src/App.tsx index 81a0464..d3d4b3f 100644 --- a/apps/web/src/App.tsx +++ b/apps/web/src/App.tsx @@ -17,6 +17,7 @@ import TwoFactorAuth from "./pages/TwoFactorAuth" import Billing from "./pages/Billing" import Integrations from "./pages/Integrations" import ProjectTemplates from "./pages/ProjectTemplates" +import Invoices from "./pages/Invoices" import Nav from "./components/Nav" import CommandPalette from "./components/CommandPalette" import KeyboardHelp from "./components/KeyboardHelp" @@ -133,6 +134,13 @@ const documentsRoute = createRoute({ component: Documents }) +const invoicesRoute = createRoute({ + getParentRoute: () => rootRoute, + path: "/invoices", + beforeLoad: authCheck, + component: Invoices +}) + const profileRoute = createRoute({ getParentRoute: () => rootRoute, path: "/profile", @@ -161,46 +169,44 @@ const integrationsRoute = createRoute({ component: Integrations }) -const adminRoute = createRoute({ +const settingsRoute = createRoute({ getParentRoute: () => rootRoute, - path: "/admin", - beforeLoad: adminCheck, - component: () => -}) - -const adminUsersRoute = createRoute({ - getParentRoute: () => adminRoute, - path: "/users", - component: AdminUsers -}) - -const adminSettingsRoute = createRoute({ - getParentRoute: () => adminRoute, path: "/settings", + beforeLoad: authCheck, component: Settings }) -const adminAuditLogRoute = createRoute({ - getParentRoute: () => adminRoute, - path: "/audit-log", +const adminUsersRoute = createRoute({ + getParentRoute: () => rootRoute, + path: "/admin/users", + beforeLoad: adminCheck, + component: AdminUsers +}) + +const auditLogRoute = createRoute({ + getParentRoute: () => rootRoute, + path: "/admin/audit-log", + beforeLoad: adminCheck, component: AuditLog }) -const adminWebhooksRoute = createRoute({ - getParentRoute: () => adminRoute, - path: "/webhooks", +const webhooksRoute = createRoute({ + getParentRoute: () => rootRoute, + path: "/admin/webhooks", + beforeLoad: adminCheck, component: Webhooks }) -const adminTemplatesRoute = createRoute({ - getParentRoute: () => adminRoute, - path: "/templates", +const projectTemplatesRoute = createRoute({ + getParentRoute: () => rootRoute, + path: "/admin/templates", + beforeLoad: adminCheck, component: ProjectTemplates }) -const routeTree = rootRoute.addChildren([ - loginRoute, +const routeTree = [ indexRoute, + loginRoute, timeEntriesRoute, calendarRoute, customersRoute, @@ -208,14 +214,22 @@ const routeTree = rootRoute.addChildren([ projectsRoute, projectDetailRoute, documentsRoute, + invoicesRoute, profileRoute, twoFactorRoute, billingRoute, integrationsRoute, - adminRoute -]) + settingsRoute, + adminUsersRoute, + auditLogRoute, + webhooksRoute, + projectTemplatesRoute +] -const router = createRouter({ routeTree }) +const router = createRouter({ + routeTree, + defaultPreload: 'intent' +}) declare module "@tanstack/react-router" { interface Register { diff --git a/apps/web/src/components/Nav.tsx b/apps/web/src/components/Nav.tsx index f724278..e17f6dd 100644 --- a/apps/web/src/components/Nav.tsx +++ b/apps/web/src/components/Nav.tsx @@ -16,7 +16,8 @@ import { Zap, CreditCard, Languages, - LogOut + LogOut, + FileText } from "lucide-react" import { useQuery } from "@tanstack/react-query" import { api } from "../lib/api" @@ -40,6 +41,7 @@ export default function Nav() { { label: "Calendar", to: "/calendar", icon: Calendar }, { label: "Customers", to: "/customers", icon: Users }, { label: "Projects", to: "/projects", icon: FolderKanban }, + { label: "Invoices", to: "/invoices", icon: FileText }, { label: "Integrations", to: "/integrations", icon: Zap }, { label: "Billing", to: "/billing", icon: CreditCard }, ] @@ -110,34 +112,25 @@ export default function Nav() {
-
- {user && ( - - )} - -
+
+ + @@ -147,10 +140,16 @@ export default function Nav() { {/* Mobile Menu */} {isMobileMenuOpen && ( -
+
{allItems.map((item) => ( ))} +
+ +
)}