import config from "@payload-config"; import { getPayload } from "payload"; import { notFound } from "next/navigation"; import Link from "next/link"; import type { Vehicle, Resource, Technology, Structure } from "@/payload-types"; import { RichText } from "@payloadcms/richtext-lexical/react"; import { convertLexicalToPlaintext } from "@payloadcms/richtext-lexical/plaintext"; import { ArrowLeftIcon, BoxIcon, Building2Icon, ClockIcon, CrosshairIcon, GaugeIcon, HeartIcon, ShieldIcon, TruckIcon, WrenchIcon, } from "lucide-react"; import { Item, ItemContent, ItemDescription, ItemHeader, ItemMedia, ItemTitle, } from "@/components/ui/item"; interface VehicleDetailPageProps { params: Promise<{ id: string }>; } const categoryColors: Record = { civilian: "bg-muted text-muted-foreground", utility: "bg-blue-500/20 text-blue-400", transport: "bg-green-500/20 text-green-400", weaponized: "bg-red-500/20 text-red-400", military: "bg-amber-500/20 text-amber-400", }; const armorColors: Record = { none: "bg-muted text-muted-foreground", light: "bg-green-500/20 text-green-400", medium: "bg-amber-500/20 text-amber-400", heavy: "bg-red-500/20 text-red-400", composite: "bg-purple-500/20 text-purple-400", }; export default async function VehicleDetailPage({ params, }: VehicleDetailPageProps) { const { id } = await params; const payload = await getPayload({ config }); const vehicle = await payload .findByID({ collection: "vehicles", id: Number(id), depth: 2, }) .catch(() => null); if (!vehicle) { notFound(); } const materials = (vehicle.materials ?? []).map((m) => ({ resource: m.resource as Resource, amount: m.amount ?? 0, })); const requiredTech = (vehicle.requiredTech ?? []) as Technology[]; const scrapReturns = (vehicle.scrapReturns ?? []).map((s) => ({ resource: s.resource as Resource, amount: s.amount ?? 0, chance: s.chance ?? 100, })); const upkeepCosts = (vehicle.upkeepCosts ?? []).map((u) => ({ resource: u.resource as Resource, amount: u.amount ?? 0, })); const producingStructures = vehicle.requiredStructure?.docs?.filter( (s): s is Structure => typeof s === "object" && s !== null, ) ?? []; return (
Back to Vehicles

{vehicle.name}

{(vehicle.category ?? []).map((cat) => ( {cat} ))}
{vehicle.description && ( Description )} {materials.length > 0 && ( Construction Materials {vehicle.constructionTime && ( {vehicle.constructionTime} tick{vehicle.constructionTime !== 1 ? "s" : ""} )}
{materials.map((mat, index) => ( {mat.resource.name}: {mat.amount.toLocaleString()} ))}
)} {requiredTech.length > 0 && (

Required Technologies

{requiredTech.map((tech) => ( {tech.name} ))}
)} {(vehicle.maxHealth || vehicle.armorRating || vehicle.maxSpeedOnRoad || vehicle.maxSpeedOffRoad || vehicle.maxAirspeed || vehicle.maxKnots) && (

Combat & Performance

{vehicle.maxHealth && ( Max Health {vehicle.maxHealth.toLocaleString()} )} {vehicle.armorRating && ( Armor Rating {vehicle.armorRating} )} {vehicle.maxSpeedOnRoad && ( Speed (Road) {vehicle.maxSpeedOnRoad} km/h )} {vehicle.maxSpeedOffRoad && ( Speed (Off-Road) {vehicle.maxSpeedOffRoad} km/h )} {vehicle.maxAirspeed && ( Airspeed {vehicle.maxAirspeed} km/h )} {vehicle.maxKnots && ( Max Knots {vehicle.maxKnots} kn )}
)} {(vehicle.width || vehicle.height || vehicle.maxMass || vehicle.aceCargoSlots) && (

Logistics

{(vehicle.width || vehicle.height) && ( Grid Dimensions {vehicle.width ?? "—"}×{vehicle.height ?? "—"} )} {vehicle.maxMass && ( Cargo Capacity {vehicle.maxMass.toLocaleString()} kg )} {vehicle.aceCargoSlots != null && ( ACE Cargo Slots {vehicle.aceCargoSlots} )}
)} {(scrapReturns.length > 0 || upkeepCosts.length > 0) && (

Maintenance

{scrapReturns.length > 0 && ( Scrap Returns
{scrapReturns.map((scrap, index) => ( {scrap.resource.name}: {scrap.amount.toLocaleString()} {scrap.chance < 100 && ( ({scrap.chance}%) )} ))}
)} {upkeepCosts.length > 0 && ( Upkeep Costs Per game tick (every hour)
{upkeepCosts.map((upkeep, index) => ( {upkeep.resource.name}: {upkeep.amount.toLocaleString()}/tick ))}
)}
)} {producingStructures.length > 0 && (

Produced By

{producingStructures.map((structure) => (
{structure.name}
{convertLexicalToPlaintext({ data: structure.description }).slice(0, 120)}
))}
)}
); }