diff --git a/package.json b/package.json
index 12ad67f..95df9f2 100644
--- a/package.json
+++ b/package.json
@@ -4,7 +4,7 @@
"type": "module",
"scripts": {
"dev": "mprocs \"npm run start\" \"pocketbase serve\"",
- "start": "vite --port 3000",
+ "start": "VITE_POCKETBASE_URL=http://localhost:8090 vite --port 3000",
"build": "vite build && tsc",
"serve": "vite preview",
"test": "vitest run",
diff --git a/src/components/documents/DocumentPrintRow.tsx b/src/components/documents/DocumentPrintRow.tsx
new file mode 100644
index 0000000..123fbb5
--- /dev/null
+++ b/src/components/documents/DocumentPrintRow.tsx
@@ -0,0 +1,64 @@
+// DocumentRow.tsx
+// Generic row component for displaying any document type.
+import {
+ isLocation,
+ isMonster,
+ isNpc,
+ isScene,
+ isSecret,
+ isSession,
+ isTreasure,
+ type Document,
+} from "@/lib/types";
+import { LocationPrintRow } from "./location/LocationPrintRow";
+import { MonsterPrintRow } from "./monsters/MonsterPrintRow";
+import { TreasurePrintRow } from "./treasure/TreasurePrintRow";
+import { SecretPrintRow } from "./secret/SecretPrintRow";
+import { NpcPrintRow } from "./npc/NpcPrintRow";
+import { ScenePrintRow } from "./scene/ScenePrintRow";
+import { SessionPrintRow } from "./session/SessionPrintRow";
+
+/**
+ * Renders a row for any document type. Prioritizes Session, then Secret, then falls back to ID and creation time.
+ * If rendering a SecretRow, uses the provided session prop if available.
+ */
+export const DocumentPrintRow = ({ document }: { document: Document }) => {
+ if (isLocation(document)) {
+ return ;
+ }
+
+ if (isMonster(document)) {
+ return ;
+ }
+
+ if (isNpc(document)) {
+ return ;
+ }
+
+ if (isSession(document)) {
+ return ;
+ }
+
+ if (isSecret(document)) {
+ return ;
+ }
+
+ if (isScene(document)) {
+ return ;
+ }
+
+ if (isTreasure(document)) {
+ return ;
+ }
+
+ // Fallback: show ID and creation time
+ return (
+
+
+ Unrecognized Document
+
+
ID: {document.id}
+
Created: {document.created}
+
+ );
+};
diff --git a/src/components/documents/location/LocationPrintRow.tsx b/src/components/documents/location/LocationPrintRow.tsx
new file mode 100644
index 0000000..00c1694
--- /dev/null
+++ b/src/components/documents/location/LocationPrintRow.tsx
@@ -0,0 +1,13 @@
+import type { Location } from "@/lib/types";
+
+/**
+ * Renders an print-friendly location row
+ */
+export const LocationPrintRow = ({ location }: { location: Location }) => {
+ return (
+
+ {location.data.location.name}
+ {location.data.location.description}
+
+ );
+};
diff --git a/src/components/documents/monsters/MonsterPrintRow.tsx b/src/components/documents/monsters/MonsterPrintRow.tsx
new file mode 100644
index 0000000..0b4fd30
--- /dev/null
+++ b/src/components/documents/monsters/MonsterPrintRow.tsx
@@ -0,0 +1,8 @@
+import type { Monster } from "@/lib/types";
+
+/**
+ * Renders an editable monster row
+ */
+export const MonsterPrintRow = ({ monster }: { monster: Monster }) => {
+ return {monster.data.monster.name};
+};
diff --git a/src/components/documents/npc/NpcPrintRow.tsx b/src/components/documents/npc/NpcPrintRow.tsx
new file mode 100644
index 0000000..de9366c
--- /dev/null
+++ b/src/components/documents/npc/NpcPrintRow.tsx
@@ -0,0 +1,13 @@
+import type { Npc } from "@/lib/types";
+
+/**
+ * Renders an editable npc row
+ */
+export const NpcPrintRow = ({ npc }: { npc: Npc }) => {
+ return (
+
+ {npc.data.npc.name}
+ {npc.data.npc.description}
+
+ );
+};
diff --git a/src/components/documents/scene/ScenePrintRow.tsx b/src/components/documents/scene/ScenePrintRow.tsx
new file mode 100644
index 0000000..de5b162
--- /dev/null
+++ b/src/components/documents/scene/ScenePrintRow.tsx
@@ -0,0 +1,8 @@
+import type { Scene } from "@/lib/types";
+
+/**
+ * Renders an editable scene row
+ */
+export const ScenePrintRow = ({ scene }: { scene: Scene }) => {
+ return {scene.data.scene.text};
+};
diff --git a/src/components/documents/secret/SecretPrintRow.tsx b/src/components/documents/secret/SecretPrintRow.tsx
new file mode 100644
index 0000000..ac68c0a
--- /dev/null
+++ b/src/components/documents/secret/SecretPrintRow.tsx
@@ -0,0 +1,24 @@
+// SecretRow.tsx
+// Displays a single secret with discovered checkbox and text.
+import type { Secret } from "@/lib/types";
+
+/**
+ * Renders a secret row with a discovered checkbox and secret text.
+ * Handles updating the discovered state and discoveredIn relationship.
+ */
+export const SecretPrintRow = ({ secret }: { secret: Secret }) => {
+ return (
+
+
+
+ {(secret.data as any)?.secret?.text || (
+ (No secret text)
+ )}
+
+
+ );
+};
diff --git a/src/components/documents/session/SessionPrintRow.tsx b/src/components/documents/session/SessionPrintRow.tsx
new file mode 100644
index 0000000..3d48a07
--- /dev/null
+++ b/src/components/documents/session/SessionPrintRow.tsx
@@ -0,0 +1,10 @@
+import type { Session } from "@/lib/types";
+
+export const SessionPrintRow = ({ session }: { session: Session }) => {
+ return (
+
+
StrongStart
+
{session.data.session.strongStart}
+
+ );
+};
diff --git a/src/components/documents/treasure/TreasurePrintRow.tsx b/src/components/documents/treasure/TreasurePrintRow.tsx
new file mode 100644
index 0000000..d30bffb
--- /dev/null
+++ b/src/components/documents/treasure/TreasurePrintRow.tsx
@@ -0,0 +1,24 @@
+// TreasureRow.tsx
+// Displays a single treasure with discovered checkbox and text.
+import type { Treasure } from "@/lib/types";
+
+/**
+ * Renders a treasure row with a discovered checkbox and treasure text.
+ * Handles updating the discovered state and discoveredIn relationship.
+ */
+export const TreasurePrintRow = ({ treasure }: { treasure: Treasure }) => {
+ return (
+
+
+
+ {(treasure.data as any)?.treasure?.text || (
+ (No treasure text)
+ )}
+
+
+ );
+};
diff --git a/src/config.ts b/src/config.ts
index 132eeef..7d6dd19 100644
--- a/src/config.ts
+++ b/src/config.ts
@@ -3,4 +3,5 @@
*
* This includes endpoints and other environment-specific settings.
*/
-export const POCKETBASE_URL: string = import.meta.env.VITE_POCKETBASE_URL || "http://127.0.0.1:8090"; // Update as needed for deployment
+export const POCKETBASE_URL: string =
+ import.meta.env.VITE_POCKETBASE_URL || "/"; // Update as needed for deployment
diff --git a/src/routeTree.gen.ts b/src/routeTree.gen.ts
index a17a742..f35f166 100644
--- a/src/routeTree.gen.ts
+++ b/src/routeTree.gen.ts
@@ -11,208 +11,258 @@
// Import Routes
import { Route as rootRoute } from './routes/__root'
-import { Route as LoginImport } from './routes/login'
-import { Route as AboutImport } from './routes/about'
-import { Route as AuthenticatedImport } from './routes/_authenticated'
-import { Route as IndexImport } from './routes/index'
-import { Route as AuthenticatedCampaignsIndexImport } from './routes/_authenticated/campaigns.index'
-import { Route as AuthenticatedDocumentDocumentIdImport } from './routes/_authenticated/document.$documentId'
-import { Route as AuthenticatedCampaignsCampaignIdImport } from './routes/_authenticated/campaigns.$campaignId'
+import { Route as AppImport } from './routes/_app'
+import { Route as AppIndexImport } from './routes/_app/index'
+import { Route as AppLoginImport } from './routes/_app/login'
+import { Route as AppAboutImport } from './routes/_app/about'
+import { Route as AppAuthenticatedImport } from './routes/_app/_authenticated'
+import { Route as AppAuthenticatedCampaignsIndexImport } from './routes/_app/_authenticated/campaigns.index'
+import { Route as AppAuthenticatedDocumentDocumentIdImport } from './routes/_app/_authenticated/document.$documentId'
+import { Route as AppAuthenticatedCampaignsCampaignIdImport } from './routes/_app/_authenticated/campaigns.$campaignId'
+import { Route as AppauthenticatedDocumentDocumentIdPrintImport } from './routes/_app_._authenticated.document_.$documentId.print'
// Create/Update Routes
-const LoginRoute = LoginImport.update({
- id: '/login',
- path: '/login',
+const AppRoute = AppImport.update({
+ id: '/_app',
getParentRoute: () => rootRoute,
} as any)
-const AboutRoute = AboutImport.update({
- id: '/about',
- path: '/about',
- getParentRoute: () => rootRoute,
-} as any)
-
-const AuthenticatedRoute = AuthenticatedImport.update({
- id: '/_authenticated',
- getParentRoute: () => rootRoute,
-} as any)
-
-const IndexRoute = IndexImport.update({
+const AppIndexRoute = AppIndexImport.update({
id: '/',
path: '/',
- getParentRoute: () => rootRoute,
+ getParentRoute: () => AppRoute,
} as any)
-const AuthenticatedCampaignsIndexRoute =
- AuthenticatedCampaignsIndexImport.update({
+const AppLoginRoute = AppLoginImport.update({
+ id: '/login',
+ path: '/login',
+ getParentRoute: () => AppRoute,
+} as any)
+
+const AppAboutRoute = AppAboutImport.update({
+ id: '/about',
+ path: '/about',
+ getParentRoute: () => AppRoute,
+} as any)
+
+const AppAuthenticatedRoute = AppAuthenticatedImport.update({
+ id: '/_authenticated',
+ getParentRoute: () => AppRoute,
+} as any)
+
+const AppAuthenticatedCampaignsIndexRoute =
+ AppAuthenticatedCampaignsIndexImport.update({
id: '/campaigns/',
path: '/campaigns/',
- getParentRoute: () => AuthenticatedRoute,
+ getParentRoute: () => AppAuthenticatedRoute,
} as any)
-const AuthenticatedDocumentDocumentIdRoute =
- AuthenticatedDocumentDocumentIdImport.update({
+const AppAuthenticatedDocumentDocumentIdRoute =
+ AppAuthenticatedDocumentDocumentIdImport.update({
id: '/document/$documentId',
path: '/document/$documentId',
- getParentRoute: () => AuthenticatedRoute,
+ getParentRoute: () => AppAuthenticatedRoute,
} as any)
-const AuthenticatedCampaignsCampaignIdRoute =
- AuthenticatedCampaignsCampaignIdImport.update({
+const AppAuthenticatedCampaignsCampaignIdRoute =
+ AppAuthenticatedCampaignsCampaignIdImport.update({
id: '/campaigns/$campaignId',
path: '/campaigns/$campaignId',
- getParentRoute: () => AuthenticatedRoute,
+ getParentRoute: () => AppAuthenticatedRoute,
+ } as any)
+
+const AppauthenticatedDocumentDocumentIdPrintRoute =
+ AppauthenticatedDocumentDocumentIdPrintImport.update({
+ id: '/_app_/_authenticated/document_/$documentId/print',
+ path: '/document/$documentId/print',
+ getParentRoute: () => rootRoute,
} as any)
// Populate the FileRoutesByPath interface
declare module '@tanstack/react-router' {
interface FileRoutesByPath {
- '/': {
- id: '/'
- path: '/'
- fullPath: '/'
- preLoaderRoute: typeof IndexImport
- parentRoute: typeof rootRoute
- }
- '/_authenticated': {
- id: '/_authenticated'
+ '/_app': {
+ id: '/_app'
path: ''
fullPath: ''
- preLoaderRoute: typeof AuthenticatedImport
+ preLoaderRoute: typeof AppImport
parentRoute: typeof rootRoute
}
- '/about': {
- id: '/about'
+ '/_app/_authenticated': {
+ id: '/_app/_authenticated'
+ path: ''
+ fullPath: ''
+ preLoaderRoute: typeof AppAuthenticatedImport
+ parentRoute: typeof AppImport
+ }
+ '/_app/about': {
+ id: '/_app/about'
path: '/about'
fullPath: '/about'
- preLoaderRoute: typeof AboutImport
- parentRoute: typeof rootRoute
+ preLoaderRoute: typeof AppAboutImport
+ parentRoute: typeof AppImport
}
- '/login': {
- id: '/login'
+ '/_app/login': {
+ id: '/_app/login'
path: '/login'
fullPath: '/login'
- preLoaderRoute: typeof LoginImport
- parentRoute: typeof rootRoute
+ preLoaderRoute: typeof AppLoginImport
+ parentRoute: typeof AppImport
}
- '/_authenticated/campaigns/$campaignId': {
- id: '/_authenticated/campaigns/$campaignId'
+ '/_app/': {
+ id: '/_app/'
+ path: '/'
+ fullPath: '/'
+ preLoaderRoute: typeof AppIndexImport
+ parentRoute: typeof AppImport
+ }
+ '/_app/_authenticated/campaigns/$campaignId': {
+ id: '/_app/_authenticated/campaigns/$campaignId'
path: '/campaigns/$campaignId'
fullPath: '/campaigns/$campaignId'
- preLoaderRoute: typeof AuthenticatedCampaignsCampaignIdImport
- parentRoute: typeof AuthenticatedImport
+ preLoaderRoute: typeof AppAuthenticatedCampaignsCampaignIdImport
+ parentRoute: typeof AppAuthenticatedImport
}
- '/_authenticated/document/$documentId': {
- id: '/_authenticated/document/$documentId'
+ '/_app/_authenticated/document/$documentId': {
+ id: '/_app/_authenticated/document/$documentId'
path: '/document/$documentId'
fullPath: '/document/$documentId'
- preLoaderRoute: typeof AuthenticatedDocumentDocumentIdImport
- parentRoute: typeof AuthenticatedImport
+ preLoaderRoute: typeof AppAuthenticatedDocumentDocumentIdImport
+ parentRoute: typeof AppAuthenticatedImport
}
- '/_authenticated/campaigns/': {
- id: '/_authenticated/campaigns/'
+ '/_app/_authenticated/campaigns/': {
+ id: '/_app/_authenticated/campaigns/'
path: '/campaigns'
fullPath: '/campaigns'
- preLoaderRoute: typeof AuthenticatedCampaignsIndexImport
- parentRoute: typeof AuthenticatedImport
+ preLoaderRoute: typeof AppAuthenticatedCampaignsIndexImport
+ parentRoute: typeof AppAuthenticatedImport
+ }
+ '/_app_/_authenticated/document_/$documentId/print': {
+ id: '/_app_/_authenticated/document_/$documentId/print'
+ path: '/document/$documentId/print'
+ fullPath: '/document/$documentId/print'
+ preLoaderRoute: typeof AppauthenticatedDocumentDocumentIdPrintImport
+ parentRoute: typeof rootRoute
}
}
}
// Create and export the route tree
-interface AuthenticatedRouteChildren {
- AuthenticatedCampaignsCampaignIdRoute: typeof AuthenticatedCampaignsCampaignIdRoute
- AuthenticatedDocumentDocumentIdRoute: typeof AuthenticatedDocumentDocumentIdRoute
- AuthenticatedCampaignsIndexRoute: typeof AuthenticatedCampaignsIndexRoute
+interface AppAuthenticatedRouteChildren {
+ AppAuthenticatedCampaignsCampaignIdRoute: typeof AppAuthenticatedCampaignsCampaignIdRoute
+ AppAuthenticatedDocumentDocumentIdRoute: typeof AppAuthenticatedDocumentDocumentIdRoute
+ AppAuthenticatedCampaignsIndexRoute: typeof AppAuthenticatedCampaignsIndexRoute
}
-const AuthenticatedRouteChildren: AuthenticatedRouteChildren = {
- AuthenticatedCampaignsCampaignIdRoute: AuthenticatedCampaignsCampaignIdRoute,
- AuthenticatedDocumentDocumentIdRoute: AuthenticatedDocumentDocumentIdRoute,
- AuthenticatedCampaignsIndexRoute: AuthenticatedCampaignsIndexRoute,
+const AppAuthenticatedRouteChildren: AppAuthenticatedRouteChildren = {
+ AppAuthenticatedCampaignsCampaignIdRoute:
+ AppAuthenticatedCampaignsCampaignIdRoute,
+ AppAuthenticatedDocumentDocumentIdRoute:
+ AppAuthenticatedDocumentDocumentIdRoute,
+ AppAuthenticatedCampaignsIndexRoute: AppAuthenticatedCampaignsIndexRoute,
}
-const AuthenticatedRouteWithChildren = AuthenticatedRoute._addFileChildren(
- AuthenticatedRouteChildren,
-)
+const AppAuthenticatedRouteWithChildren =
+ AppAuthenticatedRoute._addFileChildren(AppAuthenticatedRouteChildren)
+
+interface AppRouteChildren {
+ AppAuthenticatedRoute: typeof AppAuthenticatedRouteWithChildren
+ AppAboutRoute: typeof AppAboutRoute
+ AppLoginRoute: typeof AppLoginRoute
+ AppIndexRoute: typeof AppIndexRoute
+}
+
+const AppRouteChildren: AppRouteChildren = {
+ AppAuthenticatedRoute: AppAuthenticatedRouteWithChildren,
+ AppAboutRoute: AppAboutRoute,
+ AppLoginRoute: AppLoginRoute,
+ AppIndexRoute: AppIndexRoute,
+}
+
+const AppRouteWithChildren = AppRoute._addFileChildren(AppRouteChildren)
export interface FileRoutesByFullPath {
- '/': typeof IndexRoute
- '': typeof AuthenticatedRouteWithChildren
- '/about': typeof AboutRoute
- '/login': typeof LoginRoute
- '/campaigns/$campaignId': typeof AuthenticatedCampaignsCampaignIdRoute
- '/document/$documentId': typeof AuthenticatedDocumentDocumentIdRoute
- '/campaigns': typeof AuthenticatedCampaignsIndexRoute
+ '': typeof AppAuthenticatedRouteWithChildren
+ '/about': typeof AppAboutRoute
+ '/login': typeof AppLoginRoute
+ '/': typeof AppIndexRoute
+ '/campaigns/$campaignId': typeof AppAuthenticatedCampaignsCampaignIdRoute
+ '/document/$documentId': typeof AppAuthenticatedDocumentDocumentIdRoute
+ '/campaigns': typeof AppAuthenticatedCampaignsIndexRoute
+ '/document/$documentId/print': typeof AppauthenticatedDocumentDocumentIdPrintRoute
}
export interface FileRoutesByTo {
- '/': typeof IndexRoute
- '': typeof AuthenticatedRouteWithChildren
- '/about': typeof AboutRoute
- '/login': typeof LoginRoute
- '/campaigns/$campaignId': typeof AuthenticatedCampaignsCampaignIdRoute
- '/document/$documentId': typeof AuthenticatedDocumentDocumentIdRoute
- '/campaigns': typeof AuthenticatedCampaignsIndexRoute
+ '': typeof AppAuthenticatedRouteWithChildren
+ '/about': typeof AppAboutRoute
+ '/login': typeof AppLoginRoute
+ '/': typeof AppIndexRoute
+ '/campaigns/$campaignId': typeof AppAuthenticatedCampaignsCampaignIdRoute
+ '/document/$documentId': typeof AppAuthenticatedDocumentDocumentIdRoute
+ '/campaigns': typeof AppAuthenticatedCampaignsIndexRoute
+ '/document/$documentId/print': typeof AppauthenticatedDocumentDocumentIdPrintRoute
}
export interface FileRoutesById {
__root__: typeof rootRoute
- '/': typeof IndexRoute
- '/_authenticated': typeof AuthenticatedRouteWithChildren
- '/about': typeof AboutRoute
- '/login': typeof LoginRoute
- '/_authenticated/campaigns/$campaignId': typeof AuthenticatedCampaignsCampaignIdRoute
- '/_authenticated/document/$documentId': typeof AuthenticatedDocumentDocumentIdRoute
- '/_authenticated/campaigns/': typeof AuthenticatedCampaignsIndexRoute
+ '/_app': typeof AppRouteWithChildren
+ '/_app/_authenticated': typeof AppAuthenticatedRouteWithChildren
+ '/_app/about': typeof AppAboutRoute
+ '/_app/login': typeof AppLoginRoute
+ '/_app/': typeof AppIndexRoute
+ '/_app/_authenticated/campaigns/$campaignId': typeof AppAuthenticatedCampaignsCampaignIdRoute
+ '/_app/_authenticated/document/$documentId': typeof AppAuthenticatedDocumentDocumentIdRoute
+ '/_app/_authenticated/campaigns/': typeof AppAuthenticatedCampaignsIndexRoute
+ '/_app_/_authenticated/document_/$documentId/print': typeof AppauthenticatedDocumentDocumentIdPrintRoute
}
export interface FileRouteTypes {
fileRoutesByFullPath: FileRoutesByFullPath
fullPaths:
- | '/'
| ''
| '/about'
| '/login'
+ | '/'
| '/campaigns/$campaignId'
| '/document/$documentId'
| '/campaigns'
+ | '/document/$documentId/print'
fileRoutesByTo: FileRoutesByTo
to:
- | '/'
| ''
| '/about'
| '/login'
+ | '/'
| '/campaigns/$campaignId'
| '/document/$documentId'
| '/campaigns'
+ | '/document/$documentId/print'
id:
| '__root__'
- | '/'
- | '/_authenticated'
- | '/about'
- | '/login'
- | '/_authenticated/campaigns/$campaignId'
- | '/_authenticated/document/$documentId'
- | '/_authenticated/campaigns/'
+ | '/_app'
+ | '/_app/_authenticated'
+ | '/_app/about'
+ | '/_app/login'
+ | '/_app/'
+ | '/_app/_authenticated/campaigns/$campaignId'
+ | '/_app/_authenticated/document/$documentId'
+ | '/_app/_authenticated/campaigns/'
+ | '/_app_/_authenticated/document_/$documentId/print'
fileRoutesById: FileRoutesById
}
export interface RootRouteChildren {
- IndexRoute: typeof IndexRoute
- AuthenticatedRoute: typeof AuthenticatedRouteWithChildren
- AboutRoute: typeof AboutRoute
- LoginRoute: typeof LoginRoute
+ AppRoute: typeof AppRouteWithChildren
+ AppauthenticatedDocumentDocumentIdPrintRoute: typeof AppauthenticatedDocumentDocumentIdPrintRoute
}
const rootRouteChildren: RootRouteChildren = {
- IndexRoute: IndexRoute,
- AuthenticatedRoute: AuthenticatedRouteWithChildren,
- AboutRoute: AboutRoute,
- LoginRoute: LoginRoute,
+ AppRoute: AppRouteWithChildren,
+ AppauthenticatedDocumentDocumentIdPrintRoute:
+ AppauthenticatedDocumentDocumentIdPrintRoute,
}
export const routeTree = rootRoute
@@ -225,40 +275,54 @@ export const routeTree = rootRoute
"__root__": {
"filePath": "__root.tsx",
"children": [
- "/",
- "/_authenticated",
- "/about",
- "/login"
+ "/_app",
+ "/_app_/_authenticated/document_/$documentId/print"
]
},
- "/": {
- "filePath": "index.tsx"
- },
- "/_authenticated": {
- "filePath": "_authenticated.tsx",
+ "/_app": {
+ "filePath": "_app.tsx",
"children": [
- "/_authenticated/campaigns/$campaignId",
- "/_authenticated/document/$documentId",
- "/_authenticated/campaigns/"
+ "/_app/_authenticated",
+ "/_app/about",
+ "/_app/login",
+ "/_app/"
]
},
- "/about": {
- "filePath": "about.tsx"
+ "/_app/_authenticated": {
+ "filePath": "_app/_authenticated.tsx",
+ "parent": "/_app",
+ "children": [
+ "/_app/_authenticated/campaigns/$campaignId",
+ "/_app/_authenticated/document/$documentId",
+ "/_app/_authenticated/campaigns/"
+ ]
},
- "/login": {
- "filePath": "login.tsx"
+ "/_app/about": {
+ "filePath": "_app/about.tsx",
+ "parent": "/_app"
},
- "/_authenticated/campaigns/$campaignId": {
- "filePath": "_authenticated/campaigns.$campaignId.tsx",
- "parent": "/_authenticated"
+ "/_app/login": {
+ "filePath": "_app/login.tsx",
+ "parent": "/_app"
},
- "/_authenticated/document/$documentId": {
- "filePath": "_authenticated/document.$documentId.tsx",
- "parent": "/_authenticated"
+ "/_app/": {
+ "filePath": "_app/index.tsx",
+ "parent": "/_app"
},
- "/_authenticated/campaigns/": {
- "filePath": "_authenticated/campaigns.index.tsx",
- "parent": "/_authenticated"
+ "/_app/_authenticated/campaigns/$campaignId": {
+ "filePath": "_app/_authenticated/campaigns.$campaignId.tsx",
+ "parent": "/_app/_authenticated"
+ },
+ "/_app/_authenticated/document/$documentId": {
+ "filePath": "_app/_authenticated/document.$documentId.tsx",
+ "parent": "/_app/_authenticated"
+ },
+ "/_app/_authenticated/campaigns/": {
+ "filePath": "_app/_authenticated/campaigns.index.tsx",
+ "parent": "/_app/_authenticated"
+ },
+ "/_app_/_authenticated/document_/$documentId/print": {
+ "filePath": "_app_._authenticated.document_.$documentId.print.tsx"
}
}
}
diff --git a/src/routes/__root.tsx b/src/routes/__root.tsx
index 246a026..6fd10a0 100644
--- a/src/routes/__root.tsx
+++ b/src/routes/__root.tsx
@@ -1,75 +1,12 @@
-import { Link, Outlet, createRootRoute } from "@tanstack/react-router";
-import { TanStackRouterDevtools } from "@tanstack/react-router-devtools";
-import { AuthProvider, useAuth } from "@/context/auth/AuthContext";
+import { AuthProvider } from "@/context/auth/AuthContext";
import { ReactQueryDevtools } from "@tanstack/react-query-devtools";
-
-/**
- * Root header with navigation and user authentication controls.
- */
-function RootHeader() {
- const { user, logout, isLoading } = useAuth();
- return (
-
- );
-}
+import { Outlet, createRootRoute } from "@tanstack/react-router";
+import { TanStackRouterDevtools } from "@tanstack/react-router-devtools";
export const Route = createRootRoute({
component: () => (
<>
-
diff --git a/src/routes/_app.tsx b/src/routes/_app.tsx
new file mode 100644
index 0000000..abdc260
--- /dev/null
+++ b/src/routes/_app.tsx
@@ -0,0 +1,77 @@
+import { useAuth } from "@/context/auth/AuthContext";
+import { Link, Outlet, createFileRoute } from "@tanstack/react-router";
+
+export const Route = createFileRoute("/_app")({
+ component: RouteComponent,
+});
+
+/**
+ * Root header with navigation and user authentication controls.
+ */
+function AppHeader() {
+ const { user, logout, isLoading } = useAuth();
+ return (
+
+ );
+}
+
+function RouteComponent() {
+ return (
+ <>
+
+
+ >
+ );
+}
diff --git a/src/routes/_authenticated.tsx b/src/routes/_app/_authenticated.tsx
similarity index 79%
rename from src/routes/_authenticated.tsx
rename to src/routes/_app/_authenticated.tsx
index f123cd7..fea59c5 100644
--- a/src/routes/_authenticated.tsx
+++ b/src/routes/_app/_authenticated.tsx
@@ -1,7 +1,7 @@
import { isAuthenticated } from "@/lib/pocketbase";
import { createFileRoute, redirect } from "@tanstack/react-router";
-export const Route = createFileRoute("/_authenticated")({
+export const Route = createFileRoute("/_app/_authenticated")({
beforeLoad: () => {
if (!isAuthenticated()) {
throw redirect({
diff --git a/src/routes/_authenticated/campaigns.$campaignId.tsx b/src/routes/_app/_authenticated/campaigns.$campaignId.tsx
similarity index 96%
rename from src/routes/_authenticated/campaigns.$campaignId.tsx
rename to src/routes/_app/_authenticated/campaigns.$campaignId.tsx
index 13a82dc..a008734 100644
--- a/src/routes/_authenticated/campaigns.$campaignId.tsx
+++ b/src/routes/_app/_authenticated/campaigns.$campaignId.tsx
@@ -6,7 +6,7 @@ import { Button } from "@headlessui/react";
import { useQueryClient, useSuspenseQuery } from "@tanstack/react-query";
import { Loader } from "@/components/Loader";
-export const Route = createFileRoute("/_authenticated/campaigns/$campaignId")({
+export const Route = createFileRoute("/_app/_authenticated/campaigns/$campaignId")({
component: RouteComponent,
pendingComponent: Loader,
});
diff --git a/src/routes/_authenticated/campaigns.index.tsx b/src/routes/_app/_authenticated/campaigns.index.tsx
similarity index 95%
rename from src/routes/_authenticated/campaigns.index.tsx
rename to src/routes/_app/_authenticated/campaigns.index.tsx
index 57aed67..170ca22 100644
--- a/src/routes/_authenticated/campaigns.index.tsx
+++ b/src/routes/_app/_authenticated/campaigns.index.tsx
@@ -6,7 +6,7 @@ import { Loader } from "@/components/Loader";
import { CreateCampaignButton } from "@/components/CreateCampaignButton";
import { useRouter } from "@tanstack/react-router";
-export const Route = createFileRoute("/_authenticated/campaigns/")({
+export const Route = createFileRoute("/_app/_authenticated/campaigns/")({
loader: async () => {
const records = await pb.collection("campaigns").getFullList();
return {
diff --git a/src/routes/_authenticated/document.$documentId.tsx b/src/routes/_app/_authenticated/document.$documentId.tsx
similarity index 95%
rename from src/routes/_authenticated/document.$documentId.tsx
rename to src/routes/_app/_authenticated/document.$documentId.tsx
index 60813e5..9d49d0e 100644
--- a/src/routes/_authenticated/document.$documentId.tsx
+++ b/src/routes/_app/_authenticated/document.$documentId.tsx
@@ -10,7 +10,7 @@ import {
import { RelationshipList } from "@/components/RelationshipList";
import { SessionForm } from "@/components/documents/session/SessionForm";
-export const Route = createFileRoute("/_authenticated/document/$documentId")({
+export const Route = createFileRoute("/_app/_authenticated/document/$documentId")({
loader: async ({ params }) => {
const doc = await pb.collection("documents").getOne(params.documentId);
const relationships: Relationship[] = await pb
diff --git a/src/routes/about.tsx b/src/routes/_app/about.tsx
similarity index 74%
rename from src/routes/about.tsx
rename to src/routes/_app/about.tsx
index 1e6c706..c2721ac 100644
--- a/src/routes/about.tsx
+++ b/src/routes/_app/about.tsx
@@ -1,6 +1,6 @@
import { createFileRoute } from '@tanstack/react-router'
-export const Route = createFileRoute('/about')({
+export const Route = createFileRoute('/_app/about')({
component: RouteComponent,
})
diff --git a/src/routes/index.tsx b/src/routes/_app/index.tsx
similarity index 80%
rename from src/routes/index.tsx
rename to src/routes/_app/index.tsx
index a0a2dfa..a8f8b4a 100644
--- a/src/routes/index.tsx
+++ b/src/routes/_app/index.tsx
@@ -1,6 +1,6 @@
import { createFileRoute } from "@tanstack/react-router";
-export const Route = createFileRoute("/")({
+export const Route = createFileRoute("/_app/")({
component: App,
});
diff --git a/src/routes/login.tsx b/src/routes/_app/login.tsx
similarity index 99%
rename from src/routes/login.tsx
rename to src/routes/_app/login.tsx
index fb2547b..f300f49 100644
--- a/src/routes/login.tsx
+++ b/src/routes/_app/login.tsx
@@ -8,7 +8,7 @@ import { useState } from "react";
* Login and signup page for authentication.
* Allows users to log in or create a new account.
*/
-export const Route = createFileRoute("/login")({
+export const Route = createFileRoute("/_app/login")({
beforeLoad: () => {
if (isAuthenticated()) {
throw redirect({
diff --git a/src/routes/_app_._authenticated.document_.$documentId.print.tsx b/src/routes/_app_._authenticated.document_.$documentId.print.tsx
new file mode 100644
index 0000000..632a4d5
--- /dev/null
+++ b/src/routes/_app_._authenticated.document_.$documentId.print.tsx
@@ -0,0 +1,73 @@
+import { DocumentPrintRow } from "@/components/documents/DocumentPrintRow";
+import { SessionPrintRow } from "@/components/documents/session/SessionPrintRow";
+import { Loader } from "@/components/Loader";
+import { pb } from "@/lib/pocketbase";
+import { RelationshipType, type Relationship, type Session } from "@/lib/types";
+import { useSuspenseQuery } from "@tanstack/react-query";
+import { createFileRoute } from "@tanstack/react-router";
+import _ from "lodash";
+
+export const Route = createFileRoute(
+ "/_app_/_authenticated/document_/$documentId/print",
+)({
+ component: RouteComponent,
+ pendingComponent: Loader,
+});
+
+function RouteComponent() {
+ const params = Route.useParams();
+ const {
+ data: { session, relationships },
+ } = useSuspenseQuery({
+ queryKey: ["session", "relationships"],
+ queryFn: async () => {
+ const session = await pb
+ .collection("documents")
+ .getOne(params.documentId);
+ const relationships: Relationship[] = await pb
+ .collection("relationships")
+ .getFullList({
+ filter: `primary = "${params.documentId}"`,
+ expand: "secondary",
+ });
+ console.log("Fetched data: ", relationships);
+ return {
+ session: session as Session,
+ relationships: _.mapValues(
+ _.groupBy(relationships, (r) => r.type),
+ (rs: Relationship[]) => rs.flatMap((r) => r.expand?.secondary),
+ ),
+ };
+ },
+ });
+
+ console.log("Parsed data: ", relationships);
+
+ return (
+
+
+
+ {[
+ RelationshipType.Scenes,
+ RelationshipType.Secrets,
+ RelationshipType.Locations,
+ RelationshipType.Npcs,
+ RelationshipType.Monsters,
+ RelationshipType.Treasures,
+ ].map((relationshipType) => (
+
+
+ {relationshipType.charAt(0).toUpperCase() +
+ relationshipType.slice(1)}
+
+
+
+ {(relationships[relationshipType] ?? []).map((item) => (
+
+ ))}
+
+
+ ))}
+
+ );
+}