| ... | @@ -3,6 +3,7 @@ import { scopedProjectKey, scopeProjectRef } from "@t3tools/client-runtime/envir | ... | @@ -3,6 +3,7 @@ import { scopedProjectKey, scopeProjectRef } from "@t3tools/client-runtime/envir |
| 3 | import { squashAtomCommandFailure } from "@t3tools/client-runtime/state/runtime"; | 3 | import { squashAtomCommandFailure } from "@t3tools/client-runtime/state/runtime"; |
| 4 | import { | 4 | import { |
| 5 | Outlet, | 5 | Outlet, |
| | 6 | Link, |
| 6 | redirect, | 7 | redirect, |
| 7 | createRootRoute, | 8 | createRootRoute, |
| 8 | type ErrorComponentProps, | 9 | type ErrorComponentProps, |
| ... | @@ -104,11 +105,27 @@ export const Route = createRootRoute({ | ... | @@ -104,11 +105,27 @@ export const Route = createRootRoute({ |
| 104 | }, | 105 | }, |
| 105 | component: RootRouteView, | 106 | component: RootRouteView, |
| 106 | errorComponent: RootRouteErrorView, | 107 | errorComponent: RootRouteErrorView, |
| | 108 | notFoundComponent: RootRouteNotFoundView, |
| 107 | head: () => ({ | 109 | head: () => ({ |
| 108 | meta: [{ name: "title", content: APP_DISPLAY_NAME }], | 110 | meta: [{ name: "title", content: APP_DISPLAY_NAME }], |
| 109 | }), | 111 | }), |
| 110 | }); | 112 | }); |
| 111 | | 113 | |
| | 114 | function RootRouteNotFoundView() { |
| | 115 | return ( |
| | 116 | <main className="flex min-h-0 min-w-0 flex-1 items-center justify-center p-6"> |
| | 117 | <div className="flex max-w-sm flex-col items-center gap-4 text-center"> |
| | 118 | <h1 className="text-lg font-medium text-foreground">Page not found</h1> |
| | 119 | <p className="text-sm text-muted-foreground"> |
| | 120 | This link doesn't point to a page in {APP_DISPLAY_NAME}. Go home to choose a project or |
| | 121 | start a thread. |
| | 122 | </p> |
| | 123 | <Button render={<Link to="/" replace />}>Go home</Button> |
| | 124 | </div> |
| | 125 | </main> |
| | 126 | ); |
| | 127 | } |
| | 128 | |
| 112 | function RootRouteView() { | 129 | function RootRouteView() { |
| 113 | useEffect(() => installDesktopPasteAsText(window.desktopBridge, window), []); | 130 | useEffect(() => installDesktopPasteAsText(window.desktopBridge, window), []); |
| 114 | const pathname = useLocation({ select: (location) => location.pathname }); | 131 | const pathname = useLocation({ select: (location) => location.pathname }); |