From ced3b0545a9c066e067552ac64180e49b413636f Mon Sep 17 00:00:00 2001 From: jacoblurie29 Date: Thu, 7 Sep 2023 17:52:00 -0500 Subject: [PATCH 01/26] Comment to start PR --- pages/Organizer/OrganizerDash.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pages/Organizer/OrganizerDash.tsx b/pages/Organizer/OrganizerDash.tsx index f2360dcd..47057171 100644 --- a/pages/Organizer/OrganizerDash.tsx +++ b/pages/Organizer/OrganizerDash.tsx @@ -33,7 +33,7 @@ export default function OrganizerDash() { return (await res.json()) as TeamData[]; }); - // Get scores data from API + // Get scores data from the API const { data: scoresData, error: scoresError } = useSWR('/api/scores', async url => { const res = await fetch(url, { method: 'GET' }); if (!res.ok) { From b9d3cce1955b989636570b4372c8217045588420 Mon Sep 17 00:00:00 2001 From: jacoblurie29 Date: Thu, 7 Sep 2023 21:44:50 -0500 Subject: [PATCH 02/26] Generic customSWR and ScheduleTab abstracted --- .../Organizer/JudgingTab/ScheduleTab.tsx | 145 +++++++++++ pages/Organizer/OrganizerDash.tsx | 230 +++--------------- utils/organizer-utils.ts | 2 +- utils/request-utils.ts | 66 +++++ 4 files changed, 249 insertions(+), 194 deletions(-) create mode 100644 components/Organizer/JudgingTab/ScheduleTab.tsx create mode 100644 utils/request-utils.ts diff --git a/components/Organizer/JudgingTab/ScheduleTab.tsx b/components/Organizer/JudgingTab/ScheduleTab.tsx new file mode 100644 index 00000000..959115c7 --- /dev/null +++ b/components/Organizer/JudgingTab/ScheduleTab.tsx @@ -0,0 +1,145 @@ +import { Button, Skeleton, Divider } from 'antd'; +import { SetStateAction, useEffect, useState } from 'react'; +import { + TIMES_JUDGED, + generateScheduleA, + generateScheduleB, + handleConfirmSchedule, +} from '../../../utils/organizer-utils'; +import OrganizerSchedule from '../../schedule'; +import useSWR, { useSWRConfig } from 'swr'; +import { ResponseError, JudgingSessionData, UserData, TeamData } from '../../../types/database'; +import Title from 'antd/lib/typography/Title'; + +const ScheduleTab = () => { + // React state + const [testingSchedule, setTestingSchedule] = useState(false); + const [sampleScheduleAData, setSampleScheduleA] = useState(undefined); + const [sampleScheduleBData, setSampleScheduleB] = useState(undefined); + + // Get judging sessions data from API + const { data: judgingSessionsData, error: judgingSessionsDataError } = useSWR( + '/api/judging-sessions', + async url => { + const res = await fetch(url, { method: 'GET' }); + if (!res.ok) { + const error = new Error('Failed to get judging sessions') as ResponseError; + error.status = res.status; + throw error; + } + return (await res.json()) as JudgingSessionData[]; + } + ); + + // Get judges data from API + const { data: judgeData, error: judgeError } = useSWR('/api/users?usertype=JUDGE', async url => { + const res = await fetch(url, { method: 'GET' }); + if (!res.ok) { + const error = new Error('Failed to get list of judges.') as ResponseError; + error.status = res.status; + throw error; + } + return (await res.json()) as UserData[]; + }); + + // Get teams data from API + const { data: teamsData, error: teamsError } = useSWR('/api/teams', async url => { + const res = await fetch(url, { method: 'GET' }); + if (!res.ok) { + const error = new Error('Failed to get list of teams.') as ResponseError; + error.status = res.status; + throw error; + } + return (await res.json()) as TeamData[]; + }); + + // Check if schedule is impossible + const isScheduleImpossible = () => + teamsData && judgeData && (teamsData.length * TIMES_JUDGED) / 12 > judgeData.length; + + useEffect(() => { + // Exit early if we don't have data yet + if (!judgingSessionsData) return; + + // Sort judging sessions by time + const time = new Date('2022-10-23T11:00:00').getTime(); + const sampleScheduleA = judgingSessionsData.filter( + judgingSession => new Date(judgingSession.time as string).getTime() < time + ); + const sampleScheduleB = judgingSessionsData.filter( + judgingSession => new Date(judgingSession.time as string).getTime() >= time + ); + + // Set the data + setSampleScheduleA(sampleScheduleA); + setSampleScheduleB(sampleScheduleB); + }, [judgingSessionsData]); + + return ( + <> + {teamsData && + judgeData && + (testingSchedule ? ( + + ) : ( + + ))} + {!judgingSessionsData && } +
+ + <> + {isScheduleImpossible() ? ( +
oops woopsy, something went fucky wucky
+ ) : ( +
schedule is possible!!
+ )} +
Count of Teams: {teamsData?.length}
+
Count of Judges: {judgeData?.length}
+ + + {Expo A} + {sampleScheduleAData && ( + ): void { + throw new Error('Function not implemented.'); + }} + sessionTimeStart={new Date('2022-10-23T10:00:00')} + sessionTimeEnd={new Date('2022-10-23T11:00:00')} + /> + )} +
+ {Expo B} + {sampleScheduleBData && ( + ): void { + throw new Error('Function not implemented.'); + }} + sessionTimeStart={new Date('2022-10-23T11:30:00')} + sessionTimeEnd={new Date('2022-10-23T12:30:00')} + /> + )} + + + ); +}; + +export default ScheduleTab; diff --git a/pages/Organizer/OrganizerDash.tsx b/pages/Organizer/OrganizerDash.tsx index 47057171..2e7903e6 100644 --- a/pages/Organizer/OrganizerDash.tsx +++ b/pages/Organizer/OrganizerDash.tsx @@ -1,152 +1,65 @@ -import { Button, Divider, Empty, Skeleton, Space, Tabs } from 'antd'; +import { Button, Empty, Skeleton, Space, Tabs } from 'antd'; import useSWR, { useSWRConfig } from 'swr'; import AllScores from '../../components/allScores'; -import ManageRoleForm from '../../components/manageRoleForm'; -import OrganizerSchedule from '../../components/schedule'; +import ManageRoleForm, { ManageFormFields } from '../../components/manageRoleForm'; import PreAddForm from '../../components/preAddForm'; -import { ResponseError, ScoreData, TeamData, UserData, PreAddData, JudgingSessionData } from '../../types/database'; +import { ResponseError, ScoreData, TeamData, UserData, PreAddData } from '../../types/database'; import PreAddDisplay from '../../components/preAddDisplay'; import ApplicantsDisplay from '../../components/applicantsDisplay'; import Events from '../../components/events'; import { signOut, useSession } from 'next-auth/react'; -import { SetStateAction, useEffect, useState } from 'react'; -import Title from 'antd/lib/typography/Title'; -import { - generateScheduleA, - generateScheduleB, - handleManageFormSubmit, - handlePreAddDelete, - TIMES_JUDGED, -} from '../../utils/organizer-utils'; +import { handleManageFormSubmit, handlePreAddDelete } from '../../utils/organizer-utils'; +import ScheduleTab from '../../components/Organizer/JudgingTab/ScheduleTab'; +import { RequestType, useCustomSWR } from '../../utils/request-utils'; export default function OrganizerDash() { const { mutate } = useSWRConfig(); - // Get teams data from API - const { data: teamsData, error: teamsError } = useSWR('/api/teams', async url => { - const res = await fetch(url, { method: 'GET' }); - if (!res.ok) { - const error = new Error('Failed to get list of teams.') as ResponseError; - error.status = res.status; - throw error; - } - return (await res.json()) as TeamData[]; + // Teams data + const { data: teamsData, error: teamsError } = useCustomSWR({ + url: '/api/teams', + method: RequestType.GET, + errorMessage: 'Failed to get list of teams.', }); - // Get scores data from the API - const { data: scoresData, error: scoresError } = useSWR('/api/scores', async url => { - const res = await fetch(url, { method: 'GET' }); - if (!res.ok) { - const error = new Error('Failed to get list of scores.') as ResponseError; - error.status = res.status; - throw error; - } - return (await res.json()) as ScoreData[]; + // Scores data + const { data: scoresData, error: scoresError } = useCustomSWR({ + url: '/api/scores', + method: RequestType.GET, + errorMessage: 'Failed to get list of scores.', }); - // Get judges data from API - const { data: judgeData, error: judgeError } = useSWR('/api/users?usertype=JUDGE', async url => { - const res = await fetch(url, { method: 'GET' }); - if (!res.ok) { - const error = new Error('Failed to get list of judges.') as ResponseError; - error.status = res.status; - throw error; - } - return (await res.json()) as UserData[]; + // Judge data + const { data: judgeData, error: judgeError } = useCustomSWR({ + url: '/api/users?usertype=JUDGE', + method: RequestType.GET, + errorMessage: 'Failed to get list of judges.', }); - // Get hackers data from API - const { data: hackers, error: hackersError } = useSWR('/api/users?usertype=HACKER', async url => { - const res = await fetch(url, { method: 'GET' }); - if (!res.ok) { - const error = new Error('Failed to get list of hackers.') as ResponseError; - error.status = res.status; - throw error; - } - return (await res.json()) as UserData[]; + // Hacker data + const { data: hackers, error: hackersError } = useCustomSWR({ + url: '/api/users?usertype=HACKER', + method: RequestType.GET, + errorMessage: 'Failed to get list of hackers.', }); - /*const { data: scheduleData, error: scheduleError } = useSWR('/api/schedule', async url => { - const res = await fetch(url, { method: 'GET' }); - if (!res.ok) { - const error = new Error('Failed to get schedule.') as ResponseError; - error.status = res.status; - throw error; - } - return (await res.json()) as ScheduleDisplay[]; - });*/ - - // Get judging sessions data from API - const { data: judgingSessionsData, error: judgingSessionsDataError } = useSWR( - '/api/judging-sessions', - async url => { - const res = await fetch(url, { method: 'GET' }); - if (!res.ok) { - const error = new Error('Failed to get judging sessions') as ResponseError; - error.status = res.status; - throw error; - } - return (await res.json()) as JudgingSessionData[]; - } - ); - - // Get preadd data from API - const { data: preAddData, error: Error } = useSWR('/api/preadd', async url => { - const res = await fetch(url, { method: 'GET' }); - if (!res.ok) { - const error = new Error('Failed to get schedule.') as ResponseError; - error.status = res.status; - throw error; - } - return (await res.json()) as PreAddData[]; + // Preadd data + const { data: preAddData, error: preAddError } = useCustomSWR({ + url: '/api/preadd', + method: RequestType.GET, + errorMessage: 'Failed to get list of preadded users.', }); - // Get all users roles from API - const { data: userData, error } = useSWR('/api/manage-role', async url => { - const res = await fetch(url, { method: 'GET' }); - if (!res.ok) { - const error = new Error('Failed to get list of all users.') as ResponseError; - error.status = res.status; - throw error; - } - - return (await res.json()) as { _id: string; name: string; email: string; userType: string }[]; + // User data + const { data: userData, error } = useCustomSWR({ + url: '/api/manage-role', + method: RequestType.GET, + errorMessage: 'Failed to get list of all users.', }); - useEffect(() => { - // Exit early if we don't have data yet - if (!judgingSessionsData) return; - - // Sort judging sessions by time - const time = new Date('2022-10-23T11:00:00').getTime(); - const sampleScheduleA = judgingSessionsData.filter( - judgingSession => new Date(judgingSession.time as string).getTime() < time - ); - const sampleScheduleB = judgingSessionsData.filter( - judgingSession => new Date(judgingSession.time as string).getTime() >= time - ); - - // Set the data - setSampleScheduleA(sampleScheduleA); - setSampleScheduleB(sampleScheduleB); - }, [judgingSessionsData]); - - // Check if schedule is impossible - const isScheduleImpossible = () => - teamsData && judgeData && (teamsData.length * TIMES_JUDGED) / 12 > judgeData.length; - // Get session data const { data: session, status } = useSession(); - // React state - const [testingSchedule, setTestingSchedule] = useState(false); - const [sampleScheduleAData, setSampleScheduleA] = useState(undefined); - const [sampleScheduleBData, setSampleScheduleB] = useState(undefined); - - function handleConfirmSchedule(arg0: JudgingSessionData[]) { - throw new Error('Function not implemented.'); - } - return ( <>
@@ -162,76 +75,7 @@ export default function OrganizerDash() { { label: `Schedule`, key: '1', - children: ( - <> - {teamsData && - judgeData && - (testingSchedule ? ( - - ) : ( - - ))} - {!judgingSessionsData && } -
- - <> - {isScheduleImpossible() ? ( -
oops woopsy, something went fucky wucky
- ) : ( -
schedule is possible!!
- )} -
Count of Teams: {teamsData?.length}
-
Count of Judges: {judgeData?.length}
- - - {Expo A} - {sampleScheduleAData && ( - ): void { - throw new Error('Function not implemented.'); - }} - sessionTimeStart={new Date('2022-10-23T10:00:00')} - sessionTimeEnd={new Date('2022-10-23T11:00:00')} - /> - )} -
- {Expo B} - {sampleScheduleBData && ( - ): void { - throw new Error('Function not implemented.'); - }} - sessionTimeStart={new Date('2022-10-23T11:30:00')} - sessionTimeEnd={new Date('2022-10-23T12:30:00')} - /> - )} - - - ), + children: , }, { label: `Judging`, diff --git a/utils/organizer-utils.ts b/utils/organizer-utils.ts index 8f26a36d..ba74c35d 100644 --- a/utils/organizer-utils.ts +++ b/utils/organizer-utils.ts @@ -127,7 +127,7 @@ export const matchTeams = (teams: TeamData[], judges: UserData[], times: Date[]) * @param {JudgingSessionData[]} judgingSessions - The array of judging session data objects to submit. * @returns {void} */ -const handleConfirmSchedule = async (judgingSessions: JudgingSessionData[]) => { +export const handleConfirmSchedule = async (judgingSessions: JudgingSessionData[]) => { const res = await fetch('/api/confirm-judging-sessions', { method: 'POST', headers: { diff --git a/utils/request-utils.ts b/utils/request-utils.ts new file mode 100644 index 00000000..0bbfb5c4 --- /dev/null +++ b/utils/request-utils.ts @@ -0,0 +1,66 @@ +import useSWR from 'swr'; +import { ResponseError } from '../types/database'; +import { useEffect, useState } from 'react'; + +/** + * A custom hook that fetches data from the specified URL and returns the data and error. + * Requires template type T to be specified. + * + * @param url - The URL to fetch data from. + * @param method - The HTTP method to use for the request. + * @param errorMessage - Optional error message to display if the request fails. + * @example + * ```tsx + * const { data, error } = useCustomSWR({ + * url: '/api/teams', + * method: RequestType.GET, + * errorMessage: 'Failed to fetch teams.' + * }); + * ``` + */ +export const useCustomSWR = (params: CustomerSWRParams) => { + const [data, setData] = useState(null); + const [error, setError] = useState(null); + + const { data: requestData, error: requestError } = useSWR(params.url, async url => { + const res = await fetch(url, { method: params.method }); + if (!res.ok) { + const error = new Error( + params.errorMessage || 'An error occurred while fetching data from the server.' + ) as ResponseError; + error.status = res.status; + throw error; + } + return (await res.json()) as T[]; + }); + + useEffect(() => { + if (requestData) { + setData(requestData); + } + if (requestError) { + setError(requestError); + } + }, [requestData, requestError]); + + return { data, error }; +}; + +/** + * All possible HTTP request types + */ +export enum RequestType { + GET = 'GET', + POST = 'POST', + PUT = 'PUT', + DELETE = 'DELETE', +} + +/** + * Parameters for the useCustomSWR hook + */ +export interface CustomerSWRParams { + url: string; + method: RequestType; + errorMessage?: string; +} From c85c673ba35b82e078e0f6029427bfcac7b31a24 Mon Sep 17 00:00:00 2001 From: jacoblurie29 Date: Thu, 7 Sep 2023 22:07:17 -0500 Subject: [PATCH 03/26] Updated SWR package to v2.2.2 --- components/LeaveButton.tsx | 4 +- .../Organizer/JudgingTab/ScheduleTab.tsx | 48 +++++++------------ components/applicantsDisplay.tsx | 2 +- components/hacker/TeamManager.tsx | 8 ++-- components/hacker/TeamSetup.tsx | 4 +- package.json | 2 +- pages/JudgeDash.tsx | 6 +-- utils/organizer-utils.ts | 6 +-- utils/request-utils.ts | 14 ++++-- yarn.lock | 18 +++++-- 10 files changed, 57 insertions(+), 55 deletions(-) diff --git a/components/LeaveButton.tsx b/components/LeaveButton.tsx index 1f64cbf1..6be5fedd 100644 --- a/components/LeaveButton.tsx +++ b/components/LeaveButton.tsx @@ -1,8 +1,8 @@ import { Button, Popconfirm } from 'antd'; import { useSWRConfig } from 'swr'; -import { ScopedMutator } from 'swr/dist/types'; +import { ScopedMutator } from 'swr/_internal'; -export default function LeaveButton({ onLeave }: { onLeave: (mutate: ScopedMutator) => Promise }) { +export default function LeaveButton({ onLeave }: { onLeave: (mutate: ScopedMutator) => Promise }) { const { mutate } = useSWRConfig(); return ( { // React state @@ -17,40 +18,25 @@ const ScheduleTab = () => { const [sampleScheduleAData, setSampleScheduleA] = useState(undefined); const [sampleScheduleBData, setSampleScheduleB] = useState(undefined); - // Get judging sessions data from API - const { data: judgingSessionsData, error: judgingSessionsDataError } = useSWR( - '/api/judging-sessions', - async url => { - const res = await fetch(url, { method: 'GET' }); - if (!res.ok) { - const error = new Error('Failed to get judging sessions') as ResponseError; - error.status = res.status; - throw error; - } - return (await res.json()) as JudgingSessionData[]; - } - ); + // Get judging sessions + const { data: judgingSessionsData, error: judgingSessionsDataError } = useCustomSWR({ + url: '/api/judging-sessions', + method: RequestType.GET, + errorMessage: 'Failed to get judging sessions', + }); - // Get judges data from API - const { data: judgeData, error: judgeError } = useSWR('/api/users?usertype=JUDGE', async url => { - const res = await fetch(url, { method: 'GET' }); - if (!res.ok) { - const error = new Error('Failed to get list of judges.') as ResponseError; - error.status = res.status; - throw error; - } - return (await res.json()) as UserData[]; + // Judge data + const { data: judgeData, error: judgeError } = useCustomSWR({ + url: '/api/users?usertype=JUDGE', + method: RequestType.GET, + errorMessage: 'Failed to get list of judges.', }); - // Get teams data from API - const { data: teamsData, error: teamsError } = useSWR('/api/teams', async url => { - const res = await fetch(url, { method: 'GET' }); - if (!res.ok) { - const error = new Error('Failed to get list of teams.') as ResponseError; - error.status = res.status; - throw error; - } - return (await res.json()) as TeamData[]; + // Teams data + const { data: teamsData, error: teamsError } = useCustomSWR({ + url: '/api/teams', + method: RequestType.GET, + errorMessage: 'Failed to get list of teams.', }); // Check if schedule is impossible diff --git a/components/applicantsDisplay.tsx b/components/applicantsDisplay.tsx index 0c3d3bab..ef132b12 100644 --- a/components/applicantsDisplay.tsx +++ b/components/applicantsDisplay.tsx @@ -12,9 +12,9 @@ import { import { DateTime } from 'luxon'; import type { ColumnsType, FilterValue, FilterConfirmProps } from 'antd/es/table/interface'; import { useSWRConfig } from 'swr'; -import { ScopedMutator } from 'swr/dist/types'; import Highlighter from 'react-highlight-words'; import { handleSubmitFailure, handleSubmitSuccess } from '../lib/helpers'; +import { ScopedMutator } from 'swr/_internal'; export interface ApplicantsDisplayProps { hackers: UserData[]; diff --git a/components/hacker/TeamManager.tsx b/components/hacker/TeamManager.tsx index 337aced0..c2e85ed6 100644 --- a/components/hacker/TeamManager.tsx +++ b/components/hacker/TeamManager.tsx @@ -1,13 +1,13 @@ import { Button, Collapse, Descriptions, Divider, Form, Input, notification, Tag } from 'antd'; import { Content } from 'antd/lib/layout/layout'; import { useSWRConfig } from 'swr'; -import { ScopedMutator } from 'swr/dist/types'; import { handleSubmitFailure } from '../../lib/helpers'; import { TeamProfile } from '../../types/client'; import LeaveButton from '../LeaveButton'; +import { ScopedMutator } from 'swr/_internal'; const { Panel } = Collapse; -async function handleSubmit(formData: { teamName: string } | { devpost: string }, mutate: ScopedMutator) { +async function handleSubmit(formData: { teamName: string } | { devpost: string }, mutate: ScopedMutator) { const res = await fetch('/api/team-management', { method: 'PATCH', headers: { @@ -24,7 +24,7 @@ async function handleSubmit(formData: { teamName: string } | { devpost: string } return false; } -async function handleLeaveTeam(mutate: ScopedMutator) { +async function handleLeaveTeam(mutate: ScopedMutator) { const res = await fetch('/api/team-management', { method: 'DELETE', headers: { @@ -41,7 +41,7 @@ async function handleLeaveTeam(mutate: ScopedMutator) { export default function TeamManager({ profile }: { profile: TeamProfile }) { // TODO: STYLE THIS! const { name, joinCode, devpost, members } = profile; - const onFormFinish = async (data: { teamName: string } | { devpost: string }, mutate: ScopedMutator) => { + const onFormFinish = async (data: { teamName: string } | { devpost: string }, mutate: ScopedMutator) => { const success = await handleSubmit(data, mutate); if (success) { notification['success']({ diff --git a/components/hacker/TeamSetup.tsx b/components/hacker/TeamSetup.tsx index e39eeeaa..0c8cfad6 100644 --- a/components/hacker/TeamSetup.tsx +++ b/components/hacker/TeamSetup.tsx @@ -1,12 +1,12 @@ import { Col, Divider, Row } from 'antd'; import { Content } from 'antd/lib/layout/layout'; import { useSWRConfig } from 'swr'; -import { ScopedMutator } from 'swr/dist/types'; import { handleSubmitFailure } from '../../lib/helpers'; import { NewTeamFields } from '../../types/client'; import TeamCard from '../TeamCard'; +import { ScopedMutator } from 'swr/_internal'; -async function handleSubmit(formData: NewTeamFields | { joinCode: string }, mutate: ScopedMutator) { +async function handleSubmit(formData: NewTeamFields | { joinCode: string }, mutate: ScopedMutator) { const res = await fetch('/api/team-management', { method: 'POST', headers: { diff --git a/package.json b/package.json index e594e38e..6ca9409e 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,7 @@ "react": "18.0.0", "react-dom": "18.0.0", "react-highlight-words": "^0.18.0", - "swr": "^1.3.0", + "swr": "^2.2.2", "ts-command-line-args": "^2.2.1" }, "devDependencies": { diff --git a/pages/JudgeDash.tsx b/pages/JudgeDash.tsx index a3000d6d..6abfa0cc 100644 --- a/pages/JudgeDash.tsx +++ b/pages/JudgeDash.tsx @@ -1,13 +1,13 @@ import { Button, Divider, notification, Skeleton } from 'antd'; import { Dispatch, SetStateAction, useEffect, useState } from 'react'; import useSWR, { useSWRConfig } from 'swr'; -import { ScopedMutator } from 'swr/dist/types'; import JudgingForm from '../components/judges/JudgingForm'; import { JudgeSchedule } from '../components/schedule'; import TeamSelect from '../components/judges/TeamSelect'; import { JudgingFormFields, ScheduleDisplay, TeamSelectData } from '../types/client'; import { JudgingSessionData, ResponseError, TeamData } from '../types/database'; import { signOut, useSession } from 'next-auth/react'; +import { ScopedMutator } from 'swr/_internal'; const GENERIC_ERROR_MESSAGE = 'Oops, something went wrong!'; const GENERIC_ERROR_DESCRIPTION = 'Please try again or contact an organizer if the problem persists.'; @@ -35,7 +35,7 @@ function handleSubmitFailure(errorDescription: string) { async function handleSubmit( formData: JudgingFormFields, - mutate: ScopedMutator, + mutate: ScopedMutator, teamId: string, isNewForm: boolean, setIsNewForm: React.Dispatch> @@ -81,7 +81,7 @@ export default function JudgeDash() { // Get data for form component, formData will be false if teamId is not yet set. const { data: formData, error: formError } = useSWR( () => (teamID ? ['/api/judging-form', teamID] : null), - async (url, id) => { + async (url: any, id: any) => { const res = await fetch(`${url}?id=${id}`, { method: 'GET' }); if (!res.ok) { if (res.status === 404) { diff --git a/utils/organizer-utils.ts b/utils/organizer-utils.ts index ba74c35d..78f498c2 100644 --- a/utils/organizer-utils.ts +++ b/utils/organizer-utils.ts @@ -1,4 +1,4 @@ -import { ScopedMutator } from 'swr/dist/types'; +import { ScopedMutator } from 'swr/_internal'; import { ManageFormFields } from '../components/manageRoleForm'; import { generateTimes } from '../components/schedule'; import { handleSubmitSuccess, handleSubmitFailure } from '../lib/helpers'; @@ -47,7 +47,7 @@ export const generateScheduleB = (teams: TeamData[], judges: UserData[]) => { * @param {ManageFormFields} roleData - The form data for the role being managed. * @param {ScopedMutator} mutate - The scoped mutator function to update the query cache. */ -export const handleManageFormSubmit = async (roleData: ManageFormFields, mutate: ScopedMutator) => { +export const handleManageFormSubmit = async (roleData: ManageFormFields, mutate: ScopedMutator) => { const res = await fetch(`/api/manage-role`, { method: 'PATCH', headers: { @@ -69,7 +69,7 @@ export const handleManageFormSubmit = async (roleData: ManageFormFields, mutate: * @returns {void} * @throws {Error} If the deletion fails with an error response. */ -export const handlePreAddDelete = async (user: PreAddData, mutate: ScopedMutator) => { +export const handlePreAddDelete = async (user: PreAddData, mutate: ScopedMutator) => { console.log('logging user obj', user); const res = await fetch('/api/preadd', { method: 'DELETE', diff --git a/utils/request-utils.ts b/utils/request-utils.ts index 0bbfb5c4..8ff00d57 100644 --- a/utils/request-utils.ts +++ b/utils/request-utils.ts @@ -21,8 +21,13 @@ import { useEffect, useState } from 'react'; export const useCustomSWR = (params: CustomerSWRParams) => { const [data, setData] = useState(null); const [error, setError] = useState(null); + const [isLoading, setIsLoading] = useState(false); - const { data: requestData, error: requestError } = useSWR(params.url, async url => { + const { + data: requestData, + error: requestError, + isLoading: requestLoading, + } = useSWR(params.url, async url => { const res = await fetch(url, { method: params.method }); if (!res.ok) { const error = new Error( @@ -41,9 +46,12 @@ export const useCustomSWR = (params: CustomerSWRParams) => { if (requestError) { setError(requestError); } - }, [requestData, requestError]); + if (requestLoading) { + setIsLoading(requestLoading); + } + }, [requestData, requestError, requestLoading]); - return { data, error }; + return { data, error, isLoading }; }; /** diff --git a/yarn.lock b/yarn.lock index 289c91f9..e08e3981 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1713,6 +1713,11 @@ classnames@2.x, classnames@^2.2.1, classnames@^2.2.3, classnames@^2.2.5, classna resolved "https://registry.npmjs.org/classnames/-/classnames-2.3.1.tgz" integrity sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA== +client-only@^0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/client-only/-/client-only-0.0.1.tgz#38bba5d403c41ab150bff64a95c85013cf73bca1" + integrity sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA== + color-convert@^1.9.0: version "1.9.3" resolved "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz" @@ -3901,10 +3906,13 @@ supports-preserve-symlinks-flag@^1.0.0: resolved "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz" integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== -swr@^1.3.0: - version "1.3.0" - resolved "https://registry.npmjs.org/swr/-/swr-1.3.0.tgz" - integrity sha512-dkghQrOl2ORX9HYrMDtPa7LTVHJjCTeZoB1dqTbnnEDlSvN8JEKpYIYurDfvbQFUUS8Cg8PceFVZNkW0KNNYPw== +swr@^2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/swr/-/swr-2.2.2.tgz#abcb1f9c97e10527789884169d58b878472d4c98" + integrity sha512-CbR41AoMD4TQBQw9ic3GTXspgfM9Y8Mdhb5Ob4uIKXhWqnRLItwA5fpGvB7SmSw3+zEjb0PdhiEumtUvYoQ+bQ== + dependencies: + client-only "^0.0.1" + use-sync-external-store "^1.2.0" table-layout@^1.0.2: version "1.0.2" @@ -4021,7 +4029,7 @@ uri-js@^4.2.2: dependencies: punycode "^2.1.0" -use-sync-external-store@1.2.0: +use-sync-external-store@1.2.0, use-sync-external-store@^1.2.0: version "1.2.0" resolved "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz" integrity sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA== From 3a9f2817eed6d0391f2f04dfa936022fa7f4380b Mon Sep 17 00:00:00 2001 From: jacoblurie29 Date: Thu, 7 Sep 2023 22:52:47 -0500 Subject: [PATCH 04/26] Refactor sample to potential and simplify UI logic --- .../Organizer/JudgingTab/ScheduleTab.tsx | 168 ++++++++++-------- components/schedule.tsx | 1 - pages/Organizer/OrganizerDash.tsx | 4 +- utils/request-utils.ts | 8 +- 4 files changed, 104 insertions(+), 77 deletions(-) diff --git a/components/Organizer/JudgingTab/ScheduleTab.tsx b/components/Organizer/JudgingTab/ScheduleTab.tsx index 0401cd71..88b35f99 100644 --- a/components/Organizer/JudgingTab/ScheduleTab.tsx +++ b/components/Organizer/JudgingTab/ScheduleTab.tsx @@ -7,33 +7,43 @@ import { handleConfirmSchedule, } from '../../../utils/organizer-utils'; import OrganizerSchedule from '../../schedule'; -import useSWR, { useSWRConfig } from 'swr'; import { ResponseError, JudgingSessionData, UserData, TeamData } from '../../../types/database'; import Title from 'antd/lib/typography/Title'; import { RequestType, useCustomSWR } from '../../../utils/request-utils'; const ScheduleTab = () => { // React state - const [testingSchedule, setTestingSchedule] = useState(false); - const [sampleScheduleAData, setSampleScheduleA] = useState(undefined); - const [sampleScheduleBData, setSampleScheduleB] = useState(undefined); + const [potentialScheduleA, setPotentialScheduleA] = useState(undefined); + const [potentialScheduleB, setPotentialScheduleB] = useState(undefined); // Get judging sessions - const { data: judgingSessionsData, error: judgingSessionsDataError } = useCustomSWR({ + const { + data: judgingSessions, + error: judgingSessionsError, + isLoading: isLoadingJudgingSessions, + } = useCustomSWR({ url: '/api/judging-sessions', method: RequestType.GET, errorMessage: 'Failed to get judging sessions', }); // Judge data - const { data: judgeData, error: judgeError } = useCustomSWR({ + const { + data: judgesData, + error: judgesError, + isLoading: isLoadingJudges, + } = useCustomSWR({ url: '/api/users?usertype=JUDGE', method: RequestType.GET, errorMessage: 'Failed to get list of judges.', }); // Teams data - const { data: teamsData, error: teamsError } = useCustomSWR({ + const { + data: teamsData, + error: teamsError, + isLoading: isLoadingTeams, + } = useCustomSWR({ url: '/api/teams', method: RequestType.GET, errorMessage: 'Failed to get list of teams.', @@ -41,89 +51,105 @@ const ScheduleTab = () => { // Check if schedule is impossible const isScheduleImpossible = () => - teamsData && judgeData && (teamsData.length * TIMES_JUDGED) / 12 > judgeData.length; + teamsData && judgesData && (teamsData.length * TIMES_JUDGED) / 12 > judgesData.length; + + // Confirm sample schedule + const handleConfirmSampleSchedule = ( + sampleA: JudgingSessionData[] | undefined, + sampleB: JudgingSessionData[] | undefined + ) => { + // Exit early if we don't have data yet + if (!sampleA || !sampleB) return; + + // Confirm schedule with sample data + handleConfirmSchedule(sampleA); + handleConfirmSchedule(sampleB); + }; + + // Set sample schedule + const handleCreateNewPotentialSchedules = (teams: TeamData[], judges: UserData[]) => { + if (!window.confirm('Are you sure you want to create a new schedule?')) return; + + setPotentialScheduleA(generateScheduleA(teams, judges)); + setPotentialScheduleB(generateScheduleB(teams, judges)); + }; useEffect(() => { // Exit early if we don't have data yet - if (!judgingSessionsData) return; + if (!judgingSessions) return; // Sort judging sessions by time const time = new Date('2022-10-23T11:00:00').getTime(); - const sampleScheduleA = judgingSessionsData.filter( + const sampleScheduleA = judgingSessions.filter( judgingSession => new Date(judgingSession.time as string).getTime() < time ); - const sampleScheduleB = judgingSessionsData.filter( + const sampleScheduleB = judgingSessions.filter( judgingSession => new Date(judgingSession.time as string).getTime() >= time ); // Set the data - setSampleScheduleA(sampleScheduleA); - setSampleScheduleB(sampleScheduleB); - }, [judgingSessionsData]); + setPotentialScheduleA(sampleScheduleA); + setPotentialScheduleB(sampleScheduleB); + }, [judgingSessions]); + + const error = judgingSessionsError || judgesError || teamsError; + const dataNull = !judgingSessions || !judgesData || !teamsData; + const loading = isLoadingJudgingSessions || isLoadingJudges || isLoadingTeams; return ( <> - {teamsData && - judgeData && - (testingSchedule ? ( + {loading ? ( +
Loading...
+ ) : error || dataNull ? ( +
{error ? (error as ResponseError).message : 'Failed to get data.'}
+ ) : ( + <> - ) : ( - - ))} - {!judgingSessionsData && } -
- - <> - {isScheduleImpossible() ? ( -
oops woopsy, something went fucky wucky
- ) : ( -
schedule is possible!!
- )} -
Count of Teams: {teamsData?.length}
-
Count of Judges: {judgeData?.length}
- - - {Expo A} - {sampleScheduleAData && ( - ): void { - throw new Error('Function not implemented.'); - }} - sessionTimeStart={new Date('2022-10-23T10:00:00')} - sessionTimeEnd={new Date('2022-10-23T11:00:00')} - /> - )} -
- {Expo B} - {sampleScheduleBData && ( - ): void { - throw new Error('Function not implemented.'); - }} - sessionTimeStart={new Date('2022-10-23T11:30:00')} - sessionTimeEnd={new Date('2022-10-23T12:30:00')} - /> + {potentialScheduleA && potentialScheduleB && ( + + )} + +
+ {isScheduleImpossible() ? ( +
The schedule is impossible! Run.
+ ) : ( +
The schedule is possible!
+ )} +
Count of Teams: {teamsData?.length}
+
Count of Judges: {judgesData?.length}
+ Expo A + {potentialScheduleA && ( + ): void { + throw new Error('Function not implemented.'); + }} + sessionTimeStart={new Date('2022-10-23T10:00:00')} + sessionTimeEnd={new Date('2022-10-23T11:00:00')} + /> + )} +
+ Expo B + {potentialScheduleB && ( + ): void { + throw new Error('Function not implemented.'); + }} + sessionTimeStart={new Date('2022-10-23T11:30:00')} + sessionTimeEnd={new Date('2022-10-23T12:30:00')} + /> + )} + )} - ); }; diff --git a/components/schedule.tsx b/components/schedule.tsx index 04c19a58..ec030f12 100644 --- a/components/schedule.tsx +++ b/components/schedule.tsx @@ -89,7 +89,6 @@ export function generateTimes(start: Date, end: Date, interval: number) { const times = []; let current = start; while (current < end) { - console.log(current); times.push(current); current = new Date(current.getTime() + interval * 60000); } diff --git a/pages/Organizer/OrganizerDash.tsx b/pages/Organizer/OrganizerDash.tsx index 2e7903e6..a652bbfc 100644 --- a/pages/Organizer/OrganizerDash.tsx +++ b/pages/Organizer/OrganizerDash.tsx @@ -1,9 +1,9 @@ import { Button, Empty, Skeleton, Space, Tabs } from 'antd'; -import useSWR, { useSWRConfig } from 'swr'; +import { useSWRConfig } from 'swr'; import AllScores from '../../components/allScores'; import ManageRoleForm, { ManageFormFields } from '../../components/manageRoleForm'; import PreAddForm from '../../components/preAddForm'; -import { ResponseError, ScoreData, TeamData, UserData, PreAddData } from '../../types/database'; +import { ScoreData, TeamData, UserData, PreAddData } from '../../types/database'; import PreAddDisplay from '../../components/preAddDisplay'; import ApplicantsDisplay from '../../components/applicantsDisplay'; import Events from '../../components/events'; diff --git a/utils/request-utils.ts b/utils/request-utils.ts index 8ff00d57..06dc8e58 100644 --- a/utils/request-utils.ts +++ b/utils/request-utils.ts @@ -3,7 +3,7 @@ import { ResponseError } from '../types/database'; import { useEffect, useState } from 'react'; /** - * A custom hook that fetches data from the specified URL and returns the data and error. + * A custom hook that fetches data from the specified URL and returns the data, loading status, and error. * Requires template type T to be specified. * * @param url - The URL to fetch data from. @@ -11,7 +11,7 @@ import { useEffect, useState } from 'react'; * @param errorMessage - Optional error message to display if the request fails. * @example * ```tsx - * const { data, error } = useCustomSWR({ + * const { data, error, isLoading } = useCustomSWR({ * url: '/api/teams', * method: RequestType.GET, * errorMessage: 'Failed to fetch teams.' @@ -47,7 +47,9 @@ export const useCustomSWR = (params: CustomerSWRParams) => { setError(requestError); } if (requestLoading) { - setIsLoading(requestLoading); + setIsLoading(true); + } else { + setIsLoading(false); } }, [requestData, requestError, requestLoading]); From 7c721f110977cd4646ae84cad953b424a2234b04 Mon Sep 17 00:00:00 2001 From: jacoblurie29 Date: Thu, 7 Sep 2023 22:59:29 -0500 Subject: [PATCH 05/26] First run finished for refactor of ScheduleTab --- .../Organizer/JudgingTab/ScheduleTab.tsx | 37 ++++++++++--------- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/components/Organizer/JudgingTab/ScheduleTab.tsx b/components/Organizer/JudgingTab/ScheduleTab.tsx index 88b35f99..791d4966 100644 --- a/components/Organizer/JudgingTab/ScheduleTab.tsx +++ b/components/Organizer/JudgingTab/ScheduleTab.tsx @@ -53,23 +53,25 @@ const ScheduleTab = () => { const isScheduleImpossible = () => teamsData && judgesData && (teamsData.length * TIMES_JUDGED) / 12 > judgesData.length; - // Confirm sample schedule - const handleConfirmSampleSchedule = ( - sampleA: JudgingSessionData[] | undefined, - sampleB: JudgingSessionData[] | undefined + // Confirm potential schedule + const handleConfirmPotentialSchedules = ( + potentialScheduleA: JudgingSessionData[] | undefined, + potentialScheduleB: JudgingSessionData[] | undefined ) => { // Exit early if we don't have data yet - if (!sampleA || !sampleB) return; + if (!potentialScheduleA || !potentialScheduleB) return; - // Confirm schedule with sample data - handleConfirmSchedule(sampleA); - handleConfirmSchedule(sampleB); + // Send requests to confirm the schedule + handleConfirmSchedule(potentialScheduleA); + handleConfirmSchedule(potentialScheduleB); }; - // Set sample schedule + // Set potential schedule const handleCreateNewPotentialSchedules = (teams: TeamData[], judges: UserData[]) => { + // Confirm with user if (!window.confirm('Are you sure you want to create a new schedule?')) return; + // Set that potential schedules as newly generated schedules setPotentialScheduleA(generateScheduleA(teams, judges)); setPotentialScheduleB(generateScheduleB(teams, judges)); }; @@ -80,18 +82,17 @@ const ScheduleTab = () => { // Sort judging sessions by time const time = new Date('2022-10-23T11:00:00').getTime(); - const sampleScheduleA = judgingSessions.filter( - judgingSession => new Date(judgingSession.time as string).getTime() < time + + // Set the data after filtering it by time + setPotentialScheduleA( + judgingSessions.filter(judgingSession => new Date(judgingSession.time as string).getTime() < time) ); - const sampleScheduleB = judgingSessions.filter( - judgingSession => new Date(judgingSession.time as string).getTime() >= time + setPotentialScheduleB( + judgingSessions.filter(judgingSession => new Date(judgingSession.time as string).getTime() >= time) ); - - // Set the data - setPotentialScheduleA(sampleScheduleA); - setPotentialScheduleB(sampleScheduleB); }, [judgingSessions]); + // Combine all the loading, null, and error states const error = judgingSessionsError || judgesError || teamsError; const dataNull = !judgingSessions || !judgesData || !teamsData; const loading = isLoadingJudgingSessions || isLoadingJudges || isLoadingTeams; @@ -111,7 +112,7 @@ const ScheduleTab = () => { {potentialScheduleA && potentialScheduleB && ( From ec9ae42599f6433e35a47b724b5c9b811d60c641 Mon Sep 17 00:00:00 2001 From: jacoblurie29 Date: Thu, 7 Sep 2023 23:04:04 -0500 Subject: [PATCH 06/26] Update next-auth package to reflext SWR changes --- package.json | 2 +- yarn.lock | 82 ++++++++++++++++++++++++++++++---------------------- 2 files changed, 48 insertions(+), 36 deletions(-) diff --git a/package.json b/package.json index 6ca9409e..12413621 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ "mongoose": "^6.6.1", "nanoid": "^4.0.0", "next": "12.2.5", - "next-auth": "^4.10.3", + "next-auth": "^4.23.1", "node-ical": "^0.15.1", "react": "18.0.0", "react-dom": "18.0.0", diff --git a/yarn.lock b/yarn.lock index e08e3981..819b31d8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1145,13 +1145,20 @@ core-js-pure "^3.20.2" regenerator-runtime "^0.13.4" -"@babel/runtime@^7.10.1", "@babel/runtime@^7.10.2", "@babel/runtime@^7.10.4", "@babel/runtime@^7.11.1", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.16.3", "@babel/runtime@^7.18.0", "@babel/runtime@^7.18.3": +"@babel/runtime@^7.10.1", "@babel/runtime@^7.10.2", "@babel/runtime@^7.10.4", "@babel/runtime@^7.11.1", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.18.0", "@babel/runtime@^7.18.3": version "7.18.3" resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.18.3.tgz" integrity sha512-38Y8f7YUhce/K7RMwTp7m0uCumpv9hZkitCbBClqQIow1qSbCvGkcegKOXpEWCQLfWmevgRiWokZ1GkpfhbZug== dependencies: regenerator-runtime "^0.13.4" +"@babel/runtime@^7.20.13": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.22.15.tgz#38f46494ccf6cf020bd4eed7124b425e83e523b8" + integrity sha512-T0O+aa+4w0u06iNmapipJXMV4HoUir03hpx3/YqXXhu9xim3w+dVphjFWl1OH8NbZHw5Lbm9k45drDkgq2VNNA== + dependencies: + regenerator-runtime "^0.14.0" + "@ctrl/tinycolor@^3.4.0": version "3.4.1" resolved "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-3.4.1.tgz" @@ -1304,10 +1311,10 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" -"@panva/hkdf@^1.0.1": - version "1.0.2" - resolved "https://registry.npmjs.org/@panva/hkdf/-/hkdf-1.0.2.tgz" - integrity sha512-MSAs9t3Go7GUkMhpKC44T58DJ5KGk2vBo+h1cqQeqlMfdGkxaVB78ZWpv9gYi/g2fa4sopag9gJsNvS8XGgWJA== +"@panva/hkdf@^1.0.2": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@panva/hkdf/-/hkdf-1.1.1.tgz#ab9cd8755d1976e72fc77a00f7655a64efe6cd5d" + integrity sha512-dhPeilub1NuIG0X5Kvhh9lH4iW3ZsHlnzwgwbOlgwQ2wG1IqFzsgHqmKPk3WzsdWAeaxKJxgM0+W433RmN45GA== "@rushstack/eslint-patch@^1.1.3": version "1.1.4" @@ -1772,10 +1779,10 @@ concat-map@0.0.1: resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== -cookie@^0.4.1: - version "0.4.2" - resolved "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz" - integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA== +cookie@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b" + integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== copy-to-clipboard@^3.2.0: version "3.3.1" @@ -2617,10 +2624,10 @@ isexe@^2.0.0: resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz" integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== -jose@^4.1.4, jose@^4.3.7: - version "4.10.0" - resolved "https://registry.npmjs.org/jose/-/jose-4.10.0.tgz" - integrity sha512-KEhB/eLGLomWGPTb+/RNbYsTjIyx03JmbqAyIyiXBuNSa7CmNrJd5ysFhblayzs/e/vbOPMUaLnjHUMhGp4yLw== +jose@^4.11.4, jose@^4.14.4: + version "4.14.6" + resolved "https://registry.yarnpkg.com/jose/-/jose-4.14.6.tgz#94dca1d04a0ad8c6bff0998cdb51220d473cc3af" + integrity sha512-EqJPEUlZD0/CSUMubKtMaYUOtWe91tZXTWMJZoKSbLk+KtdhNdcvppH8lA9XwVu2V4Ailvsj0GBZJ2ZwDjfesQ== js-sdsl@^4.1.4: version "4.1.4" @@ -2885,17 +2892,17 @@ natural-compare@^1.4.0: resolved "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz" integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== -next-auth@^4.10.3: - version "4.10.3" - resolved "https://registry.npmjs.org/next-auth/-/next-auth-4.10.3.tgz" - integrity sha512-7zc4aXYc/EEln7Pkcsn21V1IevaTZsMLJwapfbnKA4+JY0+jFzWbt5p/ljugesGIrN4VOZhpZIw50EaFZyghJQ== +next-auth@^4.23.1: + version "4.23.1" + resolved "https://registry.yarnpkg.com/next-auth/-/next-auth-4.23.1.tgz#7a82f5327cf4c7e32819da4eb977f2251a23c3cf" + integrity sha512-mL083z8KgRtlrIV6CDca2H1kduWJuK/3pTS0Fe2og15KOm4v2kkLGdSDfc2g+019aEBrJUT0pPW2Xx42ImN1WA== dependencies: - "@babel/runtime" "^7.16.3" - "@panva/hkdf" "^1.0.1" - cookie "^0.4.1" - jose "^4.3.7" + "@babel/runtime" "^7.20.13" + "@panva/hkdf" "^1.0.2" + cookie "^0.5.0" + jose "^4.11.4" oauth "^0.9.15" - openid-client "^5.1.0" + openid-client "^5.4.0" preact "^10.6.3" preact-render-to-string "^5.1.19" uuid "^8.3.2" @@ -2946,9 +2953,9 @@ object-assign@^4.1.1: resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz" integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== -object-hash@^2.0.1: +object-hash@^2.2.0: version "2.2.0" - resolved "https://registry.npmjs.org/object-hash/-/object-hash-2.2.0.tgz" + resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-2.2.0.tgz#5ad518581eefc443bd763472b8ff2e9c2c0d54a5" integrity sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw== object-inspect@^1.12.0, object-inspect@^1.9.0: @@ -3016,10 +3023,10 @@ object.values@^1.1.5: define-properties "^1.1.3" es-abstract "^1.19.1" -oidc-token-hash@^5.0.1: - version "5.0.1" - resolved "https://registry.npmjs.org/oidc-token-hash/-/oidc-token-hash-5.0.1.tgz" - integrity sha512-EvoOtz6FIEBzE+9q253HsLCVRiK/0doEJ2HCvvqMQb3dHZrP3WlJKYtJ55CRTw4jmYomzH4wkPuCj/I3ZvpKxQ== +oidc-token-hash@^5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/oidc-token-hash/-/oidc-token-hash-5.0.3.tgz#9a229f0a1ce9d4fc89bcaee5478c97a889e7b7b6" + integrity sha512-IF4PcGgzAr6XXSff26Sk/+P4KZFJVuHAJZj3wgO3vX2bMdNVp/QXTP3P7CEm9V1IdG8lDLY3HhiqpsE/nOwpPw== once@1.4.0, once@^1.3.0: version "1.4.0" @@ -3028,15 +3035,15 @@ once@1.4.0, once@^1.3.0: dependencies: wrappy "1" -openid-client@^5.1.0: - version "5.1.6" - resolved "https://registry.npmjs.org/openid-client/-/openid-client-5.1.6.tgz" - integrity sha512-HTFaXWdUHvLFw4GaEMgC0jXYBgpjgzQQNHW1pZsSqJorSgrXzxJ+4u/LWCGaClDEse5HLjXRV+zU5Bn3OefiZw== +openid-client@^5.4.0: + version "5.4.3" + resolved "https://registry.yarnpkg.com/openid-client/-/openid-client-5.4.3.tgz#c75d2f6d07a25d383a72c8ff34605a36b7e2cd73" + integrity sha512-sVQOvjsT/sbSfYsQI/9liWQGVZH/Pp3rrtlGEwgk/bbHfrUDZ24DN57lAagIwFtuEu+FM9Ev7r85s8S/yPjimQ== dependencies: - jose "^4.1.4" + jose "^4.14.4" lru-cache "^6.0.0" - object-hash "^2.0.1" - oidc-token-hash "^5.0.1" + object-hash "^2.2.0" + oidc-token-hash "^5.0.3" optionator@^0.9.1: version "0.9.1" @@ -3659,6 +3666,11 @@ regenerator-runtime@^0.13.4: resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz" integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA== +regenerator-runtime@^0.14.0: + version "0.14.0" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz#5e19d68eb12d486f797e15a3c6a918f7cec5eb45" + integrity sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA== + regexp.prototype.flags@^1.4.1, regexp.prototype.flags@^1.4.3: version "1.4.3" resolved "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz" From 818c9a91e8621637cd2ec5972208cfe30fb7d08b Mon Sep 17 00:00:00 2001 From: jacoblurie29 Date: Thu, 7 Sep 2023 23:12:35 -0500 Subject: [PATCH 07/26] Revert SWR package to previous version, next-auth package requires update as well will have to investigate in future --- .../Organizer/JudgingTab/ScheduleTab.tsx | 23 ++++--------------- package.json | 2 +- utils/request-utils.ts | 18 ++++----------- yarn.lock | 18 ++++----------- 4 files changed, 15 insertions(+), 46 deletions(-) diff --git a/components/Organizer/JudgingTab/ScheduleTab.tsx b/components/Organizer/JudgingTab/ScheduleTab.tsx index 791d4966..9394bb5e 100644 --- a/components/Organizer/JudgingTab/ScheduleTab.tsx +++ b/components/Organizer/JudgingTab/ScheduleTab.tsx @@ -17,33 +17,21 @@ const ScheduleTab = () => { const [potentialScheduleB, setPotentialScheduleB] = useState(undefined); // Get judging sessions - const { - data: judgingSessions, - error: judgingSessionsError, - isLoading: isLoadingJudgingSessions, - } = useCustomSWR({ + const { data: judgingSessions, error: judgingSessionsError } = useCustomSWR({ url: '/api/judging-sessions', method: RequestType.GET, errorMessage: 'Failed to get judging sessions', }); // Judge data - const { - data: judgesData, - error: judgesError, - isLoading: isLoadingJudges, - } = useCustomSWR({ + const { data: judgesData, error: judgesError } = useCustomSWR({ url: '/api/users?usertype=JUDGE', method: RequestType.GET, errorMessage: 'Failed to get list of judges.', }); // Teams data - const { - data: teamsData, - error: teamsError, - isLoading: isLoadingTeams, - } = useCustomSWR({ + const { data: teamsData, error: teamsError } = useCustomSWR({ url: '/api/teams', method: RequestType.GET, errorMessage: 'Failed to get list of teams.', @@ -95,13 +83,12 @@ const ScheduleTab = () => { // Combine all the loading, null, and error states const error = judgingSessionsError || judgesError || teamsError; const dataNull = !judgingSessions || !judgesData || !teamsData; - const loading = isLoadingJudgingSessions || isLoadingJudges || isLoadingTeams; return ( <> - {loading ? ( + {dataNull ? (
Loading...
- ) : error || dataNull ? ( + ) : error ? (
{error ? (error as ResponseError).message : 'Failed to get data.'}
) : ( <> diff --git a/package.json b/package.json index 12413621..437f5ff6 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,7 @@ "react": "18.0.0", "react-dom": "18.0.0", "react-highlight-words": "^0.18.0", - "swr": "^2.2.2", + "swr": "1.3.0", "ts-command-line-args": "^2.2.1" }, "devDependencies": { diff --git a/utils/request-utils.ts b/utils/request-utils.ts index 06dc8e58..3db2fdcc 100644 --- a/utils/request-utils.ts +++ b/utils/request-utils.ts @@ -21,13 +21,8 @@ import { useEffect, useState } from 'react'; export const useCustomSWR = (params: CustomerSWRParams) => { const [data, setData] = useState(null); const [error, setError] = useState(null); - const [isLoading, setIsLoading] = useState(false); - const { - data: requestData, - error: requestError, - isLoading: requestLoading, - } = useSWR(params.url, async url => { + const { data: requestData, error: requestError } = useSWR(params.url, async url => { const res = await fetch(url, { method: params.method }); if (!res.ok) { const error = new Error( @@ -46,17 +41,12 @@ export const useCustomSWR = (params: CustomerSWRParams) => { if (requestError) { setError(requestError); } - if (requestLoading) { - setIsLoading(true); - } else { - setIsLoading(false); - } - }, [requestData, requestError, requestLoading]); + }, [requestData, requestError]); - return { data, error, isLoading }; + return { data, error }; }; -/** +/* * All possible HTTP request types */ export enum RequestType { diff --git a/yarn.lock b/yarn.lock index 819b31d8..0e35ad6b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1720,11 +1720,6 @@ classnames@2.x, classnames@^2.2.1, classnames@^2.2.3, classnames@^2.2.5, classna resolved "https://registry.npmjs.org/classnames/-/classnames-2.3.1.tgz" integrity sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA== -client-only@^0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/client-only/-/client-only-0.0.1.tgz#38bba5d403c41ab150bff64a95c85013cf73bca1" - integrity sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA== - color-convert@^1.9.0: version "1.9.3" resolved "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz" @@ -3918,13 +3913,10 @@ supports-preserve-symlinks-flag@^1.0.0: resolved "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz" integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== -swr@^2.2.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/swr/-/swr-2.2.2.tgz#abcb1f9c97e10527789884169d58b878472d4c98" - integrity sha512-CbR41AoMD4TQBQw9ic3GTXspgfM9Y8Mdhb5Ob4uIKXhWqnRLItwA5fpGvB7SmSw3+zEjb0PdhiEumtUvYoQ+bQ== - dependencies: - client-only "^0.0.1" - use-sync-external-store "^1.2.0" +swr@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/swr/-/swr-1.3.0.tgz#c6531866a35b4db37b38b72c45a63171faf9f4e8" + integrity sha512-dkghQrOl2ORX9HYrMDtPa7LTVHJjCTeZoB1dqTbnnEDlSvN8JEKpYIYurDfvbQFUUS8Cg8PceFVZNkW0KNNYPw== table-layout@^1.0.2: version "1.0.2" @@ -4041,7 +4033,7 @@ uri-js@^4.2.2: dependencies: punycode "^2.1.0" -use-sync-external-store@1.2.0, use-sync-external-store@^1.2.0: +use-sync-external-store@1.2.0: version "1.2.0" resolved "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz" integrity sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA== From 9a07f6793d1a9749aa7d808590a3b3571bc1d945 Mon Sep 17 00:00:00 2001 From: jacoblurie29 Date: Thu, 7 Sep 2023 23:16:25 -0500 Subject: [PATCH 08/26] Reverted important changes for reversion of swr package --- components/LeaveButton.tsx | 2 +- components/applicantsDisplay.tsx | 2 +- components/hacker/TeamManager.tsx | 2 +- components/hacker/TeamSetup.tsx | 2 +- pages/JudgeDash.tsx | 2 +- utils/organizer-utils.ts | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/components/LeaveButton.tsx b/components/LeaveButton.tsx index 6be5fedd..bb994c23 100644 --- a/components/LeaveButton.tsx +++ b/components/LeaveButton.tsx @@ -1,6 +1,6 @@ import { Button, Popconfirm } from 'antd'; import { useSWRConfig } from 'swr'; -import { ScopedMutator } from 'swr/_internal'; +import { ScopedMutator } from 'swr/dist/types'; export default function LeaveButton({ onLeave }: { onLeave: (mutate: ScopedMutator) => Promise }) { const { mutate } = useSWRConfig(); diff --git a/components/applicantsDisplay.tsx b/components/applicantsDisplay.tsx index ef132b12..5e2d6ffb 100644 --- a/components/applicantsDisplay.tsx +++ b/components/applicantsDisplay.tsx @@ -14,7 +14,7 @@ import type { ColumnsType, FilterValue, FilterConfirmProps } from 'antd/es/table import { useSWRConfig } from 'swr'; import Highlighter from 'react-highlight-words'; import { handleSubmitFailure, handleSubmitSuccess } from '../lib/helpers'; -import { ScopedMutator } from 'swr/_internal'; +import { ScopedMutator } from 'swr/dist/types'; export interface ApplicantsDisplayProps { hackers: UserData[]; diff --git a/components/hacker/TeamManager.tsx b/components/hacker/TeamManager.tsx index c2e85ed6..ae937472 100644 --- a/components/hacker/TeamManager.tsx +++ b/components/hacker/TeamManager.tsx @@ -4,7 +4,7 @@ import { useSWRConfig } from 'swr'; import { handleSubmitFailure } from '../../lib/helpers'; import { TeamProfile } from '../../types/client'; import LeaveButton from '../LeaveButton'; -import { ScopedMutator } from 'swr/_internal'; +import { ScopedMutator } from 'swr/dist/types'; const { Panel } = Collapse; async function handleSubmit(formData: { teamName: string } | { devpost: string }, mutate: ScopedMutator) { diff --git a/components/hacker/TeamSetup.tsx b/components/hacker/TeamSetup.tsx index 0c8cfad6..1896651a 100644 --- a/components/hacker/TeamSetup.tsx +++ b/components/hacker/TeamSetup.tsx @@ -4,7 +4,7 @@ import { useSWRConfig } from 'swr'; import { handleSubmitFailure } from '../../lib/helpers'; import { NewTeamFields } from '../../types/client'; import TeamCard from '../TeamCard'; -import { ScopedMutator } from 'swr/_internal'; +import { ScopedMutator } from 'swr/dist/types'; async function handleSubmit(formData: NewTeamFields | { joinCode: string }, mutate: ScopedMutator) { const res = await fetch('/api/team-management', { diff --git a/pages/JudgeDash.tsx b/pages/JudgeDash.tsx index 6abfa0cc..ef81227c 100644 --- a/pages/JudgeDash.tsx +++ b/pages/JudgeDash.tsx @@ -7,7 +7,7 @@ import TeamSelect from '../components/judges/TeamSelect'; import { JudgingFormFields, ScheduleDisplay, TeamSelectData } from '../types/client'; import { JudgingSessionData, ResponseError, TeamData } from '../types/database'; import { signOut, useSession } from 'next-auth/react'; -import { ScopedMutator } from 'swr/_internal'; +import { ScopedMutator } from 'swr/dist/types'; const GENERIC_ERROR_MESSAGE = 'Oops, something went wrong!'; const GENERIC_ERROR_DESCRIPTION = 'Please try again or contact an organizer if the problem persists.'; diff --git a/utils/organizer-utils.ts b/utils/organizer-utils.ts index 78f498c2..3a752584 100644 --- a/utils/organizer-utils.ts +++ b/utils/organizer-utils.ts @@ -1,4 +1,4 @@ -import { ScopedMutator } from 'swr/_internal'; +import { ScopedMutator } from 'swr/dist/types'; import { ManageFormFields } from '../components/manageRoleForm'; import { generateTimes } from '../components/schedule'; import { handleSubmitSuccess, handleSubmitFailure } from '../lib/helpers'; From 959cb60c5b361ee3c05903832af22faee8ead46d Mon Sep 17 00:00:00 2001 From: jacoblurie29 Date: Thu, 7 Sep 2023 23:17:59 -0500 Subject: [PATCH 09/26] Reverted version of next-auth --- package.json | 2 +- yarn.lock | 34 +++++++++++++++++----------------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/package.json b/package.json index 437f5ff6..a85564ee 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ "mongoose": "^6.6.1", "nanoid": "^4.0.0", "next": "12.2.5", - "next-auth": "^4.23.1", + "next-auth": "4.10.3", "node-ical": "^0.15.1", "react": "18.0.0", "react-dom": "18.0.0", diff --git a/yarn.lock b/yarn.lock index 0e35ad6b..e002f89e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1152,7 +1152,7 @@ dependencies: regenerator-runtime "^0.13.4" -"@babel/runtime@^7.20.13": +"@babel/runtime@^7.16.3": version "7.22.15" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.22.15.tgz#38f46494ccf6cf020bd4eed7124b425e83e523b8" integrity sha512-T0O+aa+4w0u06iNmapipJXMV4HoUir03hpx3/YqXXhu9xim3w+dVphjFWl1OH8NbZHw5Lbm9k45drDkgq2VNNA== @@ -1311,7 +1311,7 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" -"@panva/hkdf@^1.0.2": +"@panva/hkdf@^1.0.1": version "1.1.1" resolved "https://registry.yarnpkg.com/@panva/hkdf/-/hkdf-1.1.1.tgz#ab9cd8755d1976e72fc77a00f7655a64efe6cd5d" integrity sha512-dhPeilub1NuIG0X5Kvhh9lH4iW3ZsHlnzwgwbOlgwQ2wG1IqFzsgHqmKPk3WzsdWAeaxKJxgM0+W433RmN45GA== @@ -1774,10 +1774,10 @@ concat-map@0.0.1: resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== -cookie@^0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b" - integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== +cookie@^0.4.1: + version "0.4.2" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.2.tgz#0e41f24de5ecf317947c82fc789e06a884824432" + integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA== copy-to-clipboard@^3.2.0: version "3.3.1" @@ -2619,7 +2619,7 @@ isexe@^2.0.0: resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz" integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== -jose@^4.11.4, jose@^4.14.4: +jose@^4.14.4, jose@^4.3.7: version "4.14.6" resolved "https://registry.yarnpkg.com/jose/-/jose-4.14.6.tgz#94dca1d04a0ad8c6bff0998cdb51220d473cc3af" integrity sha512-EqJPEUlZD0/CSUMubKtMaYUOtWe91tZXTWMJZoKSbLk+KtdhNdcvppH8lA9XwVu2V4Ailvsj0GBZJ2ZwDjfesQ== @@ -2887,17 +2887,17 @@ natural-compare@^1.4.0: resolved "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz" integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== -next-auth@^4.23.1: - version "4.23.1" - resolved "https://registry.yarnpkg.com/next-auth/-/next-auth-4.23.1.tgz#7a82f5327cf4c7e32819da4eb977f2251a23c3cf" - integrity sha512-mL083z8KgRtlrIV6CDca2H1kduWJuK/3pTS0Fe2og15KOm4v2kkLGdSDfc2g+019aEBrJUT0pPW2Xx42ImN1WA== +next-auth@4.10.3: + version "4.10.3" + resolved "https://registry.yarnpkg.com/next-auth/-/next-auth-4.10.3.tgz#0a952dd5004fd2ac2ba414c990922cf9b33951a3" + integrity sha512-7zc4aXYc/EEln7Pkcsn21V1IevaTZsMLJwapfbnKA4+JY0+jFzWbt5p/ljugesGIrN4VOZhpZIw50EaFZyghJQ== dependencies: - "@babel/runtime" "^7.20.13" - "@panva/hkdf" "^1.0.2" - cookie "^0.5.0" - jose "^4.11.4" + "@babel/runtime" "^7.16.3" + "@panva/hkdf" "^1.0.1" + cookie "^0.4.1" + jose "^4.3.7" oauth "^0.9.15" - openid-client "^5.4.0" + openid-client "^5.1.0" preact "^10.6.3" preact-render-to-string "^5.1.19" uuid "^8.3.2" @@ -3030,7 +3030,7 @@ once@1.4.0, once@^1.3.0: dependencies: wrappy "1" -openid-client@^5.4.0: +openid-client@^5.1.0: version "5.4.3" resolved "https://registry.yarnpkg.com/openid-client/-/openid-client-5.4.3.tgz#c75d2f6d07a25d383a72c8ff34605a36b7e2cd73" integrity sha512-sVQOvjsT/sbSfYsQI/9liWQGVZH/Pp3rrtlGEwgk/bbHfrUDZ24DN57lAagIwFtuEu+FM9Ev7r85s8S/yPjimQ== From fb9c34383663c9ee6d20a68e59d9684cae9cacb3 Mon Sep 17 00:00:00 2001 From: jacoblurie29 Date: Thu, 7 Sep 2023 23:19:02 -0500 Subject: [PATCH 10/26] One more minor change --- package.json | 2 +- yarn.lock | 34 +++++++++++++++++----------------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/package.json b/package.json index a85564ee..e0ead7a4 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ "mongoose": "^6.6.1", "nanoid": "^4.0.0", "next": "12.2.5", - "next-auth": "4.10.3", + "next-auth": "^4.10.3", "node-ical": "^0.15.1", "react": "18.0.0", "react-dom": "18.0.0", diff --git a/yarn.lock b/yarn.lock index e002f89e..27d513f1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1152,7 +1152,7 @@ dependencies: regenerator-runtime "^0.13.4" -"@babel/runtime@^7.16.3": +"@babel/runtime@^7.20.13": version "7.22.15" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.22.15.tgz#38f46494ccf6cf020bd4eed7124b425e83e523b8" integrity sha512-T0O+aa+4w0u06iNmapipJXMV4HoUir03hpx3/YqXXhu9xim3w+dVphjFWl1OH8NbZHw5Lbm9k45drDkgq2VNNA== @@ -1311,7 +1311,7 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" -"@panva/hkdf@^1.0.1": +"@panva/hkdf@^1.0.2": version "1.1.1" resolved "https://registry.yarnpkg.com/@panva/hkdf/-/hkdf-1.1.1.tgz#ab9cd8755d1976e72fc77a00f7655a64efe6cd5d" integrity sha512-dhPeilub1NuIG0X5Kvhh9lH4iW3ZsHlnzwgwbOlgwQ2wG1IqFzsgHqmKPk3WzsdWAeaxKJxgM0+W433RmN45GA== @@ -1774,10 +1774,10 @@ concat-map@0.0.1: resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== -cookie@^0.4.1: - version "0.4.2" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.2.tgz#0e41f24de5ecf317947c82fc789e06a884824432" - integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA== +cookie@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b" + integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== copy-to-clipboard@^3.2.0: version "3.3.1" @@ -2619,7 +2619,7 @@ isexe@^2.0.0: resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz" integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== -jose@^4.14.4, jose@^4.3.7: +jose@^4.11.4, jose@^4.14.4: version "4.14.6" resolved "https://registry.yarnpkg.com/jose/-/jose-4.14.6.tgz#94dca1d04a0ad8c6bff0998cdb51220d473cc3af" integrity sha512-EqJPEUlZD0/CSUMubKtMaYUOtWe91tZXTWMJZoKSbLk+KtdhNdcvppH8lA9XwVu2V4Ailvsj0GBZJ2ZwDjfesQ== @@ -2887,17 +2887,17 @@ natural-compare@^1.4.0: resolved "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz" integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== -next-auth@4.10.3: - version "4.10.3" - resolved "https://registry.yarnpkg.com/next-auth/-/next-auth-4.10.3.tgz#0a952dd5004fd2ac2ba414c990922cf9b33951a3" - integrity sha512-7zc4aXYc/EEln7Pkcsn21V1IevaTZsMLJwapfbnKA4+JY0+jFzWbt5p/ljugesGIrN4VOZhpZIw50EaFZyghJQ== +next-auth@^4.10.3: + version "4.23.1" + resolved "https://registry.yarnpkg.com/next-auth/-/next-auth-4.23.1.tgz#7a82f5327cf4c7e32819da4eb977f2251a23c3cf" + integrity sha512-mL083z8KgRtlrIV6CDca2H1kduWJuK/3pTS0Fe2og15KOm4v2kkLGdSDfc2g+019aEBrJUT0pPW2Xx42ImN1WA== dependencies: - "@babel/runtime" "^7.16.3" - "@panva/hkdf" "^1.0.1" - cookie "^0.4.1" - jose "^4.3.7" + "@babel/runtime" "^7.20.13" + "@panva/hkdf" "^1.0.2" + cookie "^0.5.0" + jose "^4.11.4" oauth "^0.9.15" - openid-client "^5.1.0" + openid-client "^5.4.0" preact "^10.6.3" preact-render-to-string "^5.1.19" uuid "^8.3.2" @@ -3030,7 +3030,7 @@ once@1.4.0, once@^1.3.0: dependencies: wrappy "1" -openid-client@^5.1.0: +openid-client@^5.4.0: version "5.4.3" resolved "https://registry.yarnpkg.com/openid-client/-/openid-client-5.4.3.tgz#c75d2f6d07a25d383a72c8ff34605a36b7e2cd73" integrity sha512-sVQOvjsT/sbSfYsQI/9liWQGVZH/Pp3rrtlGEwgk/bbHfrUDZ24DN57lAagIwFtuEu+FM9Ev7r85s8S/yPjimQ== From 9695ad33e021ed52fd1652cc9c40b250595f0425 Mon Sep 17 00:00:00 2001 From: jacoblurie29 Date: Thu, 7 Sep 2023 23:21:27 -0500 Subject: [PATCH 11/26] Another small change --- package.json | 2 +- yarn.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index e0ead7a4..e594e38e 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,7 @@ "react": "18.0.0", "react-dom": "18.0.0", "react-highlight-words": "^0.18.0", - "swr": "1.3.0", + "swr": "^1.3.0", "ts-command-line-args": "^2.2.1" }, "devDependencies": { diff --git a/yarn.lock b/yarn.lock index 27d513f1..49c1a3cc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3913,7 +3913,7 @@ supports-preserve-symlinks-flag@^1.0.0: resolved "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz" integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== -swr@1.3.0: +swr@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/swr/-/swr-1.3.0.tgz#c6531866a35b4db37b38b72c45a63171faf9f4e8" integrity sha512-dkghQrOl2ORX9HYrMDtPa7LTVHJjCTeZoB1dqTbnnEDlSvN8JEKpYIYurDfvbQFUUS8Cg8PceFVZNkW0KNNYPw== From 307ef4cf89bcbf51a1e36727e2e1f731f21775a8 Mon Sep 17 00:00:00 2001 From: jacoblurie29 Date: Thu, 7 Sep 2023 23:24:41 -0500 Subject: [PATCH 12/26] Added some ignores to test a theory about vercel breaking --- pages/api/teams.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pages/api/teams.ts b/pages/api/teams.ts index c3c6bab2..f7e016b0 100644 --- a/pages/api/teams.ts +++ b/pages/api/teams.ts @@ -20,10 +20,12 @@ export default async function handler( ): Promise { // only judges and organizers can access this endpoint const session = await getSession({ req }); + // @ts-ignore if (!['JUDGE', 'ORGANIZER'].includes(session?.userType as string)) return res.status(403).send('Forbidden'); if (req.method === 'GET') { const teams = await Team.find(); + // @ts-ignore switch (session!.userType) { // send all team info to organizer case 'ORGANIZER': { @@ -33,6 +35,7 @@ export default async function handler( // send pertinent team info to judge case 'JUDGE': { // get the judge + // @ts-ignore const judgeID = session!.userID as ObjectId; // get the teams assigned to the judge From e38951af8ed5c758cd63d6c09229ca7ed2255572 Mon Sep 17 00:00:00 2001 From: jacoblurie29 Date: Thu, 7 Sep 2023 23:27:40 -0500 Subject: [PATCH 13/26] Remove ignores --- pages/api/teams.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/pages/api/teams.ts b/pages/api/teams.ts index f7e016b0..c3c6bab2 100644 --- a/pages/api/teams.ts +++ b/pages/api/teams.ts @@ -20,12 +20,10 @@ export default async function handler( ): Promise { // only judges and organizers can access this endpoint const session = await getSession({ req }); - // @ts-ignore if (!['JUDGE', 'ORGANIZER'].includes(session?.userType as string)) return res.status(403).send('Forbidden'); if (req.method === 'GET') { const teams = await Team.find(); - // @ts-ignore switch (session!.userType) { // send all team info to organizer case 'ORGANIZER': { @@ -35,7 +33,6 @@ export default async function handler( // send pertinent team info to judge case 'JUDGE': { // get the judge - // @ts-ignore const judgeID = session!.userID as ObjectId; // get the teams assigned to the judge From bb70048f919c9f3405765e2801486be8f29891ce Mon Sep 17 00:00:00 2001 From: jacoblurie29 Date: Thu, 7 Sep 2023 23:30:41 -0500 Subject: [PATCH 14/26] Fixed the issue --- yarn.lock | 86 ++++++++++++++++++++++++------------------------------- 1 file changed, 37 insertions(+), 49 deletions(-) diff --git a/yarn.lock b/yarn.lock index 49c1a3cc..4b914d44 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1145,20 +1145,13 @@ core-js-pure "^3.20.2" regenerator-runtime "^0.13.4" -"@babel/runtime@^7.10.1", "@babel/runtime@^7.10.2", "@babel/runtime@^7.10.4", "@babel/runtime@^7.11.1", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.18.0", "@babel/runtime@^7.18.3": +"@babel/runtime@^7.10.1", "@babel/runtime@^7.10.2", "@babel/runtime@^7.10.4", "@babel/runtime@^7.11.1", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.16.3", "@babel/runtime@^7.18.0", "@babel/runtime@^7.18.3": version "7.18.3" resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.18.3.tgz" integrity sha512-38Y8f7YUhce/K7RMwTp7m0uCumpv9hZkitCbBClqQIow1qSbCvGkcegKOXpEWCQLfWmevgRiWokZ1GkpfhbZug== dependencies: regenerator-runtime "^0.13.4" -"@babel/runtime@^7.20.13": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.22.15.tgz#38f46494ccf6cf020bd4eed7124b425e83e523b8" - integrity sha512-T0O+aa+4w0u06iNmapipJXMV4HoUir03hpx3/YqXXhu9xim3w+dVphjFWl1OH8NbZHw5Lbm9k45drDkgq2VNNA== - dependencies: - regenerator-runtime "^0.14.0" - "@ctrl/tinycolor@^3.4.0": version "3.4.1" resolved "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-3.4.1.tgz" @@ -1311,10 +1304,10 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" -"@panva/hkdf@^1.0.2": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@panva/hkdf/-/hkdf-1.1.1.tgz#ab9cd8755d1976e72fc77a00f7655a64efe6cd5d" - integrity sha512-dhPeilub1NuIG0X5Kvhh9lH4iW3ZsHlnzwgwbOlgwQ2wG1IqFzsgHqmKPk3WzsdWAeaxKJxgM0+W433RmN45GA== +"@panva/hkdf@^1.0.1": + version "1.0.2" + resolved "https://registry.npmjs.org/@panva/hkdf/-/hkdf-1.0.2.tgz" + integrity sha512-MSAs9t3Go7GUkMhpKC44T58DJ5KGk2vBo+h1cqQeqlMfdGkxaVB78ZWpv9gYi/g2fa4sopag9gJsNvS8XGgWJA== "@rushstack/eslint-patch@^1.1.3": version "1.1.4" @@ -1774,10 +1767,10 @@ concat-map@0.0.1: resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== -cookie@^0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b" - integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== +cookie@^0.4.1: + version "0.4.2" + resolved "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz" + integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA== copy-to-clipboard@^3.2.0: version "3.3.1" @@ -2619,10 +2612,10 @@ isexe@^2.0.0: resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz" integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== -jose@^4.11.4, jose@^4.14.4: - version "4.14.6" - resolved "https://registry.yarnpkg.com/jose/-/jose-4.14.6.tgz#94dca1d04a0ad8c6bff0998cdb51220d473cc3af" - integrity sha512-EqJPEUlZD0/CSUMubKtMaYUOtWe91tZXTWMJZoKSbLk+KtdhNdcvppH8lA9XwVu2V4Ailvsj0GBZJ2ZwDjfesQ== +jose@^4.1.4, jose@^4.3.7: + version "4.10.0" + resolved "https://registry.npmjs.org/jose/-/jose-4.10.0.tgz" + integrity sha512-KEhB/eLGLomWGPTb+/RNbYsTjIyx03JmbqAyIyiXBuNSa7CmNrJd5ysFhblayzs/e/vbOPMUaLnjHUMhGp4yLw== js-sdsl@^4.1.4: version "4.1.4" @@ -2888,16 +2881,16 @@ natural-compare@^1.4.0: integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== next-auth@^4.10.3: - version "4.23.1" - resolved "https://registry.yarnpkg.com/next-auth/-/next-auth-4.23.1.tgz#7a82f5327cf4c7e32819da4eb977f2251a23c3cf" - integrity sha512-mL083z8KgRtlrIV6CDca2H1kduWJuK/3pTS0Fe2og15KOm4v2kkLGdSDfc2g+019aEBrJUT0pPW2Xx42ImN1WA== - dependencies: - "@babel/runtime" "^7.20.13" - "@panva/hkdf" "^1.0.2" - cookie "^0.5.0" - jose "^4.11.4" + version "4.10.3" + resolved "https://registry.npmjs.org/next-auth/-/next-auth-4.10.3.tgz" + integrity sha512-7zc4aXYc/EEln7Pkcsn21V1IevaTZsMLJwapfbnKA4+JY0+jFzWbt5p/ljugesGIrN4VOZhpZIw50EaFZyghJQ== + dependencies: + "@babel/runtime" "^7.16.3" + "@panva/hkdf" "^1.0.1" + cookie "^0.4.1" + jose "^4.3.7" oauth "^0.9.15" - openid-client "^5.4.0" + openid-client "^5.1.0" preact "^10.6.3" preact-render-to-string "^5.1.19" uuid "^8.3.2" @@ -2948,9 +2941,9 @@ object-assign@^4.1.1: resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz" integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== -object-hash@^2.2.0: +object-hash@^2.0.1: version "2.2.0" - resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-2.2.0.tgz#5ad518581eefc443bd763472b8ff2e9c2c0d54a5" + resolved "https://registry.npmjs.org/object-hash/-/object-hash-2.2.0.tgz" integrity sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw== object-inspect@^1.12.0, object-inspect@^1.9.0: @@ -3018,10 +3011,10 @@ object.values@^1.1.5: define-properties "^1.1.3" es-abstract "^1.19.1" -oidc-token-hash@^5.0.3: - version "5.0.3" - resolved "https://registry.yarnpkg.com/oidc-token-hash/-/oidc-token-hash-5.0.3.tgz#9a229f0a1ce9d4fc89bcaee5478c97a889e7b7b6" - integrity sha512-IF4PcGgzAr6XXSff26Sk/+P4KZFJVuHAJZj3wgO3vX2bMdNVp/QXTP3P7CEm9V1IdG8lDLY3HhiqpsE/nOwpPw== +oidc-token-hash@^5.0.1: + version "5.0.1" + resolved "https://registry.npmjs.org/oidc-token-hash/-/oidc-token-hash-5.0.1.tgz" + integrity sha512-EvoOtz6FIEBzE+9q253HsLCVRiK/0doEJ2HCvvqMQb3dHZrP3WlJKYtJ55CRTw4jmYomzH4wkPuCj/I3ZvpKxQ== once@1.4.0, once@^1.3.0: version "1.4.0" @@ -3030,15 +3023,15 @@ once@1.4.0, once@^1.3.0: dependencies: wrappy "1" -openid-client@^5.4.0: - version "5.4.3" - resolved "https://registry.yarnpkg.com/openid-client/-/openid-client-5.4.3.tgz#c75d2f6d07a25d383a72c8ff34605a36b7e2cd73" - integrity sha512-sVQOvjsT/sbSfYsQI/9liWQGVZH/Pp3rrtlGEwgk/bbHfrUDZ24DN57lAagIwFtuEu+FM9Ev7r85s8S/yPjimQ== +openid-client@^5.1.0: + version "5.1.6" + resolved "https://registry.npmjs.org/openid-client/-/openid-client-5.1.6.tgz" + integrity sha512-HTFaXWdUHvLFw4GaEMgC0jXYBgpjgzQQNHW1pZsSqJorSgrXzxJ+4u/LWCGaClDEse5HLjXRV+zU5Bn3OefiZw== dependencies: - jose "^4.14.4" + jose "^4.1.4" lru-cache "^6.0.0" - object-hash "^2.2.0" - oidc-token-hash "^5.0.3" + object-hash "^2.0.1" + oidc-token-hash "^5.0.1" optionator@^0.9.1: version "0.9.1" @@ -3661,11 +3654,6 @@ regenerator-runtime@^0.13.4: resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz" integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA== -regenerator-runtime@^0.14.0: - version "0.14.0" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz#5e19d68eb12d486f797e15a3c6a918f7cec5eb45" - integrity sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA== - regexp.prototype.flags@^1.4.1, regexp.prototype.flags@^1.4.3: version "1.4.3" resolved "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz" @@ -3915,7 +3903,7 @@ supports-preserve-symlinks-flag@^1.0.0: swr@^1.3.0: version "1.3.0" - resolved "https://registry.yarnpkg.com/swr/-/swr-1.3.0.tgz#c6531866a35b4db37b38b72c45a63171faf9f4e8" + resolved "https://registry.npmjs.org/swr/-/swr-1.3.0.tgz" integrity sha512-dkghQrOl2ORX9HYrMDtPa7LTVHJjCTeZoB1dqTbnnEDlSvN8JEKpYIYurDfvbQFUUS8Cg8PceFVZNkW0KNNYPw== table-layout@^1.0.2: @@ -4100,4 +4088,4 @@ yallist@^4.0.0: yocto-queue@^0.1.0: version "0.1.0" resolved "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz" - integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== + integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== \ No newline at end of file From f27d6cbe6f329dd81bbf01887d085438d829846e Mon Sep 17 00:00:00 2001 From: jacoblurie29 Date: Sat, 9 Sep 2023 12:43:59 -0500 Subject: [PATCH 15/26] Refactor and abstract JudgingTab --- .../Organizer/JudgingTab/JudgingTab.tsx | 45 +++++++++++++++++++ .../ScheduleTab.tsx | 0 pages/Organizer/OrganizerDash.tsx | 42 ++--------------- 3 files changed, 48 insertions(+), 39 deletions(-) create mode 100644 components/Organizer/JudgingTab/JudgingTab.tsx rename components/Organizer/{JudgingTab => ScheduleTab}/ScheduleTab.tsx (100%) diff --git a/components/Organizer/JudgingTab/JudgingTab.tsx b/components/Organizer/JudgingTab/JudgingTab.tsx new file mode 100644 index 00000000..315c5c8b --- /dev/null +++ b/components/Organizer/JudgingTab/JudgingTab.tsx @@ -0,0 +1,45 @@ +import { Skeleton } from 'antd'; +import { TeamData, ScoreData, UserData } from '../../../types/database'; +import { useCustomSWR, RequestType } from '../../../utils/request-utils'; +import AllScores from '../../allScores'; + +const JudgingTab = () => { + // Teams data + const { data: teamsData, error: teamsError } = useCustomSWR({ + url: '/api/teams', + method: RequestType.GET, + errorMessage: 'Failed to get list of teams.', + }); + + // Scores data + const { data: scoresData, error: scoresError } = useCustomSWR({ + url: '/api/scores', + method: RequestType.GET, + errorMessage: 'Failed to get list of scores.', + }); + + // Judge data + const { data: judgeData, error: judgeError } = useCustomSWR({ + url: '/api/users?usertype=JUDGE', + method: RequestType.GET, + errorMessage: 'Failed to get list of judges.', + }); + + // Combine all the loading, null, and error states + const error = teamsError || scoresError || judgeError; + const dataNull = !teamsData || !scoresData || !judgeData; + + return ( + <> + {dataNull ? ( +
Loading...
+ ) : error ? ( +
Failed to load data.
+ ) : ( + + )} + + ); +}; + +export default JudgingTab; diff --git a/components/Organizer/JudgingTab/ScheduleTab.tsx b/components/Organizer/ScheduleTab/ScheduleTab.tsx similarity index 100% rename from components/Organizer/JudgingTab/ScheduleTab.tsx rename to components/Organizer/ScheduleTab/ScheduleTab.tsx diff --git a/pages/Organizer/OrganizerDash.tsx b/pages/Organizer/OrganizerDash.tsx index a652bbfc..d9dfb648 100644 --- a/pages/Organizer/OrganizerDash.tsx +++ b/pages/Organizer/OrganizerDash.tsx @@ -9,33 +9,13 @@ import ApplicantsDisplay from '../../components/applicantsDisplay'; import Events from '../../components/events'; import { signOut, useSession } from 'next-auth/react'; import { handleManageFormSubmit, handlePreAddDelete } from '../../utils/organizer-utils'; -import ScheduleTab from '../../components/Organizer/JudgingTab/ScheduleTab'; +import ScheduleTab from '../../components/Organizer/ScheduleTab/ScheduleTab'; import { RequestType, useCustomSWR } from '../../utils/request-utils'; +import JudgingTab from '../../components/Organizer/JudgingTab/JudgingTab'; export default function OrganizerDash() { const { mutate } = useSWRConfig(); - // Teams data - const { data: teamsData, error: teamsError } = useCustomSWR({ - url: '/api/teams', - method: RequestType.GET, - errorMessage: 'Failed to get list of teams.', - }); - - // Scores data - const { data: scoresData, error: scoresError } = useCustomSWR({ - url: '/api/scores', - method: RequestType.GET, - errorMessage: 'Failed to get list of scores.', - }); - - // Judge data - const { data: judgeData, error: judgeError } = useCustomSWR({ - url: '/api/users?usertype=JUDGE', - method: RequestType.GET, - errorMessage: 'Failed to get list of judges.', - }); - // Hacker data const { data: hackers, error: hackersError } = useCustomSWR({ url: '/api/users?usertype=HACKER', @@ -80,23 +60,7 @@ export default function OrganizerDash() { { label: `Judging`, key: '2', - children: ( - <> - {!teamsData && } - {teamsData && ( - <> - {/* Add dropdown here w/ functionality */} - {judgeData && scoresData && ( - - )} - - )} - - ), + children: , }, { label: `Manage Users`, From 6ab88af02c10b0eb9d8e9069666b760c9ebea014 Mon Sep 17 00:00:00 2001 From: lisaliuu <82255401+lisaliuu@users.noreply.github.com> Date: Sun, 10 Sep 2023 20:03:37 -0500 Subject: [PATCH 16/26] Refactor Manage Users tab --- .../ManageUsersTab/ManageUsersTab.tsx | 36 +++++++++++++++++++ pages/Organizer/OrganizerDash.tsx | 29 ++------------- 2 files changed, 39 insertions(+), 26 deletions(-) create mode 100644 components/Organizer/ManageUsersTab/ManageUsersTab.tsx diff --git a/components/Organizer/ManageUsersTab/ManageUsersTab.tsx b/components/Organizer/ManageUsersTab/ManageUsersTab.tsx new file mode 100644 index 00000000..79b515a7 --- /dev/null +++ b/components/Organizer/ManageUsersTab/ManageUsersTab.tsx @@ -0,0 +1,36 @@ +import {Empty, Skeleton } from 'antd'; +import { useSWRConfig } from 'swr'; +import { useCustomSWR, RequestType } from '../../../utils/request-utils'; +import ManageRoleForm, { ManageFormFields } from '../../../components/manageRoleForm'; +import { handleManageFormSubmit} from '../../../utils/organizer-utils'; + +const ManageUsersTab = () => { + const { mutate } = useSWRConfig(); + + // User data + const { data: userData, error } = useCustomSWR({ + url: '/api/manage-role', + method: RequestType.GET, + errorMessage: 'Failed to get list of all users.', + }); + + return ( + <> + {!userData && } + {userData && userData.length == 0 && ( + No users lmao} + /> + )} + {userData && userData.length > 0 && ( + handleManageFormSubmit(formData, mutate)} + /> + )} + + ) +} + +export default ManageUsersTab \ No newline at end of file diff --git a/pages/Organizer/OrganizerDash.tsx b/pages/Organizer/OrganizerDash.tsx index d9dfb648..b73ee6a9 100644 --- a/pages/Organizer/OrganizerDash.tsx +++ b/pages/Organizer/OrganizerDash.tsx @@ -1,17 +1,17 @@ import { Button, Empty, Skeleton, Space, Tabs } from 'antd'; import { useSWRConfig } from 'swr'; import AllScores from '../../components/allScores'; -import ManageRoleForm, { ManageFormFields } from '../../components/manageRoleForm'; import PreAddForm from '../../components/preAddForm'; import { ScoreData, TeamData, UserData, PreAddData } from '../../types/database'; import PreAddDisplay from '../../components/preAddDisplay'; import ApplicantsDisplay from '../../components/applicantsDisplay'; import Events from '../../components/events'; import { signOut, useSession } from 'next-auth/react'; -import { handleManageFormSubmit, handlePreAddDelete } from '../../utils/organizer-utils'; +import { handlePreAddDelete } from '../../utils/organizer-utils'; import ScheduleTab from '../../components/Organizer/ScheduleTab/ScheduleTab'; import { RequestType, useCustomSWR } from '../../utils/request-utils'; import JudgingTab from '../../components/Organizer/JudgingTab/JudgingTab'; +import ManageUsersTab from '../../components/Organizer/ManageUsersTab/ManageUsersTab'; export default function OrganizerDash() { const { mutate } = useSWRConfig(); @@ -30,13 +30,6 @@ export default function OrganizerDash() { errorMessage: 'Failed to get list of preadded users.', }); - // User data - const { data: userData, error } = useCustomSWR({ - url: '/api/manage-role', - method: RequestType.GET, - errorMessage: 'Failed to get list of all users.', - }); - // Get session data const { data: session, status } = useSession(); @@ -65,23 +58,7 @@ export default function OrganizerDash() { { label: `Manage Users`, key: '3', - children: ( - <> - {!userData && } - {userData && userData.length == 0 && ( - No users lmao} - /> - )} - {userData && userData.length > 0 && ( - handleManageFormSubmit(formData, mutate)} - /> - )} - - ), + children: }, { label: `Pre-Add Users`, From a18c21ec3a1781fca28772844ce7150feb19088a Mon Sep 17 00:00:00 2001 From: lisaliuu Date: Mon, 11 Sep 2023 01:18:35 +0000 Subject: [PATCH 17/26] Run Prettier --- .../ManageUsersTab/ManageUsersTab.tsx | 50 ++++++++----------- pages/Organizer/OrganizerDash.tsx | 2 +- 2 files changed, 23 insertions(+), 29 deletions(-) diff --git a/components/Organizer/ManageUsersTab/ManageUsersTab.tsx b/components/Organizer/ManageUsersTab/ManageUsersTab.tsx index 79b515a7..ecc92f9b 100644 --- a/components/Organizer/ManageUsersTab/ManageUsersTab.tsx +++ b/components/Organizer/ManageUsersTab/ManageUsersTab.tsx @@ -1,36 +1,30 @@ -import {Empty, Skeleton } from 'antd'; +import { Empty, Skeleton } from 'antd'; import { useSWRConfig } from 'swr'; import { useCustomSWR, RequestType } from '../../../utils/request-utils'; import ManageRoleForm, { ManageFormFields } from '../../../components/manageRoleForm'; -import { handleManageFormSubmit} from '../../../utils/organizer-utils'; +import { handleManageFormSubmit } from '../../../utils/organizer-utils'; const ManageUsersTab = () => { - const { mutate } = useSWRConfig(); + const { mutate } = useSWRConfig(); - // User data - const { data: userData, error } = useCustomSWR({ - url: '/api/manage-role', - method: RequestType.GET, - errorMessage: 'Failed to get list of all users.', - }); + // User data + const { data: userData, error } = useCustomSWR({ + url: '/api/manage-role', + method: RequestType.GET, + errorMessage: 'Failed to get list of all users.', + }); - return ( - <> - {!userData && } - {userData && userData.length == 0 && ( - No users lmao} - /> - )} - {userData && userData.length > 0 && ( - handleManageFormSubmit(formData, mutate)} - /> - )} - - ) -} + return ( + <> + {!userData && } + {userData && userData.length == 0 && ( + No users lmao} /> + )} + {userData && userData.length > 0 && ( + handleManageFormSubmit(formData, mutate)} /> + )} + + ); +}; -export default ManageUsersTab \ No newline at end of file +export default ManageUsersTab; diff --git a/pages/Organizer/OrganizerDash.tsx b/pages/Organizer/OrganizerDash.tsx index b73ee6a9..715cec06 100644 --- a/pages/Organizer/OrganizerDash.tsx +++ b/pages/Organizer/OrganizerDash.tsx @@ -58,7 +58,7 @@ export default function OrganizerDash() { { label: `Manage Users`, key: '3', - children: + children: , }, { label: `Pre-Add Users`, From d4d76a97b61b686c07b2f05ea4682631cbba3298 Mon Sep 17 00:00:00 2001 From: lisaliuu <82255401+lisaliuu@users.noreply.github.com> Date: Sun, 10 Sep 2023 20:25:00 -0500 Subject: [PATCH 18/26] Refactor Pre-Add Users tab --- .../PreAddUsersTab/PreAddUsersTab.tsx | 38 +++++++++++++++++++ pages/Organizer/OrganizerDash.tsx | 31 ++------------- 2 files changed, 41 insertions(+), 28 deletions(-) create mode 100644 components/Organizer/PreAddUsersTab/PreAddUsersTab.tsx diff --git a/components/Organizer/PreAddUsersTab/PreAddUsersTab.tsx b/components/Organizer/PreAddUsersTab/PreAddUsersTab.tsx new file mode 100644 index 00000000..7964a290 --- /dev/null +++ b/components/Organizer/PreAddUsersTab/PreAddUsersTab.tsx @@ -0,0 +1,38 @@ +import {Empty, Skeleton } from 'antd'; +import { useSWRConfig } from 'swr'; +import { useCustomSWR, RequestType } from '../../../utils/request-utils'; +import { handlePreAddDelete } from '../../../utils/organizer-utils'; +import {PreAddData } from '../../../types/database'; +import PreAddForm from '../../../components/preAddForm'; +import PreAddDisplay from '../../../components/preAddDisplay'; + +const PreAddUsersTab = () => { + const { mutate } = useSWRConfig(); + + // Preadd data + const { data: preAddData, error: preAddError } = useCustomSWR({ + url: '/api/preadd', + method: RequestType.GET, + errorMessage: 'Failed to get list of preadded users.', + }); + + return ( + <> + {preAddData && preAddData.length == 0 && ( + No preadded users lmao} + /> + )} + {preAddData && preAddData.length > 0 && ( + handlePreAddDelete(user, mutate)} + /> + )} + + + ) +} + +export default PreAddUsersTab \ No newline at end of file diff --git a/pages/Organizer/OrganizerDash.tsx b/pages/Organizer/OrganizerDash.tsx index b73ee6a9..d4ba08d3 100644 --- a/pages/Organizer/OrganizerDash.tsx +++ b/pages/Organizer/OrganizerDash.tsx @@ -1,17 +1,15 @@ import { Button, Empty, Skeleton, Space, Tabs } from 'antd'; import { useSWRConfig } from 'swr'; import AllScores from '../../components/allScores'; -import PreAddForm from '../../components/preAddForm'; -import { ScoreData, TeamData, UserData, PreAddData } from '../../types/database'; -import PreAddDisplay from '../../components/preAddDisplay'; +import { ScoreData, TeamData, UserData } from '../../types/database'; import ApplicantsDisplay from '../../components/applicantsDisplay'; import Events from '../../components/events'; import { signOut, useSession } from 'next-auth/react'; -import { handlePreAddDelete } from '../../utils/organizer-utils'; import ScheduleTab from '../../components/Organizer/ScheduleTab/ScheduleTab'; import { RequestType, useCustomSWR } from '../../utils/request-utils'; import JudgingTab from '../../components/Organizer/JudgingTab/JudgingTab'; import ManageUsersTab from '../../components/Organizer/ManageUsersTab/ManageUsersTab'; +import PreAddUsersTab from '../../components/Organizer/PreAddUsersTab/PreAddUsersTab'; export default function OrganizerDash() { const { mutate } = useSWRConfig(); @@ -23,13 +21,6 @@ export default function OrganizerDash() { errorMessage: 'Failed to get list of hackers.', }); - // Preadd data - const { data: preAddData, error: preAddError } = useCustomSWR({ - url: '/api/preadd', - method: RequestType.GET, - errorMessage: 'Failed to get list of preadded users.', - }); - // Get session data const { data: session, status } = useSession(); @@ -63,23 +54,7 @@ export default function OrganizerDash() { { label: `Pre-Add Users`, key: '4', - children: ( - <> - {preAddData && preAddData.length == 0 && ( - No preadded users lmao} - /> - )} - {preAddData && preAddData.length > 0 && ( - handlePreAddDelete(user, mutate)} - /> - )} - - - ), + children: }, { label: `Manage Applications`, From c52a7046ddde22b690b1688bfbd5ee7e5a444a7d Mon Sep 17 00:00:00 2001 From: lisaliuu Date: Mon, 11 Sep 2023 01:31:52 +0000 Subject: [PATCH 19/26] Run Prettier --- .../PreAddUsersTab/PreAddUsersTab.tsx | 38 ++++++++----------- pages/Organizer/OrganizerDash.tsx | 2 +- 2 files changed, 17 insertions(+), 23 deletions(-) diff --git a/components/Organizer/PreAddUsersTab/PreAddUsersTab.tsx b/components/Organizer/PreAddUsersTab/PreAddUsersTab.tsx index 7964a290..e28b044d 100644 --- a/components/Organizer/PreAddUsersTab/PreAddUsersTab.tsx +++ b/components/Organizer/PreAddUsersTab/PreAddUsersTab.tsx @@ -1,13 +1,13 @@ -import {Empty, Skeleton } from 'antd'; +import { Empty, Skeleton } from 'antd'; import { useSWRConfig } from 'swr'; import { useCustomSWR, RequestType } from '../../../utils/request-utils'; import { handlePreAddDelete } from '../../../utils/organizer-utils'; -import {PreAddData } from '../../../types/database'; +import { PreAddData } from '../../../types/database'; import PreAddForm from '../../../components/preAddForm'; import PreAddDisplay from '../../../components/preAddDisplay'; const PreAddUsersTab = () => { - const { mutate } = useSWRConfig(); + const { mutate } = useSWRConfig(); // Preadd data const { data: preAddData, error: preAddError } = useCustomSWR({ @@ -16,23 +16,17 @@ const PreAddUsersTab = () => { errorMessage: 'Failed to get list of preadded users.', }); - return ( - <> - {preAddData && preAddData.length == 0 && ( - No preadded users lmao} - /> - )} - {preAddData && preAddData.length > 0 && ( - handlePreAddDelete(user, mutate)} - /> - )} - - - ) -} + return ( + <> + {preAddData && preAddData.length == 0 && ( + No preadded users lmao} /> + )} + {preAddData && preAddData.length > 0 && ( + handlePreAddDelete(user, mutate)} /> + )} + + + ); +}; -export default PreAddUsersTab \ No newline at end of file +export default PreAddUsersTab; diff --git a/pages/Organizer/OrganizerDash.tsx b/pages/Organizer/OrganizerDash.tsx index 32e7770d..3e1083b0 100644 --- a/pages/Organizer/OrganizerDash.tsx +++ b/pages/Organizer/OrganizerDash.tsx @@ -54,7 +54,7 @@ export default function OrganizerDash() { { label: `Pre-Add Users`, key: '4', - children: + children: , }, { label: `Manage Applications`, From 94b50c470fa5b20e887495e6f66a09b353e55861 Mon Sep 17 00:00:00 2001 From: jacoblurie29 Date: Mon, 11 Sep 2023 09:03:44 -0500 Subject: [PATCH 20/26] Refactor applicants tab and restructure folders --- .../ApplicantsTab/ApplicantsTab.tsx} | 32 +++++++++++-------- .../EventsTab/EventsTab.tsx} | 8 +++-- pages/Organizer/OrganizerDash.tsx | 23 +++---------- 3 files changed, 29 insertions(+), 34 deletions(-) rename components/{applicantsDisplay.tsx => Organizer/ApplicantsTab/ApplicantsTab.tsx} (94%) rename components/{events.tsx => Organizer/EventsTab/EventsTab.tsx} (97%) diff --git a/components/applicantsDisplay.tsx b/components/Organizer/ApplicantsTab/ApplicantsTab.tsx similarity index 94% rename from components/applicantsDisplay.tsx rename to components/Organizer/ApplicantsTab/ApplicantsTab.tsx index 5e2d6ffb..0e845cda 100644 --- a/components/applicantsDisplay.tsx +++ b/components/Organizer/ApplicantsTab/ApplicantsTab.tsx @@ -1,7 +1,7 @@ import { Table, Tag, Button, Checkbox, Modal, Input, Popover, Space } from 'antd'; import type { InputRef } from 'antd'; import React, { useState, useRef, useEffect } from 'react'; -import { ApplicationStatus, UserData } from '../types/database'; +import { ApplicationStatus, UserData } from '../../../types/database'; import { CheckCircleOutlined, EyeOutlined, @@ -13,12 +13,9 @@ import { DateTime } from 'luxon'; import type { ColumnsType, FilterValue, FilterConfirmProps } from 'antd/es/table/interface'; import { useSWRConfig } from 'swr'; import Highlighter from 'react-highlight-words'; -import { handleSubmitFailure, handleSubmitSuccess } from '../lib/helpers'; +import { handleSubmitFailure, handleSubmitSuccess } from '../../../lib/helpers'; import { ScopedMutator } from 'swr/dist/types'; - -export interface ApplicantsDisplayProps { - hackers: UserData[]; -} +import { RequestType, useCustomSWR } from '../../../utils/request-utils'; const APPLICATION_STATUSES = [ 'Created', @@ -74,7 +71,7 @@ const APPLICATION_KEY_MAP = { mlhComms: 'MLH Communications', }; -const acceptReject = (id: string, applicationStatus: ApplicationStatus, mutate: ScopedMutator, hackers: any) => { +const acceptReject = (id: string, applicationStatus: ApplicationStatus, mutate: ScopedMutator, hackers: UserData[]) => { fetch('/api/accept-reject', { method: 'POST', headers: { @@ -86,7 +83,7 @@ const acceptReject = (id: string, applicationStatus: ApplicationStatus, mutate: }), }).then(() => { const newHackers: UserData[] = JSON.parse(JSON.stringify(hackers)); // Deep copies the object - const idx = newHackers.findIndex((x: any) => x._id === id); + const idx = newHackers.findIndex((x: UserData) => x._id.toString() === id); newHackers[idx].applicationStatus = applicationStatus; mutate( '/api/users?usertype=HACKER', @@ -98,7 +95,7 @@ const acceptReject = (id: string, applicationStatus: ApplicationStatus, mutate: }); }; -const createPopover = (record: any, mutate: ScopedMutator, hackers: any) => { +const createPopover = (record: any, mutate: ScopedMutator, hackers: UserData[]) => { return (