import config from "@payload-config"; import { getPayload } from "payload"; import { notFound } from "next/navigation"; import Link from "next/link"; import type { Faction, Media, Mission } from "@/payload-types"; import { RichText } from "@payloadcms/richtext-lexical/react"; import { ArrowLeftIcon, CalendarDaysIcon, ChevronRightIcon, ShieldIcon, TargetIcon, UsersIcon, } from "lucide-react"; import { Item, ItemContent, ItemDescription, ItemHeader, ItemTitle } from "@/components/ui/item"; import { MissionCard } from "@/components/frontend/intelligence/MissionCard"; import { statusColors as missionStatusColors } from "@/lib/intelligence/missionColors"; interface CampaignDetailPageProps { params: Promise<{ id: string }>; } const statusColors: Record = { concept: "bg-muted text-muted-foreground", inProgress: "bg-blue-500/20 text-blue-400", completed: "bg-emerald-500/20 text-emerald-400", }; const factionTypeColors: Record = { majorFaction: "bg-blue-500/20 text-blue-400", minorFaction: "bg-muted text-muted-foreground", corporation: "bg-amber-500/20 text-amber-400", special: "bg-purple-500/20 text-purple-400", }; export default async function CampaignDetailPage({ params }: CampaignDetailPageProps) { const { id } = await params; const payload = await getPayload({ config }); const campaign = await payload .findByID({ collection: "campaigns", id: Number(id), depth: 1, select: { id: true, name: true, summary: true, status: true, startDate: true, endDate: true, owner: true, coverImage: true, description: true, }, }) .catch(() => null); const owner = campaign?.owner; const ownerName = owner && typeof owner === "object" && "displayName" in owner ? owner.displayName : "Unknown"; if (!campaign) { notFound(); } const coverImage = typeof campaign.coverImage === "object" && campaign.coverImage !== null ? (campaign.coverImage as Media) : null; const coverImageUrl = coverImage?.url ?? null; const [missionsRes, factionsRes] = await Promise.all([ payload .find({ collection: "missions", where: { "classification.campaign": { equals: campaign.id } }, sort: "-classification.startDateTime", limit: 100, depth: 1, select: { name: true, codeName: true, summary: true, operationType: true, classification: true, ownershipAndStatus: true, missionRoles: true, coverImage: true, }, }) .catch(() => ({ docs: [] })), payload.find({ collection: "factions", where: { associatedCampaigns: { equals: campaign.id } }, limit: 100, depth: 0, select: { name: true, type: true, description: true }, }), ]); const missions = missionsRes.docs as Mission[]; const factions = factionsRes.docs as Faction[]; const startDate = campaign.startDate ? new Date(campaign.startDate).toLocaleDateString("en-US", { year: "numeric", month: "short", day: "numeric", }) : null; const endDate = campaign.endDate ? new Date(campaign.endDate).toLocaleDateString("en-US", { year: "numeric", month: "short", day: "numeric", }) : null; // Mission status breakdown const statusCounts: Record = {}; for (const m of missions) { const s = m.ownershipAndStatus.status; statusCounts[s] = (statusCounts[s] ?? 0) + 1; } return (
Back to Campaigns
{coverImageUrl ? ( ) : (
)}
{campaign.status === "inProgress" ? "In Progress" : campaign.status.charAt(0).toUpperCase() + campaign.status.slice(1)}

{campaign.name}

{campaign.summary}

{(startDate || endDate) && (
{startDate && {startDate}} {startDate && endDate && —} {endDate ? {endDate} : startDate ? Present : null}
)}
{/* ── Main Content (2/3) ──────────────────────────── */}
{campaign.description && ( Description )}

Missions

{missions.length} mission{missions.length !== 1 ? "s" : ""}
{missions.length > 0 ? (
{missions.map((mission) => ( ))}
) : (

No missions in this campaign yet.

)}
{/* ── Right Sidebar (1/3) ─────────────────────────── */}
{/* Campaign Stats */}
Campaign Stats
Total Missions {missions.length}
{Object.entries(statusCounts).map(([status, count]) => (
{status} {count}
))}
Duration {startDate} {endDate ? ` — ${endDate}` : " — Present"}
Owner {ownerName}
{/* Faction Roster */} {factions.length > 0 && (
Faction Roster
View all
{factions.map((faction) => (
{faction.name} {faction.type === "majorFaction" ? "Major" : faction.type === "minorFaction" ? "Minor" : faction.type}
))}
)}
); }