"use client"; import Link from "next/link"; import type { Campaign, Map, Media, User } from "@/payload-types"; import { cn } from "@/lib/utils"; import { operationTypeColors, operationTypeLabels, statusColors, } from "@/lib/intelligence/missionColors"; import { Item, ItemContent, ItemDescription, ItemHeader, ItemMedia, ItemTitle, } from "@/components/ui/item"; import { CalendarDaysIcon, ChevronRightIcon, ClockIcon, CrosshairIcon, MapPinIcon, UserIcon, UsersIcon, } from "lucide-react"; export interface MissionCardProps { readonly mission: { readonly id: number; readonly name: string; readonly codeName: string; readonly summary: string; readonly operationType: "main" | "side" | "external"; readonly classification: { readonly missionType: "Zeus" | "PvE" | "PvP" | "PvPvE" | "Training" | "Special"; readonly startDateTime: string; readonly estimatedDuration: number; readonly map: number | Map; readonly campaign?: number | Campaign | null; }; readonly ownershipAndStatus: { readonly status: | "Concept" | "Planning" | "Ready" | "Scheduled" | "Active" | "Completed" | "Cancelled"; }; readonly missionRoles?: { readonly maxPlayers: number; } | null; readonly createdBy?: number | User | null; readonly coverImage?: number | Media | null; }; readonly variant?: "default" | "image"; readonly showFullDetails?: boolean; } export function MissionCard({ mission, variant, showFullDetails = false, }: MissionCardProps) { const resolvedVariant = variant ?? (mission.coverImage ? "image" : "default"); const coverImage = typeof mission.coverImage === "object" && mission.coverImage !== null ? mission.coverImage : null; const coverImageUrl = coverImage?.url ?? null; const map = typeof mission.classification.map === "object" && mission.classification.map !== null ? mission.classification.map : null; const campaign = typeof mission.classification.campaign === "object" && mission.classification.campaign !== null ? mission.classification.campaign : null; const createdByUser = typeof mission.createdBy === "object" && mission.createdBy !== null ? mission.createdBy : null; const hostLabel = createdByUser ? (createdByUser.displayName || createdByUser.username) : null; const showHost = mission.operationType === "side" && hostLabel !== null; const startDate = new Date(mission.classification.startDateTime); const dateStr = startDate.toLocaleDateString("en-US", { weekday: "short", month: "short", day: "numeric", }); const timeStr = startDate.toLocaleTimeString("en-US", { hour: "2-digit", minute: "2-digit", }); const durationHours = Math.floor(mission.classification.estimatedDuration / 60); const durationMinutes = mission.classification.estimatedDuration % 60; const durationLabel = durationMinutes > 0 ? `${durationHours}h ${durationMinutes}m` : `${durationHours}h`; const imageCard = resolvedVariant === "image" && coverImageUrl !== null; return ( {resolvedVariant === "image" && coverImageUrl !== null && (
)}
{mission.codeName} {mission.name}
{operationTypeLabels[mission.operationType] ?? mission.operationType} Operation {mission.ownershipAndStatus.status}
{mission.summary}
{dateStr} at {timeStr} {showFullDetails && ( {durationLabel} )} {map && ( {map.name} )} {mission.missionRoles?.maxPlayers && ( {mission.missionRoles.maxPlayers} slots )} {showHost && ( Hosted by {hostLabel} )} {campaign && {campaign.name}}
View details
); }