From 63c7a7dbe33a2e9622e559acbfd0c96f3c13dd7b Mon Sep 17 00:00:00 2001 From: Julian Weng Date: Fri, 25 Oct 2024 18:03:13 -0400 Subject: [PATCH] Fix Wharton Council cycle application extension functionality --- backend/clubs/views.py | 51 +++++++++++- .../Settings/WhartonApplicationCycles.tsx | 81 ++++++++++++++----- 2 files changed, 111 insertions(+), 21 deletions(-) diff --git a/backend/clubs/views.py b/backend/clubs/views.py index c71dd1c65..d8a127c62 100644 --- a/backend/clubs/views.py +++ b/backend/clubs/views.py @@ -6562,6 +6562,52 @@ def remove_clubs_from_exception(self, *args, **kwargs): ) return Response([]) + @action(detail=True, methods=["GET"]) + def club_applications(self, *args, **kwargs): + """ + Retrieve club applications for given cycle + --- + requestBody: + content: {} + responses: + "200": + content: + application/json: + schema: + type: array + items: + type: object + properties: + name: + type: string + id: + type: integer + application_end_time: + type: string + format: date-time + application_end_time_exception: + type: string + club__name: + type: string + club__code: + type: string + --- + """ + cycle = self.get_object() + + return Response( + ClubApplication.objects.filter(application_cycle=cycle) + .select_related("club") + .values( + "name", + "id", + "application_end_time", + "application_end_time_exception", + "club__name", + "club__code", + ) + ) + @action(detail=True, methods=["GET"]) def applications(self, *args, **kwargs): """ @@ -6570,7 +6616,10 @@ def applications(self, *args, **kwargs): requestBody: {} responses: "200": - content: {} + content: + text/csv: + schema: + type: string --- """ cycle = self.get_object() diff --git a/frontend/components/Settings/WhartonApplicationCycles.tsx b/frontend/components/Settings/WhartonApplicationCycles.tsx index 88bae600b..223b36ad0 100644 --- a/frontend/components/Settings/WhartonApplicationCycles.tsx +++ b/frontend/components/Settings/WhartonApplicationCycles.tsx @@ -13,16 +13,17 @@ import ModelForm from '../ModelForm' const fields = ( <> - - - - + + + + ) type Cycle = { name: string id: number | null + endDate: Date } type ClubOption = { @@ -35,7 +36,8 @@ type ExtensionOption = { clubName: string endDate: Date exception?: boolean - changed: boolean + originalEndDate: Date + originalException: boolean } const ScrollWrapper = styled.div` @@ -44,17 +46,24 @@ const ScrollWrapper = styled.div` height: 40vh; ` +type ClubApplicationWithClub = ClubApplication & { + club__name: string + club__code: number +} + const WhartonApplicationCycles = (): ReactElement => { const [editMembership, setEditMembership] = useState(false) const [membershipCycle, setMembershipCycle] = useState({ name: '', id: null, + endDate: new Date(), }) const [editExtensions, setEditExtensions] = useState(false) const [extensionsCycle, setExtensionsCycle] = useState({ name: '', id: null, + endDate: new Date(), }) const [clubsSelectedMembership, setClubsSelectedMembership] = useState< @@ -81,7 +90,10 @@ const WhartonApplicationCycles = (): ReactElement => { const closeExtensionsModal = (): void => { setEditExtensions(false) // calculate clubs that have changed - const clubsToUpdate = clubsExtensions.filter((x) => x.changed) + const clubsToUpdate = clubsExtensions.filter( + (x) => + x.originalEndDate !== x.endDate || x.originalException !== x.exception, + ) // split into clubs with exceptions and clubs without const clubsExceptions = clubsToUpdate.filter((x) => x.exception) const clubsNoExceptions = clubsToUpdate.filter((x) => !x.exception) @@ -147,18 +159,23 @@ const WhartonApplicationCycles = (): ReactElement => { useEffect(() => { if (extensionsCycle && extensionsCycle.id != null) { - doApiRequest(`/cycles/${extensionsCycle.id}/clubs?format=json`) + doApiRequest( + `/cycles/${extensionsCycle.id}/club_applications?format=json`, + ) .then((resp) => resp.json()) .then((data) => { - const initialOptions = data.map((club: ClubApplication) => { - return { - id: club.id, - clubName: club.name, - endDate: new Date(club.application_end_time), - exception: club.application_end_time_exception, - changed: false, - } - }) + const initialOptions = data.map( + (application: ClubApplicationWithClub) => { + return { + id: application.id, + clubName: application.club__name, + endDate: new Date(application.application_end_time), + exception: application.application_end_time_exception, + originalEndDate: new Date(application.application_end_time), + originalException: application.application_end_time_exception, + } + }, + ) setClubsExtensions(initialOptions) }) } @@ -190,7 +207,11 @@ const WhartonApplicationCycles = (): ReactElement => { + {clubsExtensions.some( + (x) => + !x.exception && + !x.originalException && + x.endDate.getTime() !== extensionsCycle.endDate.getTime(), + ) && ( +

+ To change the end date for a club, you must also check its + exception box. +

+ )} )}