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": [],
|
||||
"current_feature": "time-entry-templates-page",
|
||||
"current_feature": "router-phase21",
|
||||
"started_at": "2026-05-23T08:09:40.135892",
|
||||
"attempted_features": [
|
||||
"keyboard-undo-stack",
|
||||
"snippet-shortcuts",
|
||||
"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.
|
||||
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
|
||||
- `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 Integrations from "./pages/Integrations"
|
||||
import ProjectTemplates from "./pages/ProjectTemplates"
|
||||
import TimeEntryTemplates from "./pages/TimeEntryTemplates"
|
||||
import Invoices from "./pages/Invoices"
|
||||
import ApiKeys from "./pages/ApiKeys"
|
||||
import AcceptInvite from "./pages/AcceptInvite"
|
||||
@ -29,6 +30,7 @@ import OnboardingTour from "./components/OnboardingTour"
|
||||
import VersionBadge from "./components/VersionBadge"
|
||||
import QuickAdd from "./components/QuickAdd"
|
||||
import IdleDetector from "./components/IdleDetector"
|
||||
import UndoStack from "./components/UndoStack"
|
||||
import { ToastProvider } from "./components/Toast"
|
||||
import ErrorBoundary from "./components/ErrorBoundary"
|
||||
import { api } from "./lib/api"
|
||||
@ -44,6 +46,7 @@ const rootRoute = createRootRoute({
|
||||
<KeyboardHelp />
|
||||
<OnboardingTour />
|
||||
<QuickAdd />
|
||||
<UndoStack />
|
||||
<Outlet />
|
||||
</div>
|
||||
<footer className="border-t bg-white py-2 text-center">
|
||||
@ -118,6 +121,13 @@ const timeEntriesRoute = createRoute({
|
||||
component: TimeEntries
|
||||
})
|
||||
|
||||
const timeEntryTemplatesRoute = createRoute({
|
||||
getParentRoute: () => rootRoute,
|
||||
path: "/time-entry-templates",
|
||||
beforeLoad: authCheck,
|
||||
component: TimeEntryTemplates
|
||||
})
|
||||
|
||||
const calendarRoute = createRoute({
|
||||
getParentRoute: () => rootRoute,
|
||||
path: "/calendar",
|
||||
@ -153,6 +163,13 @@ const projectDetailRoute = createRoute({
|
||||
component: ProjectDetail
|
||||
})
|
||||
|
||||
const projectTemplatesRoute = createRoute({
|
||||
getParentRoute: () => rootRoute,
|
||||
path: "/project-templates",
|
||||
beforeLoad: authCheck,
|
||||
component: ProjectTemplates
|
||||
})
|
||||
|
||||
const profileRoute = createRoute({
|
||||
getParentRoute: () => rootRoute,
|
||||
path: "/profile",
|
||||
@ -216,16 +233,9 @@ const integrationsRoute = createRoute({
|
||||
component: Integrations
|
||||
})
|
||||
|
||||
const projectTemplatesRoute = createRoute({
|
||||
getParentRoute: () => rootRoute,
|
||||
path: "/admin/project-templates",
|
||||
beforeLoad: adminCheck,
|
||||
component: ProjectTemplates
|
||||
})
|
||||
|
||||
const invoicesRoute = createRoute({
|
||||
getParentRoute: () => rootRoute,
|
||||
path: "/billing/invoices",
|
||||
path: "/invoices",
|
||||
beforeLoad: authCheck,
|
||||
component: Invoices
|
||||
})
|
||||
@ -237,18 +247,20 @@ const apiKeysRoute = createRoute({
|
||||
component: ApiKeys
|
||||
})
|
||||
|
||||
const routeTree = rootRoute.addChildren([
|
||||
const routeTree = [
|
||||
indexRoute,
|
||||
loginRoute,
|
||||
forgotPasswordRoute,
|
||||
resetPasswordRoute,
|
||||
acceptInviteRoute,
|
||||
timeEntriesRoute,
|
||||
timeEntryTemplatesRoute,
|
||||
calendarRoute,
|
||||
customersRoute,
|
||||
customerDetailRoute,
|
||||
projectsRoute,
|
||||
projectDetailRoute,
|
||||
projectTemplatesRoute,
|
||||
profileRoute,
|
||||
adminUsersRoute,
|
||||
settingsRoute,
|
||||
@ -258,12 +270,14 @@ const routeTree = rootRoute.addChildren([
|
||||
twoFactorRoute,
|
||||
billingRoute,
|
||||
integrationsRoute,
|
||||
projectTemplatesRoute,
|
||||
invoicesRoute,
|
||||
apiKeysRoute
|
||||
])
|
||||
]
|
||||
|
||||
const router = createRouter({ routeTree })
|
||||
const router = createRouter({
|
||||
routeTree,
|
||||
defaultPreload: 'intent'
|
||||
})
|
||||
|
||||
declare module "@tanstack/react-router" {
|
||||
interface Register {
|
||||
|
||||
@ -17,7 +17,8 @@ import {
|
||||
CreditCard,
|
||||
Languages,
|
||||
LogOut,
|
||||
FileText
|
||||
FileText,
|
||||
LayoutTemplate
|
||||
} from "lucide-react"
|
||||
import { useQuery } from "@tanstack/react-query"
|
||||
import { api } from "../lib/api"
|
||||
@ -42,6 +43,7 @@ export default function Nav() {
|
||||
{ label: "Customers", to: "/customers", icon: Users },
|
||||
{ label: "Projects", to: "/projects", icon: FolderKanban },
|
||||
{ label: "Invoices", to: "/invoices", icon: FileText },
|
||||
{ label: "Templates", to: "/templates", icon: LayoutTemplate },
|
||||
{ label: "Integrations", to: "/integrations", icon: Zap },
|
||||
{ label: "Billing", to: "/billing", icon: CreditCard },
|
||||
]
|
||||
@ -114,33 +116,32 @@ export default function Nav() {
|
||||
onClick={toggleTheme}
|
||||
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"
|
||||
title="Toggle Theme"
|
||||
>
|
||||
{theme === 'dark' ? <Sun className="w-5 h-5" /> : <Moon className="w-5 h-5" />}
|
||||
</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">
|
||||
<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>
|
||||
<div className="h-6 w-px bg-gray-200 dark:bg-slate-800 mx-1" />
|
||||
|
||||
<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>
|
||||
|
||||
{/* 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>
|
||||
)
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user