feat: add Space route with Tldraw integration and session validation

This commit is contained in:
2025-09-04 00:23:00 -03:00
parent b3c491561b
commit 6360efbab1
5 changed files with 844 additions and 4 deletions

View File

@@ -32,5 +32,5 @@
"source.fixAll.biome": "explicit",
"source.organizeImports.biome": "explicit"
},
"cSpell.words": ["Reflecto"]
"cSpell.words": ["Reflecto", "Tldraw"]
}

View File

@@ -34,6 +34,7 @@
"react-dom": "^19.0.0",
"sonner": "^2.0.5",
"tailwind-merge": "^3.3.1",
"tldraw": "^3.15.4",
"tw-animate-css": "^1.2.5",
"vite-plugin-pwa": "^1.0.1",
"zod": "^4.0.2"

View File

@@ -9,10 +9,16 @@
// Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified.
import { Route as rootRouteImport } from './routes/__root'
import { Route as SpaceRouteImport } from './routes/space'
import { Route as LoginRouteImport } from './routes/login'
import { Route as DashboardRouteImport } from './routes/dashboard'
import { Route as IndexRouteImport } from './routes/index'
const SpaceRoute = SpaceRouteImport.update({
id: '/space',
path: '/space',
getParentRoute: () => rootRouteImport,
} as any)
const LoginRoute = LoginRouteImport.update({
id: '/login',
path: '/login',
@@ -33,34 +39,45 @@ export interface FileRoutesByFullPath {
'/': typeof IndexRoute
'/dashboard': typeof DashboardRoute
'/login': typeof LoginRoute
'/space': typeof SpaceRoute
}
export interface FileRoutesByTo {
'/': typeof IndexRoute
'/dashboard': typeof DashboardRoute
'/login': typeof LoginRoute
'/space': typeof SpaceRoute
}
export interface FileRoutesById {
__root__: typeof rootRouteImport
'/': typeof IndexRoute
'/dashboard': typeof DashboardRoute
'/login': typeof LoginRoute
'/space': typeof SpaceRoute
}
export interface FileRouteTypes {
fileRoutesByFullPath: FileRoutesByFullPath
fullPaths: '/' | '/dashboard' | '/login'
fullPaths: '/' | '/dashboard' | '/login' | '/space'
fileRoutesByTo: FileRoutesByTo
to: '/' | '/dashboard' | '/login'
id: '__root__' | '/' | '/dashboard' | '/login'
to: '/' | '/dashboard' | '/login' | '/space'
id: '__root__' | '/' | '/dashboard' | '/login' | '/space'
fileRoutesById: FileRoutesById
}
export interface RootRouteChildren {
IndexRoute: typeof IndexRoute
DashboardRoute: typeof DashboardRoute
LoginRoute: typeof LoginRoute
SpaceRoute: typeof SpaceRoute
}
declare module '@tanstack/react-router' {
interface FileRoutesByPath {
'/space': {
id: '/space'
path: '/space'
fullPath: '/space'
preLoaderRoute: typeof SpaceRouteImport
parentRoute: typeof rootRouteImport
}
'/login': {
id: '/login'
path: '/login'
@@ -89,6 +106,7 @@ const rootRouteChildren: RootRouteChildren = {
IndexRoute: IndexRoute,
DashboardRoute: DashboardRoute,
LoginRoute: LoginRoute,
SpaceRoute: SpaceRoute,
}
export const routeTree = rootRouteImport
._addFileChildren(rootRouteChildren)

View File

@@ -0,0 +1,36 @@
import { createFileRoute } from "@tanstack/react-router";
import { useEffect, useMemo } from "react";
import { Tldraw } from "tldraw";
import { z } from "zod";
import "tldraw/tldraw.css";
import { authClient } from "@/lib/auth-client";
export const Route = createFileRoute("/space")({
validateSearch: z.object({
id: z.string().optional(),
}).parse,
component: SpaceRoute,
});
function SpaceRoute() {
const { id } = Route.useSearch();
const { data: session, isPending } = authClient.useSession();
const navigate = Route.useNavigate();
useEffect(() => {
if (!((session || isPending) && id)) {
navigate({
to: "/login",
});
}
}, [session, isPending, navigate, id]);
// Use a stable persistence key so tabs with same id share state locally
const persistenceKey = useMemo(() => `space-${id ?? "default"}`, [id]);
return (
<div className="mx-4 mt-4" style={{ position: "relative", inset: 0 }}>
<Tldraw inferDarkMode persistenceKey={persistenceKey} />
</div>
);
}

785
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff