diff --git a/app/(protected)/admin/cohort/[id]/page.tsx b/app/(protected)/admin/cohort/[id]/page.tsx
index ce4fc31..589e202 100644
--- a/app/(protected)/admin/cohort/[id]/page.tsx
+++ b/app/(protected)/admin/cohort/[id]/page.tsx
@@ -5,7 +5,7 @@ import { requireAdmin } from "../../../../../lib/guards";
import { prisma } from "../../../../../lib/prisma";
import { editQuestion, endCohort, reviewApplication } from "../actions";
-const TABS = [
+const STATUS_TABS = [
{ key: "pending", label: "Pending", status: ApplicationStatus.SUBMITTED },
{ key: "approved", label: "Approved", status: ApplicationStatus.APPROVED },
{ key: "rejected", label: "Not approved", status: ApplicationStatus.REJECTED },
@@ -14,7 +14,7 @@ const TABS = [
export default async function CohortDetailPage({
params,
searchParams,
-}: Readonly<{ params: { id: string }; searchParams?: { status?: string } }>) {
+}: Readonly<{ params: { id: string }; searchParams?: { status?: string; view?: string } }>) {
await requireAdmin();
const cohort = await prisma.cohort.findUnique({ where: { id: params.id } });
@@ -23,21 +23,27 @@ export default async function CohortDetailPage({
redirect("/admin/cohort");
}
- const activeTab = TABS.find((tab) => tab.key === searchParams?.status) ?? TABS[0];
+ const view = searchParams?.view === "edit" ? "edit" : "review";
+ const activeStatus =
+ STATUS_TABS.find((tab) => tab.key === searchParams?.status) ?? STATUS_TABS[0];
- // Applications live on the cohort screen, filtered by status for this cohort's year.
- const [applications, counts] = await Promise.all([
- prisma.application.findMany({
- where: { cohortId: cohort.id, status: activeTab.status },
- orderBy: { updatedAt: "asc" },
- include: { user: { include: { profile: true } } },
- }),
- prisma.application.groupBy({
- by: ["status"],
- where: { cohortId: cohort.id },
- _count: { _all: true },
- }),
- ]);
+ // Only the Review tab renders applications, so skip both queries on Edit
+ // (the findMany joins user + profile — wasted work otherwise).
+ const [applications, counts] =
+ view === "review"
+ ? await Promise.all([
+ prisma.application.findMany({
+ where: { cohortId: cohort.id, status: activeStatus.status },
+ orderBy: { updatedAt: "asc" },
+ include: { user: { include: { profile: true } } },
+ }),
+ prisma.application.groupBy({
+ by: ["status"],
+ where: { cohortId: cohort.id },
+ _count: { _all: true },
+ }),
+ ])
+ : [[], []];
const countByStatus = new Map(counts.map((row) => [row.status, row._count._all]));
const questions = parseQuestions(cohort.questions);
@@ -54,182 +60,205 @@ export default async function CohortDetailPage({
Cohort {cohort.year} {cohort.isActive ? "(Active)" : "(Ended)"}
- {cohort.isActive ? (
-
- ) : (
-
- Recruitment for this cohort has ended. Open a new year from the Cohorts page to start
- recruiting again.
-
- )}
+
+
+ {view === "edit" ? (
+ <>
+ {cohort.isActive ? (
+
+ ) : (
+
+ Recruitment for this cohort has ended. Open a new year from the Cohorts page to
+ start recruiting again.
+
+ )}
+
+
+
Application questions
+ {questions.length === 0 ? (
+
+ {cohort.isActive
+ ? "No questions yet. Add the first one below."
+ : "No questions set."}
+
+ ) : cohort.isActive ? (
+
+ {questions.map((question, index) => (
+
+ ))}
+
+ ) : (
+ // Ended cohort: questions are read-only so historical answers stay labelled.
+
+ {questions.map((question) => (
+
+ {question.label}
+ {question.required ? " (required)" : ""}
+
+ ))}
+
+ )}
-
-
Application questions
- {questions.length === 0 ? (
-
- {cohort.isActive ? "No questions yet. Add the first one below." : "No questions set."}
-
- ) : cohort.isActive ? (
-
- {questions.map((question, index) => (
-
- ))}
+ ) : null}
- ) : (
- // Ended cohort: questions are read-only so historical answers stay labelled.
-
- {questions.map((question) => (
-
- {question.label}
- {question.required ? " (required)" : ""}
-
+ >
+ ) : (
+
- )}
+
- {cohort.isActive ? (
-
- ) : null}
-
-
-
-
Applications
-
-
- {applications.length === 0 ? (
-
No applications in this view.
- ) : (
-
- {applications.map((application) => {
- const answers = parseAnswers(application.answers);
- return (
-
-
-
{application.user.name ?? application.user.email}
-
- {application.user.email} · Submitted{" "}
- {dateFormatter.format(application.createdAt)}
-
-
- Batch: {application.user.profile?.batch ?? "Not provided"}{" "}
- · Branch:{" "}
- {application.user.profile?.branch ?? "Not provided"}
-
- {questions.map((question) => (
-
- {question.label}:{" "}
- {answers[question.id] || "Not provided"}
+ {applications.length === 0 ? (
+
No applications in this view.
+ ) : (
+
+ {applications.map((application) => {
+ const answers = parseAnswers(application.answers);
+ return (
+
+
+
{application.user.name ?? application.user.email}
+
+ {application.user.email} · Submitted{" "}
+ {dateFormatter.format(application.createdAt)}
- ))}
- {/* Cohort has no questions — fall back to the legacy free-text fields. */}
- {questions.length === 0 ? (
- <>
-
- Goals: {application.goals || "Not provided"}
-
-
- Experience: {application.experience || "Not provided"}
+
+ Batch:{" "}
+ {application.user.profile?.batch ?? "Not provided"} ·{" "}
+ Branch:{" "}
+ {application.user.profile?.branch ?? "Not provided"}
+
+ {questions.map((question) => (
+
+ {question.label}:{" "}
+ {answers[question.id] || "Not provided"}
- {application.whyJoin ? (
+ ))}
+ {/* Cohort has no questions — fall back to the legacy free-text fields. */}
+ {questions.length === 0 ? (
+ <>
+
+ Goals: {application.goals || "Not provided"}
+
- Why join: {application.whyJoin}
+ Experience:{" "}
+ {application.experience || "Not provided"}
- ) : null}
- >
+ {application.whyJoin ? (
+
+ Why join: {application.whyJoin}
+
+ ) : null}
+ >
+ ) : null}
+
+ {application.status === ApplicationStatus.SUBMITTED ? (
+
) : null}
-
- {application.status === ApplicationStatus.SUBMITTED ? (
-
- ) : null}
-
- );
- })}
-
- )}
-
+
+ );
+ })}
+
+ )}
+
+ )}
);