Skip to content

Commit

Permalink
Added hacker applicants overview
Browse files Browse the repository at this point in the history
  • Loading branch information
IanWearsHat committed Dec 21, 2024
1 parent 709a54a commit bf68051
Show file tree
Hide file tree
Showing 3 changed files with 169 additions and 0 deletions.
134 changes: 134 additions & 0 deletions apps/site/src/app/admin/applicants/hackers/HackerApplicants.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
"use client";

import { useRouter } from "next/navigation";

import { useContext, useState } from "react";

import Box from "@cloudscape-design/components/box";
import Cards from "@cloudscape-design/components/cards";
import Header from "@cloudscape-design/components/header";
import Link from "@cloudscape-design/components/link";

import { useFollowWithNextLink } from "@/app/admin/layout/common";
import useHackerApplicants, {
HackerApplicantSummary,
} from "@/lib/admin/useHackerApplicants";

import ApplicantFilters, { Options } from "../components/ApplicantFilters";
import ApplicantStatus from "../components/ApplicantStatus";

import UserContext from "@/lib/admin/UserContext";
import { isApplicationManager } from "@/lib/admin/authorization";

function HackerApplicants() {
const router = useRouter();

const { roles } = useContext(UserContext);

if (!isApplicationManager(roles)) {
router.push("/admin/dashboard");
}

const [selectedStatuses, setSelectedStatuses] = useState<Options>([]);
const [selectedDecisions, setSelectedDecisions] = useState<Options>([]);
const { applicantList, loading } = useHackerApplicants();

const selectedStatusValues = selectedStatuses.map(({ value }) => value);
const selectedDecisionValues = selectedDecisions.map(({ value }) => value);

const filteredApplicants = applicantList.filter(
(applicant) =>
(selectedStatuses.length === 0 ||
selectedStatusValues.includes(applicant.status)) &&
(selectedDecisions.length === 0 ||
selectedDecisionValues.includes(applicant.decision || "-")),
);

const items = filteredApplicants;

const counter =
selectedStatuses.length > 0 || selectedDecisions.length > 0
? `(${items.length}/${applicantList.length})`
: `(${applicantList.length})`;

const emptyContent = (
<Box textAlign="center" color="inherit">
No applicants
</Box>
);

return (
<Cards
cardDefinition={{
header: CardHeader,
sections: [
{
id: "uid",
header: "UID",
content: ({ _id }) => _id,
},
{
id: "school",
header: "School",
content: ({ application_data }) => application_data.school,
},
{
id: "status",
header: "Status",
content: ApplicantStatus,
},
{
id: "submission_time",
header: "Applied",
content: ({ application_data }) =>
new Date(application_data.submission_time).toLocaleDateString(),
},
{
id: "avg_score",
header: "Averaged Score",
content: ({ avg_score }) => (avg_score === -1 ? "-" : avg_score),
},
{
id: "decision",
header: "Decision",
content: DecisionStatus,
},
],
}}
// visibleSections={preferences.visibleContent}
loading={loading}
loadingText="Loading applicants"
items={items}
trackBy="_id"
variant="full-page"
filter={
<ApplicantFilters
selectedStatuses={selectedStatuses}
setSelectedStatuses={setSelectedStatuses}
selectedDecisions={selectedDecisions}
setSelectedDecisions={setSelectedDecisions}
/>
}
empty={emptyContent}
header={<Header counter={counter}>Applicants</Header>}
/>
);
}

const CardHeader = ({ _id, first_name, last_name }: HackerApplicantSummary) => {
const followWithNextLink = useFollowWithNextLink();
return (
<Link
href={`/admin/applicants/${_id}`}
fontSize="inherit"
onFollow={followWithNextLink}
>
{first_name} {last_name}
</Link>
);
};

const DecisionStatus = ({ decision }: HackerApplicantSummary) =>
decision ? <ApplicantStatus status={decision} /> : "-";

export default HackerApplicants;
1 change: 1 addition & 0 deletions apps/site/src/app/admin/applicants/hackers/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as default } from "./HackerApplicants";
34 changes: 34 additions & 0 deletions apps/site/src/lib/admin/useHackerApplicants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import axios from "axios";
import useSWR from "swr";

import { Decision, Status } from "./useApplicant";

export interface HackerApplicantSummary {
_id: string;
first_name: string;
last_name: string;
status: Status;
decision: Decision | null;
num_reviewers: number;
avg_score: number;
application_data: {
school: string;
submission_time: string;
};
}

const fetcher = async (url: string) => {
const res = await axios.get<HackerApplicantSummary[]>(url);
return res.data;
};

function useHackerApplicants() {
const { data, error, isLoading } = useSWR<HackerApplicantSummary[]>(
"/api/admin/hackerApplicants",
fetcher,
);

return { applicantList: data || [], loading: isLoading, error };
}

export default useHackerApplicants;

0 comments on commit bf68051

Please sign in to comment.