import config from "@payload-config"; import { headers as nextHeaders } from "next/headers"; import { getPayload } from "payload"; import { ClipboardCheck } from "lucide-react"; import { SurveyList, type SurveyListItem } from "@/components/frontend/surveys/SurveyList"; import { isSurveyOpen, surveyAudienceMatches } from "@/lib/surveys/evaluate"; import type { User } from "@/payload-types"; export const metadata = { title: "Surveys: Polaris Task Force", }; function audienceContext(user: User) { const roleIds = (user.roleDocs ?? []) .map((r) => (typeof r === "object" ? r.id : r)) .filter((id): id is number => typeof id === "number"); return { userId: user.id, roleIds }; } export default async function SurveysPage() { const headers = await nextHeaders(); const payload = await getPayload({ config }); const { user } = await payload.auth({ headers, canSetHeaders: false }); // The (frontend) layout renders LandingPage for guests; this only guards // the authed render path's types. if (!user || user.collection !== "users") return null; const [formsResult, profileRes] = await Promise.all([ payload.find({ collection: "forms", sort: "-createdAt", limit: 100, depth: 1, }), payload.find({ collection: "profiles", where: { user: { equals: user.id } }, limit: 1, depth: 1, }), ]); const heldQualifications = (profileRes.docs[0]?.progression?.qualifications ?? []) .map((q) => (typeof q === "object" && q !== null && "name" in q ? (q.name as string) : typeof q === "string" ? q : null)) .filter((n): n is string => n !== null); const ctx = { ...audienceContext(user), qualificationNames: heldQualifications }; const now = Date.now(); const items: SurveyListItem[] = formsResult.docs .filter((form) => isSurveyOpen(form, now) && surveyAudienceMatches(form, ctx)) .map((form) => ({ id: form.id, title: form.title, openUntil: form.activeUntil ?? null, questionCount: form.fields?.filter((f) => f.blockType !== "message").length ?? 0, })); return (
Open surveys for you to take.