Adds session list to campaign page
This commit is contained in:
@@ -16,6 +16,7 @@ import { Route as AboutImport } from './routes/about'
|
|||||||
import { Route as AuthenticatedImport } from './routes/_authenticated'
|
import { Route as AuthenticatedImport } from './routes/_authenticated'
|
||||||
import { Route as IndexImport } from './routes/index'
|
import { Route as IndexImport } from './routes/index'
|
||||||
import { Route as AuthenticatedCampaignsIndexImport } from './routes/_authenticated/campaigns.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 AuthenticatedCampaignsCampaignIdImport } from './routes/_authenticated/campaigns.$campaignId'
|
||||||
|
|
||||||
// Create/Update Routes
|
// Create/Update Routes
|
||||||
@@ -50,6 +51,13 @@ const AuthenticatedCampaignsIndexRoute =
|
|||||||
getParentRoute: () => AuthenticatedRoute,
|
getParentRoute: () => AuthenticatedRoute,
|
||||||
} as any)
|
} as any)
|
||||||
|
|
||||||
|
const AuthenticatedDocumentDocumentIdRoute =
|
||||||
|
AuthenticatedDocumentDocumentIdImport.update({
|
||||||
|
id: '/document/$documentId',
|
||||||
|
path: '/document/$documentId',
|
||||||
|
getParentRoute: () => AuthenticatedRoute,
|
||||||
|
} as any)
|
||||||
|
|
||||||
const AuthenticatedCampaignsCampaignIdRoute =
|
const AuthenticatedCampaignsCampaignIdRoute =
|
||||||
AuthenticatedCampaignsCampaignIdImport.update({
|
AuthenticatedCampaignsCampaignIdImport.update({
|
||||||
id: '/campaigns/$campaignId',
|
id: '/campaigns/$campaignId',
|
||||||
@@ -96,6 +104,13 @@ declare module '@tanstack/react-router' {
|
|||||||
preLoaderRoute: typeof AuthenticatedCampaignsCampaignIdImport
|
preLoaderRoute: typeof AuthenticatedCampaignsCampaignIdImport
|
||||||
parentRoute: typeof AuthenticatedImport
|
parentRoute: typeof AuthenticatedImport
|
||||||
}
|
}
|
||||||
|
'/_authenticated/document/$documentId': {
|
||||||
|
id: '/_authenticated/document/$documentId'
|
||||||
|
path: '/document/$documentId'
|
||||||
|
fullPath: '/document/$documentId'
|
||||||
|
preLoaderRoute: typeof AuthenticatedDocumentDocumentIdImport
|
||||||
|
parentRoute: typeof AuthenticatedImport
|
||||||
|
}
|
||||||
'/_authenticated/campaigns/': {
|
'/_authenticated/campaigns/': {
|
||||||
id: '/_authenticated/campaigns/'
|
id: '/_authenticated/campaigns/'
|
||||||
path: '/campaigns'
|
path: '/campaigns'
|
||||||
@@ -110,11 +125,13 @@ declare module '@tanstack/react-router' {
|
|||||||
|
|
||||||
interface AuthenticatedRouteChildren {
|
interface AuthenticatedRouteChildren {
|
||||||
AuthenticatedCampaignsCampaignIdRoute: typeof AuthenticatedCampaignsCampaignIdRoute
|
AuthenticatedCampaignsCampaignIdRoute: typeof AuthenticatedCampaignsCampaignIdRoute
|
||||||
|
AuthenticatedDocumentDocumentIdRoute: typeof AuthenticatedDocumentDocumentIdRoute
|
||||||
AuthenticatedCampaignsIndexRoute: typeof AuthenticatedCampaignsIndexRoute
|
AuthenticatedCampaignsIndexRoute: typeof AuthenticatedCampaignsIndexRoute
|
||||||
}
|
}
|
||||||
|
|
||||||
const AuthenticatedRouteChildren: AuthenticatedRouteChildren = {
|
const AuthenticatedRouteChildren: AuthenticatedRouteChildren = {
|
||||||
AuthenticatedCampaignsCampaignIdRoute: AuthenticatedCampaignsCampaignIdRoute,
|
AuthenticatedCampaignsCampaignIdRoute: AuthenticatedCampaignsCampaignIdRoute,
|
||||||
|
AuthenticatedDocumentDocumentIdRoute: AuthenticatedDocumentDocumentIdRoute,
|
||||||
AuthenticatedCampaignsIndexRoute: AuthenticatedCampaignsIndexRoute,
|
AuthenticatedCampaignsIndexRoute: AuthenticatedCampaignsIndexRoute,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,6 +145,7 @@ export interface FileRoutesByFullPath {
|
|||||||
'/about': typeof AboutRoute
|
'/about': typeof AboutRoute
|
||||||
'/login': typeof LoginRoute
|
'/login': typeof LoginRoute
|
||||||
'/campaigns/$campaignId': typeof AuthenticatedCampaignsCampaignIdRoute
|
'/campaigns/$campaignId': typeof AuthenticatedCampaignsCampaignIdRoute
|
||||||
|
'/document/$documentId': typeof AuthenticatedDocumentDocumentIdRoute
|
||||||
'/campaigns': typeof AuthenticatedCampaignsIndexRoute
|
'/campaigns': typeof AuthenticatedCampaignsIndexRoute
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,6 +155,7 @@ export interface FileRoutesByTo {
|
|||||||
'/about': typeof AboutRoute
|
'/about': typeof AboutRoute
|
||||||
'/login': typeof LoginRoute
|
'/login': typeof LoginRoute
|
||||||
'/campaigns/$campaignId': typeof AuthenticatedCampaignsCampaignIdRoute
|
'/campaigns/$campaignId': typeof AuthenticatedCampaignsCampaignIdRoute
|
||||||
|
'/document/$documentId': typeof AuthenticatedDocumentDocumentIdRoute
|
||||||
'/campaigns': typeof AuthenticatedCampaignsIndexRoute
|
'/campaigns': typeof AuthenticatedCampaignsIndexRoute
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -147,6 +166,7 @@ export interface FileRoutesById {
|
|||||||
'/about': typeof AboutRoute
|
'/about': typeof AboutRoute
|
||||||
'/login': typeof LoginRoute
|
'/login': typeof LoginRoute
|
||||||
'/_authenticated/campaigns/$campaignId': typeof AuthenticatedCampaignsCampaignIdRoute
|
'/_authenticated/campaigns/$campaignId': typeof AuthenticatedCampaignsCampaignIdRoute
|
||||||
|
'/_authenticated/document/$documentId': typeof AuthenticatedDocumentDocumentIdRoute
|
||||||
'/_authenticated/campaigns/': typeof AuthenticatedCampaignsIndexRoute
|
'/_authenticated/campaigns/': typeof AuthenticatedCampaignsIndexRoute
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -158,9 +178,17 @@ export interface FileRouteTypes {
|
|||||||
| '/about'
|
| '/about'
|
||||||
| '/login'
|
| '/login'
|
||||||
| '/campaigns/$campaignId'
|
| '/campaigns/$campaignId'
|
||||||
|
| '/document/$documentId'
|
||||||
| '/campaigns'
|
| '/campaigns'
|
||||||
fileRoutesByTo: FileRoutesByTo
|
fileRoutesByTo: FileRoutesByTo
|
||||||
to: '/' | '' | '/about' | '/login' | '/campaigns/$campaignId' | '/campaigns'
|
to:
|
||||||
|
| '/'
|
||||||
|
| ''
|
||||||
|
| '/about'
|
||||||
|
| '/login'
|
||||||
|
| '/campaigns/$campaignId'
|
||||||
|
| '/document/$documentId'
|
||||||
|
| '/campaigns'
|
||||||
id:
|
id:
|
||||||
| '__root__'
|
| '__root__'
|
||||||
| '/'
|
| '/'
|
||||||
@@ -168,6 +196,7 @@ export interface FileRouteTypes {
|
|||||||
| '/about'
|
| '/about'
|
||||||
| '/login'
|
| '/login'
|
||||||
| '/_authenticated/campaigns/$campaignId'
|
| '/_authenticated/campaigns/$campaignId'
|
||||||
|
| '/_authenticated/document/$documentId'
|
||||||
| '/_authenticated/campaigns/'
|
| '/_authenticated/campaigns/'
|
||||||
fileRoutesById: FileRoutesById
|
fileRoutesById: FileRoutesById
|
||||||
}
|
}
|
||||||
@@ -209,6 +238,7 @@ export const routeTree = rootRoute
|
|||||||
"filePath": "_authenticated.tsx",
|
"filePath": "_authenticated.tsx",
|
||||||
"children": [
|
"children": [
|
||||||
"/_authenticated/campaigns/$campaignId",
|
"/_authenticated/campaigns/$campaignId",
|
||||||
|
"/_authenticated/document/$documentId",
|
||||||
"/_authenticated/campaigns/"
|
"/_authenticated/campaigns/"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -222,6 +252,10 @@ export const routeTree = rootRoute
|
|||||||
"filePath": "_authenticated/campaigns.$campaignId.tsx",
|
"filePath": "_authenticated/campaigns.$campaignId.tsx",
|
||||||
"parent": "/_authenticated"
|
"parent": "/_authenticated"
|
||||||
},
|
},
|
||||||
|
"/_authenticated/document/$documentId": {
|
||||||
|
"filePath": "_authenticated/document.$documentId.tsx",
|
||||||
|
"parent": "/_authenticated"
|
||||||
|
},
|
||||||
"/_authenticated/campaigns/": {
|
"/_authenticated/campaigns/": {
|
||||||
"filePath": "_authenticated/campaigns.index.tsx",
|
"filePath": "_authenticated/campaigns.index.tsx",
|
||||||
"parent": "/_authenticated"
|
"parent": "/_authenticated"
|
||||||
|
|||||||
@@ -5,13 +5,22 @@ import type { Campaign } from "@/lib/types";
|
|||||||
export const Route = createFileRoute("/_authenticated/campaigns/$campaignId")({
|
export const Route = createFileRoute("/_authenticated/campaigns/$campaignId")({
|
||||||
loader: async ({ params }) => {
|
loader: async ({ params }) => {
|
||||||
const record = await pb.collection("campaigns").getOne(params.campaignId);
|
const record = await pb.collection("campaigns").getOne(params.campaignId);
|
||||||
return { campaign: { id: record.id, name: record.name } as Campaign };
|
// Fetch all documents for this campaign
|
||||||
|
const docs = await pb.collection("documents").getFullList({
|
||||||
|
filter: `campaign = "${params.campaignId}"`,
|
||||||
|
});
|
||||||
|
// Filter to only those with data.session
|
||||||
|
const sessions = docs.filter((doc: any) => doc.data && doc.data.session);
|
||||||
|
return {
|
||||||
|
campaign: { id: record.id, name: record.name } as Campaign,
|
||||||
|
sessions,
|
||||||
|
};
|
||||||
},
|
},
|
||||||
component: RouteComponent,
|
component: RouteComponent,
|
||||||
});
|
});
|
||||||
|
|
||||||
function RouteComponent() {
|
function RouteComponent() {
|
||||||
const { campaign } = Route.useLoaderData();
|
const { campaign, sessions } = Route.useLoaderData();
|
||||||
return (
|
return (
|
||||||
<div className="max-w-xl mx-auto py-8">
|
<div className="max-w-xl mx-auto py-8">
|
||||||
<div className="mb-2">
|
<div className="mb-2">
|
||||||
@@ -23,6 +32,26 @@ function RouteComponent() {
|
|||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
<h2 className="text-2xl font-bold mb-4 text-slate-100">{campaign.name}</h2>
|
<h2 className="text-2xl font-bold mb-4 text-slate-100">{campaign.name}</h2>
|
||||||
|
<h3 className="text-lg font-semibold mb-2 text-slate-200">Sessions</h3>
|
||||||
|
{sessions && sessions.length > 0 ? (
|
||||||
|
<div>
|
||||||
|
<ul className="space-y-2">
|
||||||
|
{sessions.map((s: any) => (
|
||||||
|
<li key={s.id}>
|
||||||
|
<Link
|
||||||
|
to="/document/$documentId"
|
||||||
|
params={{ documentId: s.id }}
|
||||||
|
className="block px-4 py-2 rounded bg-slate-800 hover:bg-violet-700 text-slate-100 transition-colors"
|
||||||
|
>
|
||||||
|
{s.data.session.strongStart || <span className="italic text-slate-400">(No strong start)</span>}
|
||||||
|
</Link>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<div className="text-slate-400">No sessions found for this campaign.</div>
|
||||||
|
)}
|
||||||
{/* More campaign details can go here */}
|
{/* More campaign details can go here */}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user