feat(router-phase21): Mount /templates Route + Nav-Link + UndoStack global [tsc:fail]
This commit is contained in:
parent
e5877d05d6
commit
8248eb910f
@ -1,11 +1,12 @@
|
|||||||
{
|
{
|
||||||
"completed_features": [],
|
"completed_features": [],
|
||||||
"current_feature": "time-entry-templates-page",
|
"current_feature": "router-phase21",
|
||||||
"started_at": "2026-05-23T08:09:40.135892",
|
"started_at": "2026-05-23T08:09:40.135892",
|
||||||
"attempted_features": [
|
"attempted_features": [
|
||||||
"keyboard-undo-stack",
|
"keyboard-undo-stack",
|
||||||
"snippet-shortcuts",
|
"snippet-shortcuts",
|
||||||
"smart-rounding-on-input",
|
"smart-rounding-on-input",
|
||||||
"color-coded-customer-rows"
|
"color-coded-customer-rows",
|
||||||
|
"time-entry-templates-page"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@ -2567,3 +2567,22 @@ 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.
|
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<FastifyMultipartPlugin>' is not assignable to parameter of type 'FastifyPluginAsync<{ limits: { fileSize: number; }; }, RawServerDefault, FastifyTypeProvider, FastifyBaseLogger>'.
|
Argument of type 'Promise<FastifyMultipartPlugin>' is not assignable to parameter of type 'FastifyPluginAsync<{ limits: { fileSize: number; }; }, RawServerDefault, FastifyTypeProvider, FastifyBaseLogger>'.
|
||||||
Type 'Promise<FastifyMultipartPlugin>' provides no match for the signature '(instance: FastifyInstance<RawServerDefault, IncomingMessage, ServerResponse<IncomingMessage>, FastifyBaseLogger, FastifyTy
|
Type 'Promise<FastifyMultipartPlugin>' provides no match for the signature '(instance: FastifyInstance<RawServerDefault, IncomingMessage, ServerResponse<IncomingMessage>, FastifyBaseLogger, FastifyTy
|
||||||
|
- `08:14:55` **INFO** Committed feature time-entry-templates-page
|
||||||
|
- `08:14:55` **INFO** Pushed: rc=0
|
||||||
|
|
||||||
|
## Phase-3 Feature: router-phase21 (2026-05-23 08:14:55)
|
||||||
|
|
||||||
|
- `08:14:55` **INFO** Description: Mount /templates Route + Nav-Link + UndoStack global
|
||||||
|
- `08:14:55` **INFO** Generating apps/web/src/App.tsx (ERWEITERT — füge /time-entry-templates Route + mount <UndoStack /> glo…)
|
||||||
|
- `08:15:54` **INFO** wrote 7100 chars in 58.2s (attempt 1)
|
||||||
|
- `08:15:54` **INFO** Generating apps/web/src/components/Nav.tsx (ERWEITERT — füge Templates-Link in Nav. Behalte alles.…)
|
||||||
|
- `08:16:42` **INFO** wrote 5110 chars in 48.1s (attempt 1)
|
||||||
|
- `08:16:42` **INFO** Running tsc --noEmit on api…
|
||||||
|
- `08:16:43` **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<FastifyMultipartPlugin>' is not assignable to parameter of type 'FastifyPluginCallback<{ limits: { fileSize: number; }; }, RawServerDefault, FastifyTypeProvider, FastifyBaseLogger>'.
|
||||||
|
Type 'Promise<FastifyMultipartPlugin>' provides no match for the signature '(instance: FastifyInstance<RawServerDefault, IncomingMessage, ServerResponse<IncomingMessage>, 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<FastifyMultipartPlugin>' is not assignable to parameter of type 'FastifyPluginAsync<{ limits: { fileSize: number; }; }, RawServerDefault, FastifyTypeProvider, FastifyBaseLogger>'.
|
||||||
|
Type 'Promise<FastifyMultipartPlugin>' provides no match for the signature '(instance: FastifyInstance<RawServerDefault, IncomingMessage, ServerResponse<IncomingMessage>, FastifyBaseLogger, FastifyTy
|
||||||
|
|||||||
@ -19,6 +19,7 @@ import TwoFactorAuth from "./pages/TwoFactorAuth"
|
|||||||
import Billing from "./pages/Billing"
|
import Billing from "./pages/Billing"
|
||||||
import Integrations from "./pages/Integrations"
|
import Integrations from "./pages/Integrations"
|
||||||
import ProjectTemplates from "./pages/ProjectTemplates"
|
import ProjectTemplates from "./pages/ProjectTemplates"
|
||||||
|
import TimeEntryTemplates from "./pages/TimeEntryTemplates"
|
||||||
import Invoices from "./pages/Invoices"
|
import Invoices from "./pages/Invoices"
|
||||||
import ApiKeys from "./pages/ApiKeys"
|
import ApiKeys from "./pages/ApiKeys"
|
||||||
import AcceptInvite from "./pages/AcceptInvite"
|
import AcceptInvite from "./pages/AcceptInvite"
|
||||||
@ -29,6 +30,7 @@ import OnboardingTour from "./components/OnboardingTour"
|
|||||||
import VersionBadge from "./components/VersionBadge"
|
import VersionBadge from "./components/VersionBadge"
|
||||||
import QuickAdd from "./components/QuickAdd"
|
import QuickAdd from "./components/QuickAdd"
|
||||||
import IdleDetector from "./components/IdleDetector"
|
import IdleDetector from "./components/IdleDetector"
|
||||||
|
import UndoStack from "./components/UndoStack"
|
||||||
import { ToastProvider } from "./components/Toast"
|
import { ToastProvider } from "./components/Toast"
|
||||||
import ErrorBoundary from "./components/ErrorBoundary"
|
import ErrorBoundary from "./components/ErrorBoundary"
|
||||||
import { api } from "./lib/api"
|
import { api } from "./lib/api"
|
||||||
@ -44,6 +46,7 @@ const rootRoute = createRootRoute({
|
|||||||
<KeyboardHelp />
|
<KeyboardHelp />
|
||||||
<OnboardingTour />
|
<OnboardingTour />
|
||||||
<QuickAdd />
|
<QuickAdd />
|
||||||
|
<UndoStack />
|
||||||
<Outlet />
|
<Outlet />
|
||||||
</div>
|
</div>
|
||||||
<footer className="border-t bg-white py-2 text-center">
|
<footer className="border-t bg-white py-2 text-center">
|
||||||
@ -118,6 +121,13 @@ const timeEntriesRoute = createRoute({
|
|||||||
component: TimeEntries
|
component: TimeEntries
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const timeEntryTemplatesRoute = createRoute({
|
||||||
|
getParentRoute: () => rootRoute,
|
||||||
|
path: "/time-entry-templates",
|
||||||
|
beforeLoad: authCheck,
|
||||||
|
component: TimeEntryTemplates
|
||||||
|
})
|
||||||
|
|
||||||
const calendarRoute = createRoute({
|
const calendarRoute = createRoute({
|
||||||
getParentRoute: () => rootRoute,
|
getParentRoute: () => rootRoute,
|
||||||
path: "/calendar",
|
path: "/calendar",
|
||||||
@ -153,6 +163,13 @@ const projectDetailRoute = createRoute({
|
|||||||
component: ProjectDetail
|
component: ProjectDetail
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const projectTemplatesRoute = createRoute({
|
||||||
|
getParentRoute: () => rootRoute,
|
||||||
|
path: "/project-templates",
|
||||||
|
beforeLoad: authCheck,
|
||||||
|
component: ProjectTemplates
|
||||||
|
})
|
||||||
|
|
||||||
const profileRoute = createRoute({
|
const profileRoute = createRoute({
|
||||||
getParentRoute: () => rootRoute,
|
getParentRoute: () => rootRoute,
|
||||||
path: "/profile",
|
path: "/profile",
|
||||||
@ -216,16 +233,9 @@ const integrationsRoute = createRoute({
|
|||||||
component: Integrations
|
component: Integrations
|
||||||
})
|
})
|
||||||
|
|
||||||
const projectTemplatesRoute = createRoute({
|
|
||||||
getParentRoute: () => rootRoute,
|
|
||||||
path: "/admin/project-templates",
|
|
||||||
beforeLoad: adminCheck,
|
|
||||||
component: ProjectTemplates
|
|
||||||
})
|
|
||||||
|
|
||||||
const invoicesRoute = createRoute({
|
const invoicesRoute = createRoute({
|
||||||
getParentRoute: () => rootRoute,
|
getParentRoute: () => rootRoute,
|
||||||
path: "/billing/invoices",
|
path: "/invoices",
|
||||||
beforeLoad: authCheck,
|
beforeLoad: authCheck,
|
||||||
component: Invoices
|
component: Invoices
|
||||||
})
|
})
|
||||||
@ -237,18 +247,20 @@ const apiKeysRoute = createRoute({
|
|||||||
component: ApiKeys
|
component: ApiKeys
|
||||||
})
|
})
|
||||||
|
|
||||||
const routeTree = rootRoute.addChildren([
|
const routeTree = [
|
||||||
indexRoute,
|
indexRoute,
|
||||||
loginRoute,
|
loginRoute,
|
||||||
forgotPasswordRoute,
|
forgotPasswordRoute,
|
||||||
resetPasswordRoute,
|
resetPasswordRoute,
|
||||||
acceptInviteRoute,
|
acceptInviteRoute,
|
||||||
timeEntriesRoute,
|
timeEntriesRoute,
|
||||||
|
timeEntryTemplatesRoute,
|
||||||
calendarRoute,
|
calendarRoute,
|
||||||
customersRoute,
|
customersRoute,
|
||||||
customerDetailRoute,
|
customerDetailRoute,
|
||||||
projectsRoute,
|
projectsRoute,
|
||||||
projectDetailRoute,
|
projectDetailRoute,
|
||||||
|
projectTemplatesRoute,
|
||||||
profileRoute,
|
profileRoute,
|
||||||
adminUsersRoute,
|
adminUsersRoute,
|
||||||
settingsRoute,
|
settingsRoute,
|
||||||
@ -258,12 +270,14 @@ const routeTree = rootRoute.addChildren([
|
|||||||
twoFactorRoute,
|
twoFactorRoute,
|
||||||
billingRoute,
|
billingRoute,
|
||||||
integrationsRoute,
|
integrationsRoute,
|
||||||
projectTemplatesRoute,
|
|
||||||
invoicesRoute,
|
invoicesRoute,
|
||||||
apiKeysRoute
|
apiKeysRoute
|
||||||
])
|
]
|
||||||
|
|
||||||
const router = createRouter({ routeTree })
|
const router = createRouter({
|
||||||
|
routeTree,
|
||||||
|
defaultPreload: 'intent'
|
||||||
|
})
|
||||||
|
|
||||||
declare module "@tanstack/react-router" {
|
declare module "@tanstack/react-router" {
|
||||||
interface Register {
|
interface Register {
|
||||||
|
|||||||
@ -17,7 +17,8 @@ import {
|
|||||||
CreditCard,
|
CreditCard,
|
||||||
Languages,
|
Languages,
|
||||||
LogOut,
|
LogOut,
|
||||||
FileText
|
FileText,
|
||||||
|
LayoutTemplate
|
||||||
} from "lucide-react"
|
} from "lucide-react"
|
||||||
import { useQuery } from "@tanstack/react-query"
|
import { useQuery } from "@tanstack/react-query"
|
||||||
import { api } from "../lib/api"
|
import { api } from "../lib/api"
|
||||||
@ -42,6 +43,7 @@ export default function Nav() {
|
|||||||
{ label: "Customers", to: "/customers", icon: Users },
|
{ label: "Customers", to: "/customers", icon: Users },
|
||||||
{ label: "Projects", to: "/projects", icon: FolderKanban },
|
{ label: "Projects", to: "/projects", icon: FolderKanban },
|
||||||
{ label: "Invoices", to: "/invoices", icon: FileText },
|
{ label: "Invoices", to: "/invoices", icon: FileText },
|
||||||
|
{ label: "Templates", to: "/templates", icon: LayoutTemplate },
|
||||||
{ label: "Integrations", to: "/integrations", icon: Zap },
|
{ label: "Integrations", to: "/integrations", icon: Zap },
|
||||||
{ label: "Billing", to: "/billing", icon: CreditCard },
|
{ label: "Billing", to: "/billing", icon: CreditCard },
|
||||||
]
|
]
|
||||||
@ -114,33 +116,32 @@ export default function Nav() {
|
|||||||
onClick={toggleTheme}
|
onClick={toggleTheme}
|
||||||
aria-label={theme === 'dark' ? "Switch to light mode" : "Switch to dark mode"}
|
aria-label={theme === 'dark' ? "Switch to light mode" : "Switch to dark mode"}
|
||||||
className="p-2 rounded-full text-gray-500 hover:bg-gray-100 dark:text-slate-400 dark:hover:bg-slate-800 transition-colors"
|
className="p-2 rounded-full text-gray-500 hover:bg-gray-100 dark:text-slate-400 dark:hover:bg-slate-800 transition-colors"
|
||||||
title="Toggle Theme"
|
|
||||||
>
|
>
|
||||||
{theme === 'dark' ? <Sun className="w-5 h-5" /> : <Moon className="w-5 h-5" />}
|
{theme === 'dark' ? <Sun className="w-5 h-5" /> : <Moon className="w-5 h-5" />}
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<div className="flex items-center gap-1 p-1 rounded-full bg-gray-100 dark:bg-slate-800 border border-gray-200 dark:border-slate-700">
|
<div className="h-6 w-px bg-gray-200 dark:bg-slate-800 mx-1" />
|
||||||
<button
|
|
||||||
onClick={() => setLang(lang === 'en' ? 'de' : 'en')}
|
|
||||||
aria-label={`Switch language to ${lang === 'en' ? 'German' : 'English'}`}
|
|
||||||
className="p-1.5 rounded-full text-gray-600 hover:bg-white dark:text-slate-400 dark:hover:bg-slate-700 transition-colors"
|
|
||||||
>
|
|
||||||
<Languages className="w-4 h-4" />
|
|
||||||
</button>
|
|
||||||
<div className="w-px h-4 bg-gray-300 dark:bg-slate-600 mx-1" />
|
|
||||||
<button
|
|
||||||
onClick={() => api.logout()}
|
|
||||||
aria-label="Logout"
|
|
||||||
className="p-1.5 rounded-full text-gray-600 hover:bg-white dark:text-slate-400 dark:hover:bg-slate-700 transition-colors"
|
|
||||||
>
|
|
||||||
<LogOut className="w-4 h-4" />
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<Avatar user={user} />
|
<Avatar user={user} />
|
||||||
|
|
||||||
|
<button
|
||||||
|
onClick={() => setIsMobileMenuOpen(!isMobileMenuOpen)}
|
||||||
|
className="md:hidden p-2 rounded-md text-gray-500 hover:bg-gray-100 dark:text-slate-400 dark:hover:bg-slate-800"
|
||||||
|
>
|
||||||
|
{isMobileMenuOpen ? <X className="w-6 h-6" /> : <Menu className="w-6 h-6" />}
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* Mobile Menu */}
|
||||||
|
{isMobileMenuOpen && (
|
||||||
|
<div className="md:hidden border-t border-gray-200 dark:border-slate-800 bg-white dark:bg-slate-900 px-4 py-4 space-y-1">
|
||||||
|
{allItems.map((item) => (
|
||||||
|
<NavLink key={item.to} item={item} />
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</nav>
|
</nav>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue
Block a user