129 lines
3.7 KiB
TypeScript
129 lines
3.7 KiB
TypeScript
import { useCallback } from "react";
|
|
import { createFileRoute, Link } from "@tanstack/react-router";
|
|
import { pb } from "@/lib/pocketbase";
|
|
import { SessionRow } from "@/components/documents/session/SessionRow";
|
|
import { Button } from "@headlessui/react";
|
|
import { useQueryClient, useSuspenseQuery } from "@tanstack/react-query";
|
|
import { Loader } from "@/components/Loader";
|
|
import type { Relationship } from "@/lib/types";
|
|
|
|
export const Route = createFileRoute(
|
|
"/_app/_authenticated/campaigns/$campaignId",
|
|
)({
|
|
component: RouteComponent,
|
|
pendingComponent: Loader,
|
|
});
|
|
|
|
function RouteComponent() {
|
|
const queryClient = useQueryClient();
|
|
const params = Route.useParams();
|
|
|
|
const {
|
|
data: { campaign, sessions },
|
|
} = useSuspenseQuery({
|
|
queryKey: ["campaign"],
|
|
queryFn: async () => {
|
|
const campaign = await pb
|
|
.collection("campaigns")
|
|
.getOne(params.campaignId);
|
|
// Fetch all documents for this campaign
|
|
const sessions = await pb.collection("documents").getFullList({
|
|
filter: `campaign = "${params.campaignId}" && type = 'session'`,
|
|
sort: "-created",
|
|
});
|
|
return {
|
|
campaign,
|
|
sessions,
|
|
};
|
|
},
|
|
});
|
|
|
|
const createNewSession = useCallback(async () => {
|
|
// Check for a previous session
|
|
const prevSession = await pb
|
|
.collection("documents")
|
|
.getFirstListItem(`campaign = "${campaign.id}" && type = 'session'`, {
|
|
sort: "-created",
|
|
});
|
|
|
|
console.log("Previous session: ", {
|
|
id: prevSession.id,
|
|
created: prevSession.created,
|
|
});
|
|
|
|
const newSession = await pb.collection("documents").create({
|
|
campaign: campaign.id,
|
|
type: "session",
|
|
data: {
|
|
strongStart: "",
|
|
},
|
|
});
|
|
|
|
// If any relations, then copy things over
|
|
if (prevSession) {
|
|
const prevRelations = await pb
|
|
.collection<Relationship>("relationships")
|
|
.getFullList({
|
|
filter: `primary = "${prevSession.id}"`,
|
|
});
|
|
|
|
console.log(`Found ${prevRelations.length} previous relations`);
|
|
|
|
for (const relation of prevRelations) {
|
|
console.log(
|
|
`Adding ${relation.secondary.length} items to ${relation.type}`,
|
|
);
|
|
await pb.collection("relationships").create({
|
|
primary: newSession.id,
|
|
type: relation.type,
|
|
secondary: relation.secondary,
|
|
});
|
|
}
|
|
}
|
|
|
|
queryClient.invalidateQueries({ queryKey: ["campaign"] });
|
|
}, [campaign]);
|
|
|
|
return (
|
|
<div className="max-w-xl mx-auto py-8">
|
|
<div className="mb-2">
|
|
<Link
|
|
to="/campaigns"
|
|
className="text-slate-400 hover:text-violet-400 text-sm underline underline-offset-2 transition-colors"
|
|
>
|
|
← Back to campaigns
|
|
</Link>
|
|
</div>
|
|
<h2 className="text-2xl font-bold mb-4 text-slate-100">
|
|
{campaign.name}
|
|
</h2>
|
|
<div className="flex justify-between">
|
|
<h3 className="text-lg font-semibold mb-2 text-slate-200">Sessions</h3>
|
|
<div>
|
|
<Button
|
|
onClick={() => createNewSession()}
|
|
className="inline-flex items-center justify-center rounded bg-violet-600 hover:bg-violet-700 text-white px-4 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-violet-400"
|
|
>
|
|
New Session
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
{sessions && sessions.length > 0 ? (
|
|
<div>
|
|
<ul className="space-y-2">
|
|
{sessions.map((s: any) => (
|
|
<li key={s.id}>
|
|
<SessionRow session={s} />
|
|
</li>
|
|
))}
|
|
</ul>
|
|
</div>
|
|
) : (
|
|
<div className="text-slate-400">
|
|
No sessions found for this campaign.
|
|
</div>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|