import config from "@payload-config"; import { isPayloadUser } from "@/utils/access-control/isPayloadUser"; import { getPayload } from "payload"; import { headers as nextHeaders } from "next/headers"; import type { Media, Rank, User } from "@/payload-types"; import { UsersIcon } from "lucide-react"; import { RosterView } from "@/components/frontend/roster/RosterView"; export const metadata = { title: "Unit Roster — Polaris Task Force", }; export type RosterMember = { profileId: number; user: Pick; enlistmentDate: string | null; xp: number; rank: Pick & { insigniaUrl?: string | null; }; assignmentName?: string; assignmentType?: string; assignmentCallsign?: string; isLeader: boolean; }; export type RosterAssignment = { id: number; name: string; type: string; callsign?: string; leaderId?: number; memberIds: number[]; subAssignmentIds: number[]; }; export default async function RosterPage() { const headers = await nextHeaders(); const payload = await getPayload({ config }); const { user: authUser } = await payload.auth({ headers, canSetHeaders: false }); const currentUser = isPayloadUser(authUser) ? authUser : null; const [profileRes, assignmentRes] = await Promise.all([ payload.find({ collection: "profiles", limit: 500, depth: 2, select: { user: true, rank: true, dossier: true, progression: true, }, }), payload.find({ collection: "assignments", limit: 200, depth: 1, select: { name: true, type: true, callsign: true, leader: true, members: true, subAssignments: true, }, }), ]); const profiles = profileRes.docs; const members: RosterMember[] = profiles.map((profile) => { const user = profile.user as User; const rank = profile.rank as Rank; const insigniaUrl = rank.insignia && typeof rank.insignia === "object" ? (rank.insignia as Media).url : null; let assignmentName: string | undefined; let assignmentType: string | undefined; let assignmentCallsign: string | undefined; let isLeader = false; for (const assignment of assignmentRes.docs) { const memberIds = (assignment.members ?? []) .map((m) => (typeof m === "object" ? m.id : m)) .filter(Boolean); const leaderId = assignment.leader && typeof assignment.leader === "object" ? assignment.leader.id : assignment.leader; if (memberIds.includes(user.id) || leaderId === user.id) { assignmentName = assignment.name; assignmentType = assignment.type; assignmentCallsign = assignment.callsign ?? undefined; if (leaderId === user.id) isLeader = true; break; } } return { profileId: profile.id, user: { id: user.id, displayName: user.displayName, username: user.username }, enlistmentDate: profile.dossier?.enlistmentDate ?? null, xp: profile.progression?.xp ?? 0, rank: { id: rank.id, name: rank.name, abbreviation: rank.abbreviation, _order: rank._order, insigniaUrl, }, assignmentName, assignmentType, assignmentCallsign, isLeader, }; }); const assignments: RosterAssignment[] = assignmentRes.docs.map((a) => ({ id: a.id, name: a.name, type: a.type, callsign: a.callsign ?? undefined, leaderId: a.leader && typeof a.leader === "object" ? a.leader.id : (a.leader as number | undefined), memberIds: (a.members ?? []) .map((m) => (typeof m === "object" ? m.id : m)) .filter(Boolean) as number[], subAssignmentIds: (a.subAssignments ?? []) .map((s) => (typeof s === "object" ? s.id : s)) .filter(Boolean) as number[], })); return (

Unit Roster

{members.length} operator{members.length !== 1 ? "s" : ""} across {assignments.length}{" "} assignment{assignments.length !== 1 ? "s" : ""}

); }