diff --git a/components/admin/DropdownMenu.tsx b/components/admin/DropdownMenu.tsx index cf5aa4ad..455b5363 100644 --- a/components/admin/DropdownMenu.tsx +++ b/components/admin/DropdownMenu.tsx @@ -22,6 +22,7 @@ const DropdownMenu: React.FC<{ onChange?: (value: string) => void }> = ({ > + ); diff --git a/components/admin/InterviewTable.tsx b/components/admin/InterviewTable.tsx new file mode 100644 index 00000000..eb4e88f4 --- /dev/null +++ b/components/admin/InterviewTable.tsx @@ -0,0 +1,202 @@ +import { MuiThemeProvider } from "@material-ui/core/styles"; +import { fetchGraphql } from "@utils/makegqlrequest"; +import MUIDataTable from "mui-datatables"; +import React, { useEffect, useState } from "react"; +import { getInterviewTableColumns } from "./InterviewTableColumn"; +import ApplicantRole from "entities/applicationRole"; +import { ResumeIcon } from "@components/icons/resume.icon"; +import { applicationTableQueries } from "graphql/queries"; +import { getMuiTheme } from "utils/muidatatable"; +import ExpandableRowTable from "./ExpandableRowTable"; + +interface TableProps { + activeRole?: ApplicantRole; + whichChoiceTab?: number; + setNumFirstChoiceEntries: (tab: number) => void; + numFirstChoiceEntries?: number; + setNumSecondChoiceEntries: (tab: number) => void; + numSecondChoiceEntries?: number; +} + +const InterviewTable: React.FC = ({ + activeRole, + whichChoiceTab, + setNumFirstChoiceEntries, + setNumSecondChoiceEntries, +}) => { + const [firstChoiceApplications, setFirstChoiceApplications] = useState( + [], + ); + const [secondChoiceApplications, setSecondChoiceApplications] = useState< + any[] + >([]); + useEffect(() => { + fetchApplicationsByRole(); + }, [activeRole, whichChoiceTab]); + + const fetchApplicationsByRole = async () => { + const currentRole = activeRole || ApplicantRole.vpe; + try { + const firstChoiceResult = await fetchGraphql( + applicationTableQueries.applicationsByRole, + { + role: currentRole, + }, + ); + + const secondChoiceResult = await fetchGraphql( + applicationTableQueries.applicationsBySecondChoiceRole, + { + role: currentRole, + }, + ); + setFirstChoiceApplications(firstChoiceResult.data.applicationTable); + setNumFirstChoiceEntries(firstChoiceResult.data.applicationTable.length); + + setSecondChoiceApplications( + secondChoiceResult.data.secondChoiceRoleApplicationTable, + ); + setNumSecondChoiceEntries( + secondChoiceResult.data.secondChoiceRoleApplicationTable.length, + ); + } catch (error) { + console.error("Error fetching applications:", error); + } + }; + + const createStudentRow = (application: any) => { + const app = application.application; + + return { + id: app.id, + name: app.firstName + " " + app.lastName, + resume: ( + + + View Resume + + ), + term: app.academicYear, + program: app.program, + status: app.status, + secondChoice: app.secondChoiceRole, + secondChoiceStatus: app.secondChoiceStatus, + }; + }; + + const getTableRows = () => { + if (!whichChoiceTab) { + return firstChoiceApplications.map(createStudentRow); + } + return secondChoiceApplications.map(createStudentRow); + }; + + const generateMockInnerData = () => { + return [ + { + "Reviewer Name": "John Doe", + PFSG: 4, + "Team Player": 3, + D2L: 6, + Skill: 5, + "Skill Category": "junior", + "Reviewer Comments": "Great work presenting your case study.", + }, + // Add as many objects as you want to simulate different rows + ]; + }; + + const renderExpandableRow = ( + rowData: any, + rowMeta: { dataIndex: number }, + ) => { + const innerData = generateMockInnerData(); // Use mock data for testing + const application = { + secondChoiceRole: "Graphic Designer", + recommendForSecondChoice: true, + adminComments: "Great", + }; + + const innerColumns = [ + { + name: "Reviewer Name", + options: { filter: false, sort: false }, + }, + { name: "PFSG", options: { filter: false, sort: false } }, + { name: "Team Player", options: { filter: false, sort: false } }, + { name: "D2L", options: { filter: false, sort: false } }, + { name: "Skill", options: { filter: false, sort: false } }, + { + name: "Skill Category", + options: { filter: false, sort: false }, + }, + { + name: "Reviewer Comments", + options: { filter: false, sort: false }, + }, + // You may add more columns as needed + ]; + + return ( + + + +
+ +
+
+
+ 2nd Choice: +

{application.secondChoiceRole}

+
+ +
+ + Recommend for 2nd Choice +
+
+
+ + Admin Comments: + +

{application.adminComments}

+
+
+
+ + + +
+ ); + }; + + return ( + + + + ); +}; + +export default InterviewTable; diff --git a/components/admin/InterviewTableColumn.tsx b/components/admin/InterviewTableColumn.tsx new file mode 100644 index 00000000..fca345f4 --- /dev/null +++ b/components/admin/InterviewTableColumn.tsx @@ -0,0 +1,101 @@ +import { MUIDataTableColumn } from "mui-datatables"; +import { LinkIcon } from "@components/icons/link.icon"; +import { Status, SkillCategory } from "@utils/muidatatable"; +import { router } from "next/router"; + +export const getInterviewTableColumns = (): MUIDataTableColumn[] => { + const handleNameClick = (appId: string) => { + router.push(`/review?reviewId=${appId}`); + }; + + const columns: MUIDataTableColumn[] = [ + { + name: "id", + options: { + display: "excluded", + filter: false, + searchable: false, + sort: false, + }, + }, + { + name: "name", + label: "Application", + options: { + filter: false, + // sortCompare: (order: "asc" | "desc") => createSortFunction(order), + searchable: true, + customBodyRender(value, tableMeta, updateValue) { + const appId = tableMeta.rowData[0]; + return ( +
handleNameClick(appId)} + className="flex items-center cursor-pointer" + > + + {value} +
+ ); + }, + }, + }, + { + name: "term", + label: "Term", + options: { + filter: false, + sort: true, + searchable: true, + }, + }, + { + name: "status", + label: "Status", + options: { + filter: true, + sort: true, + searchable: true, + filterOptions: { + names: [ + "accepted", + "applied", + "interviewed", + "in review", + "pending", + "rejected", + ], + }, + filterType: "multiselect", + customBodyRender(value, tableMeta, updateValue) { + return ; + }, + }, + }, + { + name: "skillCategory", + label: "Skill Category", + options: { + filter: true, + sort: true, + searchable: true, + filterOptions: { + names: ["intermediate", "junior", "senior"], + }, + filterType: "multiselect", + customBodyRender(value, tableMeta, updateValue) { + return ; + }, + }, + }, + { + name: "resume", + label: "Resume", + options: { + filter: false, + sort: true, + searchable: true, + }, + }, + ]; + return columns; +}; diff --git a/components/admin/InterviewTableTitle.tsx b/components/admin/InterviewTableTitle.tsx new file mode 100644 index 00000000..3690121e --- /dev/null +++ b/components/admin/InterviewTableTitle.tsx @@ -0,0 +1,42 @@ +import React, { FC } from "react"; +import Tabs from "@mui/material/Tabs"; +import Tab from "@mui/material/Tab"; + +interface TitleProps { + numFirstChoiceEntries?: number; + numSecondChoiceEntries?: number; + setWhichChoiceTab: (tab: number) => void; + whichChoiceTab?: number; +} +interface TabDescriptionProps { + title: string; + numEntries: number | undefined; + pillStyle: string; +} + +interface SimpleTableTitleProps { + numEntries: number | undefined; +} + +const InterviewTableTitle: React.FC = ({ numEntries }) => { + const pillStyle = + "border-2 border-blue-100 text-blue rounded-full px-4 py-2 m-2 font-large inline-block"; + + return ( +
+
+ Applicants {numEntries} Entries +
+
+ ); +}; + +export default InterviewTableTitle; \ No newline at end of file diff --git a/components/admin/Table.tsx b/components/admin/Table.tsx index 2f73e1e6..b3afdb74 100644 --- a/components/admin/Table.tsx +++ b/components/admin/Table.tsx @@ -9,6 +9,9 @@ import TableTitle from "./DashboardTableTitle"; import ApplicationsTable from "./ApplicationsTable"; import ApplicantRole from "entities/applicationRole"; import ReviewTable from "./ReviewTable"; +import InterviewTableTitle from "./InterviewTableTitle"; +import { SecondChoiceStatus } from "@utils/muidatatable"; +import InterviewTable from "./InterviewTable"; export enum OrganizationalArea { Engineering = "Engineering", @@ -75,31 +78,57 @@ const Table: FC = () => { />
- + {selectedDropdownItem === "Review Dashboard" && ( - + <> + + + )} {selectedDropdownItem === "Delegation Dashboard" && ( - + <> + + + + )} {selectedDropdownItem === "Interview Dashboard" && ( + // TODO: PASS IN COUNT OF CANDIDATES WITH INTERVIEW STATUS + <> + + + )}