"use client"; import Link from "next/link"; import type { Campaign } from "@/payload-types"; import { cn } from "@/lib/utils"; import { ClockIcon, CrosshairIcon, UsersIcon } from "lucide-react"; interface CampaignCardCampaign extends Pick< Campaign, "id" | "name" | "summary" | "status" | "startDate" | "endDate" > { readonly coverImageUrl: string | null; readonly missionCount: number; readonly avgPlayers: number; readonly avgDurationMinutes: number; } type CampaignCardInput = CampaignCardCampaign | Campaign; interface CampaignCardProps { readonly campaign: CampaignCardInput; } 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 statusLabels: Record = { concept: "Concept", inProgress: "In Progress", completed: "Completed", }; export function CampaignCard({ campaign }: CampaignCardProps) { const coverImageUrl = "coverImageUrl" in campaign ? campaign.coverImageUrl : typeof campaign.coverImage === "object" && campaign.coverImage !== null ? (campaign.coverImage.url ?? null) : null; const missionCount = "missionCount" in campaign ? campaign.missionCount : 0; const avgPlayers = "avgPlayers" in campaign ? campaign.avgPlayers : 0; const avgDurationMinutes = "avgDurationMinutes" in campaign ? campaign.avgDurationMinutes : 0; const roundedDuration = Math.round(avgDurationMinutes); const durationHours = Math.floor(roundedDuration / 60); const durationMinutes = roundedDuration % 60; const durationLabel = roundedDuration >= 60 ? `${durationHours}h ${durationMinutes}m` : `${roundedDuration}m`; const playersLabel = Number.isInteger(avgPlayers) ? avgPlayers.toString() : avgPlayers.toFixed(1); const owner = (campaign as any).owner; const ownerName = owner && typeof owner === "object" && "displayName" in owner ? owner.displayName : "Unknown"; return (
{coverImageUrl !== null ? ( ) : (
); }