From b66fd42aaaf48a17294b871f0cef3fb4cebba31e Mon Sep 17 00:00:00 2001 From: Wenlan Ji Date: Mon, 9 Oct 2023 15:02:35 -0400 Subject: [PATCH 001/112] completed initial add roommate --- .../Nav/components/NavLinks/index.jsx | 10 ++++++++ src/routes.jsx | 6 +++++ src/services/housing.ts | 3 +++ src/views/HousingLottery/index.jsx | 23 +++++++++++++++++++ 4 files changed, 42 insertions(+) create mode 100644 src/views/HousingLottery/index.jsx diff --git a/src/components/Nav/components/NavLinks/index.jsx b/src/components/Nav/components/NavLinks/index.jsx index 1dfd4c6479..68795774f6 100644 --- a/src/components/Nav/components/NavLinks/index.jsx +++ b/src/components/Nav/components/NavLinks/index.jsx @@ -148,6 +148,15 @@ const GordonNavLinks = ({ onLinkClick }) => { /> ); + const housingLotteryButton = ( + + ); + const helpButton = ( { {linksButton} {helpButton} {aboutButton} + {housingLotteryButton} {paletteOptionsButton} {feedbackButton} {adminButton} diff --git a/src/routes.jsx b/src/routes.jsx index 263a1a4fb9..e6f047ed6f 100644 --- a/src/routes.jsx +++ b/src/routes.jsx @@ -1,4 +1,5 @@ import About from './views/About'; +import HousingLottery from './views/HousingLottery'; import Admin from './views/Admin'; import ApartmentApp from './views/ApartmentApp'; import BannerSubmission from './views/BannerSubmission'; @@ -34,6 +35,11 @@ const routes = [ path: '/about', element: , }, + { + name: 'HousingLottery', + path: '/housingLottery', + element: , + }, { name: 'Wellness', path: '/wellness', diff --git a/src/services/housing.ts b/src/services/housing.ts index 674c4b7547..4c89d2f7eb 100644 --- a/src/services/housing.ts +++ b/src/services/housing.ts @@ -164,6 +164,8 @@ const getSubmittedApartmentApplications = async (): Promise => http.put(`housing/apartment/applications/${applicationID}/submit`); +const addRoommate = (value: string) => http.put(`housing/housing_lottery/${value}`); + const housingService = { getApartmentSelectionDate, getApartmentHalls, @@ -174,6 +176,7 @@ const housingService = { getApartmentApplication, getSubmittedApartmentApplications, submitApplication, + addRoommate, }; export default housingService; diff --git a/src/views/HousingLottery/index.jsx b/src/views/HousingLottery/index.jsx new file mode 100644 index 0000000000..3f1aac25b2 --- /dev/null +++ b/src/views/HousingLottery/index.jsx @@ -0,0 +1,23 @@ +import { Input } from '@mui/material'; +import { useState } from 'react'; +import housingService from 'services/housing'; + +const HousingLottery = () => { + const [message, setMessage] = useState(''); + + const handleChange = (event) => { + setMessage(event.target.value); + }; + const handleClick = async () => { + await housingService.addRoommate(message); + }; + + return ( +
+ + +
+ ); +}; + +export default HousingLottery; From 67ce383189c26962ba8871baf95234e54dc94871 Mon Sep 17 00:00:00 2001 From: Eric Date: Thu, 19 Oct 2023 22:35:40 -0400 Subject: [PATCH 002/112] First draft of the preferred hall box --- src/views/HousingLottery/index.jsx | 64 +++++++++++++++++++++++++----- 1 file changed, 54 insertions(+), 10 deletions(-) diff --git a/src/views/HousingLottery/index.jsx b/src/views/HousingLottery/index.jsx index 3f1aac25b2..c3845c61bd 100644 --- a/src/views/HousingLottery/index.jsx +++ b/src/views/HousingLottery/index.jsx @@ -1,23 +1,67 @@ -import { Input } from '@mui/material'; +import { Card, CardContent, CardHeader, Grid, Input, TextField, Typography } from '@mui/material'; import { useState } from 'react'; import housingService from 'services/housing'; const HousingLottery = () => { - const [message, setMessage] = useState(''); + const [rank, setRank] = useState(''); + const [search, setSearch] = useState(''); - const handleChange = (event) => { - setMessage(event.target.value); + + const handleSearch = (event) => { + setSearch(event.target.value); }; - const handleClick = async () => { - await housingService.addRoommate(message); + const handleRank = (event) => { + setRank(event.target.value); }; + + // const handleClick = async () => { + // await housingService.addRoommate(message); + // }; - return ( -
- - + const searchHallTitle = ( +
+ Preferred Halls
); + + return ( + //
+ // + // + //
+ + + + + + + + + + + + + + + + + + ); }; export default HousingLottery; From 2d07c59490ee084b2461b85a7e78aa2e46b65723 Mon Sep 17 00:00:00 2001 From: Eric Date: Sat, 21 Oct 2023 17:35:07 -0400 Subject: [PATCH 003/112] Added a submit button to the Demo --- .../HousingLottery/HousingLottery.module.scss | 12 +++++++++++ src/views/HousingLottery/index.jsx | 20 ++++++++++++++++--- 2 files changed, 29 insertions(+), 3 deletions(-) create mode 100644 src/views/HousingLottery/HousingLottery.module.scss diff --git a/src/views/HousingLottery/HousingLottery.module.scss b/src/views/HousingLottery/HousingLottery.module.scss new file mode 100644 index 0000000000..3903ad5a9b --- /dev/null +++ b/src/views/HousingLottery/HousingLottery.module.scss @@ -0,0 +1,12 @@ +.submit_button { +// padding: 5px; +// height: 40px; +// width: 100px; + position: "absolute"; + margin: "auto"; + top: 45px; + bottom: 0; + left: 70px; + height: 45px; + width: 120px; +} \ No newline at end of file diff --git a/src/views/HousingLottery/index.jsx b/src/views/HousingLottery/index.jsx index c3845c61bd..8550f11e2a 100644 --- a/src/views/HousingLottery/index.jsx +++ b/src/views/HousingLottery/index.jsx @@ -1,6 +1,15 @@ -import { Card, CardContent, CardHeader, Grid, Input, TextField, Typography } from '@mui/material'; +import { + Button, + Card, + CardContent, + CardHeader, + Grid, + Input, + TextField, +} from '@mui/material'; import { useState } from 'react'; import housingService from 'services/housing'; +import styles from './HousingLottery.module.css'; const HousingLottery = () => { const [rank, setRank] = useState(''); @@ -40,13 +49,12 @@ const HousingLottery = () => { id="standard-basic" variant="standard" label="Rank" - inputProps={{inputMode:'numeric'}} value={search} onChange={handleSearch} fullWidth /> - + { fullWidth /> + From 7c9d6823e6e91c61b66a1223f9867ba55797ca83 Mon Sep 17 00:00:00 2001 From: Wenlan Ji Date: Sun, 22 Oct 2023 16:58:40 -0400 Subject: [PATCH 004/112] add route for preferred hall --- src/services/housing.ts | 5 ++- src/views/HousingLottery/index.jsx | 59 +++++++++++------------------- 2 files changed, 25 insertions(+), 39 deletions(-) diff --git a/src/services/housing.ts b/src/services/housing.ts index 4c89d2f7eb..5280674451 100644 --- a/src/services/housing.ts +++ b/src/services/housing.ts @@ -164,7 +164,9 @@ const getSubmittedApartmentApplications = async (): Promise => http.put(`housing/apartment/applications/${applicationID}/submit`); -const addRoommate = (value: string) => http.put(`housing/housing_lottery/${value}`); +const addRoommate = (value: string) => http.put(`housing/housing_lottery/roommate/${value}`); +const addHall = (rank: number, hall: string) => + http.put(`housing/housing_lottery/hall/${rank}`, hall); const housingService = { getApartmentSelectionDate, @@ -177,6 +179,7 @@ const housingService = { getSubmittedApartmentApplications, submitApplication, addRoommate, + addHall, }; export default housingService; diff --git a/src/views/HousingLottery/index.jsx b/src/views/HousingLottery/index.jsx index 8550f11e2a..5ed4011857 100644 --- a/src/views/HousingLottery/index.jsx +++ b/src/views/HousingLottery/index.jsx @@ -1,37 +1,25 @@ -import { - Button, - Card, - CardContent, - CardHeader, - Grid, - Input, - TextField, -} from '@mui/material'; +import { Button, Card, CardContent, CardHeader, Grid, TextField } from '@mui/material'; import { useState } from 'react'; import housingService from 'services/housing'; import styles from './HousingLottery.module.css'; const HousingLottery = () => { const [rank, setRank] = useState(''); - const [search, setSearch] = useState(''); + const [hall, setHall] = useState(''); - - const handleSearch = (event) => { - setSearch(event.target.value); - }; const handleRank = (event) => { setRank(event.target.value); }; - - // const handleClick = async () => { - // await housingService.addRoommate(message); - // }; - const searchHallTitle = ( -
- Preferred Halls -
- ); + const handleHall = (event) => { + setHall(event.target.value); + }; + + const handleClick = async () => { + await housingService.addHall(rank, hall); + }; + + const searchHallTitle =
Preferred Halls
; return ( //
@@ -41,37 +29,32 @@ const HousingLottery = () => { - - + + - + /> - + /> - - + From 41c9003359bc2edca603107493a18b2522493ed7 Mon Sep 17 00:00:00 2001 From: Bennett Forkner <43764277+bennettforkner@users.noreply.github.com> Date: Tue, 24 Oct 2023 10:12:23 -0400 Subject: [PATCH 005/112] Add Senior Project branch to ci.yml --- .github/workflows/ci.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 955dd7afc1..2821f083a7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,6 +8,7 @@ on: branches: - develop - master + - senior-project jobs: build: @@ -59,3 +60,10 @@ jobs: with: name: build-prod path: dist + + - name: Upload master build artifacts for deployment + if: ${{ github.ref == 'refs/heads/senior-project' }} + uses: actions/upload-artifact@v3 + with: + name: build-senior-project + path: dist From f96a2c2a8c0f641bde37602882cc3e44b7e6b1b6 Mon Sep 17 00:00:00 2001 From: Bennett Forkner <43764277+bennettforkner@users.noreply.github.com> Date: Tue, 24 Oct 2023 10:13:17 -0400 Subject: [PATCH 006/112] Update ci.yml --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2821f083a7..53adc0a727 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -61,7 +61,7 @@ jobs: name: build-prod path: dist - - name: Upload master build artifacts for deployment + - name: Upload senior-project build artifacts for deployment if: ${{ github.ref == 'refs/heads/senior-project' }} uses: actions/upload-artifact@v3 with: From 76829406c49e34b0b2368c81e8a27d380d6f9702 Mon Sep 17 00:00:00 2001 From: Bennett Forkner <43764277+bennettforkner@users.noreply.github.com> Date: Tue, 24 Oct 2023 11:18:14 -0400 Subject: [PATCH 007/112] Set API URL to 360apisp --- .env.development | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.env.development b/.env.development index 91179686b9..19be702663 100644 --- a/.env.development +++ b/.env.development @@ -4,7 +4,7 @@ # VITE_API_URL=https://360Api.gordon.edu/ # @TRAIN - VITE_API_URL=https://360ApiTrain.gordon.edu/ + VITE_API_URL=https://360ApiSP.gordon.edu/ # @LOCALHOST # VITE_API_URL=http://localhost:51626/ From fbddf1d57e77755cee62c1cca39913e1e5d56c28 Mon Sep 17 00:00:00 2001 From: Bennett Forkner <43764277+bennettforkner@users.noreply.github.com> Date: Tue, 24 Oct 2023 11:18:51 -0400 Subject: [PATCH 008/112] Point API to 360APISP --- .env.production | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.env.production b/.env.production index adf7e4f84f..b238b31c1d 100644 --- a/.env.production +++ b/.env.production @@ -5,4 +5,4 @@ VITE_ANALYTICS_ID=G-2FE78G0CBN # @TRAIN -VITE_API_URL=https://360ApiTrain.gordon.edu/ +VITE_API_URL=https://360ApiSP.gordon.edu/ From 0ef16480a9ae7a15488edad7582df544ed57197d Mon Sep 17 00:00:00 2001 From: Wenlan Ji Date: Wed, 1 Nov 2023 19:58:04 -0400 Subject: [PATCH 009/112] rename add hall and preferred hall --- src/services/housing.ts | 2 + src/views/HousingLottery/index.jsx | 62 ++----------------- .../PreferredHall/HallSlotComponent/index.jsx | 48 ++++++++++++++ .../studentView/PreferredHall/index.jsx | 29 +++++++++ 4 files changed, 84 insertions(+), 57 deletions(-) create mode 100644 src/views/HousingLottery/studentView/PreferredHall/HallSlotComponent/index.jsx create mode 100644 src/views/HousingLottery/studentView/PreferredHall/index.jsx diff --git a/src/services/housing.ts b/src/services/housing.ts index 5280674451..335b334d86 100644 --- a/src/services/housing.ts +++ b/src/services/housing.ts @@ -61,6 +61,7 @@ const getApartmentSelectionDate = async (): Promise => { }; const getApartmentHalls = (): Promise => http.get('housing/halls/apartments'); +const getTraditionalHalls = (): Promise => http.get('housing/halls/traditionals'); const getCurrentApplicationID = (username: string = ''): Promise => http.get(username ? `housing/apartment/${username}/` : 'housing/apartment/'); @@ -171,6 +172,7 @@ const addHall = (rank: number, hall: string) => const housingService = { getApartmentSelectionDate, getApartmentHalls, + getTraditionalHalls, getCurrentApplicationID, saveApartmentApplication, deleteApartmentApplication, diff --git a/src/views/HousingLottery/index.jsx b/src/views/HousingLottery/index.jsx index 5ed4011857..2b36118139 100644 --- a/src/views/HousingLottery/index.jsx +++ b/src/views/HousingLottery/index.jsx @@ -1,64 +1,12 @@ -import { Button, Card, CardContent, CardHeader, Grid, TextField } from '@mui/material'; -import { useState } from 'react'; +import { FormControl, Button, Card, CardContent, CardHeader, Grid, TextField } from '@mui/material'; +import { useState, useEffect } from 'react'; import housingService from 'services/housing'; import styles from './HousingLottery.module.css'; +import SearchField from 'views/PeopleSearch/components/SearchFieldList/components/SearchField'; +import PreferredHall from './studentView/PreferredHall'; const HousingLottery = () => { - const [rank, setRank] = useState(''); - const [hall, setHall] = useState(''); - - const handleRank = (event) => { - setRank(event.target.value); - }; - - const handleHall = (event) => { - setHall(event.target.value); - }; - - const handleClick = async () => { - await housingService.addHall(rank, hall); - }; - - const searchHallTitle =
Preferred Halls
; - - return ( - //
- // - // - //
- - - - - - - - - - - - - - - - - - - ); + return ; }; export default HousingLottery; diff --git a/src/views/HousingLottery/studentView/PreferredHall/HallSlotComponent/index.jsx b/src/views/HousingLottery/studentView/PreferredHall/HallSlotComponent/index.jsx new file mode 100644 index 0000000000..0e3019f10a --- /dev/null +++ b/src/views/HousingLottery/studentView/PreferredHall/HallSlotComponent/index.jsx @@ -0,0 +1,48 @@ +import { FormControl, Button, Card, CardContent, CardHeader, Grid, TextField } from '@mui/material'; +import { useState, useEffect } from 'react'; +import housingService from 'services/housing'; +import styles from '../../../HousingLottery.module.css'; +import SearchField from 'views/PeopleSearch/components/SearchFieldList/components/SearchField'; + +/** + * + * @param {number} rank + * @returns + */ +const HallSlot = ({ rank }) => { + console.log('rank ' + rank); + const [hall, setHall] = useState(''); + const [hallList, setHallList] = useState([]); + + useEffect(() => { + housingService.getTraditionalHalls().then(setHallList); + }, []); + + const handleClick = async () => { + await housingService.addHall(rank, hall); + }; + + return ( + + + {rank[0]} + + + + setHall(event.target.value)} + options={hallList} + select + size={200} + /> + + + + ); +}; + +export default HallSlot; diff --git a/src/views/HousingLottery/studentView/PreferredHall/index.jsx b/src/views/HousingLottery/studentView/PreferredHall/index.jsx new file mode 100644 index 0000000000..ef736d8dea --- /dev/null +++ b/src/views/HousingLottery/studentView/PreferredHall/index.jsx @@ -0,0 +1,29 @@ +import { Button, Card, CardContent, CardHeader, Grid, TextField } from '@mui/material'; +import { useState } from 'react'; +import HallSlot from './HallSlotComponent'; + +const PreferredHallsCard = () => { + const [count, setCount] = useState(1); + const [preferredHallList, setPreferredHallList] = useState([[], []]); + const searchHallTitle =
Preferred Halls
; + + return ( + + + + + + {Array(count).fill()} + + + + + + + + ); +}; + +export default PreferredHallsCard; From 33a0716a99ee74830b741ea41cca7e9420c3a23a Mon Sep 17 00:00:00 2001 From: Wenlan Ji Date: Fri, 3 Nov 2023 07:10:49 -0400 Subject: [PATCH 010/112] figuring out adding any number of halls --- src/services/housing.ts | 3 +- .../PreferredHall/HallSlotComponent/index.jsx | 27 ++++++----- .../studentView/PreferredHall/index.jsx | 46 +++++++++++++++++-- 3 files changed, 59 insertions(+), 17 deletions(-) diff --git a/src/services/housing.ts b/src/services/housing.ts index 335b334d86..f821e306a9 100644 --- a/src/services/housing.ts +++ b/src/services/housing.ts @@ -166,8 +166,7 @@ const submitApplication = (applicationID: number): Promise => http.put(`housing/apartment/applications/${applicationID}/submit`); const addRoommate = (value: string) => http.put(`housing/housing_lottery/roommate/${value}`); -const addHall = (rank: number, hall: string) => - http.put(`housing/housing_lottery/hall/${rank}`, hall); +const addHall = (hallList: string[]) => http.put(`housing/housing_lottery/hall`, hallList); const housingService = { getApartmentSelectionDate, diff --git a/src/views/HousingLottery/studentView/PreferredHall/HallSlotComponent/index.jsx b/src/views/HousingLottery/studentView/PreferredHall/HallSlotComponent/index.jsx index 0e3019f10a..294b6a2d5f 100644 --- a/src/views/HousingLottery/studentView/PreferredHall/HallSlotComponent/index.jsx +++ b/src/views/HousingLottery/studentView/PreferredHall/HallSlotComponent/index.jsx @@ -9,38 +9,43 @@ import SearchField from 'views/PeopleSearch/components/SearchFieldList/component * @param {number} rank * @returns */ -const HallSlot = ({ rank }) => { +const HallSlot = ({ rank, hallList, func }) => { console.log('rank ' + rank); const [hall, setHall] = useState(''); - const [hallList, setHallList] = useState([]); + //const [hallList, setHallList] = useState([]); - useEffect(() => { - housingService.getTraditionalHalls().then(setHallList); - }, []); + // useEffect(() => { + // housingService.getTraditionalHalls().then(setHallList); + // }, []); - const handleClick = async () => { - await housingService.addHall(rank, hall); + // const handleClick = async () => { + // await housingService.addHall(rank, hall); + // }; + + const selectPreferredHall = (event) => { + setHall(event.target.value); + func(rank, event.target.value); }; return ( - {rank[0]} + {rank} setHall(event.target.value)} + updateValue={(event) => selectPreferredHall(event)} options={hallList} select size={200} /> - + */} ); }; diff --git a/src/views/HousingLottery/studentView/PreferredHall/index.jsx b/src/views/HousingLottery/studentView/PreferredHall/index.jsx index ef736d8dea..7b8e178d54 100644 --- a/src/views/HousingLottery/studentView/PreferredHall/index.jsx +++ b/src/views/HousingLottery/studentView/PreferredHall/index.jsx @@ -1,11 +1,43 @@ import { Button, Card, CardContent, CardHeader, Grid, TextField } from '@mui/material'; -import { useState } from 'react'; +import { useState, useEffect } from 'react'; import HallSlot from './HallSlotComponent'; +import housingService from 'services/housing'; +import styles from '../../HousingLottery.module.css'; const PreferredHallsCard = () => { const [count, setCount] = useState(1); - const [preferredHallList, setPreferredHallList] = useState([[], []]); + // let rankList = []; + // const [preferredHallList, setPreferredHallList] = useState([]); // map or dictionary + let preferredHallList = []; const searchHallTitle =
Preferred Halls
; + const [hallList, setHallList] = useState([]); + + useEffect(() => { + housingService.getTraditionalHalls().then(setHallList); + }, []); + + // useEffect(() => { }, [count]); + + // const addHall = () => { + // rankList.push(count); + // console.log("count: " + count + ", list: " + rankList); + // setCount(count + 1); + // } + + function updatePreferredHallList(rank, hall) { + preferredHallList[rank - 1] = hall; + } + + const addPreferredHall = () => { + setCount(count + 1); + console.log(count); + let html = ``; + document.getElementById('hallSlots').insertAdjacentHTML('beforeend', html.outerHTML); + }; + + const handleClick = async () => { + await housingService.addHall(preferredHallList); + }; return ( @@ -13,13 +45,19 @@ const PreferredHallsCard = () => { - {Array(count).fill()} + + + {/* + */} + {/* {Array(count).fill()} */} + - + From d33b8cf1e6298c9ddc7b76f67b3c8d4205739df8 Mon Sep 17 00:00:00 2001 From: Wenlan Ji Date: Sat, 4 Nov 2023 16:12:07 -0400 Subject: [PATCH 011/112] add halls with the correct rank --- .../studentView/PreferredHall/index.jsx | 39 +++++++++---------- 1 file changed, 18 insertions(+), 21 deletions(-) diff --git a/src/views/HousingLottery/studentView/PreferredHall/index.jsx b/src/views/HousingLottery/studentView/PreferredHall/index.jsx index 7b8e178d54..2a518d70e6 100644 --- a/src/views/HousingLottery/studentView/PreferredHall/index.jsx +++ b/src/views/HousingLottery/studentView/PreferredHall/index.jsx @@ -6,39 +6,28 @@ import styles from '../../HousingLottery.module.css'; const PreferredHallsCard = () => { const [count, setCount] = useState(1); - // let rankList = []; - // const [preferredHallList, setPreferredHallList] = useState([]); // map or dictionary - let preferredHallList = []; - const searchHallTitle =
Preferred Halls
; const [hallList, setHallList] = useState([]); + const searchHallTitle =
Preferred Halls
; + let preferredHallList = []; useEffect(() => { housingService.getTraditionalHalls().then(setHallList); }, []); - // useEffect(() => { }, [count]); - - // const addHall = () => { - // rankList.push(count); - // console.log("count: " + count + ", list: " + rankList); - // setCount(count + 1); - // } - function updatePreferredHallList(rank, hall) { preferredHallList[rank - 1] = hall; } const addPreferredHall = () => { setCount(count + 1); - console.log(count); - let html = ``; - document.getElementById('hallSlots').insertAdjacentHTML('beforeend', html.outerHTML); }; const handleClick = async () => { await housingService.addHall(preferredHallList); }; + const hallArray = Array(count).fill(0); + return ( @@ -46,18 +35,26 @@ const PreferredHallsCard = () => { - - {/* - */} - {/* {Array(count).fill()} */} + {hallArray.map((value, index) => ( + + ))} - + + + - From f9668f9ed6700ecd07bb283ff9ab06896dbc7589 Mon Sep 17 00:00:00 2001 From: Wenlan Ji Date: Sat, 4 Nov 2023 17:51:05 -0400 Subject: [PATCH 012/112] enable updating preferred hall --- .../PreferredHall/HallSlotComponent/index.jsx | 3 --- .../studentView/PreferredHall/index.jsx | 24 ++++++++++++++----- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/views/HousingLottery/studentView/PreferredHall/HallSlotComponent/index.jsx b/src/views/HousingLottery/studentView/PreferredHall/HallSlotComponent/index.jsx index 294b6a2d5f..b096cbf288 100644 --- a/src/views/HousingLottery/studentView/PreferredHall/HallSlotComponent/index.jsx +++ b/src/views/HousingLottery/studentView/PreferredHall/HallSlotComponent/index.jsx @@ -43,9 +43,6 @@ const HallSlot = ({ rank, hallList, func }) => { size={200} /> - {/* */} ); }; diff --git a/src/views/HousingLottery/studentView/PreferredHall/index.jsx b/src/views/HousingLottery/studentView/PreferredHall/index.jsx index 2a518d70e6..3136b98e00 100644 --- a/src/views/HousingLottery/studentView/PreferredHall/index.jsx +++ b/src/views/HousingLottery/studentView/PreferredHall/index.jsx @@ -7,21 +7,33 @@ import styles from '../../HousingLottery.module.css'; const PreferredHallsCard = () => { const [count, setCount] = useState(1); const [hallList, setHallList] = useState([]); + const [preferredHallList, setPreferredHallList] = useState([]); + let myPreferredHallList = []; const searchHallTitle =
Preferred Halls
; - let preferredHallList = []; useEffect(() => { housingService.getTraditionalHalls().then(setHallList); }, []); + // useEffect(() => { + // setPreferredHallList(myPreferredHallList); + // }, [myPreferredHallList]); + + // function updatePreferredHallList(rank, hall) { + // myPreferredHallList[rank - 1] = hall; + // // setPreferredHallList(myPreferredHallList); + // console.log("myPreferredHallList: " + myPreferredHallList) + // console.log("preferredHallList: " + preferredHallList) + // } + function updatePreferredHallList(rank, hall) { - preferredHallList[rank - 1] = hall; + let newList = preferredHallList; + console.log('newList before ' + newList); + newList[rank - 1] = hall; + console.log('newList after ' + newList); + setPreferredHallList(newList); } - const addPreferredHall = () => { - setCount(count + 1); - }; - const handleClick = async () => { await housingService.addHall(preferredHallList); }; From 20ffd791c14c02f7b8282e98fd0799bf1fb54e55 Mon Sep 17 00:00:00 2001 From: Eric Date: Mon, 6 Nov 2023 16:35:47 -0500 Subject: [PATCH 013/112] Added add participant and Information Box --- .../HousingLottery/HousingLottery.module.scss | 137 +++++++++++++++++- .../components/ApplicantListItem/index.jsx | 132 +++++++++++++++++ .../components/ApplicantList/index.jsx | 98 +++++++++++++ .../components/InstructionsCard/index.jsx | 135 +++++++++++++++++ src/views/HousingLottery/index.jsx | 29 +++- 5 files changed, 518 insertions(+), 13 deletions(-) create mode 100644 src/views/HousingLottery/components/StudentApplication/components/ApplicantList/components/ApplicantListItem/index.jsx create mode 100644 src/views/HousingLottery/components/StudentApplication/components/ApplicantList/index.jsx create mode 100644 src/views/HousingLottery/components/StudentApplication/components/InstructionsCard/index.jsx diff --git a/src/views/HousingLottery/HousingLottery.module.scss b/src/views/HousingLottery/HousingLottery.module.scss index 3903ad5a9b..4ef339e3db 100644 --- a/src/views/HousingLottery/HousingLottery.module.scss +++ b/src/views/HousingLottery/HousingLottery.module.scss @@ -1,12 +1,135 @@ .submit_button { -// padding: 5px; -// height: 40px; -// width: 100px; position: "absolute"; margin: "auto"; - top: 45px; + top: 15px; bottom: 0; - left: 70px; - height: 45px; - width: 120px; + left: 45em; + right: 20em; + height: 3em; + width: 9em; +} + +.add_applicant_button { + position: "absolute"; + margin: "auto"; + top: 15px; + bottom: 0; + left: 43em; + right: 5em; + height: 3em; + width: 11em; +} + +// +// +//Imported from ApartmentApp.module.scss +.people_search_parent { + @extend %list_item; + + :global { + .gc360_quick_search_root { + border-color: var(--mui-palette-neutral-main); // override to black instead of white + } + + .gc360_quick_search_dropdown { + position: inherit; + } + } +} + +strong.over_emphasized { + text-transform: uppercase; + text-decoration: underline; +} + +.apartment_card_header { + background-color: var(--mui-palette-primary-main); + color: var(--mui-palette-primary-contrastText); + + :global { + .MuiTypography-colorTextSecondary { + color: var(--mui-palette-primary-contrastText); + font-size: 1.25rem; + } + + .MuiCardHeader-subheader { + color: var(--mui-palette-primary-contrastText); + } + } +} + +.apartment_instructions { + & :global(.MuiTypography-root) { + padding: 0.25rem 0.75rem; + } + + & :global(.MuiTypography-paragraph) { + text-align: left; + } + + & :global(.MuiTableContainer-root) { + border: 1px solid var(--mui-palette-neutral-700); + border-radius: 4px; + } +} + +.list_item, +%list_item { + color: var(--mui-palette-neutral-700); +} + +.nested_list_item { + padding-left: 48px; + padding-right: 16px; +} + +.bordered_list_item { + @extend %list_item; + border: 1px solid var(--mui-palette-primary-main); +} + +.error { + color: var(--mui-palette-error-main); +} + +:global(.MuiGrid-item) .sticky_page_bottom_bar { + position: -webkit-sticky; + position: sticky; + bottom: 0px; + border-top: 8px; // The seems to be ignoring these, I will investigate this in the near future + margin-top: 8px; // The seems to be ignoring these + + :global(.MuiCard-root), + .sticky_page_bottom_bar { + box-shadow: 0px 0px 4px; + position: sticky; + } +} + +.apartment_agreements_form_control { + text-align: left; + + &_label { + color: var(--mui-palette-neutral-700); + } + + // (CSSMODULES - fix mui overrides - disable no-descending-specificity) + /* stylelint-disable-next-line */ + & :global(.MuiDivider-root) { + margin-top: 0.5em; + margin-bottom: 0.5em; + } +} + +.email { + color: var(--mui-palette-primary-main); + display: flex; + + &:hover { + color: var(--mui-palette-secondary-main); + } + + &_icon { + margin-right: 0.75rem; + } } \ No newline at end of file diff --git a/src/views/HousingLottery/components/StudentApplication/components/ApplicantList/components/ApplicantListItem/index.jsx b/src/views/HousingLottery/components/StudentApplication/components/ApplicantList/components/ApplicantListItem/index.jsx new file mode 100644 index 0000000000..f243e0a45d --- /dev/null +++ b/src/views/HousingLottery/components/StudentApplication/components/ApplicantList/components/ApplicantListItem/index.jsx @@ -0,0 +1,132 @@ +import { + Avatar, + Divider, + Grid, + IconButton, + ListItem, + ListItemAvatar, + ListItemSecondaryAction, + ListItemText, +} from '@mui/material'; +import ClearIcon from '@mui/icons-material/Clear'; +import PersonIcon from '@mui/icons-material/Person'; +import StarIcon from '@mui/icons-material/Star'; +import StarBorderIcon from '@mui/icons-material/StarBorder'; +import { Fragment, useEffect, useState } from 'react'; +import { Link } from 'react-router-dom'; +import { Class } from 'services/peopleSearch'; +import user from 'services/user'; +import styles from '../../../../../../HousingLottery.module.css'; + +/** + * @typedef { import('services/user').StudentProfileInfo } StudentProfileInfo + */ + +/** + * Renders the list item for the apartment applicant list + * + * @param {Object} props The React component props + * @param {boolean} props.disabled boolean to disable the interactive elements of this list item + * @param {StudentProfileInfo} props.profile The StudentProfileInfo of the applicant + * @param {boolean} props.isApplicationEditor boolean indicating whether this list item corresponds to the application editor + * @param {Function} props.onChangeEditor Callback for change editor button + * @param {Function} props.onApplicantRemove Callback for remove applicant button + * @returns {JSX.Element} JSX Element for the applicant list item + */ +const ApplicantListItem = ({ + disabled, + profile, + isApplicationEditor, + onChangeEditor, + onApplicantRemove, +}) => { + const [avatar, setAvatar] = useState(null); + const [hasNickName, setHasNickname] = useState(false); + + useEffect(() => { + loadAvatar(profile); + setHasNickname(profile.FirstName !== profile.NickName && profile.NickName !== ''); + }, [profile]); + + /** + * Creates the Avatar image of the given user + * + * @async + * @function loadAvatar + * @param {StudentProfileInfo} profile The StudentProfileInfo object for the student represented by this list item + */ + const loadAvatar = async (profile) => { + try { + const { def: defaultImage, pref: preferredImage } = await user.getImage(profile.AD_Username); + setAvatar(preferredImage || defaultImage); + } catch { + setAvatar( + + + , + ); + } + }; + + const displayName = hasNickName + ? `${profile.FirstName} ${profile.LastName} (${profile.NickName})` + : `${profile.FirstName} ${profile.LastName}`; + + return ( + + + + {avatar ? ( + + ) : ( + + + + )} + + + + + + + + + + profile && onChangeEditor?.(profile)} + size="large" + > + {isApplicationEditor ? : } + + + + profile?.AD_Username && onApplicantRemove?.(profile.AD_Username)} + size="large" + > + + + + + + + + + ); +}; + +export default ApplicantListItem; diff --git a/src/views/HousingLottery/components/StudentApplication/components/ApplicantList/index.jsx b/src/views/HousingLottery/components/StudentApplication/components/ApplicantList/index.jsx new file mode 100644 index 0000000000..be09ec1479 --- /dev/null +++ b/src/views/HousingLottery/components/StudentApplication/components/ApplicantList/index.jsx @@ -0,0 +1,98 @@ +import { + Card, + CardContent, + CardHeader, + Collapse, + Divider, + Grid, + List, + ListItem, + ListItemIcon, + ListItemText, +} from '@mui/material'; +import AddIcon from '@mui/icons-material/Add'; +import ClearIcon from '@mui/icons-material/Clear'; +import ExpandLess from '@mui/icons-material/ExpandLess'; +import ExpandMore from '@mui/icons-material/ExpandMore'; +import HelpIcon from '@mui/icons-material/Help'; +import StarBorder from '@mui/icons-material/StarBorder'; +import GordonQuickSearch from 'components/Header/components/QuickSearch'; +import { useState } from 'react'; +// @TODO CSSMODULES - outside directory +import styles from '../../../../HousingLottery.module.css'; +import ApplicantListItem from './components/ApplicantListItem/index.jsx'; + + +/** + * @typedef { import('services/housing').ApartmentApplicant } ApartmentApplicant + * @typedef { import('services/housing').ApplicationDetails } ApplicationDetails + * @typedef { import('services/user').StudentProfileInfo } StudentProfileInfo + */ + +/** + * Renders the list of applicants, displayed by name, username, and class standing. + * + * @param {Object} props The React component props + * @param {boolean} props.disabled boolean to disable the interactive elements of this list + * @param {StudentProfileInfo} props.editorProfile The StudentProfileInfo of the application editor + * @param {ApartmentApplicant[]} props.applicants Array of applicant info + * @param {Function} props.onSearchSubmit Callback for apartment people search submission + * @param {Function} props.onChangeEditor Callback for change editor button + * @param {Function} props.onApplicantRemove Callback for remove applicant button + * @returns {JSX.Element} JSX Element for the applicant list + */ +const ApplicantList = ({ + disabled, + editorProfile, + applicants, + onSearchSubmit, + onChangeEditor, + onApplicantRemove, +}) => { + const [showHelp, setShowHelp] = useState(false); + return ( + + + + + + + {applicants?.length > 0 ? ( + applicants.map((applicant) => ( + + )) + ) : ( + + + + )} + + + + + disabled || onSearchSubmit(selectedUsername)} + /> + + + + + + ); +}; + +export default ApplicantList; diff --git a/src/views/HousingLottery/components/StudentApplication/components/InstructionsCard/index.jsx b/src/views/HousingLottery/components/StudentApplication/components/InstructionsCard/index.jsx new file mode 100644 index 0000000000..e665c3a483 --- /dev/null +++ b/src/views/HousingLottery/components/StudentApplication/components/InstructionsCard/index.jsx @@ -0,0 +1,135 @@ +import { + Card, + CardContent, + CardHeader, + Grid, + Paper, + Table, + TableBody, + TableCell, + TableContainer, + TableRow, + Typography, +} from '@mui/material/'; +import { useEffect, useState } from 'react'; +import housing from 'services/housing'; +// @TODO CSSMODULES - outside directory +import styles from '../../../../HousingLottery.module.css'; + +/** + * Renders a card displaying the apartment application instructions + * + * @returns {JSX.Element} JSX Element for the instructions card + */ +const InstructionsCard = () => { + const [apartmentSelectionDate, setApartmentSelectionDate] = useState(); + const [thisYear, setThisYear] = useState(); + + useEffect(() => { + const loadSelectionDate = async () => + setApartmentSelectionDate(await housing.getApartmentSelectionDate()); + + loadSelectionDate(); + + setThisYear(new Date().getFullYear()); + }, []); + + const rows = [ + { description: 'Current Freshman', points: 1 }, + { description: 'Current Sophomore', points: 2 }, + { description: 'Current Junior', points: 3 }, + { description: 'Current Senior', points: 4 }, + { description: '23+ years old', points: 1 }, + { description: 'Full-time, off-campus program credit', points: 1 }, + { description: 'Academic/Chapel probation', points: -1 }, + { description: 'Possible academic suspension', points: -2 }, + { description: `${thisYear - 1}-${thisYear} Disciplinary Probation`, points: -3 }, + ]; + + return ( + + + + + Apartments provide an alternative to the traditional residence hall setting and offer a + unique community experience. To be eligible to live in an apartment, students must be at + least 20 years old as of Sept. 1, {thisYear} or have junior or senior + academic standing. Students who were on disciplinary probation at any time during the{' '} + {thisYear - 1}-{thisYear} academic year must also receive approval from the Dean of + Student Life or the Assistant Dean of Student Life to be eligible to apply for an + apartment. Each applicant must be registered as a full-time student by{' '} + {apartmentSelectionDate}. + + + Each group of students desiring to live in a Tavilla or Bromley apartment or in The + Village must submit an application. Your application can include a student who is studying + abroad or not enrolled for the Spring {thisYear} semester – simply list their name + on the application. + + + Full-time, off-campus program credit: Students fulfilling academic + program requirements through student teaching or a full-time internship will qualify for + the full-time, off-campus program credit. It is the responsibility of applicants to claim + this credit on the application. + + + Applications must be for a full apartment: If applying for a six-person + apartment, there must be six people on the application who will be here for the{' '} + fall semester (four people on a + four-person application, etc.). Applications with an incorrect number of applicants will + not be considered. + + + An application is not a guarantee! + + + Due to the large number of applications typically received for apartments, not all + applications will be awarded an apartment. If you do not receive an apartment, you will + need to secure housing through the housing lottery. + + + How are apartments awarded? + + + Apartments are awarded in order of point total for each type of apartment (4-person, + 6-person, etc.). Each individual on an application will have points given/taken away using + the following scale: + + + + + + + {rows.map((row) => ( + + {row.description} + {row.points} + + ))} + +
+
+
+
+
+ + If You Are Approved... + + + You will be notified of your placement in an apartment/Village{' '} + + building + {' '} + no later than Apr. 13. Further information about specific apartment/room selection will be + communicated in that email. + +
+
+ ); +}; + +export default InstructionsCard; diff --git a/src/views/HousingLottery/index.jsx b/src/views/HousingLottery/index.jsx index 5ed4011857..d3d47135a2 100644 --- a/src/views/HousingLottery/index.jsx +++ b/src/views/HousingLottery/index.jsx @@ -2,11 +2,15 @@ import { Button, Card, CardContent, CardHeader, Grid, TextField } from '@mui/mat import { useState } from 'react'; import housingService from 'services/housing'; import styles from './HousingLottery.module.css'; +import ApplicantList from './components/StudentApplication/components/ApplicantList/index.jsx'; +import InstructionsCard from './components/StudentApplication/components/InstructionsCard/index.jsx'; + const HousingLottery = () => { const [rank, setRank] = useState(''); const [hall, setHall] = useState(''); + const handleRank = (event) => { setRank(event.target.value); }; @@ -20,14 +24,15 @@ const HousingLottery = () => { }; const searchHallTitle =
Preferred Halls
; + // const searchStudentTitle =
Student Applicants
; return ( //
// // //
- - + + @@ -41,7 +46,7 @@ const HousingLottery = () => { fullWidth /> - + { fullWidth /> - + + + + + + + + + ); }; From a90439a13a492729f17f8f6a874f4297d22853c1 Mon Sep 17 00:00:00 2001 From: Zhijie Wang Date: Sun, 12 Nov 2023 21:51:10 -0500 Subject: [PATCH 014/112] styling for preferred hall box --- .../HousingLottery/HousingLottery.module.scss | 29 ++++++++++++++++--- .../studentView/PreferredHall/index.jsx | 9 +++++- 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/src/views/HousingLottery/HousingLottery.module.scss b/src/views/HousingLottery/HousingLottery.module.scss index 3903ad5a9b..e362fc58d1 100644 --- a/src/views/HousingLottery/HousingLottery.module.scss +++ b/src/views/HousingLottery/HousingLottery.module.scss @@ -1,12 +1,33 @@ +.addHall_button { + margin-right: 10px; + position: "absolute"; + margin: "auto"; + top: 15px; + bottom: 40px; + left: 10px; + right: 10px; + height: 45px; + width: 120px; +} + .submit_button { // padding: 5px; // height: 40px; // width: 100px; position: "absolute"; margin: "auto"; - top: 45px; - bottom: 0; - left: 70px; + top: 25px; + bottom: 40px; + left: 10px; + right: 10px; height: 45px; width: 120px; -} \ No newline at end of file +} + +.rankLabel { + text-align: left; + font-weight: bold; + margin-top: 10px; +} + + diff --git a/src/views/HousingLottery/studentView/PreferredHall/index.jsx b/src/views/HousingLottery/studentView/PreferredHall/index.jsx index 3136b98e00..e1fd37fd17 100644 --- a/src/views/HousingLottery/studentView/PreferredHall/index.jsx +++ b/src/views/HousingLottery/studentView/PreferredHall/index.jsx @@ -46,6 +46,10 @@ const PreferredHallsCard = () => { +
Rank
+ {preferredHallList.map((hall, index) => ( + + ))} {hallArray.map((value, index) => ( @@ -53,6 +57,7 @@ const PreferredHallsCard = () => { - From d5b6c2a47ad786c06849e693b8c4e2c4dc44b0a8 Mon Sep 17 00:00:00 2001 From: Zhijie Wang Date: Sun, 12 Nov 2023 21:55:16 -0500 Subject: [PATCH 015/112] styling for preferred hall box --- src/views/HousingLottery/HousingLottery.module.scss | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/views/HousingLottery/HousingLottery.module.scss b/src/views/HousingLottery/HousingLottery.module.scss index e362fc58d1..55214c761d 100644 --- a/src/views/HousingLottery/HousingLottery.module.scss +++ b/src/views/HousingLottery/HousingLottery.module.scss @@ -1,5 +1,4 @@ -.addHall_button { - margin-right: 10px; +.addHall_button { position: "absolute"; margin: "auto"; top: 15px; From 6fe775a8ad8c7b9dd83f3eb1ea074bf4ea337319 Mon Sep 17 00:00:00 2001 From: Wenlan Ji Date: Mon, 13 Nov 2023 08:23:09 -0500 Subject: [PATCH 016/112] keep student from selecting same hall --- .../PreferredHall/HallSlotComponent/index.jsx | 69 +++++++++++++++---- .../studentView/PreferredHall/index.jsx | 29 ++++---- 2 files changed, 69 insertions(+), 29 deletions(-) diff --git a/src/views/HousingLottery/studentView/PreferredHall/HallSlotComponent/index.jsx b/src/views/HousingLottery/studentView/PreferredHall/HallSlotComponent/index.jsx index b096cbf288..45c941d227 100644 --- a/src/views/HousingLottery/studentView/PreferredHall/HallSlotComponent/index.jsx +++ b/src/views/HousingLottery/studentView/PreferredHall/HallSlotComponent/index.jsx @@ -1,31 +1,56 @@ -import { FormControl, Button, Card, CardContent, CardHeader, Grid, TextField } from '@mui/material'; +import { + FormControl, + Button, + Card, + CardContent, + CardHeader, + Grid, + TextField, + ListItemSecondaryAction, + IconButton, +} from '@mui/material'; import { useState, useEffect } from 'react'; -import housingService from 'services/housing'; -import styles from '../../../HousingLottery.module.css'; +import ClearIcon from '@mui/icons-material/Clear'; import SearchField from 'views/PeopleSearch/components/SearchFieldList/components/SearchField'; +import GordonSnackbar from 'components/Snackbar'; /** * * @param {number} rank * @returns */ -const HallSlot = ({ rank, hallList, func }) => { +const HallSlot = ({ + rank, + hallList, + preferredHallList, + updatePreferredHallList, + deletePreferHall, +}) => { console.log('rank ' + rank); const [hall, setHall] = useState(''); - //const [hallList, setHallList] = useState([]); - - // useEffect(() => { - // housingService.getTraditionalHalls().then(setHallList); - // }, []); - - // const handleClick = async () => { - // await housingService.addHall(rank, hall); - // }; + const [snackbar, setSnackbar] = useState({ message: '', severity: null, open: false }); const selectPreferredHall = (event) => { + if (preferredHallList.length > 0) { + for (let i = 0; i < preferredHallList.length; i++) { + if (event.target.value == preferredHallList[i]) { + setSnackbar({ + message: 'You have already selected this hall.', + severity: 'error', + open: true, + }); + return; + } + } + } setHall(event.target.value); - func(rank, event.target.value); + updatePreferredHallList(rank, event.target.value); }; + console.log('preferredHallList ' + preferredHallList); + + function myFuc() { + alert('yeah'); + } return ( @@ -42,7 +67,23 @@ const HallSlot = ({ rank, hallList, func }) => { select size={200} /> + {/* + + */} + + setSnackbar((s) => ({ ...s, open: false }))} + />
); }; diff --git a/src/views/HousingLottery/studentView/PreferredHall/index.jsx b/src/views/HousingLottery/studentView/PreferredHall/index.jsx index 3136b98e00..11203ae626 100644 --- a/src/views/HousingLottery/studentView/PreferredHall/index.jsx +++ b/src/views/HousingLottery/studentView/PreferredHall/index.jsx @@ -8,30 +8,17 @@ const PreferredHallsCard = () => { const [count, setCount] = useState(1); const [hallList, setHallList] = useState([]); const [preferredHallList, setPreferredHallList] = useState([]); - let myPreferredHallList = []; const searchHallTitle =
Preferred Halls
; useEffect(() => { housingService.getTraditionalHalls().then(setHallList); }, []); - // useEffect(() => { - // setPreferredHallList(myPreferredHallList); - // }, [myPreferredHallList]); - - // function updatePreferredHallList(rank, hall) { - // myPreferredHallList[rank - 1] = hall; - // // setPreferredHallList(myPreferredHallList); - // console.log("myPreferredHallList: " + myPreferredHallList) - // console.log("preferredHallList: " + preferredHallList) - // } - function updatePreferredHallList(rank, hall) { let newList = preferredHallList; - console.log('newList before ' + newList); newList[rank - 1] = hall; - console.log('newList after ' + newList); setPreferredHallList(newList); + return newList; } const handleClick = async () => { @@ -40,6 +27,12 @@ const PreferredHallsCard = () => { const hallArray = Array(count).fill(0); + function deletePreferHall(myNum) { + debugger; + hallArray.splice(myNum, 1); + console.log('deletePreferHall' + hallArray); + } + return ( @@ -48,7 +41,13 @@ const PreferredHallsCard = () => { {hallArray.map((value, index) => ( - + ))} From a79b6bf36da6f02e2f5b15109b3356ec10ee73f7 Mon Sep 17 00:00:00 2001 From: Wenlan Ji Date: Mon, 13 Nov 2023 08:41:21 -0500 Subject: [PATCH 017/112] make submit button float to right --- .../HousingLottery/HousingLottery.module.scss | 25 +++++++++++-------- .../studentView/PreferredHall/index.jsx | 17 +++++++------ 2 files changed, 23 insertions(+), 19 deletions(-) diff --git a/src/views/HousingLottery/HousingLottery.module.scss b/src/views/HousingLottery/HousingLottery.module.scss index 55214c761d..ac8940e127 100644 --- a/src/views/HousingLottery/HousingLottery.module.scss +++ b/src/views/HousingLottery/HousingLottery.module.scss @@ -1,6 +1,6 @@ -.addHall_button { - position: "absolute"; - margin: "auto"; +.addHall_button { + position: 'absolute'; + margin: 'auto'; top: 15px; bottom: 40px; left: 10px; @@ -10,23 +10,26 @@ } .submit_button { -// padding: 5px; -// height: 40px; -// width: 100px; - position: "absolute"; - margin: "auto"; - top: 25px; + // padding: 5px; + // height: 40px; + // width: 100px; + position: 'absolute'; + margin: 'auto'; + top: 15px; bottom: 40px; left: 10px; right: 10px; height: 45px; width: 120px; + float: right; } .rankLabel { text-align: left; font-weight: bold; - margin-top: 10px; + margin-top: 10px; } - +#hallSlots { + padding: 10px; +} diff --git a/src/views/HousingLottery/studentView/PreferredHall/index.jsx b/src/views/HousingLottery/studentView/PreferredHall/index.jsx index 91f4bf4b99..06ad494b78 100644 --- a/src/views/HousingLottery/studentView/PreferredHall/index.jsx +++ b/src/views/HousingLottery/studentView/PreferredHall/index.jsx @@ -41,8 +41,13 @@ const PreferredHallsCard = () => {
Rank
{preferredHallList.map((hall, index) => ( - - ))} + + ))} {hallArray.map((value, index) => ( { - - - From 94a22166f23a80a961e6494af46807a05d2296b6 Mon Sep 17 00:00:00 2001 From: Wenlan Ji Date: Mon, 13 Nov 2023 08:49:22 -0500 Subject: [PATCH 018/112] change default menu item from all to none --- .../PreferredHall/HallSlotComponent/index.jsx | 4 +- .../components/SearchField/index.tsx | 44 +++++++++++++++++++ 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/src/views/HousingLottery/studentView/PreferredHall/HallSlotComponent/index.jsx b/src/views/HousingLottery/studentView/PreferredHall/HallSlotComponent/index.jsx index 45c941d227..9fba4826ee 100644 --- a/src/views/HousingLottery/studentView/PreferredHall/HallSlotComponent/index.jsx +++ b/src/views/HousingLottery/studentView/PreferredHall/HallSlotComponent/index.jsx @@ -11,7 +11,7 @@ import { } from '@mui/material'; import { useState, useEffect } from 'react'; import ClearIcon from '@mui/icons-material/Clear'; -import SearchField from 'views/PeopleSearch/components/SearchFieldList/components/SearchField'; +import { HallSearchField } from 'views/PeopleSearch/components/SearchFieldList/components/SearchField'; import GordonSnackbar from 'components/Snackbar'; /** @@ -59,7 +59,7 @@ const HallSlot = ({
- selectPreferredHall(event)} diff --git a/src/views/PeopleSearch/components/SearchFieldList/components/SearchField/index.tsx b/src/views/PeopleSearch/components/SearchFieldList/components/SearchField/index.tsx index 3d059f4ddf..e385168dd8 100644 --- a/src/views/PeopleSearch/components/SearchFieldList/components/SearchField/index.tsx +++ b/src/views/PeopleSearch/components/SearchFieldList/components/SearchField/index.tsx @@ -37,6 +37,12 @@ const defaultMenuItem = ( ); +const HalldefaultMenuItem = ( + + None + +); + const mapOptionsToMenuItems = (options: string[] | SelectOption[]) => options.map((option) => typeof option === 'string' ? ( @@ -88,4 +94,42 @@ const SearchField = ({ ); }; +export const HallSearchField = ({ + name, + value, + updateValue, + Icon, + disabled = false, + select = false, + options = undefined, +}: SearchFieldProps) => { + const isLargeScreen = useMediaQuery('(min-width: 600px)'); + + return ( + + {isLargeScreen && Icon && ( + + + + )} + + + {select && options && [HalldefaultMenuItem, mapOptionsToMenuItems(options)]} + + + + ); +}; + export default SearchField; From fe3d6cad50b55a16b8fcc458337b9d4b3eb97de3 Mon Sep 17 00:00:00 2001 From: Wenlan Ji Date: Mon, 9 Oct 2023 15:02:35 -0400 Subject: [PATCH 019/112] completed initial add roommate --- .../Nav/components/NavLinks/index.jsx | 10 ++++++++ src/routes.jsx | 6 +++++ src/services/housing.ts | 3 +++ src/views/HousingLottery/index.jsx | 23 +++++++++++++++++++ 4 files changed, 42 insertions(+) create mode 100644 src/views/HousingLottery/index.jsx diff --git a/src/components/Nav/components/NavLinks/index.jsx b/src/components/Nav/components/NavLinks/index.jsx index 1dfd4c6479..68795774f6 100644 --- a/src/components/Nav/components/NavLinks/index.jsx +++ b/src/components/Nav/components/NavLinks/index.jsx @@ -148,6 +148,15 @@ const GordonNavLinks = ({ onLinkClick }) => { /> ); + const housingLotteryButton = ( + + ); + const helpButton = ( { {linksButton} {helpButton} {aboutButton} + {housingLotteryButton} {paletteOptionsButton} {feedbackButton} {adminButton} diff --git a/src/routes.jsx b/src/routes.jsx index 263a1a4fb9..e6f047ed6f 100644 --- a/src/routes.jsx +++ b/src/routes.jsx @@ -1,4 +1,5 @@ import About from './views/About'; +import HousingLottery from './views/HousingLottery'; import Admin from './views/Admin'; import ApartmentApp from './views/ApartmentApp'; import BannerSubmission from './views/BannerSubmission'; @@ -34,6 +35,11 @@ const routes = [ path: '/about', element: , }, + { + name: 'HousingLottery', + path: '/housingLottery', + element: , + }, { name: 'Wellness', path: '/wellness', diff --git a/src/services/housing.ts b/src/services/housing.ts index 674c4b7547..4c89d2f7eb 100644 --- a/src/services/housing.ts +++ b/src/services/housing.ts @@ -164,6 +164,8 @@ const getSubmittedApartmentApplications = async (): Promise => http.put(`housing/apartment/applications/${applicationID}/submit`); +const addRoommate = (value: string) => http.put(`housing/housing_lottery/${value}`); + const housingService = { getApartmentSelectionDate, getApartmentHalls, @@ -174,6 +176,7 @@ const housingService = { getApartmentApplication, getSubmittedApartmentApplications, submitApplication, + addRoommate, }; export default housingService; diff --git a/src/views/HousingLottery/index.jsx b/src/views/HousingLottery/index.jsx new file mode 100644 index 0000000000..3f1aac25b2 --- /dev/null +++ b/src/views/HousingLottery/index.jsx @@ -0,0 +1,23 @@ +import { Input } from '@mui/material'; +import { useState } from 'react'; +import housingService from 'services/housing'; + +const HousingLottery = () => { + const [message, setMessage] = useState(''); + + const handleChange = (event) => { + setMessage(event.target.value); + }; + const handleClick = async () => { + await housingService.addRoommate(message); + }; + + return ( +
+ + +
+ ); +}; + +export default HousingLottery; From 0a0a05f44b66d49910ec86dd3a4f1718d8c02de5 Mon Sep 17 00:00:00 2001 From: Eric Date: Mon, 13 Nov 2023 15:20:40 -0500 Subject: [PATCH 020/112] Added Agreement form on top of current progress --- src/routes.jsx | 2 +- src/views/HousingLottery/HousingLottery.jsx | 346 ++++++++++++++++++ .../components/Agreements/index.jsx | 158 ++++++++ .../components/InstructionsCard/index.jsx | 135 ------- src/views/HousingLottery/index.jsx | 81 ---- 5 files changed, 505 insertions(+), 217 deletions(-) create mode 100644 src/views/HousingLottery/HousingLottery.jsx create mode 100644 src/views/HousingLottery/components/StudentApplication/components/Agreements/index.jsx delete mode 100644 src/views/HousingLottery/components/StudentApplication/components/InstructionsCard/index.jsx delete mode 100644 src/views/HousingLottery/index.jsx diff --git a/src/routes.jsx b/src/routes.jsx index e6f047ed6f..fa3245a873 100644 --- a/src/routes.jsx +++ b/src/routes.jsx @@ -1,5 +1,5 @@ import About from './views/About'; -import HousingLottery from './views/HousingLottery'; +import HousingLottery from './views/HousingLottery/HousingLottery.jsx'; import Admin from './views/Admin'; import ApartmentApp from './views/ApartmentApp'; import BannerSubmission from './views/BannerSubmission'; diff --git a/src/views/HousingLottery/HousingLottery.jsx b/src/views/HousingLottery/HousingLottery.jsx new file mode 100644 index 0000000000..b26f48155f --- /dev/null +++ b/src/views/HousingLottery/HousingLottery.jsx @@ -0,0 +1,346 @@ +import { Button, Card, CardContent, CardHeader, Grid, TextField } from '@mui/material'; +import { Dispatch, SetStateAction, useCallback, useEffect, useState } from 'react'; +import housingService from 'services/housing'; +import styles from './HousingLottery.module.css'; +import ApplicantList from './components/StudentApplication/components/ApplicantList'; +import Agreements from './components/StudentApplication/components/Agreements'; + + +const HousingLottery = () => { + const [rank, setRank] = useState(''); + const [hall, setHall] = useState(''); + const [canEditApplication, setCanEditApplication] = useState(false); + const [agreements, setAgreements] = useState(false); // Represents the state of the agreements card. True if all checkboxes checked, false otherwise + const [deleting, setDeleting] = useState(false); + + + + const handleRank = (event) => { + setRank(event.target.value); + }; + + const handleHall = (event) => { + setHall(event.target.value); + }; + + const handleClick = async () => { + await housingService.addHall(rank, hall); + }; + + const searchHallTitle =
Preferred Halls
; + // const searchStudentTitle =
Student Applicants
; + + return ( + //
+ // + // + //
+ + + + + + + + + + + + + + + + + + + + + + + + setAgreements(newState)} + /> + + + ); +}; + +export default HousingLottery; + + +// +// +// +// +// Testing nb.1 +// +// +// +// +// +// + + +// import { Button, Card, CardContent, CardHeader, Grid, TextField } from '@mui/material'; +// import { Dispatch, SetStateAction, useCallback, useEffect, useState } from 'react'; +// import housingService from 'services/housing'; +// import styles from './HousingLottery.module.css'; +// import ApplicantList from './components/StudentApplication/components/ApplicantList/index.jsx'; + +// /** +// * +// * @param {StudentProfileInfo} props.userProfile The student profile info of the current user +// * @returns +// */ +// const HousingLottery = ({ userProfile }) => { +// console.log('userProfile', userProfile); + +// const BLANK_APPLICATION_DETAILS = { +// ApplicationID: null, +// DateSubmitted: null, +// DateModified: null, +// EditorProfile: null, +// Applicants: [], +// ApartmentChoices: [], +// }; + +// const [loading, setLoading] = useState(true); +// const [rank, setRank] = useState(''); +// const [hall, setHall] = useState(''); +// const [canEditApplication, setCanEditApplication] = useState(false); +// const [applicationDetails, setApplicationDetails] = useState(BLANK_APPLICATION_DETAILS); + +// const handleChangeEditor = (profile) => { +// if (canEditApplication && profile) { +// if ( +// applicationDetails.Applicants.some( +// (applicant) => applicant.Profile.AD_Username === profile.AD_Username, +// ) +// ) { +// setNewEditorProfile(profile); + +// let insertText = ''; +// if (profile.fullName) { +// insertText = ` to ${profile.fullName}`; +// } else if (profile?.FirstName && profile?.LastName) { +// insertText = ` to ${profile.FirstName} ${profile.LastName}`; +// } +// const dialogText = ( +// +// You are about to change the editor{insertText}. +//
+// If you change the application editor, you will no longer be able to edit this +// application yourself. All unsaved changes will be saved automatically. +//
+// Are you sure you want to change the application editor? +//
+// ); +// createDialog(DIALOG_PROPS.changeEditor, dialogText); +// } +// } +// }; + + +// useEffect( +// () => +// setCanEditApplication( +// userProfile?.AD_Username === applicationDetails?.EditorProfile?.AD_Username ?? false, +// ), +// [applicationDetails?.EditorProfile?.AD_Username, userProfile?.AD_Username], +// ); + +// useEffect( +// () => +// setCanEditApplication( +// userProfile?.AD_Username === applicationDetails?.EditorProfile?.AD_Username ?? false, +// ), +// [applicationDetails?.EditorProfile?.AD_Username, userProfile?.AD_Username], +// ); + +// const loadApplication = useCallback(async () => { +// const initializeNewApplication = () => { +// const initialApplicants = [ +// { Profile: userProfile, Username: userProfile.AD_Username, OffCampusProgram: '' }, +// ]; +// setApplicationDetails({ +// ...BLANK_APPLICATION_DETAILS, +// EditorProfile: userProfile, +// Gender: userProfile.Gender, +// Applicants: initialApplicants, +// }); +// setUnsavedChanges(true); +// }; + +// let result = false; +// try { +// // Check if the current user is on an application. Returns the application ID number if found +// const newApplicationID = await housing.getCurrentApplicationID(); +// if (newApplicationID > 0) { +// setApplicationExists(true); +// const newApplicationDetails = await housing.getApartmentApplication(newApplicationID); +// setApplicationDetails(newApplicationDetails); +// setUnsavedChanges(false); +// result = true; +// } else { +// throw createError(new Error('Invalid application ID'), { status: 404 }); +// } +// } catch (e) { +// if (e instanceof NotFoundError) { +// initializeNewApplication(); +// } else if (e instanceof AuthError) { +// const debugMessage = +// 'Received a 401 (Unauthorized) response, which should not be possible in this case. Please try refreshing the page, or contact CTS for support.'; +// console.error(`Debug Message: ${debugMessage}`); +// createSnackbar(debugMessage, 'error'); +// } else { +// throw e; +// } +// } finally { +// setNewEditorProfile(null); +// return result; +// } +// }, [userProfile]); + +// useEffect(() => { +// setLoading(true); +// loadApplication(); +// setLoading(false); +// }, [userProfile, loadApplication]); + +// const addApplicant = async (newApplicantUsername) => { +// try { +// // Get the profile of the selected user +// const newApplicantProfile = await user.getProfileInfo(newApplicantUsername); +// let newApplicantObject = { +// ApplicationID: applicationDetails.ApplicationID, +// Profile: newApplicantProfile, +// Username: newApplicantUsername, // Used for convenient array sorting. +// OffCampusProgram: '', +// }; + +// if ( +// applicationDetails.Applicants.some( +// (applicant) => applicant.Profile.AD_Username === newApplicantUsername, +// ) +// ) { +// // Display an error if the selected user is already in the list +// createSnackbar(`${newApplicantProfile.fullName} is already in the list.`, 'info'); +// } else { +// const validApplicant = await isApplicantValid(newApplicantObject); +// // Any relevant errors and snackbar messages are handled by `isApplicantValid()` internally +// if (validApplicant) { +// // Add the profile object to the list of applicants +// setApplicationDetails((prevApplicationDetails) => ({ +// ...prevApplicationDetails, +// Applicants: [...prevApplicationDetails.Applicants, newApplicantObject], +// })); +// setUnsavedChanges(true); +// } +// } +// } catch (error) { +// createSnackbar( +// 'Something went wrong while trying to add this person. Please try again.', +// 'error', +// ); +// console.log(error); +// } +// }; + + +// const handleRank = (event) => { +// setRank(event.target.value); +// }; + +// const handleHall = (event) => { +// setHall(event.target.value); +// }; + +// const handleClick = async () => { +// await housingService.addHall(rank, hall); +// }; + +// const searchHallTitle =
Preferred Halls
; +// // const searchStudentTitle =
Student Applicants
; + +// return ( +// //
+// // +// // +// //
+// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// MAX_NUM_APPLICANTS +// } +// editorProfile={applicationDetails.EditorProfile} +// applicants={applicationDetails.Applicants ?? []} +// onSearchSubmit={(searchSelection) => +// searchSelection && addApplicant(searchSelection) +// } +// onChangeEditor={handleChangeEditor} +// onApplicantRemove={handleApplicantRemove} +// /> +// +// +// ); +// }; + +// export default HousingLottery; diff --git a/src/views/HousingLottery/components/StudentApplication/components/Agreements/index.jsx b/src/views/HousingLottery/components/StudentApplication/components/Agreements/index.jsx new file mode 100644 index 0000000000..905e4f6ae0 --- /dev/null +++ b/src/views/HousingLottery/components/StudentApplication/components/Agreements/index.jsx @@ -0,0 +1,158 @@ +import { + Card, + CardContent, + CardHeader, + Checkbox, + Divider, + FormControl, + FormControlLabel, + FormGroup, + FormHelperText, + FormLabel, +} from '@mui/material/'; +import { Fragment, useEffect, useState } from 'react'; +import housing from 'services/housing'; +// @TODO CSSMODULES - outside directory +import styles from '../../../../HousingLottery.module.css'; + + +/** + * Renders a card displaying the apartment application instructions + * + * @param {Object} props The React component props + * @param {boolean | string} props.deleting Status of delete operation + * @param {Function} props.onChange Callback for change of the checkbox state + * @returns {JSX.Element} JSX Element for the instructions card + */ +const Agreements = ({ deleting, onChange }) => { + const [checkboxes, setCheckboxes] = useState([]); + + const loadAgreements = async () => { + const currentYear = new Date().getFullYear(); + const selectionDate = await housing.getApartmentSelectionDate(); + + const newCheckboxes = [ + { + checked: false, + label: 'Each individual on the application has agreed to be on the application', + }, + { + checked: false, + label: + 'We understand that if someone on this application has not agreed to be on the application, our application will be disqualified', + }, + { + checked: false, + label: 'Each individual on this application appears ONLY on this application', + }, + { + checked: false, + label: + "We understand that if an individual on this application also appears on another group's application, our application could be disqualified", + }, + { + checked: false, + label: `Any individual on this application who has been on disciplinary probation at any point during the ${ + currentYear - 1 + }-${currentYear} academic year has been approved to apply by the Dean of Student Life or Assistant Dean of Student Life`, + }, + { + checked: false, + label: `Each individual on this application intends to register as a full-time student by ${selectionDate}`, + }, + { + checked: false, + label: `We understand that if any member of our application fails to register as a full-time student by ${selectionDate}, our application could be disqualified`, + }, + { + checked: false, + label: + 'We have read and understand all of the information and guidelines listed in the Instructions section', + }, + { + checked: false, + label: + 'We certify that all information provided on this application is accurate, to the best of our knowledge', + }, + { + checked: false, + label: + 'We agree to host other students in our apartment during the winter break recess, in accordance with the policy outlined in the student handbook', + }, + ]; + + setCheckboxes(newCheckboxes); + }; + + useEffect(() => loadAgreements(), []); + + useEffect(() => deleting === 'success' && loadAgreements(), [deleting]); + + const handleChange = (event, index) => { + setCheckboxes((prevCheckboxes) => { + let newCheckboxes = prevCheckboxes.map((prevCheckbox, j) => + j === index ? { ...prevCheckbox, checked: event.target.checked } : prevCheckbox, + ); + onChange(newCheckboxes.every((checkbox) => checkbox.checked)); + return newCheckboxes; + }); + }; + + const AgreementChecklistItem = ({ checked, index, label, onChange }) => ( + + onChange(event, index)} + name={'agreement-' + 1} + /> + } + label={label} + key={index} + /> + + + ); + + const error = checkboxes.some((checkbox) => !checkbox.checked); + + return ( + + + + + {error && ( + + Use the checkboxes next to each statement to indicate your group's understanding + and/or affirmative answer. Failure to complete this section will result in the + disqualification of the application. + + )} + + + {checkboxes.map((checkbox, index) => ( + handleChange(event, index)} + /> + ))} + + + You must read and complete this section before you will be allowed to submit this + application + + + + + ); +}; + +export default Agreements; diff --git a/src/views/HousingLottery/components/StudentApplication/components/InstructionsCard/index.jsx b/src/views/HousingLottery/components/StudentApplication/components/InstructionsCard/index.jsx deleted file mode 100644 index e665c3a483..0000000000 --- a/src/views/HousingLottery/components/StudentApplication/components/InstructionsCard/index.jsx +++ /dev/null @@ -1,135 +0,0 @@ -import { - Card, - CardContent, - CardHeader, - Grid, - Paper, - Table, - TableBody, - TableCell, - TableContainer, - TableRow, - Typography, -} from '@mui/material/'; -import { useEffect, useState } from 'react'; -import housing from 'services/housing'; -// @TODO CSSMODULES - outside directory -import styles from '../../../../HousingLottery.module.css'; - -/** - * Renders a card displaying the apartment application instructions - * - * @returns {JSX.Element} JSX Element for the instructions card - */ -const InstructionsCard = () => { - const [apartmentSelectionDate, setApartmentSelectionDate] = useState(); - const [thisYear, setThisYear] = useState(); - - useEffect(() => { - const loadSelectionDate = async () => - setApartmentSelectionDate(await housing.getApartmentSelectionDate()); - - loadSelectionDate(); - - setThisYear(new Date().getFullYear()); - }, []); - - const rows = [ - { description: 'Current Freshman', points: 1 }, - { description: 'Current Sophomore', points: 2 }, - { description: 'Current Junior', points: 3 }, - { description: 'Current Senior', points: 4 }, - { description: '23+ years old', points: 1 }, - { description: 'Full-time, off-campus program credit', points: 1 }, - { description: 'Academic/Chapel probation', points: -1 }, - { description: 'Possible academic suspension', points: -2 }, - { description: `${thisYear - 1}-${thisYear} Disciplinary Probation`, points: -3 }, - ]; - - return ( - - - - - Apartments provide an alternative to the traditional residence hall setting and offer a - unique community experience. To be eligible to live in an apartment, students must be at - least 20 years old as of Sept. 1, {thisYear} or have junior or senior - academic standing. Students who were on disciplinary probation at any time during the{' '} - {thisYear - 1}-{thisYear} academic year must also receive approval from the Dean of - Student Life or the Assistant Dean of Student Life to be eligible to apply for an - apartment. Each applicant must be registered as a full-time student by{' '} - {apartmentSelectionDate}. - - - Each group of students desiring to live in a Tavilla or Bromley apartment or in The - Village must submit an application. Your application can include a student who is studying - abroad or not enrolled for the Spring {thisYear} semester – simply list their name - on the application. - - - Full-time, off-campus program credit: Students fulfilling academic - program requirements through student teaching or a full-time internship will qualify for - the full-time, off-campus program credit. It is the responsibility of applicants to claim - this credit on the application. - - - Applications must be for a full apartment: If applying for a six-person - apartment, there must be six people on the application who will be here for the{' '} - fall semester (four people on a - four-person application, etc.). Applications with an incorrect number of applicants will - not be considered. - - - An application is not a guarantee! - - - Due to the large number of applications typically received for apartments, not all - applications will be awarded an apartment. If you do not receive an apartment, you will - need to secure housing through the housing lottery. - - - How are apartments awarded? - - - Apartments are awarded in order of point total for each type of apartment (4-person, - 6-person, etc.). Each individual on an application will have points given/taken away using - the following scale: - - - - - - - {rows.map((row) => ( - - {row.description} - {row.points} - - ))} - -
-
-
-
-
- - If You Are Approved... - - - You will be notified of your placement in an apartment/Village{' '} - - building - {' '} - no later than Apr. 13. Further information about specific apartment/room selection will be - communicated in that email. - -
-
- ); -}; - -export default InstructionsCard; diff --git a/src/views/HousingLottery/index.jsx b/src/views/HousingLottery/index.jsx deleted file mode 100644 index d3d47135a2..0000000000 --- a/src/views/HousingLottery/index.jsx +++ /dev/null @@ -1,81 +0,0 @@ -import { Button, Card, CardContent, CardHeader, Grid, TextField } from '@mui/material'; -import { useState } from 'react'; -import housingService from 'services/housing'; -import styles from './HousingLottery.module.css'; -import ApplicantList from './components/StudentApplication/components/ApplicantList/index.jsx'; -import InstructionsCard from './components/StudentApplication/components/InstructionsCard/index.jsx'; - - -const HousingLottery = () => { - const [rank, setRank] = useState(''); - const [hall, setHall] = useState(''); - - - const handleRank = (event) => { - setRank(event.target.value); - }; - - const handleHall = (event) => { - setHall(event.target.value); - }; - - const handleClick = async () => { - await housingService.addHall(rank, hall); - }; - - const searchHallTitle =
Preferred Halls
; - // const searchStudentTitle =
Student Applicants
; - - return ( - //
- // - // - //
- - - - - - - - - - - - - - - - - - - - - - - - - - - ); -}; - -export default HousingLottery; From a755e7adc3ba889121258cbbcb8a92635f39d3d9 Mon Sep 17 00:00:00 2001 From: Zhijie Wang Date: Sat, 18 Nov 2023 19:58:00 -0500 Subject: [PATCH 021/112] create survey box for sleepying type --- .../components/PreferenceBox/index.jsx | 57 +++++++++++++++++++ src/views/HousingLottery/index.jsx | 49 ++++++++++++++-- 2 files changed, 101 insertions(+), 5 deletions(-) create mode 100644 src/views/HousingLottery/components/PreferenceBox/index.jsx diff --git a/src/views/HousingLottery/components/PreferenceBox/index.jsx b/src/views/HousingLottery/components/PreferenceBox/index.jsx new file mode 100644 index 0000000000..171ae2bf7f --- /dev/null +++ b/src/views/HousingLottery/components/PreferenceBox/index.jsx @@ -0,0 +1,57 @@ +import React, { useEffect, useState } from 'react'; +import { + Card, + CardContent, + CardHeader, + Grid, + Table, + TableBody, + TableContainer, + Typography, + FormControl, + RadioGroup, + FormControlLabel, + Radio, +} from '@mui/material'; +import housing from 'services/housing'; +import styles from '../../../../HousingLottery.module.css'; + +function SurveyQuestionBox() { + const [selectedOption, setSelectedOption] = useState(''); // Store the selected option + + // Handle the change of the selected option + const handleOptionChange = (event) => { + setSelectedOption(event.target.value); + }; + + // Your survey question text can go here + const questionText = 'Are you a night owl or a morning bird?'; + + return ( + + + + + + } + label="Night Owl" + /> + } + label="Morning Bird" + /> + + + + + ); + } + \ No newline at end of file diff --git a/src/views/HousingLottery/index.jsx b/src/views/HousingLottery/index.jsx index 3f1aac25b2..e16f7a7e35 100644 --- a/src/views/HousingLottery/index.jsx +++ b/src/views/HousingLottery/index.jsx @@ -1,21 +1,60 @@ -import { Input } from '@mui/material'; -import { useState } from 'react'; +import React, { useState } from 'react'; +import { + Input, + Button, + Radio, + RadioGroup, + FormControlLabel, +} from '@mui/material'; import housingService from 'services/housing'; const HousingLottery = () => { const [message, setMessage] = useState(''); + const [selectedOption, setSelectedOption] = useState(''); const handleChange = (event) => { setMessage(event.target.value); }; + + const handleOptionChange = (event) => { + setSelectedOption(event.target.value); + }; + const handleClick = async () => { - await housingService.addRoommate(message); + // You can access both the message and selectedOption to submit to your housing service + await housingService.addRoommate({ message, selectedOption }); }; return (
- - +
+ + + } + label="Night Owl" + /> + } + label="Morning Bird" + /> + +
+ + + +
); }; From 7f65afd835f04bb37544ddf9bac0f627968acc28 Mon Sep 17 00:00:00 2001 From: Zhijie Wang Date: Sat, 18 Nov 2023 20:34:23 -0500 Subject: [PATCH 022/112] Add one survery question -by Jay Bae --- src/views/HousingLottery/index.jsx | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/views/HousingLottery/index.jsx b/src/views/HousingLottery/index.jsx index e16f7a7e35..31b50494b4 100644 --- a/src/views/HousingLottery/index.jsx +++ b/src/views/HousingLottery/index.jsx @@ -48,6 +48,26 @@ const HousingLottery = () => { label="Morning Bird" /> + + + } + label="Quiet" + /> + } + label="Loud" + /> +
From 8c69a694d23b5c4c10b0ef1430cfd2247e550c70 Mon Sep 17 00:00:00 2001 From: Zhijie Wang Date: Sat, 18 Nov 2023 20:51:41 -0500 Subject: [PATCH 023/112] quick fix for question choice share one selectOption --- .../components/PreferenceBox/index.jsx | 17 +++++++++++ src/views/HousingLottery/index.jsx | 28 ++++++++++++------- 2 files changed, 35 insertions(+), 10 deletions(-) diff --git a/src/views/HousingLottery/components/PreferenceBox/index.jsx b/src/views/HousingLottery/components/PreferenceBox/index.jsx index 171ae2bf7f..ec640c08b8 100644 --- a/src/views/HousingLottery/components/PreferenceBox/index.jsx +++ b/src/views/HousingLottery/components/PreferenceBox/index.jsx @@ -49,6 +49,23 @@ function SurveyQuestionBox() { label="Morning Bird" /> + + } + label="Quiet" + /> + } + label="Loud" + /> + diff --git a/src/views/HousingLottery/index.jsx b/src/views/HousingLottery/index.jsx index 31b50494b4..6176c2986a 100644 --- a/src/views/HousingLottery/index.jsx +++ b/src/views/HousingLottery/index.jsx @@ -10,19 +10,24 @@ import housingService from 'services/housing'; const HousingLottery = () => { const [message, setMessage] = useState(''); - const [selectedOption, setSelectedOption] = useState(''); + const [morningOrNight, setMorningOrNight] = useState(''); + const [loudOrQuiet, setLoudOrQuiet] = useState(''); const handleChange = (event) => { setMessage(event.target.value); }; - const handleOptionChange = (event) => { - setSelectedOption(event.target.value); + const handleMorningOrNightChange = (event) => { + setMorningOrNight(event.target.value); + }; + + const handleLoudOrQuietChange = (event) => { + setLoudOrQuiet(event.target.value); }; const handleClick = async () => { - // You can access both the message and selectedOption to submit to your housing service - await housingService.addRoommate({ message, selectedOption }); + // You can access message, morningOrNight, and loudOrQuiet to submit to your housing service + await housingService.addRoommate({ message, morningOrNight, loudOrQuiet }); }; return ( @@ -34,8 +39,8 @@ const HousingLottery = () => { { label="Morning Bird" /> +
+ +
Date: Sun, 19 Nov 2023 22:33:43 -0500 Subject: [PATCH 024/112] Put survey questions into the box- by Jay Bae --- src/views/HousingLottery/index.jsx | 85 ++++++++++++++++++------------ 1 file changed, 52 insertions(+), 33 deletions(-) diff --git a/src/views/HousingLottery/index.jsx b/src/views/HousingLottery/index.jsx index 35fa4646f1..cf988fa9cc 100644 --- a/src/views/HousingLottery/index.jsx +++ b/src/views/HousingLottery/index.jsx @@ -1,6 +1,17 @@ import React, { useState } from 'react'; -import { Input, Button, Radio, RadioGroup, FormControlLabel } from '@mui/material'; +import { + Input, + Button, + Radio, + RadioGroup, + FormControlLabel, + Card, + CardHeader, + CardContent, + Grid, +} from '@mui/material'; import housingService from 'services/housing'; +import styles from './HousingLottery.module.css'; const HousingLottery = () => { const [message, setMessage] = useState(''); @@ -25,39 +36,47 @@ const HousingLottery = () => { }; return ( -
-
- - - } label="Night Owl" /> - } label="Morning Bird" /> - -
+ + + + + +
+ + + } label="Night Owl" /> + } label="Morning Bird" /> + +
-
- - - } label="Quiet" /> - } label="Loud" /> - -
- - - - -
+
+ + + } label="Quiet" /> + } label="Loud" /> + +
+ + + + + + + + + ); }; From 826789ff1e1267e5e5c3cde3c5b42fcd32dbc649 Mon Sep 17 00:00:00 2001 From: Eric Date: Mon, 20 Nov 2023 02:46:51 -0500 Subject: [PATCH 025/112] Branch to be used for Agreements, so changes made --- src/views/HousingLottery/HousingLottery.jsx | 264 +----------------- .../components/ApplicantListItem/index.jsx | 132 --------- .../components/ApplicantList/index.jsx | 98 ------- 3 files changed, 1 insertion(+), 493 deletions(-) delete mode 100644 src/views/HousingLottery/components/StudentApplication/components/ApplicantList/components/ApplicantListItem/index.jsx delete mode 100644 src/views/HousingLottery/components/StudentApplication/components/ApplicantList/index.jsx diff --git a/src/views/HousingLottery/HousingLottery.jsx b/src/views/HousingLottery/HousingLottery.jsx index b26f48155f..aa81d9ea9f 100644 --- a/src/views/HousingLottery/HousingLottery.jsx +++ b/src/views/HousingLottery/HousingLottery.jsx @@ -2,7 +2,6 @@ import { Button, Card, CardContent, CardHeader, Grid, TextField } from '@mui/mat import { Dispatch, SetStateAction, useCallback, useEffect, useState } from 'react'; import housingService from 'services/housing'; import styles from './HousingLottery.module.css'; -import ApplicantList from './components/StudentApplication/components/ApplicantList'; import Agreements from './components/StudentApplication/components/Agreements'; @@ -72,9 +71,6 @@ const HousingLottery = () => { - - - { ); }; -export default HousingLottery; - - -// -// -// -// -// Testing nb.1 -// -// -// -// -// -// - - -// import { Button, Card, CardContent, CardHeader, Grid, TextField } from '@mui/material'; -// import { Dispatch, SetStateAction, useCallback, useEffect, useState } from 'react'; -// import housingService from 'services/housing'; -// import styles from './HousingLottery.module.css'; -// import ApplicantList from './components/StudentApplication/components/ApplicantList/index.jsx'; - -// /** -// * -// * @param {StudentProfileInfo} props.userProfile The student profile info of the current user -// * @returns -// */ -// const HousingLottery = ({ userProfile }) => { -// console.log('userProfile', userProfile); - -// const BLANK_APPLICATION_DETAILS = { -// ApplicationID: null, -// DateSubmitted: null, -// DateModified: null, -// EditorProfile: null, -// Applicants: [], -// ApartmentChoices: [], -// }; - -// const [loading, setLoading] = useState(true); -// const [rank, setRank] = useState(''); -// const [hall, setHall] = useState(''); -// const [canEditApplication, setCanEditApplication] = useState(false); -// const [applicationDetails, setApplicationDetails] = useState(BLANK_APPLICATION_DETAILS); - -// const handleChangeEditor = (profile) => { -// if (canEditApplication && profile) { -// if ( -// applicationDetails.Applicants.some( -// (applicant) => applicant.Profile.AD_Username === profile.AD_Username, -// ) -// ) { -// setNewEditorProfile(profile); - -// let insertText = ''; -// if (profile.fullName) { -// insertText = ` to ${profile.fullName}`; -// } else if (profile?.FirstName && profile?.LastName) { -// insertText = ` to ${profile.FirstName} ${profile.LastName}`; -// } -// const dialogText = ( -// -// You are about to change the editor{insertText}. -//
-// If you change the application editor, you will no longer be able to edit this -// application yourself. All unsaved changes will be saved automatically. -//
-// Are you sure you want to change the application editor? -//
-// ); -// createDialog(DIALOG_PROPS.changeEditor, dialogText); -// } -// } -// }; - - -// useEffect( -// () => -// setCanEditApplication( -// userProfile?.AD_Username === applicationDetails?.EditorProfile?.AD_Username ?? false, -// ), -// [applicationDetails?.EditorProfile?.AD_Username, userProfile?.AD_Username], -// ); - -// useEffect( -// () => -// setCanEditApplication( -// userProfile?.AD_Username === applicationDetails?.EditorProfile?.AD_Username ?? false, -// ), -// [applicationDetails?.EditorProfile?.AD_Username, userProfile?.AD_Username], -// ); - -// const loadApplication = useCallback(async () => { -// const initializeNewApplication = () => { -// const initialApplicants = [ -// { Profile: userProfile, Username: userProfile.AD_Username, OffCampusProgram: '' }, -// ]; -// setApplicationDetails({ -// ...BLANK_APPLICATION_DETAILS, -// EditorProfile: userProfile, -// Gender: userProfile.Gender, -// Applicants: initialApplicants, -// }); -// setUnsavedChanges(true); -// }; - -// let result = false; -// try { -// // Check if the current user is on an application. Returns the application ID number if found -// const newApplicationID = await housing.getCurrentApplicationID(); -// if (newApplicationID > 0) { -// setApplicationExists(true); -// const newApplicationDetails = await housing.getApartmentApplication(newApplicationID); -// setApplicationDetails(newApplicationDetails); -// setUnsavedChanges(false); -// result = true; -// } else { -// throw createError(new Error('Invalid application ID'), { status: 404 }); -// } -// } catch (e) { -// if (e instanceof NotFoundError) { -// initializeNewApplication(); -// } else if (e instanceof AuthError) { -// const debugMessage = -// 'Received a 401 (Unauthorized) response, which should not be possible in this case. Please try refreshing the page, or contact CTS for support.'; -// console.error(`Debug Message: ${debugMessage}`); -// createSnackbar(debugMessage, 'error'); -// } else { -// throw e; -// } -// } finally { -// setNewEditorProfile(null); -// return result; -// } -// }, [userProfile]); - -// useEffect(() => { -// setLoading(true); -// loadApplication(); -// setLoading(false); -// }, [userProfile, loadApplication]); - -// const addApplicant = async (newApplicantUsername) => { -// try { -// // Get the profile of the selected user -// const newApplicantProfile = await user.getProfileInfo(newApplicantUsername); -// let newApplicantObject = { -// ApplicationID: applicationDetails.ApplicationID, -// Profile: newApplicantProfile, -// Username: newApplicantUsername, // Used for convenient array sorting. -// OffCampusProgram: '', -// }; - -// if ( -// applicationDetails.Applicants.some( -// (applicant) => applicant.Profile.AD_Username === newApplicantUsername, -// ) -// ) { -// // Display an error if the selected user is already in the list -// createSnackbar(`${newApplicantProfile.fullName} is already in the list.`, 'info'); -// } else { -// const validApplicant = await isApplicantValid(newApplicantObject); -// // Any relevant errors and snackbar messages are handled by `isApplicantValid()` internally -// if (validApplicant) { -// // Add the profile object to the list of applicants -// setApplicationDetails((prevApplicationDetails) => ({ -// ...prevApplicationDetails, -// Applicants: [...prevApplicationDetails.Applicants, newApplicantObject], -// })); -// setUnsavedChanges(true); -// } -// } -// } catch (error) { -// createSnackbar( -// 'Something went wrong while trying to add this person. Please try again.', -// 'error', -// ); -// console.log(error); -// } -// }; - - -// const handleRank = (event) => { -// setRank(event.target.value); -// }; - -// const handleHall = (event) => { -// setHall(event.target.value); -// }; - -// const handleClick = async () => { -// await housingService.addHall(rank, hall); -// }; - -// const searchHallTitle =
Preferred Halls
; -// // const searchStudentTitle =
Student Applicants
; - -// return ( -// //
-// // -// // -// //
-// -// -// -// -// -// -// -// -// -// -// -// -// -// -// -// -// -// -// -// -// MAX_NUM_APPLICANTS -// } -// editorProfile={applicationDetails.EditorProfile} -// applicants={applicationDetails.Applicants ?? []} -// onSearchSubmit={(searchSelection) => -// searchSelection && addApplicant(searchSelection) -// } -// onChangeEditor={handleChangeEditor} -// onApplicantRemove={handleApplicantRemove} -// /> -// -// -// ); -// }; - -// export default HousingLottery; +export default HousingLottery; \ No newline at end of file diff --git a/src/views/HousingLottery/components/StudentApplication/components/ApplicantList/components/ApplicantListItem/index.jsx b/src/views/HousingLottery/components/StudentApplication/components/ApplicantList/components/ApplicantListItem/index.jsx deleted file mode 100644 index f243e0a45d..0000000000 --- a/src/views/HousingLottery/components/StudentApplication/components/ApplicantList/components/ApplicantListItem/index.jsx +++ /dev/null @@ -1,132 +0,0 @@ -import { - Avatar, - Divider, - Grid, - IconButton, - ListItem, - ListItemAvatar, - ListItemSecondaryAction, - ListItemText, -} from '@mui/material'; -import ClearIcon from '@mui/icons-material/Clear'; -import PersonIcon from '@mui/icons-material/Person'; -import StarIcon from '@mui/icons-material/Star'; -import StarBorderIcon from '@mui/icons-material/StarBorder'; -import { Fragment, useEffect, useState } from 'react'; -import { Link } from 'react-router-dom'; -import { Class } from 'services/peopleSearch'; -import user from 'services/user'; -import styles from '../../../../../../HousingLottery.module.css'; - -/** - * @typedef { import('services/user').StudentProfileInfo } StudentProfileInfo - */ - -/** - * Renders the list item for the apartment applicant list - * - * @param {Object} props The React component props - * @param {boolean} props.disabled boolean to disable the interactive elements of this list item - * @param {StudentProfileInfo} props.profile The StudentProfileInfo of the applicant - * @param {boolean} props.isApplicationEditor boolean indicating whether this list item corresponds to the application editor - * @param {Function} props.onChangeEditor Callback for change editor button - * @param {Function} props.onApplicantRemove Callback for remove applicant button - * @returns {JSX.Element} JSX Element for the applicant list item - */ -const ApplicantListItem = ({ - disabled, - profile, - isApplicationEditor, - onChangeEditor, - onApplicantRemove, -}) => { - const [avatar, setAvatar] = useState(null); - const [hasNickName, setHasNickname] = useState(false); - - useEffect(() => { - loadAvatar(profile); - setHasNickname(profile.FirstName !== profile.NickName && profile.NickName !== ''); - }, [profile]); - - /** - * Creates the Avatar image of the given user - * - * @async - * @function loadAvatar - * @param {StudentProfileInfo} profile The StudentProfileInfo object for the student represented by this list item - */ - const loadAvatar = async (profile) => { - try { - const { def: defaultImage, pref: preferredImage } = await user.getImage(profile.AD_Username); - setAvatar(preferredImage || defaultImage); - } catch { - setAvatar( - - - , - ); - } - }; - - const displayName = hasNickName - ? `${profile.FirstName} ${profile.LastName} (${profile.NickName})` - : `${profile.FirstName} ${profile.LastName}`; - - return ( - - - - {avatar ? ( - - ) : ( - - - - )} - - - - - - - - - - profile && onChangeEditor?.(profile)} - size="large" - > - {isApplicationEditor ? : } - - - - profile?.AD_Username && onApplicantRemove?.(profile.AD_Username)} - size="large" - > - - - - - - - - - ); -}; - -export default ApplicantListItem; diff --git a/src/views/HousingLottery/components/StudentApplication/components/ApplicantList/index.jsx b/src/views/HousingLottery/components/StudentApplication/components/ApplicantList/index.jsx deleted file mode 100644 index be09ec1479..0000000000 --- a/src/views/HousingLottery/components/StudentApplication/components/ApplicantList/index.jsx +++ /dev/null @@ -1,98 +0,0 @@ -import { - Card, - CardContent, - CardHeader, - Collapse, - Divider, - Grid, - List, - ListItem, - ListItemIcon, - ListItemText, -} from '@mui/material'; -import AddIcon from '@mui/icons-material/Add'; -import ClearIcon from '@mui/icons-material/Clear'; -import ExpandLess from '@mui/icons-material/ExpandLess'; -import ExpandMore from '@mui/icons-material/ExpandMore'; -import HelpIcon from '@mui/icons-material/Help'; -import StarBorder from '@mui/icons-material/StarBorder'; -import GordonQuickSearch from 'components/Header/components/QuickSearch'; -import { useState } from 'react'; -// @TODO CSSMODULES - outside directory -import styles from '../../../../HousingLottery.module.css'; -import ApplicantListItem from './components/ApplicantListItem/index.jsx'; - - -/** - * @typedef { import('services/housing').ApartmentApplicant } ApartmentApplicant - * @typedef { import('services/housing').ApplicationDetails } ApplicationDetails - * @typedef { import('services/user').StudentProfileInfo } StudentProfileInfo - */ - -/** - * Renders the list of applicants, displayed by name, username, and class standing. - * - * @param {Object} props The React component props - * @param {boolean} props.disabled boolean to disable the interactive elements of this list - * @param {StudentProfileInfo} props.editorProfile The StudentProfileInfo of the application editor - * @param {ApartmentApplicant[]} props.applicants Array of applicant info - * @param {Function} props.onSearchSubmit Callback for apartment people search submission - * @param {Function} props.onChangeEditor Callback for change editor button - * @param {Function} props.onApplicantRemove Callback for remove applicant button - * @returns {JSX.Element} JSX Element for the applicant list - */ -const ApplicantList = ({ - disabled, - editorProfile, - applicants, - onSearchSubmit, - onChangeEditor, - onApplicantRemove, -}) => { - const [showHelp, setShowHelp] = useState(false); - return ( - - - - - - - {applicants?.length > 0 ? ( - applicants.map((applicant) => ( - - )) - ) : ( - - - - )} - - - - - disabled || onSearchSubmit(selectedUsername)} - /> - - - - - - ); -}; - -export default ApplicantList; From ea60a9f6b6e00f45f20c3db0de08dc3d66dbda42 Mon Sep 17 00:00:00 2001 From: Wenlan Ji Date: Mon, 20 Nov 2023 08:55:53 -0500 Subject: [PATCH 026/112] adding delete button --- .../PreferredHall/HallSlotComponent/index.jsx | 14 ++++++++++---- .../studentView/PreferredHall/index.jsx | 12 ++---------- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/src/views/HousingLottery/studentView/PreferredHall/HallSlotComponent/index.jsx b/src/views/HousingLottery/studentView/PreferredHall/HallSlotComponent/index.jsx index 9fba4826ee..ce4b649fea 100644 --- a/src/views/HousingLottery/studentView/PreferredHall/HallSlotComponent/index.jsx +++ b/src/views/HousingLottery/studentView/PreferredHall/HallSlotComponent/index.jsx @@ -67,15 +67,21 @@ const HallSlot = ({ select size={200} /> - {/* + + + { + console.log('onclick'); + deletePreferHall(rank - 1); + }} edge="end" aria-label="delete" size="large" > - - */} + +
{ const hallArray = Array(count).fill(0); function deletePreferHall(myNum) { - debugger; hallArray.splice(myNum, 1); - console.log('deletePreferHall' + hallArray); + console.log('deletePreferHall ' + hallArray); + console.log('deletePreferHall ' + HallSlot); } return ( @@ -40,14 +40,6 @@ const PreferredHallsCard = () => {
Rank
- {preferredHallList.map((hall, index) => ( - - ))} {hallArray.map((value, index) => ( Date: Mon, 20 Nov 2023 15:07:08 -0500 Subject: [PATCH 027/112] Styled Preferred Halls box as necessary. --- .../HousingLottery/HousingLottery.module.scss | 32 ++++++------------- .../studentView/PreferredHall/index.jsx | 22 +++++++------ 2 files changed, 22 insertions(+), 32 deletions(-) diff --git a/src/views/HousingLottery/HousingLottery.module.scss b/src/views/HousingLottery/HousingLottery.module.scss index ac8940e127..b6c163f2e6 100644 --- a/src/views/HousingLottery/HousingLottery.module.scss +++ b/src/views/HousingLottery/HousingLottery.module.scss @@ -1,27 +1,6 @@ -.addHall_button { - position: 'absolute'; - margin: 'auto'; - top: 15px; - bottom: 40px; - left: 10px; - right: 10px; +.addHall_button, .submit_button { height: 45px; - width: 120px; -} - -.submit_button { - // padding: 5px; - // height: 40px; - // width: 100px; - position: 'absolute'; - margin: 'auto'; - top: 15px; - bottom: 40px; - left: 10px; - right: 10px; - height: 45px; - width: 120px; - float: right; + margin-left: 10px; } .rankLabel { @@ -31,5 +10,12 @@ } #hallSlots { + position: relative; padding: 10px; } + +.hallSlotWrapper { + margin-top: 10px; + margin-bottom: 10px; + margin-left: 10px; +} \ No newline at end of file diff --git a/src/views/HousingLottery/studentView/PreferredHall/index.jsx b/src/views/HousingLottery/studentView/PreferredHall/index.jsx index 3f4b1e6648..a69acbed60 100644 --- a/src/views/HousingLottery/studentView/PreferredHall/index.jsx +++ b/src/views/HousingLottery/studentView/PreferredHall/index.jsx @@ -1,5 +1,6 @@ import { Button, Card, CardContent, CardHeader, Grid, TextField } from '@mui/material'; import { useState, useEffect } from 'react'; +import AddIcon from '@mui/icons-material/Add'; import HallSlot from './HallSlotComponent'; import housingService from 'services/housing'; import styles from '../../HousingLottery.module.css'; @@ -42,19 +43,22 @@ const PreferredHallsCard = () => {
Rank
{hallArray.map((value, index) => ( - +
+ +
))}
- + From cb5a0fd133b7c6d4a5018ebad673e7a143776bfe Mon Sep 17 00:00:00 2001 From: ZhiJie Wang <98111145+andrew-wzj@users.noreply.github.com> Date: Sun, 26 Nov 2023 16:35:25 -0500 Subject: [PATCH 037/112] Update HousingLottery.module.scss --- src/views/HousingLottery/HousingLottery.module.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/views/HousingLottery/HousingLottery.module.scss b/src/views/HousingLottery/HousingLottery.module.scss index b5807d5c7e..af4a5afdf3 100644 --- a/src/views/HousingLottery/HousingLottery.module.scss +++ b/src/views/HousingLottery/HousingLottery.module.scss @@ -153,4 +153,4 @@ strong.over_emphasized { &_icon { margin-right: 0.75rem; } - +} From fdbab8da23f2af3cd4bd0df6565e7835e5e8cdc4 Mon Sep 17 00:00:00 2001 From: ZhiJie Wang <98111145+andrew-wzj@users.noreply.github.com> Date: Sun, 26 Nov 2023 16:40:48 -0500 Subject: [PATCH 038/112] Update HousingLottery.jsx --- src/views/HousingLottery/HousingLottery.jsx | 268 +------------------- 1 file changed, 2 insertions(+), 266 deletions(-) diff --git a/src/views/HousingLottery/HousingLottery.jsx b/src/views/HousingLottery/HousingLottery.jsx index b26f48155f..1e8f96510e 100644 --- a/src/views/HousingLottery/HousingLottery.jsx +++ b/src/views/HousingLottery/HousingLottery.jsx @@ -28,13 +28,8 @@ const HousingLottery = () => { }; const searchHallTitle =
Preferred Halls
; - // const searchStudentTitle =
Student Applicants
; return ( - //
- // - // - //
@@ -43,7 +38,7 @@ const HousingLottery = () => { { { }; export default HousingLottery; - - -// -// -// -// -// Testing nb.1 -// -// -// -// -// -// - - -// import { Button, Card, CardContent, CardHeader, Grid, TextField } from '@mui/material'; -// import { Dispatch, SetStateAction, useCallback, useEffect, useState } from 'react'; -// import housingService from 'services/housing'; -// import styles from './HousingLottery.module.css'; -// import ApplicantList from './components/StudentApplication/components/ApplicantList/index.jsx'; - -// /** -// * -// * @param {StudentProfileInfo} props.userProfile The student profile info of the current user -// * @returns -// */ -// const HousingLottery = ({ userProfile }) => { -// console.log('userProfile', userProfile); - -// const BLANK_APPLICATION_DETAILS = { -// ApplicationID: null, -// DateSubmitted: null, -// DateModified: null, -// EditorProfile: null, -// Applicants: [], -// ApartmentChoices: [], -// }; - -// const [loading, setLoading] = useState(true); -// const [rank, setRank] = useState(''); -// const [hall, setHall] = useState(''); -// const [canEditApplication, setCanEditApplication] = useState(false); -// const [applicationDetails, setApplicationDetails] = useState(BLANK_APPLICATION_DETAILS); - -// const handleChangeEditor = (profile) => { -// if (canEditApplication && profile) { -// if ( -// applicationDetails.Applicants.some( -// (applicant) => applicant.Profile.AD_Username === profile.AD_Username, -// ) -// ) { -// setNewEditorProfile(profile); - -// let insertText = ''; -// if (profile.fullName) { -// insertText = ` to ${profile.fullName}`; -// } else if (profile?.FirstName && profile?.LastName) { -// insertText = ` to ${profile.FirstName} ${profile.LastName}`; -// } -// const dialogText = ( -// -// You are about to change the editor{insertText}. -//
-// If you change the application editor, you will no longer be able to edit this -// application yourself. All unsaved changes will be saved automatically. -//
-// Are you sure you want to change the application editor? -//
-// ); -// createDialog(DIALOG_PROPS.changeEditor, dialogText); -// } -// } -// }; - - -// useEffect( -// () => -// setCanEditApplication( -// userProfile?.AD_Username === applicationDetails?.EditorProfile?.AD_Username ?? false, -// ), -// [applicationDetails?.EditorProfile?.AD_Username, userProfile?.AD_Username], -// ); - -// useEffect( -// () => -// setCanEditApplication( -// userProfile?.AD_Username === applicationDetails?.EditorProfile?.AD_Username ?? false, -// ), -// [applicationDetails?.EditorProfile?.AD_Username, userProfile?.AD_Username], -// ); - -// const loadApplication = useCallback(async () => { -// const initializeNewApplication = () => { -// const initialApplicants = [ -// { Profile: userProfile, Username: userProfile.AD_Username, OffCampusProgram: '' }, -// ]; -// setApplicationDetails({ -// ...BLANK_APPLICATION_DETAILS, -// EditorProfile: userProfile, -// Gender: userProfile.Gender, -// Applicants: initialApplicants, -// }); -// setUnsavedChanges(true); -// }; - -// let result = false; -// try { -// // Check if the current user is on an application. Returns the application ID number if found -// const newApplicationID = await housing.getCurrentApplicationID(); -// if (newApplicationID > 0) { -// setApplicationExists(true); -// const newApplicationDetails = await housing.getApartmentApplication(newApplicationID); -// setApplicationDetails(newApplicationDetails); -// setUnsavedChanges(false); -// result = true; -// } else { -// throw createError(new Error('Invalid application ID'), { status: 404 }); -// } -// } catch (e) { -// if (e instanceof NotFoundError) { -// initializeNewApplication(); -// } else if (e instanceof AuthError) { -// const debugMessage = -// 'Received a 401 (Unauthorized) response, which should not be possible in this case. Please try refreshing the page, or contact CTS for support.'; -// console.error(`Debug Message: ${debugMessage}`); -// createSnackbar(debugMessage, 'error'); -// } else { -// throw e; -// } -// } finally { -// setNewEditorProfile(null); -// return result; -// } -// }, [userProfile]); - -// useEffect(() => { -// setLoading(true); -// loadApplication(); -// setLoading(false); -// }, [userProfile, loadApplication]); - -// const addApplicant = async (newApplicantUsername) => { -// try { -// // Get the profile of the selected user -// const newApplicantProfile = await user.getProfileInfo(newApplicantUsername); -// let newApplicantObject = { -// ApplicationID: applicationDetails.ApplicationID, -// Profile: newApplicantProfile, -// Username: newApplicantUsername, // Used for convenient array sorting. -// OffCampusProgram: '', -// }; - -// if ( -// applicationDetails.Applicants.some( -// (applicant) => applicant.Profile.AD_Username === newApplicantUsername, -// ) -// ) { -// // Display an error if the selected user is already in the list -// createSnackbar(`${newApplicantProfile.fullName} is already in the list.`, 'info'); -// } else { -// const validApplicant = await isApplicantValid(newApplicantObject); -// // Any relevant errors and snackbar messages are handled by `isApplicantValid()` internally -// if (validApplicant) { -// // Add the profile object to the list of applicants -// setApplicationDetails((prevApplicationDetails) => ({ -// ...prevApplicationDetails, -// Applicants: [...prevApplicationDetails.Applicants, newApplicantObject], -// })); -// setUnsavedChanges(true); -// } -// } -// } catch (error) { -// createSnackbar( -// 'Something went wrong while trying to add this person. Please try again.', -// 'error', -// ); -// console.log(error); -// } -// }; - - -// const handleRank = (event) => { -// setRank(event.target.value); -// }; - -// const handleHall = (event) => { -// setHall(event.target.value); -// }; - -// const handleClick = async () => { -// await housingService.addHall(rank, hall); -// }; - -// const searchHallTitle =
Preferred Halls
; -// // const searchStudentTitle =
Student Applicants
; - -// return ( -// //
-// // -// // -// //
-// -// -// -// -// -// -// -// -// -// -// -// -// -// -// -// -// -// -// -// -// MAX_NUM_APPLICANTS -// } -// editorProfile={applicationDetails.EditorProfile} -// applicants={applicationDetails.Applicants ?? []} -// onSearchSubmit={(searchSelection) => -// searchSelection && addApplicant(searchSelection) -// } -// onChangeEditor={handleChangeEditor} -// onApplicantRemove={handleApplicantRemove} -// /> -// -// -// ); -// }; - -// export default HousingLottery; From 55d5289603fe07b84a2c1aa8a80f1f21a53895da Mon Sep 17 00:00:00 2001 From: ZhiJie Wang <98111145+andrew-wzj@users.noreply.github.com> Date: Sun, 26 Nov 2023 16:51:21 -0500 Subject: [PATCH 039/112] Update HousingLottery.jsx --- src/views/HousingLottery/HousingLottery.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/views/HousingLottery/HousingLottery.jsx b/src/views/HousingLottery/HousingLottery.jsx index 1e8f96510e..fc940e794c 100644 --- a/src/views/HousingLottery/HousingLottery.jsx +++ b/src/views/HousingLottery/HousingLottery.jsx @@ -77,6 +77,6 @@ const HousingLottery = () => {
); -}; +} export default HousingLottery; From 82c7ca5679481a24c2da5d44931bf7652f14176a Mon Sep 17 00:00:00 2001 From: ZhiJie Wang <98111145+andrew-wzj@users.noreply.github.com> Date: Sun, 26 Nov 2023 16:58:24 -0500 Subject: [PATCH 040/112] Update index.jsx --- src/views/HousingLottery/index.jsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/views/HousingLottery/index.jsx b/src/views/HousingLottery/index.jsx index 02433c0793..6afb88f94c 100644 --- a/src/views/HousingLottery/index.jsx +++ b/src/views/HousingLottery/index.jsx @@ -80,4 +80,5 @@ const HousingLottery = () => {
); +}; export default HousingLottery; From 3f8d27b682dec36fd27d775dcd10925a0cff52a4 Mon Sep 17 00:00:00 2001 From: Zhijie Wang Date: Sun, 26 Nov 2023 17:35:15 -0500 Subject: [PATCH 041/112] store preferences as array --- src/views/HousingLottery/index.jsx | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/views/HousingLottery/index.jsx b/src/views/HousingLottery/index.jsx index 02433c0793..ed435ab834 100644 --- a/src/views/HousingLottery/index.jsx +++ b/src/views/HousingLottery/index.jsx @@ -1,4 +1,3 @@ - import React, { useState } from 'react'; import { Input, @@ -19,6 +18,8 @@ const HousingLottery = () => { const [message, setMessage] = useState(''); const [morningOrNight, setMorningOrNight] = useState(''); const [loudOrQuiet, setLoudOrQuiet] = useState(''); + const [preferences, setPreferences] = useState([]); + const handleChange = (event) => { setMessage(event.target.value); @@ -32,9 +33,22 @@ const HousingLottery = () => { setLoudOrQuiet(event.target.value); }; + const handlePreferenceChange = (event) => { + // Update preferences based on the selected radio button + const newPreferences = event.target.value; + setPreferences((prevPreferences) => { + if (prevPreferences.includes(newPreference)) { + // Remove the preference if it's already in the array + return prevPreferences.filter((pref) => pref !== newPreference); + } else { + // Add the preference if it's not in the array + return [...prevPreferences, newPreference]; + } + }); + }; const handleClick = async () => { // You can access message, morningOrNight, and loudOrQuiet to submit to your housing service - await housingService.addRoommate({ message, morningOrNight, loudOrQuiet }); + await housingService.addRoommate({ message, preferences}); }; return ( @@ -80,4 +94,5 @@ const HousingLottery = () => {
); + }; export default HousingLottery; From 95482e51dc118a803aa98d67407ae44a1461ce9c Mon Sep 17 00:00:00 2001 From: ZhiJie Wang <98111145+andrew-wzj@users.noreply.github.com> Date: Sun, 26 Nov 2023 17:41:46 -0500 Subject: [PATCH 042/112] Update index.jsx --- src/views/HousingLottery/index.jsx | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/views/HousingLottery/index.jsx b/src/views/HousingLottery/index.jsx index 960b70d7e7..3e240acf93 100644 --- a/src/views/HousingLottery/index.jsx +++ b/src/views/HousingLottery/index.jsx @@ -94,9 +94,6 @@ const HousingLottery = () => {
); -<<<<<<< HEAD }; -======= -}; ->>>>>>> 82c7ca5679481a24c2da5d44931bf7652f14176a + export default HousingLottery; From e872d2240b6cd27100c90d68f1b830093fe35b9e Mon Sep 17 00:00:00 2001 From: Zhijie Wang Date: Sun, 26 Nov 2023 18:51:21 -0500 Subject: [PATCH 043/112] console log to check preference storage --- src/views/HousingLottery/index.jsx | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/src/views/HousingLottery/index.jsx b/src/views/HousingLottery/index.jsx index 960b70d7e7..0a176072e3 100644 --- a/src/views/HousingLottery/index.jsx +++ b/src/views/HousingLottery/index.jsx @@ -1,4 +1,4 @@ -import React, { useState } from 'react'; +import React, { useEffect, useState } from 'react'; import { Input, Button, @@ -20,6 +20,16 @@ const HousingLottery = () => { const [loudOrQuiet, setLoudOrQuiet] = useState(''); const [preferences, setPreferences] = useState([]); + useEffect(() => { + const storedPreferences = localStorage.getItem('preferences'); + if (storedPreferences) { + setPreferences(JSON.parse(storedPreferences)); + } + }, []); + + useEffect(() => { + localStorage.setItem('preferences', JSON.stringify(preferences)); + }, [preferences]); const handleChange = (event) => { setMessage(event.target.value); @@ -35,7 +45,7 @@ const HousingLottery = () => { const handlePreferenceChange = (event) => { // Update preferences based on the selected radio button - const newPreferences = event.target.value; + const newPreference = event.target.value; setPreferences((prevPreferences) => { if (prevPreferences.includes(newPreference)) { // Remove the preference if it's already in the array @@ -48,6 +58,7 @@ const HousingLottery = () => { }; const handleClick = async () => { // You can access message, morningOrNight, and loudOrQuiet to submit to your housing service + console.log(preferences); await housingService.addRoommate({ message, preferences}); }; @@ -62,8 +73,8 @@ const HousingLottery = () => { } label="Night Owl" /> } label="Morning Bird" /> @@ -75,8 +86,8 @@ const HousingLottery = () => { } label="Quiet" /> } label="Loud" /> @@ -94,9 +105,5 @@ const HousingLottery = () => { ); -<<<<<<< HEAD }; -======= -}; ->>>>>>> 82c7ca5679481a24c2da5d44931bf7652f14176a export default HousingLottery; From 085941a2ec0f7af72159c2791df8046e73fd9e0a Mon Sep 17 00:00:00 2001 From: Zhijie Wang Date: Sun, 26 Nov 2023 19:27:44 -0500 Subject: [PATCH 044/112] fix the selection radio and use console log to check the stored preference array --- src/views/HousingLottery/index.jsx | 40 ++++++++++++------------------ 1 file changed, 16 insertions(+), 24 deletions(-) diff --git a/src/views/HousingLottery/index.jsx b/src/views/HousingLottery/index.jsx index 0a176072e3..20d8d36a84 100644 --- a/src/views/HousingLottery/index.jsx +++ b/src/views/HousingLottery/index.jsx @@ -18,18 +18,23 @@ const HousingLottery = () => { const [message, setMessage] = useState(''); const [morningOrNight, setMorningOrNight] = useState(''); const [loudOrQuiet, setLoudOrQuiet] = useState(''); - const [preferences, setPreferences] = useState([]); + useEffect(() => { - const storedPreferences = localStorage.getItem('preferences'); + const storedPreferences = localStorage.getItem('userPreferences'); if (storedPreferences) { - setPreferences(JSON.parse(storedPreferences)); + const { morningOrNight, loudOrQuiet } = storedPreferences; + setMorningOrNight(morningOrNight || ''); + setLoudOrQuiet(loudOrQuiet || ''); } }, []); useEffect(() => { - localStorage.setItem('preferences', JSON.stringify(preferences)); - }, [preferences]); + // Save preferences to local storage + const storedPreferences = JSON.stringify({ morningOrNight, loudOrQuiet }); + localStorage.setItem('userPreferences', storedPreferences); + }, [morningOrNight, loudOrQuiet]); + const handleChange = (event) => { setMessage(event.target.value); @@ -43,23 +48,10 @@ const HousingLottery = () => { setLoudOrQuiet(event.target.value); }; - const handlePreferenceChange = (event) => { - // Update preferences based on the selected radio button - const newPreference = event.target.value; - setPreferences((prevPreferences) => { - if (prevPreferences.includes(newPreference)) { - // Remove the preference if it's already in the array - return prevPreferences.filter((pref) => pref !== newPreference); - } else { - // Add the preference if it's not in the array - return [...prevPreferences, newPreference]; - } - }); - }; const handleClick = async () => { // You can access message, morningOrNight, and loudOrQuiet to submit to your housing service - console.log(preferences); - await housingService.addRoommate({ message, preferences}); + console.log({message, morningOrNight, loudOrQuiet}); + await housingService.addRoommate({ message, morningOrNight, loudOrQuiet}); }; return ( @@ -73,8 +65,8 @@ const HousingLottery = () => { } label="Night Owl" /> } label="Morning Bird" /> @@ -86,8 +78,8 @@ const HousingLottery = () => { } label="Quiet" /> } label="Loud" /> From eee4afc488fc772d333514db7a3bfcde56976e73 Mon Sep 17 00:00:00 2001 From: Zhijie Wang Date: Mon, 27 Nov 2023 15:38:02 -0500 Subject: [PATCH 045/112] remove unused file --- src/views/HousingLottery/HousingLottery.jsx | 82 --------------------- src/views/HousingLottery/index.jsx | 4 +- 2 files changed, 2 insertions(+), 84 deletions(-) delete mode 100644 src/views/HousingLottery/HousingLottery.jsx diff --git a/src/views/HousingLottery/HousingLottery.jsx b/src/views/HousingLottery/HousingLottery.jsx deleted file mode 100644 index fc940e794c..0000000000 --- a/src/views/HousingLottery/HousingLottery.jsx +++ /dev/null @@ -1,82 +0,0 @@ -import { Button, Card, CardContent, CardHeader, Grid, TextField } from '@mui/material'; -import { Dispatch, SetStateAction, useCallback, useEffect, useState } from 'react'; -import housingService from 'services/housing'; -import styles from './HousingLottery.module.css'; -import ApplicantList from './components/StudentApplication/components/ApplicantList'; -import Agreements from './components/StudentApplication/components/Agreements'; - - -const HousingLottery = () => { - const [rank, setRank] = useState(''); - const [hall, setHall] = useState(''); - const [canEditApplication, setCanEditApplication] = useState(false); - const [agreements, setAgreements] = useState(false); // Represents the state of the agreements card. True if all checkboxes checked, false otherwise - const [deleting, setDeleting] = useState(false); - - - - const handleRank = (event) => { - setRank(event.target.value); - }; - - const handleHall = (event) => { - setHall(event.target.value); - }; - - const handleClick = async () => { - await housingService.addHall(rank, hall); - }; - - const searchHallTitle =
Preferred Halls
; - - return ( - - - - - - - - - - - - - - - - - - - - - - - - setAgreements(newState)} - /> - - - ); -} - -export default HousingLottery; diff --git a/src/views/HousingLottery/index.jsx b/src/views/HousingLottery/index.jsx index 20d8d36a84..c673fd93dd 100644 --- a/src/views/HousingLottery/index.jsx +++ b/src/views/HousingLottery/index.jsx @@ -50,8 +50,8 @@ const HousingLottery = () => { const handleClick = async () => { // You can access message, morningOrNight, and loudOrQuiet to submit to your housing service - console.log({message, morningOrNight, loudOrQuiet}); - await housingService.addRoommate({ message, morningOrNight, loudOrQuiet}); + console.log({ morningOrNight, loudOrQuiet}); + await housingService.addRoommate({morningOrNight, loudOrQuiet}); }; return ( From 8b491f76940fa8e867afad688ea090c9351ed181 Mon Sep 17 00:00:00 2001 From: Eric Date: Mon, 27 Nov 2023 15:38:22 -0500 Subject: [PATCH 046/112] First draft of textField needed to add participant --- .../HousingLottery/HousingLottery.module.scss | 28 ++++++ src/views/HousingLottery/index.jsx | 19 +++- .../studentView/StudentApplicants/index.jsx | 90 +++++++++++++++++++ 3 files changed, 136 insertions(+), 1 deletion(-) create mode 100644 src/views/HousingLottery/studentView/StudentApplicants/index.jsx diff --git a/src/views/HousingLottery/HousingLottery.module.scss b/src/views/HousingLottery/HousingLottery.module.scss index 5397b0165d..0500421224 100644 --- a/src/views/HousingLottery/HousingLottery.module.scss +++ b/src/views/HousingLottery/HousingLottery.module.scss @@ -20,3 +20,31 @@ margin-bottom: 10px; margin-left: 10px; } + +.applicants_card_header { + background-color: var(--mui-palette-primary-main); + color: var(--mui-palette-primary-contrastText); + + :global { + .MuiTypography-colorTextSecondary { + color: var(--mui-palette-primary-contrastText); + font-size: 1.25rem; + } + + .MuiCardHeader-subheader { + color: var(--mui-palette-primary-contrastText); + } + } +} + +.applicants_name { + display: flexbox; + width: 10em; + margin-left: 1em; +} + +.applicants_email { + display: flexbox; + width: 24em; + margin-left: 1em; +} \ No newline at end of file diff --git a/src/views/HousingLottery/index.jsx b/src/views/HousingLottery/index.jsx index f7d50e53cb..1c46655394 100644 --- a/src/views/HousingLottery/index.jsx +++ b/src/views/HousingLottery/index.jsx @@ -1,7 +1,24 @@ +import { Button, Card, CardContent, CardHeader, Grid, List } from '@mui/material'; +import PreferredHallsCard from './studentView/PreferredHall'; import PreferredHall from './studentView/PreferredHall'; +import StudentApplicants from './studentView/StudentApplicants/index.jsx'; + + const HousingLottery = () => { - return ; + + + + return ( + + + + + + + + + ); }; export default HousingLottery; diff --git a/src/views/HousingLottery/studentView/StudentApplicants/index.jsx b/src/views/HousingLottery/studentView/StudentApplicants/index.jsx new file mode 100644 index 0000000000..1171bea23e --- /dev/null +++ b/src/views/HousingLottery/studentView/StudentApplicants/index.jsx @@ -0,0 +1,90 @@ +import { Button, Card, CardContent, CardHeader, Container, Grid, List, Stack, TextField } from '@mui/material'; +import AddIcon from '@mui/icons-material/Add'; +// eslint-disable-next-line no-unused-vars +import { Dispatch, SetStateAction, useEffect, useState } from 'react'; // eslint disabled because it doesn't recognise type imports that ARE used in JSDoc comments +// @TODO CSSMODULES - outside directory +import styles from '../../HousingLottery.module.css'; + +/** + * Renders a list of selection boxes to choosing preferred halls + * + * @param {Object} props The React component props + * @param {boolean} props.disabled boolean to disable the interactive elements of this list item + */ +const StudentApplicants = ({ + disabled +}) => { + const [firstName, setFirstName] = useState(''); + const [lastName, setLastName] = useState(''); + const [email, setEmail] = useState(''); + const [emailError, setEmailError] = useState(false); + + const handleEmailChange = (e) => { + const emailValue = e.target.value; + setEmail(emailValue); + setEmailError(!emailValue.endsWith('@gordon.edu')); + }; + + + return ( + + + + + + setFirstName(e.target.value)} + value={firstName} + fullWidth + required + className={styles.applicants_name} + helperText={'*Required'} + /> + setLastName(e.target.value)} + value={lastName} + fullWidth + required + className={styles.applicants_name} + helperText={'*Required'} + /> + + + + + + + + + ); +}; + +export default StudentApplicants; From b1166829bfbb20ffe96b5dfec3a9e49fd1116661 Mon Sep 17 00:00:00 2001 From: Zhijie Wang Date: Mon, 27 Nov 2023 15:48:39 -0500 Subject: [PATCH 047/112] All Required Remove Files --- .../components/Agreements/index.jsx | 158 ------------------ .../components/ApplicantListItem/index.jsx | 132 --------------- .../components/ApplicantList/index.jsx | 98 ----------- src/views/HousingLottery/index.jsx | 6 +- 4 files changed, 1 insertion(+), 393 deletions(-) delete mode 100644 src/views/HousingLottery/components/StudentApplication/components/Agreements/index.jsx delete mode 100644 src/views/HousingLottery/components/StudentApplication/components/ApplicantList/components/ApplicantListItem/index.jsx delete mode 100644 src/views/HousingLottery/components/StudentApplication/components/ApplicantList/index.jsx diff --git a/src/views/HousingLottery/components/StudentApplication/components/Agreements/index.jsx b/src/views/HousingLottery/components/StudentApplication/components/Agreements/index.jsx deleted file mode 100644 index 905e4f6ae0..0000000000 --- a/src/views/HousingLottery/components/StudentApplication/components/Agreements/index.jsx +++ /dev/null @@ -1,158 +0,0 @@ -import { - Card, - CardContent, - CardHeader, - Checkbox, - Divider, - FormControl, - FormControlLabel, - FormGroup, - FormHelperText, - FormLabel, -} from '@mui/material/'; -import { Fragment, useEffect, useState } from 'react'; -import housing from 'services/housing'; -// @TODO CSSMODULES - outside directory -import styles from '../../../../HousingLottery.module.css'; - - -/** - * Renders a card displaying the apartment application instructions - * - * @param {Object} props The React component props - * @param {boolean | string} props.deleting Status of delete operation - * @param {Function} props.onChange Callback for change of the checkbox state - * @returns {JSX.Element} JSX Element for the instructions card - */ -const Agreements = ({ deleting, onChange }) => { - const [checkboxes, setCheckboxes] = useState([]); - - const loadAgreements = async () => { - const currentYear = new Date().getFullYear(); - const selectionDate = await housing.getApartmentSelectionDate(); - - const newCheckboxes = [ - { - checked: false, - label: 'Each individual on the application has agreed to be on the application', - }, - { - checked: false, - label: - 'We understand that if someone on this application has not agreed to be on the application, our application will be disqualified', - }, - { - checked: false, - label: 'Each individual on this application appears ONLY on this application', - }, - { - checked: false, - label: - "We understand that if an individual on this application also appears on another group's application, our application could be disqualified", - }, - { - checked: false, - label: `Any individual on this application who has been on disciplinary probation at any point during the ${ - currentYear - 1 - }-${currentYear} academic year has been approved to apply by the Dean of Student Life or Assistant Dean of Student Life`, - }, - { - checked: false, - label: `Each individual on this application intends to register as a full-time student by ${selectionDate}`, - }, - { - checked: false, - label: `We understand that if any member of our application fails to register as a full-time student by ${selectionDate}, our application could be disqualified`, - }, - { - checked: false, - label: - 'We have read and understand all of the information and guidelines listed in the Instructions section', - }, - { - checked: false, - label: - 'We certify that all information provided on this application is accurate, to the best of our knowledge', - }, - { - checked: false, - label: - 'We agree to host other students in our apartment during the winter break recess, in accordance with the policy outlined in the student handbook', - }, - ]; - - setCheckboxes(newCheckboxes); - }; - - useEffect(() => loadAgreements(), []); - - useEffect(() => deleting === 'success' && loadAgreements(), [deleting]); - - const handleChange = (event, index) => { - setCheckboxes((prevCheckboxes) => { - let newCheckboxes = prevCheckboxes.map((prevCheckbox, j) => - j === index ? { ...prevCheckbox, checked: event.target.checked } : prevCheckbox, - ); - onChange(newCheckboxes.every((checkbox) => checkbox.checked)); - return newCheckboxes; - }); - }; - - const AgreementChecklistItem = ({ checked, index, label, onChange }) => ( - - onChange(event, index)} - name={'agreement-' + 1} - /> - } - label={label} - key={index} - /> - - - ); - - const error = checkboxes.some((checkbox) => !checkbox.checked); - - return ( - - - - - {error && ( - - Use the checkboxes next to each statement to indicate your group's understanding - and/or affirmative answer. Failure to complete this section will result in the - disqualification of the application. - - )} - - - {checkboxes.map((checkbox, index) => ( - handleChange(event, index)} - /> - ))} - - - You must read and complete this section before you will be allowed to submit this - application - - - - - ); -}; - -export default Agreements; diff --git a/src/views/HousingLottery/components/StudentApplication/components/ApplicantList/components/ApplicantListItem/index.jsx b/src/views/HousingLottery/components/StudentApplication/components/ApplicantList/components/ApplicantListItem/index.jsx deleted file mode 100644 index f243e0a45d..0000000000 --- a/src/views/HousingLottery/components/StudentApplication/components/ApplicantList/components/ApplicantListItem/index.jsx +++ /dev/null @@ -1,132 +0,0 @@ -import { - Avatar, - Divider, - Grid, - IconButton, - ListItem, - ListItemAvatar, - ListItemSecondaryAction, - ListItemText, -} from '@mui/material'; -import ClearIcon from '@mui/icons-material/Clear'; -import PersonIcon from '@mui/icons-material/Person'; -import StarIcon from '@mui/icons-material/Star'; -import StarBorderIcon from '@mui/icons-material/StarBorder'; -import { Fragment, useEffect, useState } from 'react'; -import { Link } from 'react-router-dom'; -import { Class } from 'services/peopleSearch'; -import user from 'services/user'; -import styles from '../../../../../../HousingLottery.module.css'; - -/** - * @typedef { import('services/user').StudentProfileInfo } StudentProfileInfo - */ - -/** - * Renders the list item for the apartment applicant list - * - * @param {Object} props The React component props - * @param {boolean} props.disabled boolean to disable the interactive elements of this list item - * @param {StudentProfileInfo} props.profile The StudentProfileInfo of the applicant - * @param {boolean} props.isApplicationEditor boolean indicating whether this list item corresponds to the application editor - * @param {Function} props.onChangeEditor Callback for change editor button - * @param {Function} props.onApplicantRemove Callback for remove applicant button - * @returns {JSX.Element} JSX Element for the applicant list item - */ -const ApplicantListItem = ({ - disabled, - profile, - isApplicationEditor, - onChangeEditor, - onApplicantRemove, -}) => { - const [avatar, setAvatar] = useState(null); - const [hasNickName, setHasNickname] = useState(false); - - useEffect(() => { - loadAvatar(profile); - setHasNickname(profile.FirstName !== profile.NickName && profile.NickName !== ''); - }, [profile]); - - /** - * Creates the Avatar image of the given user - * - * @async - * @function loadAvatar - * @param {StudentProfileInfo} profile The StudentProfileInfo object for the student represented by this list item - */ - const loadAvatar = async (profile) => { - try { - const { def: defaultImage, pref: preferredImage } = await user.getImage(profile.AD_Username); - setAvatar(preferredImage || defaultImage); - } catch { - setAvatar( - - - , - ); - } - }; - - const displayName = hasNickName - ? `${profile.FirstName} ${profile.LastName} (${profile.NickName})` - : `${profile.FirstName} ${profile.LastName}`; - - return ( - - - - {avatar ? ( - - ) : ( - - - - )} - - - - - - - - - - profile && onChangeEditor?.(profile)} - size="large" - > - {isApplicationEditor ? : } - - - - profile?.AD_Username && onApplicantRemove?.(profile.AD_Username)} - size="large" - > - - - - - - - - - ); -}; - -export default ApplicantListItem; diff --git a/src/views/HousingLottery/components/StudentApplication/components/ApplicantList/index.jsx b/src/views/HousingLottery/components/StudentApplication/components/ApplicantList/index.jsx deleted file mode 100644 index be09ec1479..0000000000 --- a/src/views/HousingLottery/components/StudentApplication/components/ApplicantList/index.jsx +++ /dev/null @@ -1,98 +0,0 @@ -import { - Card, - CardContent, - CardHeader, - Collapse, - Divider, - Grid, - List, - ListItem, - ListItemIcon, - ListItemText, -} from '@mui/material'; -import AddIcon from '@mui/icons-material/Add'; -import ClearIcon from '@mui/icons-material/Clear'; -import ExpandLess from '@mui/icons-material/ExpandLess'; -import ExpandMore from '@mui/icons-material/ExpandMore'; -import HelpIcon from '@mui/icons-material/Help'; -import StarBorder from '@mui/icons-material/StarBorder'; -import GordonQuickSearch from 'components/Header/components/QuickSearch'; -import { useState } from 'react'; -// @TODO CSSMODULES - outside directory -import styles from '../../../../HousingLottery.module.css'; -import ApplicantListItem from './components/ApplicantListItem/index.jsx'; - - -/** - * @typedef { import('services/housing').ApartmentApplicant } ApartmentApplicant - * @typedef { import('services/housing').ApplicationDetails } ApplicationDetails - * @typedef { import('services/user').StudentProfileInfo } StudentProfileInfo - */ - -/** - * Renders the list of applicants, displayed by name, username, and class standing. - * - * @param {Object} props The React component props - * @param {boolean} props.disabled boolean to disable the interactive elements of this list - * @param {StudentProfileInfo} props.editorProfile The StudentProfileInfo of the application editor - * @param {ApartmentApplicant[]} props.applicants Array of applicant info - * @param {Function} props.onSearchSubmit Callback for apartment people search submission - * @param {Function} props.onChangeEditor Callback for change editor button - * @param {Function} props.onApplicantRemove Callback for remove applicant button - * @returns {JSX.Element} JSX Element for the applicant list - */ -const ApplicantList = ({ - disabled, - editorProfile, - applicants, - onSearchSubmit, - onChangeEditor, - onApplicantRemove, -}) => { - const [showHelp, setShowHelp] = useState(false); - return ( - - - - - - - {applicants?.length > 0 ? ( - applicants.map((applicant) => ( - - )) - ) : ( - - - - )} - - - - - disabled || onSearchSubmit(selectedUsername)} - /> - - - - - - ); -}; - -export default ApplicantList; diff --git a/src/views/HousingLottery/index.jsx b/src/views/HousingLottery/index.jsx index c673fd93dd..bedc11ab9d 100644 --- a/src/views/HousingLottery/index.jsx +++ b/src/views/HousingLottery/index.jsx @@ -36,10 +36,6 @@ const HousingLottery = () => { }, [morningOrNight, loudOrQuiet]); - const handleChange = (event) => { - setMessage(event.target.value); - }; - const handleMorningOrNightChange = (event) => { setMorningOrNight(event.target.value); }; @@ -49,7 +45,7 @@ const HousingLottery = () => { }; const handleClick = async () => { - // You can access message, morningOrNight, and loudOrQuiet to submit to your housing service + // You can access morningOrNight, and loudOrQuiet to submit to your housing service console.log({ morningOrNight, loudOrQuiet}); await housingService.addRoommate({morningOrNight, loudOrQuiet}); }; From ea6146ea6462391b515b51809778760d89c77607 Mon Sep 17 00:00:00 2001 From: Zhijie Wang Date: Mon, 27 Nov 2023 16:16:25 -0500 Subject: [PATCH 048/112] matching the structure for senior-project --- .../components/PreferenceBox/index.jsx | 124 ++++++++++++------ src/views/HousingLottery/index.jsx | 77 +---------- 2 files changed, 89 insertions(+), 112 deletions(-) diff --git a/src/views/HousingLottery/components/PreferenceBox/index.jsx b/src/views/HousingLottery/components/PreferenceBox/index.jsx index 04b96168b5..eeafab8cef 100644 --- a/src/views/HousingLottery/components/PreferenceBox/index.jsx +++ b/src/views/HousingLottery/components/PreferenceBox/index.jsx @@ -1,57 +1,103 @@ -import React, { useEffect, useState } from 'react'; +import { useEffect, useState } from 'react'; import { - Card, - CardContent, - CardHeader, - Grid, Table, TableBody, TableContainer, Typography, FormControl, - RadioGroup, FormControlLabel, + Input, + Button, + RadioGroup, + Card, + CardContent, + CardHeader, Radio, + Grid, } from '@mui/material'; +import housingService from 'services/housing'; import housing from 'services/housing'; -import styles from '../../../../HousingLottery.module.css'; +import styles from '../../HousingLottery.module.css'; + +const Preference = () => { + const [message, setMessage] = useState(''); + const [morningOrNight, setMorningOrNight] = useState(''); + const [loudOrQuiet, setLoudOrQuiet] = useState(''); + + + useEffect(() => { + const storedPreferences = localStorage.getItem('userPreferences'); + if (storedPreferences) { + const { morningOrNight, loudOrQuiet } = storedPreferences; + setMorningOrNight(morningOrNight || ''); + setLoudOrQuiet(loudOrQuiet || ''); + } + }, []); + + useEffect(() => { + // Save preferences to local storage + const storedPreferences = JSON.stringify({ morningOrNight, loudOrQuiet }); + localStorage.setItem('userPreferences', storedPreferences); + }, [morningOrNight, loudOrQuiet]); + -function SurveyQuestionBox() { - const [selectedOption, setSelectedOption] = useState(''); // Store the selected option + const handleMorningOrNightChange = (event) => { + setMorningOrNight(event.target.value); + }; - // Handle the change of the selected option - const handleOptionChange = (event) => { - setSelectedOption(event.target.value); + const handleLoudOrQuietChange = (event) => { + setLoudOrQuiet(event.target.value); }; - // Your survey question text can go here - const questionText = 'Are you a night owl or a morning bird?'; + const handleClick = async () => { + // You can access morningOrNight, and loudOrQuiet to submit to your housing service + console.log({ morningOrNight, loudOrQuiet}); + await housingService.addRoommate({morningOrNight, loudOrQuiet}); + }; return ( - - - - - - } label="Night Owl" /> - } label="Morning Bird" /> - - - } label="Quiet" /> - } label="Loud" /> - - - - + + + + + +
+ + + } label="Night Owl" /> + } label="Morning Bird" /> + +
+ +
+ + + } label="Quiet" /> + } label="Loud" /> + +
+
+ + + + + +
+
+
); } + +export default Preference; \ No newline at end of file diff --git a/src/views/HousingLottery/index.jsx b/src/views/HousingLottery/index.jsx index bedc11ab9d..8220c4b1c7 100644 --- a/src/views/HousingLottery/index.jsx +++ b/src/views/HousingLottery/index.jsx @@ -13,84 +13,15 @@ import { import housingService from 'services/housing'; import styles from './HousingLottery.module.css'; import PreferredHall from './studentView/PreferredHall'; +import Preference from './components/PreferenceBox'; const HousingLottery = () => { - const [message, setMessage] = useState(''); - const [morningOrNight, setMorningOrNight] = useState(''); - const [loudOrQuiet, setLoudOrQuiet] = useState(''); - - useEffect(() => { - const storedPreferences = localStorage.getItem('userPreferences'); - if (storedPreferences) { - const { morningOrNight, loudOrQuiet } = storedPreferences; - setMorningOrNight(morningOrNight || ''); - setLoudOrQuiet(loudOrQuiet || ''); - } - }, []); - - useEffect(() => { - // Save preferences to local storage - const storedPreferences = JSON.stringify({ morningOrNight, loudOrQuiet }); - localStorage.setItem('userPreferences', storedPreferences); - }, [morningOrNight, loudOrQuiet]); - - - const handleMorningOrNightChange = (event) => { - setMorningOrNight(event.target.value); - }; - - const handleLoudOrQuietChange = (event) => { - setLoudOrQuiet(event.target.value); - }; - - const handleClick = async () => { - // You can access morningOrNight, and loudOrQuiet to submit to your housing service - console.log({ morningOrNight, loudOrQuiet}); - await housingService.addRoommate({morningOrNight, loudOrQuiet}); - }; return ( - - - - - -
- - - } label="Night Owl" /> - } label="Morning Bird" /> - -
- -
- - - } label="Quiet" /> - } label="Loud" /> - -
-
- - - - - -
-
+ + + ); }; From 798b607c82175d962203e184e7a46374bb20b0a6 Mon Sep 17 00:00:00 2001 From: Eric Date: Tue, 28 Nov 2023 01:44:38 -0500 Subject: [PATCH 049/112] Added applicantFields as number of max roommate --- .../HousingLottery/HousingLottery.module.scss | 9 +- .../ApplicantFields/index.jsx | 53 +++++++++ .../studentView/StudentApplicants/index.jsx | 104 +++++++----------- 3 files changed, 102 insertions(+), 64 deletions(-) create mode 100644 src/views/HousingLottery/studentView/StudentApplicants/ApplicantFields/index.jsx diff --git a/src/views/HousingLottery/HousingLottery.module.scss b/src/views/HousingLottery/HousingLottery.module.scss index 0500421224..5f2129566c 100644 --- a/src/views/HousingLottery/HousingLottery.module.scss +++ b/src/views/HousingLottery/HousingLottery.module.scss @@ -37,14 +37,19 @@ } } -.applicants_name { +.applicant_name { display: flexbox; width: 10em; margin-left: 1em; } -.applicants_email { +.applicant_email { display: flexbox; width: 24em; margin-left: 1em; +} + +.applicant_field { + padding-top: 1em; + padding-bottom: 1em; } \ No newline at end of file diff --git a/src/views/HousingLottery/studentView/StudentApplicants/ApplicantFields/index.jsx b/src/views/HousingLottery/studentView/StudentApplicants/ApplicantFields/index.jsx new file mode 100644 index 0000000000..6000195e7b --- /dev/null +++ b/src/views/HousingLottery/studentView/StudentApplicants/ApplicantFields/index.jsx @@ -0,0 +1,53 @@ +import { TextField } from '@mui/material'; +import styles from '../../../HousingLottery.module.css'; + +// Applicant input fields component +const ApplicantFields = ({ applicant, onApplicantChange, index }) => { + const handleFieldChange = (field, value) => { + onApplicantChange(index, { ...applicant, [field]: value }); + }; + + return ( + <> + handleFieldChange('firstName', e.target.value)} + value={applicant.firstName} + fullWidth + required + className={styles.applicant_name} + helperText={'*Required'} + /> + handleFieldChange('lastName', e.target.value)} + value={applicant.lastName} + fullWidth + required + className={styles.applicant_name} + helperText={'*Required'} + /> + handleFieldChange('email', e.target.value)} + value={applicant.email} + required + error={!applicant.email.endsWith('@gordon.edu')} + helperText={!applicant.email.endsWith('@gordon.edu') ? 'Not a Valid Gordon Email' : '*Required'} + className={styles.applicant_email} + /> + + ); +}; + +export default ApplicantFields; + diff --git a/src/views/HousingLottery/studentView/StudentApplicants/index.jsx b/src/views/HousingLottery/studentView/StudentApplicants/index.jsx index 1171bea23e..b679bfae76 100644 --- a/src/views/HousingLottery/studentView/StudentApplicants/index.jsx +++ b/src/views/HousingLottery/studentView/StudentApplicants/index.jsx @@ -1,82 +1,62 @@ -import { Button, Card, CardContent, CardHeader, Container, Grid, List, Stack, TextField } from '@mui/material'; +import { Button, Card, CardContent, CardHeader, Divider, Grid, TextField } from '@mui/material'; import AddIcon from '@mui/icons-material/Add'; -// eslint-disable-next-line no-unused-vars -import { Dispatch, SetStateAction, useEffect, useState } from 'react'; // eslint disabled because it doesn't recognise type imports that ARE used in JSDoc comments -// @TODO CSSMODULES - outside directory +import { useState } from 'react'; +import ApplicantFields from './ApplicantFields'; import styles from '../../HousingLottery.module.css'; -/** - * Renders a list of selection boxes to choosing preferred halls - * - * @param {Object} props The React component props - * @param {boolean} props.disabled boolean to disable the interactive elements of this list item - */ -const StudentApplicants = ({ - disabled -}) => { - const [firstName, setFirstName] = useState(''); - const [lastName, setLastName] = useState(''); - const [email, setEmail] = useState(''); - const [emailError, setEmailError] = useState(false); - const handleEmailChange = (e) => { - const emailValue = e.target.value; - setEmail(emailValue); - setEmailError(!emailValue.endsWith('@gordon.edu')); +const StudentApplicants = () => { + const [applicants, setApplicants] = useState([{ firstName: '', lastName: '', email: '' }]); + + const handleApplicantChange = (index, updatedApplicant) => { + const newApplicants = [...applicants]; + newApplicants[index] = updatedApplicant; + setApplicants(newApplicants); + }; + + const addApplicant = () => { + setApplicants([...applicants, { firstName: '', lastName: '', email: '' }]); }; - return ( - - setFirstName(e.target.value)} - value={firstName} - fullWidth - required - className={styles.applicants_name} - helperText={'*Required'} - /> - setLastName(e.target.value)} - value={lastName} - fullWidth - required - className={styles.applicants_name} - helperText={'*Required'} - /> - - + {applicants.map((applicant, index) => ( + +
+ +
+ +
+ +
+ +
+ +
+
+ ))} From 68c8cd0601602cdbc470b8f282f78463f145355d Mon Sep 17 00:00:00 2001 From: Eric Date: Tue, 28 Nov 2023 01:45:06 -0500 Subject: [PATCH 050/112] Added another ApplicantField --- .../studentView/StudentApplicants/index.jsx | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/views/HousingLottery/studentView/StudentApplicants/index.jsx b/src/views/HousingLottery/studentView/StudentApplicants/index.jsx index b679bfae76..2e8ef9d342 100644 --- a/src/views/HousingLottery/studentView/StudentApplicants/index.jsx +++ b/src/views/HousingLottery/studentView/StudentApplicants/index.jsx @@ -24,7 +24,15 @@ const StudentApplicants = () => { {applicants.map((applicant, index) => ( - + +
+ +
+
Date: Tue, 28 Nov 2023 02:26:11 -0500 Subject: [PATCH 051/112] Email is saved as array and added submit button --- .../studentView/StudentApplicants/index.jsx | 29 +++++++++++++++++-- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/src/views/HousingLottery/studentView/StudentApplicants/index.jsx b/src/views/HousingLottery/studentView/StudentApplicants/index.jsx index 2e8ef9d342..335f939f35 100644 --- a/src/views/HousingLottery/studentView/StudentApplicants/index.jsx +++ b/src/views/HousingLottery/studentView/StudentApplicants/index.jsx @@ -7,15 +7,25 @@ import styles from '../../HousingLottery.module.css'; const StudentApplicants = () => { const [applicants, setApplicants] = useState([{ firstName: '', lastName: '', email: '' }]); + const [emails, setEmails] = useState([]); const handleApplicantChange = (index, updatedApplicant) => { const newApplicants = [...applicants]; newApplicants[index] = updatedApplicant; setApplicants(newApplicants); + + const newEmails = [...emails]; + newEmails[index] = updatedApplicant.email; + setApplicants(newEmails); }; const addApplicant = () => { setApplicants([...applicants, { firstName: '', lastName: '', email: '' }]); + setEmails([...emails, '']); + }; + + const handleSubmit = () => { + console.log(emails); }; return ( @@ -58,15 +68,28 @@ const StudentApplicants = () => {
))} - - */} +
From f22b046952db4f967f5b84afa0de4b86acb5d588 Mon Sep 17 00:00:00 2001 From: Zhijie Wang Date: Tue, 28 Nov 2023 17:16:07 -0500 Subject: [PATCH 052/112] create button function only use by preference box --- src/views/HousingLottery/HousingLottery.module.scss | 2 +- src/views/HousingLottery/components/PreferenceBox/index.jsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/views/HousingLottery/HousingLottery.module.scss b/src/views/HousingLottery/HousingLottery.module.scss index af4a5afdf3..0c8729a732 100644 --- a/src/views/HousingLottery/HousingLottery.module.scss +++ b/src/views/HousingLottery/HousingLottery.module.scss @@ -1,4 +1,4 @@ -.submit_button { +.submit_preference_button { position: "absolute"; margin: "auto"; top: 15px; diff --git a/src/views/HousingLottery/components/PreferenceBox/index.jsx b/src/views/HousingLottery/components/PreferenceBox/index.jsx index eeafab8cef..6baa80f5fc 100644 --- a/src/views/HousingLottery/components/PreferenceBox/index.jsx +++ b/src/views/HousingLottery/components/PreferenceBox/index.jsx @@ -89,7 +89,7 @@ const Preference = () => {
- From 9ef990dff776cf39d4ab6d832d23d4ed4c4945db Mon Sep 17 00:00:00 2001 From: Zhijie Wang Date: Tue, 28 Nov 2023 17:24:49 -0500 Subject: [PATCH 053/112] push for file structure consistent --- src/views/HousingLottery/index.jsx | 2 +- .../{components => studentView}/PreferenceBox/index.jsx | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename src/views/HousingLottery/{components => studentView}/PreferenceBox/index.jsx (100%) diff --git a/src/views/HousingLottery/index.jsx b/src/views/HousingLottery/index.jsx index 8220c4b1c7..8c42391d87 100644 --- a/src/views/HousingLottery/index.jsx +++ b/src/views/HousingLottery/index.jsx @@ -13,7 +13,7 @@ import { import housingService from 'services/housing'; import styles from './HousingLottery.module.css'; import PreferredHall from './studentView/PreferredHall'; -import Preference from './components/PreferenceBox'; +import Preference from './studentView/PreferenceBox'; const HousingLottery = () => { diff --git a/src/views/HousingLottery/components/PreferenceBox/index.jsx b/src/views/HousingLottery/studentView/PreferenceBox/index.jsx similarity index 100% rename from src/views/HousingLottery/components/PreferenceBox/index.jsx rename to src/views/HousingLottery/studentView/PreferenceBox/index.jsx From 1b1818bebbe09d205d44b12acbfe7fcdb2a9e8ac Mon Sep 17 00:00:00 2001 From: Eric Date: Wed, 29 Nov 2023 03:02:07 -0500 Subject: [PATCH 054/112] Fixed bugs and made 4 separate input fields --- .../ApplicantFields/index.jsx | 1 - .../studentView/StudentApplicants/index.jsx | 59 ++++++------------- 2 files changed, 18 insertions(+), 42 deletions(-) diff --git a/src/views/HousingLottery/studentView/StudentApplicants/ApplicantFields/index.jsx b/src/views/HousingLottery/studentView/StudentApplicants/ApplicantFields/index.jsx index 6000195e7b..c3eca5e57b 100644 --- a/src/views/HousingLottery/studentView/StudentApplicants/ApplicantFields/index.jsx +++ b/src/views/HousingLottery/studentView/StudentApplicants/ApplicantFields/index.jsx @@ -1,7 +1,6 @@ import { TextField } from '@mui/material'; import styles from '../../../HousingLottery.module.css'; -// Applicant input fields component const ApplicantFields = ({ applicant, onApplicantChange, index }) => { const handleFieldChange = (field, value) => { onApplicantChange(index, { ...applicant, [field]: value }); diff --git a/src/views/HousingLottery/studentView/StudentApplicants/index.jsx b/src/views/HousingLottery/studentView/StudentApplicants/index.jsx index 335f939f35..1d804d183c 100644 --- a/src/views/HousingLottery/studentView/StudentApplicants/index.jsx +++ b/src/views/HousingLottery/studentView/StudentApplicants/index.jsx @@ -1,13 +1,18 @@ import { Button, Card, CardContent, CardHeader, Divider, Grid, TextField } from '@mui/material'; -import AddIcon from '@mui/icons-material/Add'; import { useState } from 'react'; import ApplicantFields from './ApplicantFields'; import styles from '../../HousingLottery.module.css'; - const StudentApplicants = () => { - const [applicants, setApplicants] = useState([{ firstName: '', lastName: '', email: '' }]); - const [emails, setEmails] = useState([]); + const initialApplicants = [ + { firstName: '', lastName: '', email: '' }, + { firstName: '', lastName: '', email: '' }, + { firstName: '', lastName: '', email: '' }, + { firstName: '', lastName: '', email: '' } + ]; + + const [applicants, setApplicants] = useState(initialApplicants); + const [emails, setEmails] = useState(initialApplicants.map(applicant => applicant.email)); const handleApplicantChange = (index, updatedApplicant) => { const newApplicants = [...applicants]; @@ -16,13 +21,14 @@ const StudentApplicants = () => { const newEmails = [...emails]; newEmails[index] = updatedApplicant.email; - setApplicants(newEmails); + setEmails(newEmails); }; - const addApplicant = () => { - setApplicants([...applicants, { firstName: '', lastName: '', email: '' }]); - setEmails([...emails, '']); - }; + // We will be having set number of applicants for the MVP and for now. + // const addApplicant = () => { + // setApplicants([...applicants, { firstName: '', lastName: '', email: '' }]); + // setEmails([...emails, '']); + // }; const handleSubmit = () => { console.log(emails); @@ -34,16 +40,8 @@ const StudentApplicants = () => { {applicants.map((applicant, index) => ( - -
- -
- -
+ +
{ />
-
- -
- -
- -
))} - + {/* */} @@ -98,6 +100,6 @@ const Preference = () => { ); -} +}; -export default Preference; \ No newline at end of file +export default Preference; diff --git a/src/views/HousingLottery/studentView/PreferredHall/index.jsx b/src/views/HousingLottery/studentView/PreferredHall/index.jsx index d1523c77fe..5c52960f50 100644 --- a/src/views/HousingLottery/studentView/PreferredHall/index.jsx +++ b/src/views/HousingLottery/studentView/PreferredHall/index.jsx @@ -5,7 +5,7 @@ import housingService from 'services/housing'; import styles from '../../HousingLottery.module.css'; import GordonSnackbar from 'components/Snackbar'; -const PreferredHallsCard = () => { +const PreferredHallsCard = ({ setPreferredHallResult }) => { const [hallList, setHallList] = useState([]); const [preferredHallList, setPreferredHallList] = useState(['', '', '', '', '', '']); const [snackbar, setSnackbar] = useState({ message: '', severity: null, open: false }); @@ -19,12 +19,9 @@ const PreferredHallsCard = () => { let newList = preferredHallList; newList[rank - 1] = hall; setPreferredHallList(newList); + setPreferredHallResult(newList); } - const handleClick = async () => { - await housingService.addHall(preferredHallList); - }; - return ( @@ -112,16 +109,6 @@ const PreferredHallsCard = () => { - - - diff --git a/src/views/HousingLottery/studentView/StudentApplicants/index.jsx b/src/views/HousingLottery/studentView/StudentApplicants/index.jsx index d3eb3104b9..56aa30968d 100644 --- a/src/views/HousingLottery/studentView/StudentApplicants/index.jsx +++ b/src/views/HousingLottery/studentView/StudentApplicants/index.jsx @@ -2,17 +2,18 @@ import { Button, Card, CardContent, CardHeader, Divider, Grid, TextField } from import { useState } from 'react'; import ApplicantFields from './ApplicantFields'; import styles from '../../HousingLottery.module.css'; +import housingService from 'services/housing'; -const StudentApplicants = () => { +const StudentApplicants = ({ setStudentApplicantResult }) => { const initialApplicants = [ { firstName: '', lastName: '', email: '' }, { firstName: '', lastName: '', email: '' }, { firstName: '', lastName: '', email: '' }, - { firstName: '', lastName: '', email: '' } + { firstName: '', lastName: '', email: '' }, ]; const [applicants, setApplicants] = useState(initialApplicants); - const [emails, setEmails] = useState(initialApplicants.map(applicant => applicant.email)); + const [emails, setEmails] = useState(initialApplicants.map((applicant) => applicant.email)); const handleApplicantChange = (index, updatedApplicant) => { const newApplicants = [...applicants]; @@ -22,10 +23,7 @@ const StudentApplicants = () => { const newEmails = [...emails]; newEmails[index] = updatedApplicant.email; setEmails(newEmails); - }; - - const handleSubmit = () => { - console.log(emails); + setStudentApplicantResult(newEmails); }; return ( @@ -42,18 +40,9 @@ const StudentApplicants = () => { index={index} />
- +
))} - - -
diff --git a/src/views/HousingLottery/studentView/index.jsx b/src/views/HousingLottery/studentView/index.jsx new file mode 100644 index 0000000000..5efee2f1cc --- /dev/null +++ b/src/views/HousingLottery/studentView/index.jsx @@ -0,0 +1,36 @@ +import { useState } from 'react'; +import { Button, Grid } from '@mui/material'; +import PreferredHall from './PreferredHall'; +import StudentApplicants from './StudentApplicants/index.jsx'; +import Preference from './PreferenceBox'; +import housingService from 'services/housing'; +import styles from '../HousingLottery.module.css'; + +const StudentView = () => { + const [preferredHallResult, setPreferredHallResult] = useState([]); + const [studentApplicantResult, setStudentApplicantResult] = useState([]); + + const handleClick = async () => { + await housingService.addHall(preferredHallResult); + await housingService.addApplicant(studentApplicantResult); + }; + + return ( + + + + + + + + + + + + + ); +}; + +export default StudentView; From 504993a37843b6c03149fd62f6f0fc26589c64cf Mon Sep 17 00:00:00 2001 From: Zhijie Wang Date: Sat, 2 Dec 2023 13:44:27 -0500 Subject: [PATCH 058/112] store preference as list --- .../studentView/PreferenceBox/index.jsx | 58 +++++++++++-------- 1 file changed, 35 insertions(+), 23 deletions(-) diff --git a/src/views/HousingLottery/studentView/PreferenceBox/index.jsx b/src/views/HousingLottery/studentView/PreferenceBox/index.jsx index 6baa80f5fc..7a25140f88 100644 --- a/src/views/HousingLottery/studentView/PreferenceBox/index.jsx +++ b/src/views/HousingLottery/studentView/PreferenceBox/index.jsx @@ -20,43 +20,55 @@ import housing from 'services/housing'; import styles from '../../HousingLottery.module.css'; const Preference = () => { - const [message, setMessage] = useState(''); - const [morningOrNight, setMorningOrNight] = useState(''); - const [loudOrQuiet, setLoudOrQuiet] = useState(''); + const [preferences, setPreferences] = useState([]); // Store preferences as an array + const [morningOrNight, setMorningOrNight] = useState(''); // Store the selected morning or night + const [loudOrQuiet, setLoudOrQuiet] = useState(''); // Store the selected loud or quiet - - useEffect(() => { - const storedPreferences = localStorage.getItem('userPreferences'); - if (storedPreferences) { - const { morningOrNight, loudOrQuiet } = storedPreferences; - setMorningOrNight(morningOrNight || ''); - setLoudOrQuiet(loudOrQuiet || ''); - } - }, []); + useEffect(() => { + const storedPreferences = localStorage.getItem('userPreferences'); + if (storedPreferences) { + const { morningOrNight, loudOrQuiet } = JSON.parse(storedPreferences); + setMorningOrNight(morningOrNight || ''); + setLoudOrQuiet(loudOrQuiet || ''); + } + }, []); - useEffect(() => { - // Save preferences to local storage - const storedPreferences = JSON.stringify({ morningOrNight, loudOrQuiet }); - localStorage.setItem('userPreferences', storedPreferences); - }, [morningOrNight, loudOrQuiet]); - + useEffect(() => { + // Save preferences to local storage + const storedPreferences = JSON.stringify({ morningOrNight, loudOrQuiet }); + localStorage.setItem('userPreferences', storedPreferences); + }, [morningOrNight, loudOrQuiet]); const handleMorningOrNightChange = (event) => { setMorningOrNight(event.target.value); + updatePreferences('morningOrNight', event.target.value); }; const handleLoudOrQuietChange = (event) => { setLoudOrQuiet(event.target.value); + updatePreferences('loudOrQuiet', event.target.value); + }; + + const updatePreferences = (type, value) => { + if (preferences.includes(type)) { + // If the preference type is already in the list, remove it + setPreferences((prevPreferences) => + prevPreferences.filter((pref) => pref !== type) + ); + } else { + // If the preference type is not in the list, add it + setPreferences((prevPreferences) => [...prevPreferences, type]); + } }; const handleClick = async () => { - // You can access morningOrNight, and loudOrQuiet to submit to your housing service - console.log({ morningOrNight, loudOrQuiet}); - await housingService.addRoommate({morningOrNight, loudOrQuiet}); + // You can access the list of preferences and selected values + console.log({ preferences, morningOrNight, loudOrQuiet }); + await housingService.addRoommate({ morningOrNight, loudOrQuiet }); }; return ( - + @@ -100,4 +112,4 @@ const Preference = () => { ); } -export default Preference; \ No newline at end of file +export default Preference; From 7f3640fac0fa76101157b6f3e00f13fa41c4fd4b Mon Sep 17 00:00:00 2001 From: Zhijie Wang Date: Sat, 2 Dec 2023 19:54:09 -0500 Subject: [PATCH 059/112] fix preference button display --- src/views/HousingLottery/HousingLottery.module.scss | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/views/HousingLottery/HousingLottery.module.scss b/src/views/HousingLottery/HousingLottery.module.scss index 36e2fef735..d42aba569d 100644 --- a/src/views/HousingLottery/HousingLottery.module.scss +++ b/src/views/HousingLottery/HousingLottery.module.scss @@ -1,12 +1,6 @@ .submit_preference_button { - position: "absolute"; - margin: "auto"; - top: 15px; - bottom: 0; - left: 45em; - right: 20em; - height: 3em; - width: 9em; + height: 45px; + margin-left: 10px; } .add_applicant_button { From 514e28939a5646a2520ca8dc10d8f32a15b6a7a1 Mon Sep 17 00:00:00 2001 From: Eric Date: Sat, 2 Dec 2023 20:25:32 -0500 Subject: [PATCH 060/112] Fixes regarding Agreements --- src/views/HousingLottery/index.jsx | 4 + .../studentView/Agreements/index.jsx | 157 ++++++++++++++++++ 2 files changed, 161 insertions(+) create mode 100644 src/views/HousingLottery/studentView/Agreements/index.jsx diff --git a/src/views/HousingLottery/index.jsx b/src/views/HousingLottery/index.jsx index 01303544ef..60187d8155 100644 --- a/src/views/HousingLottery/index.jsx +++ b/src/views/HousingLottery/index.jsx @@ -14,6 +14,7 @@ import PreferredHallsCard from './studentView/PreferredHall'; import PreferredHall from './studentView/PreferredHall'; import StudentApplicants from './studentView/StudentApplicants/index.jsx'; import Preference from './studentView/PreferenceBox'; +import Agreements from './studentView/Agreements'; import housingService from 'services/housing'; import styles from './HousingLottery.module.css'; @@ -25,6 +26,9 @@ const HousingLottery = () => { + + + diff --git a/src/views/HousingLottery/studentView/Agreements/index.jsx b/src/views/HousingLottery/studentView/Agreements/index.jsx new file mode 100644 index 0000000000..1045f55dd3 --- /dev/null +++ b/src/views/HousingLottery/studentView/Agreements/index.jsx @@ -0,0 +1,157 @@ +import { + Card, + CardContent, + CardHeader, + Checkbox, + Divider, + FormControl, + FormControlLabel, + FormGroup, + FormHelperText, + FormLabel, +} from '@mui/material/'; +import { Fragment, useEffect, useState } from 'react'; +import housing from 'services/housing'; +// @TODO CSSMODULES - outside directory +import styles from '../../HousingLottery.module.css'; + +/** + * Renders a card displaying the apartment application instructions + * + * @param {Object} props The React component props + * @param {boolean | string} props.deleting Status of delete operation + * @param {Function} props.onChange Callback for change of the checkbox state + * @returns {JSX.Element} JSX Element for the instructions card + */ +const Agreements = ({ deleting, onChange }) => { + const [checkboxes, setCheckboxes] = useState([]); + + const loadAgreements = async () => { + const currentYear = new Date().getFullYear(); + const selectionDate = await housing.getApartmentSelectionDate(); + + const newCheckboxes = [ + { + checked: false, + label: 'Each individual on the application has agreed to be on the application', + }, + { + checked: false, + label: + 'We understand that if someone on this application has not agreed to be on the application, our application will be disqualified', + }, + { + checked: false, + label: 'Each individual on this application appears ONLY on this application', + }, + { + checked: false, + label: + "We understand that if an individual on this application also appears on another group's application, our application could be disqualified", + }, + { + checked: false, + label: `Any individual on this application who has been on disciplinary probation at any point during the ${ + currentYear - 1 + }-${currentYear} academic year has been approved to apply by the Dean of Student Life or Assistant Dean of Student Life`, + }, + { + checked: false, + label: `Each individual on this application intends to register as a full-time student by ${selectionDate}`, + }, + { + checked: false, + label: `We understand that if any member of our application fails to register as a full-time student by ${selectionDate}, our application could be disqualified`, + }, + { + checked: false, + label: + 'We have read and understand all of the information and guidelines listed in the Instructions section', + }, + { + checked: false, + label: + 'We certify that all information provided on this application is accurate, to the best of our knowledge', + }, + { + checked: false, + label: + 'We agree to host other students in our apartment during the winter break recess, in accordance with the policy outlined in the student handbook', + }, + ]; + + setCheckboxes(newCheckboxes); + }; + + useEffect(() => loadAgreements(), []); + + useEffect(() => deleting === 'success' && loadAgreements(), [deleting]); + + const handleChange = (event, index) => { + setCheckboxes((prevCheckboxes) => { + let newCheckboxes = prevCheckboxes.map((prevCheckbox, j) => + j === index ? { ...prevCheckbox, checked: event.target.checked } : prevCheckbox, + ); + onChange(newCheckboxes.every((checkbox) => checkbox.checked)); + return newCheckboxes; + }); + }; + + const AgreementChecklistItem = ({ checked, index, label, onChange }) => ( + + onChange(event, index)} + name={'agreement-' + 1} + /> + } + label={label} + key={index} + /> + + + ); + + const error = checkboxes.some((checkbox) => !checkbox.checked); + + return ( + + + + + {error && ( + + Use the checkboxes next to each statement to indicate your group's understanding + and/or affirmative answer. Failure to complete this section will result in the + disqualification of the application. + + )} + + + {checkboxes.map((checkbox, index) => ( + handleChange(event, index)} + /> + ))} + + + You must read and complete this section before you will be allowed to submit this + application + + + + + ); +}; + +export default Agreements; From c480f7b2b0db6279a5fece1cd1eed0e5273fa725 Mon Sep 17 00:00:00 2001 From: Eric Date: Sat, 2 Dec 2023 20:33:11 -0500 Subject: [PATCH 061/112] minor fixes regarding agreements --- src/views/HousingLottery/HousingLottery.module.scss | 6 +++--- .../HousingLottery/studentView/Agreements/index.jsx | 10 +++++----- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/views/HousingLottery/HousingLottery.module.scss b/src/views/HousingLottery/HousingLottery.module.scss index 4b1429ffcd..065d818dc8 100644 --- a/src/views/HousingLottery/HousingLottery.module.scss +++ b/src/views/HousingLottery/HousingLottery.module.scss @@ -81,7 +81,7 @@ strong.over_emphasized { text-decoration: underline; } -.apartment_card_header { +.housing_card_header { background-color: var(--mui-palette-primary-main); color: var(--mui-palette-primary-contrastText); @@ -114,7 +114,7 @@ strong.over_emphasized { padding-bottom: 1em; } -.apartment_instructions { +.housing_instructions { & :global(.MuiTypography-root) { padding: 0.25rem 0.75rem; } @@ -162,7 +162,7 @@ strong.over_emphasized { } } -.apartment_agreements_form_control { +.housing_agreements_form_control { text-align: left; &_label { diff --git a/src/views/HousingLottery/studentView/Agreements/index.jsx b/src/views/HousingLottery/studentView/Agreements/index.jsx index 1045f55dd3..7ba72b33ce 100644 --- a/src/views/HousingLottery/studentView/Agreements/index.jsx +++ b/src/views/HousingLottery/studentView/Agreements/index.jsx @@ -16,7 +16,7 @@ import housing from 'services/housing'; import styles from '../../HousingLottery.module.css'; /** - * Renders a card displaying the apartment application instructions + * Renders a card displaying the housing application instructions * * @param {Object} props The React component props * @param {boolean | string} props.deleting Status of delete operation @@ -100,7 +100,7 @@ const Agreements = ({ deleting, onChange }) => { const AgreementChecklistItem = ({ checked, index, label, onChange }) => ( { return ( - + - + {error && ( Use the checkboxes next to each statement to indicate your group's understanding and/or affirmative answer. Failure to complete this section will result in the From 119fbdd5fae601eb90998b9348f19b9e11696765 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CJay?= Date: Sat, 2 Dec 2023 21:31:14 -0500 Subject: [PATCH 062/112] Added instructionsCard --- .../HousingLottery/HousingLottery.module.scss | 56 ++++++- src/views/HousingLottery/index.jsx | 14 +- .../studentView/Instructions/index.jsx | 139 ++++++++++++++++++ 3 files changed, 197 insertions(+), 12 deletions(-) create mode 100644 src/views/HousingLottery/studentView/Instructions/index.jsx diff --git a/src/views/HousingLottery/HousingLottery.module.scss b/src/views/HousingLottery/HousingLottery.module.scss index 065d818dc8..1bb0480708 100644 --- a/src/views/HousingLottery/HousingLottery.module.scss +++ b/src/views/HousingLottery/HousingLottery.module.scss @@ -1,6 +1,6 @@ .submit_preference_button { - position: "absolute"; - margin: "auto"; + position: 'absolute'; + margin: 'auto'; top: 15px; bottom: 0; left: 45em; @@ -10,8 +10,8 @@ } .add_applicant_button { - position: "absolute"; - margin: "auto"; + position: 'absolute'; + margin: 'auto'; top: 15px; bottom: 0; left: 43em; @@ -43,7 +43,6 @@ margin-left: 10px; } - .applicants_card_header { background-color: var(--mui-palette-primary-main); color: var(--mui-palette-primary-contrastText); @@ -60,7 +59,6 @@ } } - //Imported from ApartmentApp.module.scss .people_search_parent { @extend %list_item; @@ -189,3 +187,49 @@ strong.over_emphasized { margin-right: 0.75rem; } } + +.apartment_card_header { + background-color: var(--mui-palette-primary-main); + color: var(--mui-palette-primary-contrastText); + + :global { + .MuiTypography-colorTextSecondary { + color: var(--mui-palette-primary-contrastText); + font-size: 1.25rem; + } + + .MuiCardHeader-subheader { + color: var(--mui-palette-primary-contrastText); + } + } +} + +.apartment_instructions { + & :global(.MuiTypography-root) { + padding: 0.25rem 0.75rem; + } + + & :global(.MuiTypography-paragraph) { + text-align: left; + } + + & :global(.MuiTableContainer-root) { + border: 1px solid var(--mui-palette-neutral-700); + border-radius: 4px; + } +} + +.apartment_agreements_form_control { + text-align: left; + + &_label { + color: var(--mui-palette-neutral-700); + } + + // (CSSMODULES - fix mui overrides - disable no-descending-specificity) + /* stylelint-disable-next-line */ + & :global(.MuiDivider-root) { + margin-top: 0.5em; + margin-bottom: 0.5em; + } +} diff --git a/src/views/HousingLottery/index.jsx b/src/views/HousingLottery/index.jsx index 60187d8155..dcf5b67e79 100644 --- a/src/views/HousingLottery/index.jsx +++ b/src/views/HousingLottery/index.jsx @@ -15,25 +15,27 @@ import PreferredHall from './studentView/PreferredHall'; import StudentApplicants from './studentView/StudentApplicants/index.jsx'; import Preference from './studentView/PreferenceBox'; import Agreements from './studentView/Agreements'; +import Instructions from './studentView/Instructions'; import housingService from 'services/housing'; import styles from './HousingLottery.module.css'; - const HousingLottery = () => { - return ( + + + - + - - + + - + ); diff --git a/src/views/HousingLottery/studentView/Instructions/index.jsx b/src/views/HousingLottery/studentView/Instructions/index.jsx new file mode 100644 index 0000000000..f89a111d7f --- /dev/null +++ b/src/views/HousingLottery/studentView/Instructions/index.jsx @@ -0,0 +1,139 @@ +import { + Grid, + Paper, + Table, + TableBody, + TableCell, + TableContainer, + TableRow, + Typography, + Accordion, + AccordionSummary, + AccordionDetails, +} from '@mui/material/'; +import { useEffect, useState } from 'react'; +import ExpandMoreIcon from '@mui/icons-material/ExpandMore'; +import housing from 'services/housing'; +// @TODO CSSMODULES - outside directory +import styles from '../../HousingLottery.module.css'; + +/** + * Renders a card displaying the apartment application instructions + * + * @returns {JSX.Element} JSX Element for the instructions card + */ +const Instructions = () => { + const [apartmentSelectionDate, setApartmentSelectionDate] = useState(); + const [thisYear, setThisYear] = useState(); + + useEffect(() => { + const loadSelectionDate = async () => + setApartmentSelectionDate(await housing.getApartmentSelectionDate()); + + loadSelectionDate(); + + setThisYear(new Date().getFullYear()); + }, []); + + const rows = [ + { description: 'Current Freshman', points: 1 }, + { description: 'Current Sophomore', points: 2 }, + { description: 'Current Junior', points: 3 }, + { description: 'Current Senior', points: 4 }, + { description: '23+ years old', points: 1 }, + { description: 'Full-time, off-campus program credit', points: 1 }, + { description: 'Academic/Chapel probation', points: -1 }, + { description: 'Possible academic suspension', points: -2 }, + { description: `${thisYear - 1}-${thisYear} Disciplinary Probation`, points: -3 }, + ]; + + return ( + + } + aria-controls="instructions-panel-content" + id="instructions-panel-header" + > + On-Campus Apartments - Information and Guidelines + + + + Apartments provide an alternative to the traditional residence hall setting and offer a + unique community experience. To be eligible to live in an apartment, students must be at + least 20 years old as of Sept. 1, {thisYear} or have junior or senior + academic standing. Students who were on disciplinary probation at any time during the{' '} + {thisYear - 1}-{thisYear} academic year must also receive approval from the Dean of + Student Life or the Assistant Dean of Student Life to be eligible to apply for an + apartment. Each applicant must be registered as a full-time student by{' '} + {apartmentSelectionDate}. + + + Each group of students desiring to live in a Tavilla or Bromley apartment or in The + Village must submit an application. Your application can include a student who is studying + abroad or not enrolled for the Spring {thisYear} semester – simply list their name + on the application. + + + Full-time, off-campus program credit: Students fulfilling academic + program requirements through student teaching or a full-time internship will qualify for + the full-time, off-campus program credit. It is the responsibility of applicants to claim + this credit on the application. + + + Applications must be for a full apartment: If applying for a six-person + apartment, there must be six people on the application who will be here for the{' '} + fall semester (four people on a + four-person application, etc.). Applications with an incorrect number of applicants will + not be considered. + + + An application is not a guarantee! + + + Due to the large number of applications typically received for apartments, not all + applications will be awarded an apartment. If you do not receive an apartment, you will + need to secure housing through the housing lottery. + + + How are apartments awarded? + + + Apartments are awarded in order of point total for each type of apartment (4-person, + 6-person, etc.). Each individual on an application will have points given/taken away using + the following scale: + + + + + + + {rows.map((row) => ( + + {row.description} + {row.points} + + ))} + +
+
+
+
+
+ + If You Are Approved... + + + You will be notified of your placement in an apartment/Village{' '} + + building + {' '} + no later than Apr. 13. Further information about specific apartment/room selection will be + communicated in that email. + +
+
+ ); +}; + +export default Instructions; From 5073727614abe1b4feeb9dcc568188aaef9b7b4e Mon Sep 17 00:00:00 2001 From: Zhijie Wang Date: Sat, 2 Dec 2023 21:44:53 -0500 Subject: [PATCH 063/112] display preference as array of size 2,to update the content of preference by checking the localStorage --- src/views/HousingLottery/studentView/PreferenceBox/index.jsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/views/HousingLottery/studentView/PreferenceBox/index.jsx b/src/views/HousingLottery/studentView/PreferenceBox/index.jsx index 7a25140f88..c96cfbe332 100644 --- a/src/views/HousingLottery/studentView/PreferenceBox/index.jsx +++ b/src/views/HousingLottery/studentView/PreferenceBox/index.jsx @@ -63,7 +63,9 @@ const Preference = () => { const handleClick = async () => { // You can access the list of preferences and selected values - console.log({ preferences, morningOrNight, loudOrQuiet }); + console.log('Preferences:', preferences); + console.log('Morning or Night:', morningOrNight); + console.log('Loud or Quiet:', loudOrQuiet); await housingService.addRoommate({ morningOrNight, loudOrQuiet }); }; From 74d98a33c444ed87b331546f936abeedd91befb0 Mon Sep 17 00:00:00 2001 From: Wenlan Ji Date: Sun, 3 Dec 2023 00:11:12 -0500 Subject: [PATCH 064/112] have applicantion id --- src/services/housing.ts | 7 ++++--- src/views/HousingLottery/studentView/index.jsx | 7 +++++-- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/services/housing.ts b/src/services/housing.ts index 91ff6d4de1..8bbe5257bc 100644 --- a/src/services/housing.ts +++ b/src/services/housing.ts @@ -165,10 +165,11 @@ const getSubmittedApartmentApplications = async (): Promise => http.put(`housing/apartment/applications/${applicationID}/submit`); -const addApplicant = (emailList: string[]) => - http.put(`housing/housing_lottery/roommate`, emailList); +const addApplicant = (applicantion_id: string, emailList: string[]) => + http.put(`housing/housing_lottery/roommate/${applicantion_id}`, emailList); -const addHall = (hallList: string[]) => http.put(`housing/housing_lottery/hall`, hallList); +const addHall = (applicantion_id: string, hallList: string[]) => + http.put(`housing/housing_lottery/hall/${applicantion_id}`, hallList); const addPreference = (morningOrNight: string, loudOrQuiet: string) => http.put(`housing/housing_lottery/preference/${morningOrNight}/${loudOrQuiet}`); diff --git a/src/views/HousingLottery/studentView/index.jsx b/src/views/HousingLottery/studentView/index.jsx index 5efee2f1cc..09d44d869b 100644 --- a/src/views/HousingLottery/studentView/index.jsx +++ b/src/views/HousingLottery/studentView/index.jsx @@ -5,14 +5,17 @@ import StudentApplicants from './StudentApplicants/index.jsx'; import Preference from './PreferenceBox'; import housingService from 'services/housing'; import styles from '../HousingLottery.module.css'; +import { nanoid } from 'nanoid'; const StudentView = () => { const [preferredHallResult, setPreferredHallResult] = useState([]); const [studentApplicantResult, setStudentApplicantResult] = useState([]); + const applicantion_id = nanoid(8); const handleClick = async () => { - await housingService.addHall(preferredHallResult); - await housingService.addApplicant(studentApplicantResult); + console.log(applicantion_id); + await housingService.addHall(applicantion_id, preferredHallResult); + await housingService.addApplicant(applicantion_id, studentApplicantResult); }; return ( From 9f2e67d0c441cc4927864e710ac6388f2969d502 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CJay?= Date: Sun, 3 Dec 2023 01:16:15 -0500 Subject: [PATCH 065/112] Changed minor things --- src/views/HousingLottery/HousingLottery.module.scss | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/views/HousingLottery/HousingLottery.module.scss b/src/views/HousingLottery/HousingLottery.module.scss index 1bb0480708..1195b16965 100644 --- a/src/views/HousingLottery/HousingLottery.module.scss +++ b/src/views/HousingLottery/HousingLottery.module.scss @@ -1,6 +1,5 @@ .submit_preference_button { - position: 'absolute'; - margin: 'auto'; + margin: auto; top: 15px; bottom: 0; left: 45em; @@ -10,8 +9,7 @@ } .add_applicant_button { - position: 'absolute'; - margin: 'auto'; + margin: auto; top: 15px; bottom: 0; left: 43em; From 84007043b410c8fccac08557cc3c686f404aeada Mon Sep 17 00:00:00 2001 From: Wenlan Ji Date: Sun, 3 Dec 2023 13:14:51 -0500 Subject: [PATCH 066/112] receive json array --- src/services/housing.ts | 16 +++++++++++-- src/views/HousingLottery/adminView/index.jsx | 24 +++++++++++++++++++ src/views/HousingLottery/index.jsx | 9 ++++++- .../studentView/PreferenceBox/index.jsx | 4 +++- .../HousingLottery/studentView/index.jsx | 4 +++- 5 files changed, 52 insertions(+), 5 deletions(-) create mode 100644 src/views/HousingLottery/adminView/index.jsx diff --git a/src/services/housing.ts b/src/services/housing.ts index 8bbe5257bc..5f9d7da7e4 100644 --- a/src/services/housing.ts +++ b/src/services/housing.ts @@ -62,6 +62,14 @@ const getApartmentSelectionDate = async (): Promise => { const getApartmentHalls = (): Promise => http.get('housing/halls/apartments'); const getTraditionalHalls = (): Promise => http.get('housing/halls/traditionals'); +const getAllPreference = (): Promise => + http.get('housing/housing_lottery/all_preference'); +const getAllPreferredHall = (): Promise => + http.get('housing/housing_lottery/all_preferred_hall'); +const getAllApplicant = (): Promise => + http.get('housing/housing_lottery/all_applicant'); +const getAllSchoolYear = (): Promise => + http.get('housing/housing_lottery/all_school_year'); const getCurrentApplicationID = (username: string = ''): Promise => http.get(username ? `housing/apartment/${username}/` : 'housing/apartment/'); @@ -171,13 +179,17 @@ const addApplicant = (applicantion_id: string, emailList: string[]) => const addHall = (applicantion_id: string, hallList: string[]) => http.put(`housing/housing_lottery/hall/${applicantion_id}`, hallList); -const addPreference = (morningOrNight: string, loudOrQuiet: string) => - http.put(`housing/housing_lottery/preference/${morningOrNight}/${loudOrQuiet}`); +const addPreference = (applicantion_id: string, preferenceList: string[]) => + http.put(`housing/housing_lottery/preference/${applicantion_id}`, preferenceList); const housingService = { getApartmentSelectionDate, getApartmentHalls, getTraditionalHalls, + getAllPreference, + getAllPreferredHall, + getAllApplicant, + getAllSchoolYear, getCurrentApplicationID, saveApartmentApplication, deleteApartmentApplication, diff --git a/src/views/HousingLottery/adminView/index.jsx b/src/views/HousingLottery/adminView/index.jsx new file mode 100644 index 0000000000..389bd75f76 --- /dev/null +++ b/src/views/HousingLottery/adminView/index.jsx @@ -0,0 +1,24 @@ +import { Button, Grid } from '@mui/material'; +import housingService from 'services/housing'; +import styles from '../HousingLottery.module.css'; + +const AdminView = () => { + const handleClick = async () => { + const preference = await housingService.getAllPreference(); + const preferredHall = await housingService.getAllPreferredHall(); + const applicant = await housingService.getAllApplicant(); + const schoolYear = await housingService.getAllSchoolYear(); + console.log('preference' + preference); + console.log('preferredHall' + preferredHall); + console.log('applicant' + applicant); + console.log('schoolYear' + schoolYear); + }; + + return ( + + ); +}; + +export default AdminView; diff --git a/src/views/HousingLottery/index.jsx b/src/views/HousingLottery/index.jsx index 0e08aecfdb..93d3778ea0 100644 --- a/src/views/HousingLottery/index.jsx +++ b/src/views/HousingLottery/index.jsx @@ -1,7 +1,14 @@ +import { Grid } from '@mui/material'; import StudentView from './studentView'; +import AdminView from './adminView'; const HousingLottery = () => { - return ; + return ( + + + + + ); }; export default HousingLottery; diff --git a/src/views/HousingLottery/studentView/PreferenceBox/index.jsx b/src/views/HousingLottery/studentView/PreferenceBox/index.jsx index 6c8cc3f539..0e9cffd067 100644 --- a/src/views/HousingLottery/studentView/PreferenceBox/index.jsx +++ b/src/views/HousingLottery/studentView/PreferenceBox/index.jsx @@ -19,7 +19,7 @@ import housingService from 'services/housing'; import housing from 'services/housing'; import styles from '../../HousingLottery.module.css'; -const Preference = () => { +const Preference = ({ setPreferenceResult }) => { const [preferences, setPreferences] = useState([]); // Store preferences as an array const [morningOrNight, setMorningOrNight] = useState(''); // Store the selected morning or night const [loudOrQuiet, setLoudOrQuiet] = useState(''); // Store the selected loud or quiet @@ -53,9 +53,11 @@ const Preference = () => { if (preferences.includes(type)) { // If the preference type is already in the list, remove it setPreferences((prevPreferences) => prevPreferences.filter((pref) => pref !== type)); + setPreferenceResult((prevPreferences) => prevPreferences.filter((pref) => pref !== type)); } else { // If the preference type is not in the list, add it setPreferences((prevPreferences) => [...prevPreferences, type]); + setPreferenceResult((prevPreferences) => [...prevPreferences, type]); } }; diff --git a/src/views/HousingLottery/studentView/index.jsx b/src/views/HousingLottery/studentView/index.jsx index 09d44d869b..d9bfe8c41f 100644 --- a/src/views/HousingLottery/studentView/index.jsx +++ b/src/views/HousingLottery/studentView/index.jsx @@ -10,12 +10,14 @@ import { nanoid } from 'nanoid'; const StudentView = () => { const [preferredHallResult, setPreferredHallResult] = useState([]); const [studentApplicantResult, setStudentApplicantResult] = useState([]); + const [preferenceResult, setPreferenceResult] = useState([]); const applicantion_id = nanoid(8); const handleClick = async () => { console.log(applicantion_id); await housingService.addHall(applicantion_id, preferredHallResult); await housingService.addApplicant(applicantion_id, studentApplicantResult); + await housingService.addPreference(applicantion_id, preferenceResult); }; return ( @@ -24,7 +26,7 @@ const StudentView = () => {
- + From 750d87cfc4241fc22591746e7d9a83d5fb5e4bdd Mon Sep 17 00:00:00 2001 From: Wenlan Ji Date: Sun, 3 Dec 2023 13:47:33 -0500 Subject: [PATCH 067/112] warn the user if the application is not submitted successfully --- .../studentView/PreferenceBox/index.jsx | 19 --------------- .../HousingLottery/studentView/index.jsx | 24 +++++++++++++++---- 2 files changed, 20 insertions(+), 23 deletions(-) diff --git a/src/views/HousingLottery/studentView/PreferenceBox/index.jsx b/src/views/HousingLottery/studentView/PreferenceBox/index.jsx index 0e9cffd067..7c0032fcc2 100644 --- a/src/views/HousingLottery/studentView/PreferenceBox/index.jsx +++ b/src/views/HousingLottery/studentView/PreferenceBox/index.jsx @@ -61,14 +61,6 @@ const Preference = ({ setPreferenceResult }) => { } }; - const handleClick = async () => { - // You can access the list of preferences and selected values - console.log('Preferences:', preferences); - console.log('Morning or Night:', morningOrNight); - console.log('Loud or Quiet:', loudOrQuiet); - await housingService.addRoommate({ morningOrNight, loudOrQuiet }); - }; - return ( @@ -101,17 +93,6 @@ const Preference = ({ setPreferenceResult }) => {
- - - - - diff --git a/src/views/HousingLottery/studentView/index.jsx b/src/views/HousingLottery/studentView/index.jsx index d9bfe8c41f..f43ae96b4a 100644 --- a/src/views/HousingLottery/studentView/index.jsx +++ b/src/views/HousingLottery/studentView/index.jsx @@ -6,18 +6,28 @@ import Preference from './PreferenceBox'; import housingService from 'services/housing'; import styles from '../HousingLottery.module.css'; import { nanoid } from 'nanoid'; +import GordonSnackbar from 'components/Snackbar'; const StudentView = () => { const [preferredHallResult, setPreferredHallResult] = useState([]); const [studentApplicantResult, setStudentApplicantResult] = useState([]); const [preferenceResult, setPreferenceResult] = useState([]); const applicantion_id = nanoid(8); + const [snackbar, setSnackbar] = useState({ message: '', severity: null, open: false }); const handleClick = async () => { - console.log(applicantion_id); - await housingService.addHall(applicantion_id, preferredHallResult); - await housingService.addApplicant(applicantion_id, studentApplicantResult); - await housingService.addPreference(applicantion_id, preferenceResult); + try { + console.log(applicantion_id); + await housingService.addApplicant(applicantion_id, studentApplicantResult); + await housingService.addHall(applicantion_id, preferredHallResult); + await housingService.addPreference(applicantion_id, preferenceResult); + } catch { + setSnackbar({ + message: 'Application fail to submit. Please check your information or contact CTS.', + severity: 'error', + open: true, + }); + } }; return ( @@ -34,6 +44,12 @@ const StudentView = () => { + setSnackbar((s) => ({ ...s, open: false }))} + /> ); }; From d5f4f7a0fb77d460c3524a7176f2a74190d5f3f1 Mon Sep 17 00:00:00 2001 From: Zhijie Wang Date: Sun, 3 Dec 2023 20:33:26 -0500 Subject: [PATCH 068/112] preference console report fix and header sharing with applicant card --- .../HousingLottery/HousingLottery.module.scss | 2 +- .../studentView/PreferenceBox/index.jsx | 19 ++++++++++--------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/views/HousingLottery/HousingLottery.module.scss b/src/views/HousingLottery/HousingLottery.module.scss index 5730baf48b..c4cff4dfd2 100644 --- a/src/views/HousingLottery/HousingLottery.module.scss +++ b/src/views/HousingLottery/HousingLottery.module.scss @@ -37,7 +37,7 @@ margin-left: 10px; } - +.preferences_card_header, .applicants_card_header { background-color: var(--mui-palette-primary-main); color: var(--mui-palette-primary-contrastText); diff --git a/src/views/HousingLottery/studentView/PreferenceBox/index.jsx b/src/views/HousingLottery/studentView/PreferenceBox/index.jsx index c96cfbe332..970b48c863 100644 --- a/src/views/HousingLottery/studentView/PreferenceBox/index.jsx +++ b/src/views/HousingLottery/studentView/PreferenceBox/index.jsx @@ -50,16 +50,17 @@ const Preference = () => { }; const updatePreferences = (type, value) => { - if (preferences.includes(type)) { + setPreferences((prevPreferences) => { // If the preference type is already in the list, remove it - setPreferences((prevPreferences) => - prevPreferences.filter((pref) => pref !== type) - ); - } else { - // If the preference type is not in the list, add it - setPreferences((prevPreferences) => [...prevPreferences, type]); - } + if (prevPreferences.includes(type)) { + return prevPreferences.filter((pref) => pref !== type); + } else { + // If the preference type is not in the list, add it along with the selected value + return [...prevPreferences, { [type]: value }]; + } + }); }; + const handleClick = async () => { // You can access the list of preferences and selected values @@ -73,7 +74,7 @@ const Preference = () => { - +
From 0f1f1ed87fd72b9f789b42558e75f4484f49104e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CJay?= Date: Mon, 4 Dec 2023 09:54:36 -0500 Subject: [PATCH 069/112] Adjusted the layout of boxes in the student UI --- .../HousingLottery/HousingLottery.module.scss | 1 - src/views/HousingLottery/index.jsx | 12 +++++------ .../studentView/Instructions/index.jsx | 2 +- .../studentView/PreferenceBox/index.jsx | 20 ++++++++++--------- .../studentView/PreferredHall/index.jsx | 4 ++-- .../studentView/StudentApplicants/index.jsx | 12 ++++------- 6 files changed, 24 insertions(+), 27 deletions(-) diff --git a/src/views/HousingLottery/HousingLottery.module.scss b/src/views/HousingLottery/HousingLottery.module.scss index 1195b16965..2db1c4071c 100644 --- a/src/views/HousingLottery/HousingLottery.module.scss +++ b/src/views/HousingLottery/HousingLottery.module.scss @@ -189,7 +189,6 @@ strong.over_emphasized { .apartment_card_header { background-color: var(--mui-palette-primary-main); color: var(--mui-palette-primary-contrastText); - :global { .MuiTypography-colorTextSecondary { color: var(--mui-palette-primary-contrastText); diff --git a/src/views/HousingLottery/index.jsx b/src/views/HousingLottery/index.jsx index dcf5b67e79..6b119bd8b4 100644 --- a/src/views/HousingLottery/index.jsx +++ b/src/views/HousingLottery/index.jsx @@ -22,21 +22,21 @@ import styles from './HousingLottery.module.css'; const HousingLottery = () => { return ( - + - + - - - - + + + + ); }; diff --git a/src/views/HousingLottery/studentView/Instructions/index.jsx b/src/views/HousingLottery/studentView/Instructions/index.jsx index f89a111d7f..08d80e5b9c 100644 --- a/src/views/HousingLottery/studentView/Instructions/index.jsx +++ b/src/views/HousingLottery/studentView/Instructions/index.jsx @@ -55,7 +55,7 @@ const Instructions = () => { aria-controls="instructions-panel-content" id="instructions-panel-header" > - On-Campus Apartments - Information and Guidelines + On-Campus Apartments - Information and Guidelines diff --git a/src/views/HousingLottery/studentView/PreferenceBox/index.jsx b/src/views/HousingLottery/studentView/PreferenceBox/index.jsx index c96cfbe332..6120185d25 100644 --- a/src/views/HousingLottery/studentView/PreferenceBox/index.jsx +++ b/src/views/HousingLottery/studentView/PreferenceBox/index.jsx @@ -52,9 +52,7 @@ const Preference = () => { const updatePreferences = (type, value) => { if (preferences.includes(type)) { // If the preference type is already in the list, remove it - setPreferences((prevPreferences) => - prevPreferences.filter((pref) => pref !== type) - ); + setPreferences((prevPreferences) => prevPreferences.filter((pref) => pref !== type)); } else { // If the preference type is not in the list, add it setPreferences((prevPreferences) => [...prevPreferences, type]); @@ -63,15 +61,15 @@ const Preference = () => { const handleClick = async () => { // You can access the list of preferences and selected values - console.log('Preferences:', preferences); - console.log('Morning or Night:', morningOrNight); - console.log('Loud or Quiet:', loudOrQuiet); + console.log('Preferences:', preferences); + console.log('Morning or Night:', morningOrNight); + console.log('Loud or Quiet:', loudOrQuiet); await housingService.addRoommate({ morningOrNight, loudOrQuiet }); }; return ( - + @@ -103,7 +101,11 @@ const Preference = () => { - @@ -112,6 +114,6 @@ const Preference = () => { ); -} +}; export default Preference; diff --git a/src/views/HousingLottery/studentView/PreferredHall/index.jsx b/src/views/HousingLottery/studentView/PreferredHall/index.jsx index d1523c77fe..95d4aaeffa 100644 --- a/src/views/HousingLottery/studentView/PreferredHall/index.jsx +++ b/src/views/HousingLottery/studentView/PreferredHall/index.jsx @@ -26,8 +26,8 @@ const PreferredHallsCard = () => { }; return ( - - + + diff --git a/src/views/HousingLottery/studentView/StudentApplicants/index.jsx b/src/views/HousingLottery/studentView/StudentApplicants/index.jsx index d3eb3104b9..62710f6e97 100644 --- a/src/views/HousingLottery/studentView/StudentApplicants/index.jsx +++ b/src/views/HousingLottery/studentView/StudentApplicants/index.jsx @@ -8,11 +8,11 @@ const StudentApplicants = () => { { firstName: '', lastName: '', email: '' }, { firstName: '', lastName: '', email: '' }, { firstName: '', lastName: '', email: '' }, - { firstName: '', lastName: '', email: '' } + { firstName: '', lastName: '', email: '' }, ]; const [applicants, setApplicants] = useState(initialApplicants); - const [emails, setEmails] = useState(initialApplicants.map(applicant => applicant.email)); + const [emails, setEmails] = useState(initialApplicants.map((applicant) => applicant.email)); const handleApplicantChange = (index, updatedApplicant) => { const newApplicants = [...applicants]; @@ -42,15 +42,11 @@ const StudentApplicants = () => { index={index} />
- +
))} - From 92f884ef72996189f79d179dc5cfe7233ef080bb Mon Sep 17 00:00:00 2001 From: Eric Date: Mon, 4 Dec 2023 12:55:02 -0500 Subject: [PATCH 070/112] Added feature distinguishing user --- src/views/HousingLottery/adminView/index.jsx | 12 ++++ src/views/HousingLottery/index.jsx | 74 +++++++++++++++++++- 2 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 src/views/HousingLottery/adminView/index.jsx diff --git a/src/views/HousingLottery/adminView/index.jsx b/src/views/HousingLottery/adminView/index.jsx new file mode 100644 index 0000000000..21b53b846a --- /dev/null +++ b/src/views/HousingLottery/adminView/index.jsx @@ -0,0 +1,12 @@ +import { Grid } from '@mui/material'; + +const AdminView = () => { + + return ( + + Weee + + ); +}; + +export default AdminView; \ No newline at end of file diff --git a/src/views/HousingLottery/index.jsx b/src/views/HousingLottery/index.jsx index 0e08aecfdb..79eb747217 100644 --- a/src/views/HousingLottery/index.jsx +++ b/src/views/HousingLottery/index.jsx @@ -1,7 +1,79 @@ +import GordonLimitedAvailability from 'components/GordonLimitedAvailability'; +import GordonOffline from 'components/GordonOffline'; +import GordonUnauthenticated from 'components/GordonUnauthenticated'; +import GordonLoader from 'components/Loader'; +import { useAuthGroups, useUser } from 'hooks'; +import useNetworkStatus from 'hooks/useNetworkStatus'; import StudentView from './studentView'; +import AdminView from './adminView'; + +//Imports for application period closed view +import { Card, CardContent, Grid, Button, Link } from '@mui/material'; +// eslint-disable-next-line no-unused-vars +import { useEffect, useState } from 'react'; // eslint disabled because it doesn't recognise type imports that ARE used in JSDoc comments +import { AuthGroup } from 'services/auth'; +import styles from './HousingLottery.module.css'; + const HousingLottery = () => { - return ; + const [loading, setLoading] = useState(true); + const { profile, loading: loadingProfile } = useUser(); + const [isUserStudent, setIsUserStudent] = useState(false); + const isHousingAdmin = useAuthGroups(AuthGroup.HousingAdmin); + const isOnline = useNetworkStatus(); + + useEffect(() => { + const loadPage = async () => { + setLoading(true); + try { + setIsUserStudent(profile.PersonType.includes('stu')); + } catch { + setIsUserStudent(false); + } finally { + setLoading(false); + } + }; + + if (profile) { + loadPage(); + } else { + // Clear out component's person-specific state when authenticated becomes false + // (i.e. user logs out) so that it isn't preserved falsely for the next user + setIsUserStudent(false); + setLoading(false); + } + }, [profile]); + + + if (loading || loadingProfile) { + return ; + } else if (!profile) { + // The user is not logged in + return ; + } else if (isOnline) { + if (isHousingAdmin) { + return ( +
+ +
+ ); + } else if (isUserStudent) { + return ( +
+ +
+ ); + } else { + return ( + + ); + } + } else { + return ; + } }; export default HousingLottery; From 4cb83e63b278179b7bbdcc6197178b87e0ee809c Mon Sep 17 00:00:00 2001 From: Zhijie Wang Date: Mon, 4 Dec 2023 15:25:43 -0500 Subject: [PATCH 071/112] when the page refresh, the selected radio button should be cleared, and preference only save the immeidate value from the two questions --- .../HousingLottery/HousingLottery.module.scss | 9 +---- .../studentView/PreferenceBox/index.jsx | 40 ++++++++++++++----- 2 files changed, 32 insertions(+), 17 deletions(-) diff --git a/src/views/HousingLottery/HousingLottery.module.scss b/src/views/HousingLottery/HousingLottery.module.scss index cd2766d056..cedcf032fd 100644 --- a/src/views/HousingLottery/HousingLottery.module.scss +++ b/src/views/HousingLottery/HousingLottery.module.scss @@ -1,11 +1,6 @@ .submit_preference_button { - margin: auto; - top: 15px; - bottom: 0; - left: 45em; - right: 20em; - height: 3em; - width: 9em; + height: 45px; + margin-left: 10px; } .add_applicant_button { diff --git a/src/views/HousingLottery/studentView/PreferenceBox/index.jsx b/src/views/HousingLottery/studentView/PreferenceBox/index.jsx index 970b48c863..7a869c0506 100644 --- a/src/views/HousingLottery/studentView/PreferenceBox/index.jsx +++ b/src/views/HousingLottery/studentView/PreferenceBox/index.jsx @@ -25,6 +25,7 @@ const Preference = () => { const [loudOrQuiet, setLoudOrQuiet] = useState(''); // Store the selected loud or quiet useEffect(() => { + // Check for stored preferences in localStorage const storedPreferences = localStorage.getItem('userPreferences'); if (storedPreferences) { const { morningOrNight, loudOrQuiet } = JSON.parse(storedPreferences); @@ -33,12 +34,6 @@ const Preference = () => { } }, []); - useEffect(() => { - // Save preferences to local storage - const storedPreferences = JSON.stringify({ morningOrNight, loudOrQuiet }); - localStorage.setItem('userPreferences', storedPreferences); - }, [morningOrNight, loudOrQuiet]); - const handleMorningOrNightChange = (event) => { setMorningOrNight(event.target.value); updatePreferences('morningOrNight', event.target.value); @@ -51,16 +46,20 @@ const Preference = () => { const updatePreferences = (type, value) => { setPreferences((prevPreferences) => { - // If the preference type is already in the list, remove it - if (prevPreferences.includes(type)) { - return prevPreferences.filter((pref) => pref !== type); + // Check if the preference type is already in the list + const existingPrefIndex = prevPreferences.findIndex((pref) => Object.keys(pref)[0] === type); + + // If it exists, update the value, otherwise add it + if (existingPrefIndex !== -1) { + prevPreferences[existingPrefIndex][type] = value; + return [...prevPreferences]; } else { - // If the preference type is not in the list, add it along with the selected value return [...prevPreferences, { [type]: value }]; } }); }; + const handleClick = async () => { // You can access the list of preferences and selected values @@ -70,6 +69,27 @@ const Preference = () => { await housingService.addRoommate({ morningOrNight, loudOrQuiet }); }; + useEffect(() => { + // Save preferences to local storage + const storedPreferences = JSON.stringify({ morningOrNight, loudOrQuiet }); + localStorage.setItem('userPreferences', storedPreferences); + }, [morningOrNight, loudOrQuiet]); + + useEffect(() => { + // Check if both morningOrNight and loudOrQuiet are empty, clear localStorage + if (!morningOrNight && !loudOrQuiet) { + localStorage.removeItem('userPreferences'); + } + }, [morningOrNight, loudOrQuiet]); + + useEffect(() => { + // Clear selected radio buttons when the page is refreshed + if (!localStorage.getItem('userPreferences')) { + setMorningOrNight(''); + setLoudOrQuiet(''); + } + }, []); + return ( From cc47bc0f5472fde3ec49633925cb5b7305cd3c5d Mon Sep 17 00:00:00 2001 From: Wenlan Ji Date: Mon, 4 Dec 2023 16:23:23 -0500 Subject: [PATCH 072/112] revert the changes on databse connection --- .env.development | 4 ++-- .env.production | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.env.development b/.env.development index 91179686b9..4bddec255b 100644 --- a/.env.development +++ b/.env.development @@ -4,7 +4,7 @@ # VITE_API_URL=https://360Api.gordon.edu/ # @TRAIN - VITE_API_URL=https://360ApiTrain.gordon.edu/ + VITE_API_URL=https://360ApiSP.gordon.edu/ # @LOCALHOST -# VITE_API_URL=http://localhost:51626/ +# VITE_API_URL=http://localhost:51632/ diff --git a/.env.production b/.env.production index adf7e4f84f..b238b31c1d 100644 --- a/.env.production +++ b/.env.production @@ -5,4 +5,4 @@ VITE_ANALYTICS_ID=G-2FE78G0CBN # @TRAIN -VITE_API_URL=https://360ApiTrain.gordon.edu/ +VITE_API_URL=https://360ApiSP.gordon.edu/ From fe2f078105ef92b96053065309f3bf74ccf0a320 Mon Sep 17 00:00:00 2001 From: Wenlan Ji Date: Mon, 4 Dec 2023 16:26:06 -0500 Subject: [PATCH 073/112] revert changes on local host link --- .env.development | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.env.development b/.env.development index 4bddec255b..19be702663 100644 --- a/.env.development +++ b/.env.development @@ -7,4 +7,4 @@ VITE_API_URL=https://360ApiSP.gordon.edu/ # @LOCALHOST -# VITE_API_URL=http://localhost:51632/ +# VITE_API_URL=http://localhost:51626/ From 878d399063f2575335eb21b173a968f9347e2873 Mon Sep 17 00:00:00 2001 From: Zhijie Wang Date: Mon, 4 Dec 2023 18:26:17 -0500 Subject: [PATCH 074/112] scratch table for adminView --- src/views/HousingLottery/adminView/index.jsx | 93 +++++++++++++++++--- 1 file changed, 79 insertions(+), 14 deletions(-) diff --git a/src/views/HousingLottery/adminView/index.jsx b/src/views/HousingLottery/adminView/index.jsx index 50c8ac7ae0..193fdc2616 100644 --- a/src/views/HousingLottery/adminView/index.jsx +++ b/src/views/HousingLottery/adminView/index.jsx @@ -1,23 +1,88 @@ -import { Button, Grid } from '@mui/material'; +import React, { useState, useEffect } from 'react'; +import { + Table, + TableBody, + TableCell, + TableContainer, + TableHead, + TableRow, + Paper, + Button, + Grid, +} from '@mui/material'; import housingService from 'services/housing'; import styles from '../HousingLottery.module.css'; const AdminView = () => { - const handleClick = async () => { - const preference = await housingService.getAllPreference(); - const preferredHall = await housingService.getAllPreferredHall(); - const applicant = await housingService.getAllApplicant(); - const schoolYear = await housingService.getAllSchoolYear(); - console.log('preference' + preference); - console.log('preferredHall' + preferredHall); - console.log('applicant' + applicant); - console.log('schoolYear' + schoolYear); - }; + const [data, setData] = useState([]); + + useEffect(() => { + const fetchData = async () => { + const preference = await housingService.getAllPreference(); + const preferredHall = await housingService.getAllPreferredHall(); + const applicants = await housingService.getAllApplicants(); + const schoolYear = await housingService.getAllSchoolYear(); + + // Combine the fetched data into a single array of objects + const combinedData = applicants.map((applicant, index) => ({ + lotteryNumber: index + 1, + applicantEmails: applicant.emails.join(', '), // Assuming emails is an array + preferredHalls: preferredHall[index].halls.join(', '), // Assuming halls is an array + preference: preference[index], // Assuming preference is an object + })); + + setData(combinedData); + }; + + fetchData(); + }, []); return ( - +
+ + + + + + Lottery Number + Applicant 1’s Email + Applicant 2’s Email + Applicant 3’s Email + Applicant 4’s Email + Applicant 5’s Email + Preferred Hall 1 + Preferred Hall 2 + Preferred Hall 3 + Preferred Hall 4 + Preferred Hall 5 + Preferred Hall 6 + Preference + + + + {data.map((row) => ( + + {row.lotteryNumber} + {row.applicantEmails} + + + + + {row.preferredHalls} + + + + + + {JSON.stringify(row.preference)} + + ))} + +
+
+
); }; From 013954821db916ad7fc186b500917a9266c5ed2f Mon Sep 17 00:00:00 2001 From: Zhijie Wang Date: Mon, 4 Dec 2023 23:59:26 -0500 Subject: [PATCH 075/112] edit the columns for preferred halls and applicant's email --- src/views/HousingLottery/adminView/index.jsx | 116 +++++++++++-------- 1 file changed, 65 insertions(+), 51 deletions(-) diff --git a/src/views/HousingLottery/adminView/index.jsx b/src/views/HousingLottery/adminView/index.jsx index 193fdc2616..56169cc803 100644 --- a/src/views/HousingLottery/adminView/index.jsx +++ b/src/views/HousingLottery/adminView/index.jsx @@ -9,6 +9,7 @@ import { Paper, Button, Grid, + Typography, } from '@mui/material'; import housingService from 'services/housing'; import styles from '../HousingLottery.module.css'; @@ -24,12 +25,24 @@ const AdminView = () => { const schoolYear = await housingService.getAllSchoolYear(); // Combine the fetched data into a single array of objects - const combinedData = applicants.map((applicant, index) => ({ - lotteryNumber: index + 1, - applicantEmails: applicant.emails.join(', '), // Assuming emails is an array - preferredHalls: preferredHall[index].halls.join(', '), // Assuming halls is an array - preference: preference[index], // Assuming preference is an object - })); + const combinedData = applicants.map((applicant, index) => { + const rowData = { + lotteryNumber: index + 1, + preference: JSON.stringify(preference[index]), // Assuming preference is an object + }; + + // Add columns for applicant's emails + for (let i = 0; i < 5; i++) { + rowData[`Applicant ${i + 1}'s Email`] = applicant.emails[i] || ''; + } + + // Add columns for preferred halls + for (let i = 0; i < 6; i++) { + rowData[`Preferred Hall ${i + 1}`] = preferredHall[index].halls[i] || ''; + } + + return rowData; + }); setData(combinedData); }; @@ -38,51 +51,52 @@ const AdminView = () => { }, []); return ( -
- - - - - - Lottery Number - Applicant 1’s Email - Applicant 2’s Email - Applicant 3’s Email - Applicant 4’s Email - Applicant 5’s Email - Preferred Hall 1 - Preferred Hall 2 - Preferred Hall 3 - Preferred Hall 4 - Preferred Hall 5 - Preferred Hall 6 - Preference - - - - {data.map((row) => ( - - {row.lotteryNumber} - {row.applicantEmails} - - - - - {row.preferredHalls} - - - - - - {JSON.stringify(row.preference)} - - ))} - -
-
-
+ + + + + Admin Interface + + + + + + + Lottery Number + {Array.from({ length: 5 }, (_, i) => ( + + Applicant {i + 1}'s Email + + ))} + {Array.from({ length: 6 }, (_, i) => ( + + Preferred Hall {i + 1} + + ))} + Preference + + + + {data.map((row) => ( + + {row.lotteryNumber} + {Array.from({ length: 5 }, (_, i) => ( + {row[`Applicant ${i + 1}'s Email`]} + ))} + {Array.from({ length: 6 }, (_, i) => ( + {row[`Preferred Hall ${i + 1}`]} + ))} + {row.preference} + + ))} + +
+
+
+
+
); }; From 71403ef1597ffe1ee6186eea28a2eeb2de883181 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CJay?= Date: Tue, 5 Dec 2023 17:02:34 -0500 Subject: [PATCH 076/112] adjusted boxes again --- src/views/HousingLottery/index.jsx | 10 +++++----- .../HousingLottery/studentView/PreferenceBox/index.jsx | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/views/HousingLottery/index.jsx b/src/views/HousingLottery/index.jsx index 6b119bd8b4..da57bf1240 100644 --- a/src/views/HousingLottery/index.jsx +++ b/src/views/HousingLottery/index.jsx @@ -22,19 +22,19 @@ import styles from './HousingLottery.module.css'; const HousingLottery = () => { return ( - + - - - + + + - + diff --git a/src/views/HousingLottery/studentView/PreferenceBox/index.jsx b/src/views/HousingLottery/studentView/PreferenceBox/index.jsx index 6120185d25..8af38e7095 100644 --- a/src/views/HousingLottery/studentView/PreferenceBox/index.jsx +++ b/src/views/HousingLottery/studentView/PreferenceBox/index.jsx @@ -68,8 +68,8 @@ const Preference = () => { }; return ( - - + + From e5664cdc5a841afdce13dd7724547ce5ee84a57a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CJay?= Date: Tue, 5 Dec 2023 17:29:55 -0500 Subject: [PATCH 077/112] Adjusted boxes again after merging --- src/views/HousingLottery/studentView/index.jsx | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/views/HousingLottery/studentView/index.jsx b/src/views/HousingLottery/studentView/index.jsx index a7cec41a12..f69df4e8ee 100644 --- a/src/views/HousingLottery/studentView/index.jsx +++ b/src/views/HousingLottery/studentView/index.jsx @@ -34,21 +34,21 @@ const StudentView = () => { return ( - + - - - - - - + + + + + + From b19b6ea617ba95d59544fda60d8839633df747c9 Mon Sep 17 00:00:00 2001 From: Zhijie Wang Date: Wed, 6 Dec 2023 19:12:17 -0500 Subject: [PATCH 078/112] set limit for applicant to 4 and preferred hall to 3 --- src/views/HousingLottery/adminView/index.jsx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/views/HousingLottery/adminView/index.jsx b/src/views/HousingLottery/adminView/index.jsx index 56169cc803..2e4b317b42 100644 --- a/src/views/HousingLottery/adminView/index.jsx +++ b/src/views/HousingLottery/adminView/index.jsx @@ -32,12 +32,12 @@ const AdminView = () => { }; // Add columns for applicant's emails - for (let i = 0; i < 5; i++) { + for (let i = 0; i < 4; i++) { rowData[`Applicant ${i + 1}'s Email`] = applicant.emails[i] || ''; } // Add columns for preferred halls - for (let i = 0; i < 6; i++) { + for (let i = 0; i < 3; i++) { rowData[`Preferred Hall ${i + 1}`] = preferredHall[index].halls[i] || ''; } @@ -65,12 +65,12 @@ const AdminView = () => { Lottery Number - {Array.from({ length: 5 }, (_, i) => ( + {Array.from({ length: 4 }, (_, i) => ( Applicant {i + 1}'s Email ))} - {Array.from({ length: 6 }, (_, i) => ( + {Array.from({ length: 3 }, (_, i) => ( Preferred Hall {i + 1} @@ -82,10 +82,10 @@ const AdminView = () => { {data.map((row) => ( {row.lotteryNumber} - {Array.from({ length: 5 }, (_, i) => ( + {Array.from({ length: 4 }, (_, i) => ( {row[`Applicant ${i + 1}'s Email`]} ))} - {Array.from({ length: 6 }, (_, i) => ( + {Array.from({ length: 3 }, (_, i) => ( {row[`Preferred Hall ${i + 1}`]} ))} {row.preference} From fbe806615631ad7770a0b7ee23c98d7f79ac5850 Mon Sep 17 00:00:00 2001 From: Zhijie Wang Date: Wed, 6 Dec 2023 23:59:46 -0500 Subject: [PATCH 079/112] package update by using npm install @esbuild/darwin-x64 , and make the card header for adminUI, making the export button work to generate the csv file --- package-lock.json | 351 ++++++++++++++++++ package.json | 1 + .../HousingLottery/HousingLottery.module.scss | 2 +- src/views/HousingLottery/adminView/index.jsx | 113 ++++-- 4 files changed, 427 insertions(+), 40 deletions(-) diff --git a/package-lock.json b/package-lock.json index 41f94bf8bd..e4f5e9b920 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,7 @@ "@date-io/date-fns": "^2.16.0", "@emotion/react": "^11.10.8", "@emotion/styled": "^11.10.8", + "@esbuild/darwin-x64": "^0.19.8", "@mui/icons-material": "^5.14.9", "@mui/material": "^5.14.10", "@mui/x-date-pickers": "^5.0.20", @@ -2425,6 +2426,244 @@ "node": ">=16" } }, + "node_modules/@esbuild/android-arm": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.19.tgz", + "integrity": "sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.19.tgz", + "integrity": "sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.19.tgz", + "integrity": "sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.19.tgz", + "integrity": "sha512-80wEoCfF/hFKM6WE1FyBHc9SfUblloAWx6FJkFWTWiCoht9Mc0ARGEM47e67W9rI09YoUxJL68WHfDRYEAvOhg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.19.8", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.8.tgz", + "integrity": "sha512-3sur80OT9YdeZwIVgERAysAbwncom7b4bCI2XKLjMfPymTud7e/oY4y+ci1XVp5TfQp/bppn7xLw1n/oSQY3/Q==", + "cpu": [ + "x64" + ], + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.19.tgz", + "integrity": "sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.19.tgz", + "integrity": "sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.19.tgz", + "integrity": "sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.19.tgz", + "integrity": "sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.19.tgz", + "integrity": "sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.19.tgz", + "integrity": "sha512-2iAngUbBPMq439a+z//gE+9WBldoMp1s5GWsUSgqHLzLJ9WoZLZhpwWuym0u0u/4XmZ3gpHmzV84PonE+9IIdQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.19.tgz", + "integrity": "sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.19.tgz", + "integrity": "sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.19.tgz", + "integrity": "sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.19.tgz", + "integrity": "sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, "node_modules/@esbuild/linux-x64": { "version": "0.17.19", "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.19.tgz", @@ -2441,6 +2680,102 @@ "node": ">=12" } }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.19.tgz", + "integrity": "sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.19.tgz", + "integrity": "sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.19.tgz", + "integrity": "sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.19.tgz", + "integrity": "sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.19.tgz", + "integrity": "sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.19.tgz", + "integrity": "sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", @@ -4800,6 +5135,22 @@ "@esbuild/win32-x64": "0.17.19" } }, + "node_modules/esbuild/node_modules/@esbuild/darwin-x64": { + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.19.tgz", + "integrity": "sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, "node_modules/escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", diff --git a/package.json b/package.json index cb7e4501e6..311dcad167 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,7 @@ "@date-io/date-fns": "^2.16.0", "@emotion/react": "^11.10.8", "@emotion/styled": "^11.10.8", + "@esbuild/darwin-x64": "^0.19.8", "@mui/icons-material": "^5.14.9", "@mui/material": "^5.14.10", "@mui/x-date-pickers": "^5.0.20", diff --git a/src/views/HousingLottery/HousingLottery.module.scss b/src/views/HousingLottery/HousingLottery.module.scss index 5d146173ba..a3edbbd8cd 100644 --- a/src/views/HousingLottery/HousingLottery.module.scss +++ b/src/views/HousingLottery/HousingLottery.module.scss @@ -30,7 +30,7 @@ margin-bottom: 10px; margin-left: 10px; } - +.admin_card_header, .preferences_card_header, .applicants_card_header { background-color: var(--mui-palette-primary-main); diff --git a/src/views/HousingLottery/adminView/index.jsx b/src/views/HousingLottery/adminView/index.jsx index 2e4b317b42..e3c424f5b8 100644 --- a/src/views/HousingLottery/adminView/index.jsx +++ b/src/views/HousingLottery/adminView/index.jsx @@ -10,9 +10,14 @@ import { Button, Grid, Typography, + Card, + CardHeader, + CardContent, + Link, } from '@mui/material'; import housingService from 'services/housing'; import styles from '../HousingLottery.module.css'; +import { CSVLink } from 'react-csv'; const AdminView = () => { const [data, setData] = useState([]); @@ -31,12 +36,12 @@ const AdminView = () => { preference: JSON.stringify(preference[index]), // Assuming preference is an object }; - // Add columns for applicant's emails + // Limit the number of applicants to 4 for (let i = 0; i < 4; i++) { rowData[`Applicant ${i + 1}'s Email`] = applicant.emails[i] || ''; } - // Add columns for preferred halls + // Limit the number of preferred halls to 3 for (let i = 0; i < 3; i++) { rowData[`Preferred Hall ${i + 1}`] = preferredHall[index].halls[i] || ''; } @@ -50,51 +55,81 @@ const AdminView = () => { fetchData(); }, []); + const csvData = data.map((row) => ({ + 'Lottery Number': row.lotteryNumber, + 'Applicant 1’s Email': row['Applicant 1\'s Email'], + 'Applicant 2’s Email': row['Applicant 2\'s Email'], + 'Applicant 3’s Email': row['Applicant 3\'s Email'], + 'Applicant 4’s Email': row['Applicant 4\'s Email'], + 'Preferred Hall 1': row['Preferred Hall 1'], + 'Preferred Hall 2': row['Preferred Hall 2'], + 'Preferred Hall 3': row['Preferred Hall 3'], + 'Preference': row.preference, + })); + + const csvHeaders = [ + 'Lottery Number', + 'Applicant 1’s Email', + 'Applicant 2’s Email', + 'Applicant 3’s Email', + 'Applicant 4’s Email', + 'Preferred Hall 1', + 'Preferred Hall 2', + 'Preferred Hall 3', + 'Preference', + ]; + return ( - - - Admin Interface - - - - - - - Lottery Number - {Array.from({ length: 4 }, (_, i) => ( - - Applicant {i + 1}'s Email - - ))} - {Array.from({ length: 3 }, (_, i) => ( - - Preferred Hall {i + 1} - - ))} - Preference - - - - {data.map((row) => ( - - {row.lotteryNumber} + + + + + +
+ + + Lottery Number {Array.from({ length: 4 }, (_, i) => ( - {row[`Applicant ${i + 1}'s Email`]} + + Applicant {i + 1}'s Email + ))} {Array.from({ length: 3 }, (_, i) => ( - {row[`Preferred Hall ${i + 1}`]} + + Preferred Hall {i + 1} + ))} - {row.preference} + Preference - ))} - -
-
-
+
+ + {data.map((row) => ( + + {row.lotteryNumber} + {Array.from({ length: 4 }, (_, i) => ( + {row[`Applicant ${i + 1}'s Email`]} + ))} + {Array.from({ length: 3 }, (_, i) => ( + {row[`Preferred Hall ${i + 1}`]} + ))} + {row.preference} + + ))} + + + +
+
); From fc2d9db174896114d6c476dad2524ce1cb6e2831 Mon Sep 17 00:00:00 2001 From: Zhijie Wang Date: Thu, 7 Dec 2023 00:12:30 -0500 Subject: [PATCH 080/112] revert the change in json package --- .../HousingLottery/HousingLottery.module.scss | 2 +- src/views/HousingLottery/adminView/index.jsx | 113 ++++++++++++------ 2 files changed, 75 insertions(+), 40 deletions(-) diff --git a/src/views/HousingLottery/HousingLottery.module.scss b/src/views/HousingLottery/HousingLottery.module.scss index 5d146173ba..a3edbbd8cd 100644 --- a/src/views/HousingLottery/HousingLottery.module.scss +++ b/src/views/HousingLottery/HousingLottery.module.scss @@ -30,7 +30,7 @@ margin-bottom: 10px; margin-left: 10px; } - +.admin_card_header, .preferences_card_header, .applicants_card_header { background-color: var(--mui-palette-primary-main); diff --git a/src/views/HousingLottery/adminView/index.jsx b/src/views/HousingLottery/adminView/index.jsx index 2e4b317b42..e3c424f5b8 100644 --- a/src/views/HousingLottery/adminView/index.jsx +++ b/src/views/HousingLottery/adminView/index.jsx @@ -10,9 +10,14 @@ import { Button, Grid, Typography, + Card, + CardHeader, + CardContent, + Link, } from '@mui/material'; import housingService from 'services/housing'; import styles from '../HousingLottery.module.css'; +import { CSVLink } from 'react-csv'; const AdminView = () => { const [data, setData] = useState([]); @@ -31,12 +36,12 @@ const AdminView = () => { preference: JSON.stringify(preference[index]), // Assuming preference is an object }; - // Add columns for applicant's emails + // Limit the number of applicants to 4 for (let i = 0; i < 4; i++) { rowData[`Applicant ${i + 1}'s Email`] = applicant.emails[i] || ''; } - // Add columns for preferred halls + // Limit the number of preferred halls to 3 for (let i = 0; i < 3; i++) { rowData[`Preferred Hall ${i + 1}`] = preferredHall[index].halls[i] || ''; } @@ -50,51 +55,81 @@ const AdminView = () => { fetchData(); }, []); + const csvData = data.map((row) => ({ + 'Lottery Number': row.lotteryNumber, + 'Applicant 1’s Email': row['Applicant 1\'s Email'], + 'Applicant 2’s Email': row['Applicant 2\'s Email'], + 'Applicant 3’s Email': row['Applicant 3\'s Email'], + 'Applicant 4’s Email': row['Applicant 4\'s Email'], + 'Preferred Hall 1': row['Preferred Hall 1'], + 'Preferred Hall 2': row['Preferred Hall 2'], + 'Preferred Hall 3': row['Preferred Hall 3'], + 'Preference': row.preference, + })); + + const csvHeaders = [ + 'Lottery Number', + 'Applicant 1’s Email', + 'Applicant 2’s Email', + 'Applicant 3’s Email', + 'Applicant 4’s Email', + 'Preferred Hall 1', + 'Preferred Hall 2', + 'Preferred Hall 3', + 'Preference', + ]; + return ( - - - Admin Interface - - - - - - - Lottery Number - {Array.from({ length: 4 }, (_, i) => ( - - Applicant {i + 1}'s Email - - ))} - {Array.from({ length: 3 }, (_, i) => ( - - Preferred Hall {i + 1} - - ))} - Preference - - - - {data.map((row) => ( - - {row.lotteryNumber} + + + + + +
+ + + Lottery Number {Array.from({ length: 4 }, (_, i) => ( - {row[`Applicant ${i + 1}'s Email`]} + + Applicant {i + 1}'s Email + ))} {Array.from({ length: 3 }, (_, i) => ( - {row[`Preferred Hall ${i + 1}`]} + + Preferred Hall {i + 1} + ))} - {row.preference} + Preference - ))} - -
-
-
+ + + {data.map((row) => ( + + {row.lotteryNumber} + {Array.from({ length: 4 }, (_, i) => ( + {row[`Applicant ${i + 1}'s Email`]} + ))} + {Array.from({ length: 3 }, (_, i) => ( + {row[`Preferred Hall ${i + 1}`]} + ))} + {row.preference} + + ))} + + + + +
); From 89b6254b10d7471da32c7ff202d31764d228fc36 Mon Sep 17 00:00:00 2001 From: Zhijie Wang Date: Thu, 7 Dec 2023 01:20:30 -0500 Subject: [PATCH 081/112] resolve the depedency error and made card header and button for generate csv file --- .../HousingLottery/HousingLottery.module.scss | 2 +- src/views/HousingLottery/adminView/index.jsx | 113 ++++++++++++------ 2 files changed, 75 insertions(+), 40 deletions(-) diff --git a/src/views/HousingLottery/HousingLottery.module.scss b/src/views/HousingLottery/HousingLottery.module.scss index 5d146173ba..a3edbbd8cd 100644 --- a/src/views/HousingLottery/HousingLottery.module.scss +++ b/src/views/HousingLottery/HousingLottery.module.scss @@ -30,7 +30,7 @@ margin-bottom: 10px; margin-left: 10px; } - +.admin_card_header, .preferences_card_header, .applicants_card_header { background-color: var(--mui-palette-primary-main); diff --git a/src/views/HousingLottery/adminView/index.jsx b/src/views/HousingLottery/adminView/index.jsx index 2e4b317b42..11543e2c2d 100644 --- a/src/views/HousingLottery/adminView/index.jsx +++ b/src/views/HousingLottery/adminView/index.jsx @@ -10,9 +10,14 @@ import { Button, Grid, Typography, + Card, + CardHeader, + CardContent, + Link, } from '@mui/material'; import housingService from 'services/housing'; import styles from '../HousingLottery.module.css'; +import { CSVLink } from 'react-csv'; const AdminView = () => { const [data, setData] = useState([]); @@ -31,12 +36,12 @@ const AdminView = () => { preference: JSON.stringify(preference[index]), // Assuming preference is an object }; - // Add columns for applicant's emails + // Limit the number of applicants to 4 for (let i = 0; i < 4; i++) { rowData[`Applicant ${i + 1}'s Email`] = applicant.emails[i] || ''; } - // Add columns for preferred halls + // Limit the number of preferred halls to 3 for (let i = 0; i < 3; i++) { rowData[`Preferred Hall ${i + 1}`] = preferredHall[index].halls[i] || ''; } @@ -50,51 +55,81 @@ const AdminView = () => { fetchData(); }, []); + const csvData = data.map((row) => ({ + 'Lottery Number': row.lotteryNumber, + 'Applicant 1’s Email': row['Applicant 1\'s Email'], + 'Applicant 2’s Email': row['Applicant 2\'s Email'], + 'Applicant 3’s Email': row['Applicant 3\'s Email'], + 'Applicant 4’s Email': row['Applicant 4\'s Email'], + 'Preferred Hall 1': row['Preferred Hall 1'], + 'Preferred Hall 2': row['Preferred Hall 2'], + 'Preferred Hall 3': row['Preferred Hall 3'], + 'Preference': row.preference, + })); + + const csvHeaders = [ + 'Lottery Number', + 'Applicant 1’s Email', + 'Applicant 2’s Email', + 'Applicant 3’s Email', + 'Applicant 4’s Email', + 'Preferred Hall 1', + 'Preferred Hall 2', + 'Preferred Hall 3', + 'Preference', + ]; + return ( - - - Admin Interface - - - - - - - Lottery Number - {Array.from({ length: 4 }, (_, i) => ( - - Applicant {i + 1}'s Email - - ))} - {Array.from({ length: 3 }, (_, i) => ( - - Preferred Hall {i + 1} - - ))} - Preference - - - - {data.map((row) => ( - - {row.lotteryNumber} + + + + +
+ + + Lottery Number {Array.from({ length: 4 }, (_, i) => ( - {row[`Applicant ${i + 1}'s Email`]} + + Applicant {i + 1}'s Email + ))} {Array.from({ length: 3 }, (_, i) => ( - {row[`Preferred Hall ${i + 1}`]} + + Preferred Hall {i + 1} + ))} - {row.preference} + Preference - ))} - -
-
-
+ + + {data.map((row) => ( + + {row.lotteryNumber} + {Array.from({ length: 4 }, (_, i) => ( + {row[`Applicant ${i + 1}'s Email`]} + ))} + {Array.from({ length: 3 }, (_, i) => ( + {row[`Preferred Hall ${i + 1}`]} + ))} + {row.preference} + + ))} + + + + + +
); From 4061632fd740b575f3ce859f17f5ce89a358a6f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CJay?= Date: Thu, 7 Dec 2023 15:40:16 -0500 Subject: [PATCH 082/112] Updated package.json --- package-lock.json | 7 +++---- package.json | 1 - 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 41f94bf8bd..df97904ba2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,7 +17,6 @@ "@mui/material": "^5.14.10", "@mui/x-date-pickers": "^5.0.20", "add-to-calendar-button": "^2.2.9", - "caniuse-lite": "^1.0.30001283", "chart.js": "^2.9.4", "cropperjs": "^1.5.13", "date-fns": "^2.30.0", @@ -4139,9 +4138,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001505", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001505.tgz", - "integrity": "sha512-jaAOR5zVtxHfL0NjZyflVTtXm3D3J9P15zSJ7HmQF8dSKGA6tqzQq+0ZI3xkjyQj46I4/M0K2GbMpcAFOcbr3A==", + "version": "1.0.30001566", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001566.tgz", + "integrity": "sha512-ggIhCsTxmITBAMmK8yZjEhCO5/47jKXPu6Dha/wuCS4JePVL+3uiDEBuhu2aIoT+bqTOR8L76Ip1ARL9xYsEJA==", "funding": [ { "type": "opencollective", diff --git a/package.json b/package.json index cb7e4501e6..5a9a885901 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,6 @@ "@mui/material": "^5.14.10", "@mui/x-date-pickers": "^5.0.20", "add-to-calendar-button": "^2.2.9", - "caniuse-lite": "^1.0.30001283", "chart.js": "^2.9.4", "cropperjs": "^1.5.13", "date-fns": "^2.30.0", From d0a9bb7df14cc95d5b65f93fd3fff7c5df36b265 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CJay?= Date: Thu, 7 Dec 2023 15:58:33 -0500 Subject: [PATCH 083/112] Updated package-lock.json --- package-lock.json | 111 +++++++++++++++++++++++----------------------- 1 file changed, 56 insertions(+), 55 deletions(-) diff --git a/package-lock.json b/package-lock.json index df97904ba2..6fa4df0395 100644 --- a/package-lock.json +++ b/package-lock.json @@ -113,11 +113,12 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.5.tgz", - "integrity": "sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", + "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", "dependencies": { - "@babel/highlight": "^7.22.5" + "@babel/highlight": "^7.23.4", + "chalk": "^2.4.2" }, "engines": { "node": ">=6.9.0" @@ -188,11 +189,11 @@ } }, "node_modules/@babel/generator": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.22.5.tgz", - "integrity": "sha512-+lcUbnTRhd0jOewtFSedLyiPsD5tswKkbgcezOqqWFUVNEwoUTlpPOBmvhG7OXWLR4jMdv0czPGH5XbflnD1EA==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.5.tgz", + "integrity": "sha512-BPssCHrBD+0YrxviOa3QzpqwhNIXKEtOa2jQrm4FlmkC2apYgRnQcmPWiGZDlGxiNtltnUFolMe8497Esry+jA==", "dependencies": { - "@babel/types": "^7.22.5", + "@babel/types": "^7.23.5", "@jridgewell/gen-mapping": "^0.3.2", "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" @@ -300,20 +301,20 @@ } }, "node_modules/@babel/helper-environment-visitor": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz", - "integrity": "sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-function-name": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz", - "integrity": "sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", "dependencies": { - "@babel/template": "^7.22.5", - "@babel/types": "^7.22.5" + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" }, "engines": { "node": ">=6.9.0" @@ -450,9 +451,9 @@ } }, "node_modules/@babel/helper-split-export-declaration": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.5.tgz", - "integrity": "sha512-thqK5QFghPKWLhAV321lxF95yCg2K3Ob5yw+M3VHWfdia0IkPXUtoLH8x/6Fh486QUvzhb8YOWHChTVen2/PoQ==", + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", "dependencies": { "@babel/types": "^7.22.5" }, @@ -461,17 +462,17 @@ } }, "node_modules/@babel/helper-string-parser": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", - "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", + "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz", - "integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", "engines": { "node": ">=6.9.0" } @@ -513,12 +514,12 @@ } }, "node_modules/@babel/highlight": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.5.tgz", - "integrity": "sha512-BSKlD1hgnedS5XRnGOljZawtag7H1yPfQp0tdNJCHoH6AZ+Pcm9VvkrK59/Yy593Ypg0zMxH2BxD1VPYUQ7UIw==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", + "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", "dependencies": { - "@babel/helper-validator-identifier": "^7.22.5", - "chalk": "^2.0.0", + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", "js-tokens": "^4.0.0" }, "engines": { @@ -526,9 +527,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.5.tgz", - "integrity": "sha512-DFZMC9LJUG9PLOclRC32G63UXwzqS2koQC8dkx+PLdmt1xSePYpbT/NbsrJy8Q/muXz7o/h/d4A7Fuyixm559Q==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.5.tgz", + "integrity": "sha512-hOOqoiNXrmGdFbhgCzu6GiURxUgM27Xwd/aPuu8RfHEZPBzL1Z54okAHAQjXfcQNwvrlkAmAp4SlRTZ45vlthQ==", "bin": { "parser": "bin/babel-parser.js" }, @@ -2078,31 +2079,31 @@ } }, "node_modules/@babel/template": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.5.tgz", - "integrity": "sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", + "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", "dependencies": { - "@babel/code-frame": "^7.22.5", - "@babel/parser": "^7.22.5", - "@babel/types": "^7.22.5" + "@babel/code-frame": "^7.22.13", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.5.tgz", - "integrity": "sha512-7DuIjPgERaNo6r+PZwItpjCZEa5vyw4eJGufeLxrPdBXBoLcCJCIasvK6pK/9DVNrLZTLFhUGqaC6X/PA007TQ==", - "dependencies": { - "@babel/code-frame": "^7.22.5", - "@babel/generator": "^7.22.5", - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-function-name": "^7.22.5", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.5.tgz", + "integrity": "sha512-czx7Xy5a6sapWWRx61m1Ke1Ra4vczu1mCTtJam5zRTBOonfdJ+S/B6HYmGYu3fJtr8GGET3si6IhgWVBhJ/m8w==", + "dependencies": { + "@babel/code-frame": "^7.23.5", + "@babel/generator": "^7.23.5", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", "@babel/helper-hoist-variables": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.5", - "@babel/parser": "^7.22.5", - "@babel/types": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.23.5", + "@babel/types": "^7.23.5", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -2111,12 +2112,12 @@ } }, "node_modules/@babel/types": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.5.tgz", - "integrity": "sha512-zo3MIHGOkPOfoRXitsgHLjEXmlDaD/5KU1Uzuc9GNiZPhSqVxVRtxuPaSBZDsYZ9qV88AjtMtWW7ww98loJ9KA==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.5.tgz", + "integrity": "sha512-ON5kSOJwVO6xXVRTvOI0eOnWe7VdUcIpsovGo9U/Br4Ie4UVFQTboO2cYnDhAGU6Fp+UxSiT+pMft0SMHfuq6w==", "dependencies": { - "@babel/helper-string-parser": "^7.22.5", - "@babel/helper-validator-identifier": "^7.22.5", + "@babel/helper-string-parser": "^7.23.4", + "@babel/helper-validator-identifier": "^7.22.20", "to-fast-properties": "^2.0.0" }, "engines": { From 87d16f5afe4601931bc1f2ebdd39e36f686b62ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CJay?= Date: Fri, 8 Dec 2023 20:40:56 -0500 Subject: [PATCH 084/112] Updated .env.development --- .env.development | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.env.development b/.env.development index 19be702663..a7fd7f1f70 100644 --- a/.env.development +++ b/.env.development @@ -1,10 +1,10 @@ # Refers to the development environment using localhost # @PROD -# VITE_API_URL=https://360Api.gordon.edu/ +VITE_API_URL=https://360Api.gordon.edu/ # @TRAIN - VITE_API_URL=https://360ApiSP.gordon.edu/ +# VITE_API_URL=https://360ApiTrain.gordon.edu/ # @LOCALHOST # VITE_API_URL=http://localhost:51626/ From 48f565c0894f779944dd02ea2c4310162aa83de7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CJay?= Date: Fri, 8 Dec 2023 21:20:54 -0500 Subject: [PATCH 085/112] Fixed loading problem and adjusted the layout again --- .../HousingLottery/HousingLottery.module.scss | 14 +++++++++++++ .../studentView/PreferenceBox/index.jsx | 2 +- .../HousingLottery/studentView/index.jsx | 20 +++++++++++-------- 3 files changed, 27 insertions(+), 9 deletions(-) diff --git a/src/views/HousingLottery/HousingLottery.module.scss b/src/views/HousingLottery/HousingLottery.module.scss index b981b3cbf8..1a0ac2c13a 100644 --- a/src/views/HousingLottery/HousingLottery.module.scss +++ b/src/views/HousingLottery/HousingLottery.module.scss @@ -221,3 +221,17 @@ strong.over_emphasized { margin-bottom: 0.5em; } } + +.flexContainer { + display: flex; + flex-direction: column; + justify-content: flex-start; /* This will align children to the top */ +} + +.flexContainer > :first-child { + flex-shrink: 0; /* This ensures the 'Preferred Halls' doesn't shrink */ +} + +.flexContainer > :last-child { + flex-grow: 1; /* This allows the 'Preferences' to grow and fill available space */ +} diff --git a/src/views/HousingLottery/studentView/PreferenceBox/index.jsx b/src/views/HousingLottery/studentView/PreferenceBox/index.jsx index 049a5aaf77..3c8c0b0d9b 100644 --- a/src/views/HousingLottery/studentView/PreferenceBox/index.jsx +++ b/src/views/HousingLottery/studentView/PreferenceBox/index.jsx @@ -90,7 +90,7 @@ const Preference = () => { return ( - + diff --git a/src/views/HousingLottery/studentView/index.jsx b/src/views/HousingLottery/studentView/index.jsx index f69df4e8ee..8f554cde50 100644 --- a/src/views/HousingLottery/studentView/index.jsx +++ b/src/views/HousingLottery/studentView/index.jsx @@ -40,18 +40,22 @@ const StudentView = () => { - - - - - + + + + + + + - + + + Date: Fri, 8 Dec 2023 23:26:54 -0500 Subject: [PATCH 086/112] add new column standing as applicant's class standing --- src/views/HousingLottery/adminView/index.jsx | 23 ++++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/views/HousingLottery/adminView/index.jsx b/src/views/HousingLottery/adminView/index.jsx index 11543e2c2d..e3e0040167 100644 --- a/src/views/HousingLottery/adminView/index.jsx +++ b/src/views/HousingLottery/adminView/index.jsx @@ -34,6 +34,7 @@ const AdminView = () => { const rowData = { lotteryNumber: index + 1, preference: JSON.stringify(preference[index]), // Assuming preference is an object + standing: applicant.standing || '', // Add class standing }; // Limit the number of applicants to 4 @@ -65,6 +66,7 @@ const AdminView = () => { 'Preferred Hall 2': row['Preferred Hall 2'], 'Preferred Hall 3': row['Preferred Hall 3'], 'Preference': row.preference, + 'Class Standing': row.standing, // Add class standing to the CSV })); const csvHeaders = [ @@ -77,6 +79,7 @@ const AdminView = () => { 'Preferred Hall 2', 'Preferred Hall 3', 'Preference', + 'Class Standing', // Add class standing header ]; return ( @@ -85,6 +88,15 @@ const AdminView = () => { + @@ -101,6 +113,7 @@ const AdminView = () => { ))} Preference + Class Standing {/* Add class standing column header */} @@ -114,20 +127,12 @@ const AdminView = () => { {row[`Preferred Hall ${i + 1}`]} ))} {row.preference} + {row.standing} {/* Add class standing data */} ))}
-
From ab5a9fbf39ae587c9c3a9e9ef79a366760c16386 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CJay?= Date: Fri, 8 Dec 2023 23:35:37 -0500 Subject: [PATCH 087/112] Deleted the button in preferences box --- .../studentView/PreferenceBox/index.jsx | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/src/views/HousingLottery/studentView/PreferenceBox/index.jsx b/src/views/HousingLottery/studentView/PreferenceBox/index.jsx index 3c8c0b0d9b..ceeca24b83 100644 --- a/src/views/HousingLottery/studentView/PreferenceBox/index.jsx +++ b/src/views/HousingLottery/studentView/PreferenceBox/index.jsx @@ -120,17 +120,7 @@ const Preference = () => {
- - - - - +
From e4b805a7e2297f7110c8f5eab50db9e3174048b7 Mon Sep 17 00:00:00 2001 From: Eric Date: Sat, 9 Dec 2023 14:52:36 -0500 Subject: [PATCH 088/112] simple but necessary styling add --- src/views/HousingLottery/HousingLottery.module.scss | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/views/HousingLottery/HousingLottery.module.scss b/src/views/HousingLottery/HousingLottery.module.scss index a3edbbd8cd..5c24f29d40 100644 --- a/src/views/HousingLottery/HousingLottery.module.scss +++ b/src/views/HousingLottery/HousingLottery.module.scss @@ -222,3 +222,7 @@ strong.over_emphasized { margin-bottom: 0.5em; } } + +.csvLink { + color: var(--mui-palette-primary-contrastText); +} \ No newline at end of file From d928de06e781f4a59649d168db8753607cf876f6 Mon Sep 17 00:00:00 2001 From: Eric Date: Sun, 10 Dec 2023 05:29:19 -0500 Subject: [PATCH 089/112] Fixed StudentView to return data when submitted --- .../studentView/PreferredHall/index.jsx | 2 +- .../HousingLottery/studentView/index.jsx | 22 ++++++++++++++----- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/views/HousingLottery/studentView/PreferredHall/index.jsx b/src/views/HousingLottery/studentView/PreferredHall/index.jsx index 374295de9a..2c217ade1b 100644 --- a/src/views/HousingLottery/studentView/PreferredHall/index.jsx +++ b/src/views/HousingLottery/studentView/PreferredHall/index.jsx @@ -16,7 +16,7 @@ const PreferredHallsCard = ({ setPreferredHallResult }) => { }, []); function updatePreferredHallList(rank, hall) { - let newList = preferredHallList; + let newList = [...preferredHallList]; newList[rank - 1] = hall; setPreferredHallList(newList); setPreferredHallResult(newList); diff --git a/src/views/HousingLottery/studentView/index.jsx b/src/views/HousingLottery/studentView/index.jsx index 8f554cde50..82da65e3ae 100644 --- a/src/views/HousingLottery/studentView/index.jsx +++ b/src/views/HousingLottery/studentView/index.jsx @@ -14,15 +14,27 @@ const StudentView = () => { const [preferredHallResult, setPreferredHallResult] = useState([]); const [studentApplicantResult, setStudentApplicantResult] = useState([]); const [preferenceResult, setPreferenceResult] = useState([]); - const applicantion_id = nanoid(8); + const application_id = nanoid(8); const [snackbar, setSnackbar] = useState({ message: '', severity: null, open: false }); + console.log('Preferred Hall Result:', preferredHallResult); + console.log('Student Applicant Result:', studentApplicantResult); + console.log('Preference Result:', preferenceResult); const handleClick = async () => { + if (preferredHallResult.includes('')) { + setSnackbar({ + message: 'Please complete all hall preferences before submitting.', + severity: 'warning', + open: true, + }); + return; + } + try { - console.log(applicantion_id); - await housingService.addApplicant(applicantion_id, studentApplicantResult); - await housingService.addHall(applicantion_id, preferredHallResult); - await housingService.addPreference(applicantion_id, preferenceResult); + console.log(application_id); + await housingService.addApplicant(application_id, studentApplicantResult); + await housingService.addHall(application_id, preferredHallResult); + await housingService.addPreference(application_id, preferenceResult); } catch { setSnackbar({ message: 'Application fail to submit. Please check your information or contact CTS.', From 947b81ab71fc6a73ac124db8832e8bc154df2a6e Mon Sep 17 00:00:00 2001 From: Eric Date: Sun, 10 Dec 2023 13:41:52 -0500 Subject: [PATCH 090/112] Fixes to load preference data --- .../studentView/PreferenceBox/index.jsx | 52 ++++++++++--------- .../HousingLottery/studentView/index.jsx | 6 ++- 2 files changed, 32 insertions(+), 26 deletions(-) diff --git a/src/views/HousingLottery/studentView/PreferenceBox/index.jsx b/src/views/HousingLottery/studentView/PreferenceBox/index.jsx index ceeca24b83..dad9a2eabb 100644 --- a/src/views/HousingLottery/studentView/PreferenceBox/index.jsx +++ b/src/views/HousingLottery/studentView/PreferenceBox/index.jsx @@ -19,7 +19,7 @@ import housingService from 'services/housing'; import housing from 'services/housing'; import styles from '../../HousingLottery.module.css'; -const Preference = () => { +const Preference = ({onPreferenceChange}) => { const [preferences, setPreferences] = useState([]); // Store preferences as an array const [morningOrNight, setMorningOrNight] = useState(''); // Store the selected morning or night const [loudOrQuiet, setLoudOrQuiet] = useState(''); // Store the selected loud or quiet @@ -35,37 +35,39 @@ const Preference = () => { }, []); const handleMorningOrNightChange = (event) => { - setMorningOrNight(event.target.value); - updatePreferences('morningOrNight', event.target.value); + const newMorningOrNight = event.target.value; + setMorningOrNight(newMorningOrNight); + onPreferenceChange({ morningOrNight: newMorningOrNight, loudOrQuiet }); }; const handleLoudOrQuietChange = (event) => { - setLoudOrQuiet(event.target.value); - updatePreferences('loudOrQuiet', event.target.value); + const newLoudOrQuiet = event.target.value; + setLoudOrQuiet(newLoudOrQuiet); + onPreferenceChange({ morningOrNight, loudOrQuiet: newLoudOrQuiet }); }; - const updatePreferences = (type, value) => { - setPreferences((prevPreferences) => { - // Check if the preference type is already in the list - const existingPrefIndex = prevPreferences.findIndex((pref) => Object.keys(pref)[0] === type); + // const updatePreferences = (type, value) => { + // setPreferences((prevPreferences) => { + // // Check if the preference type is already in the list + // const existingPrefIndex = prevPreferences.findIndex((pref) => Object.keys(pref)[0] === type); - // If it exists, update the value, otherwise add it - if (existingPrefIndex !== -1) { - prevPreferences[existingPrefIndex][type] = value; - return [...prevPreferences]; - } else { - return [...prevPreferences, { [type]: value }]; - } - }); - }; + // // If it exists, update the value, otherwise add it + // if (existingPrefIndex !== -1) { + // prevPreferences[existingPrefIndex][type] = value; + // return [...prevPreferences]; + // } else { + // return [...prevPreferences, { [type]: value }]; + // } + // }); + // }; - const handleClick = async () => { - // You can access the list of preferences and selected values - console.log('Preferences:', preferences); - console.log('Morning or Night:', morningOrNight); - console.log('Loud or Quiet:', loudOrQuiet); - await housingService.addRoommate({ morningOrNight, loudOrQuiet }); - }; + // const handleClick = async () => { + // // You can access the list of preferences and selected values + // console.log('Preferences:', preferences); + // console.log('Morning or Night:', morningOrNight); + // console.log('Loud or Quiet:', loudOrQuiet); + // await housingService.addRoommate({ morningOrNight, loudOrQuiet }); + // }; useEffect(() => { // Save preferences to local storage diff --git a/src/views/HousingLottery/studentView/index.jsx b/src/views/HousingLottery/studentView/index.jsx index 82da65e3ae..e0c1e57d97 100644 --- a/src/views/HousingLottery/studentView/index.jsx +++ b/src/views/HousingLottery/studentView/index.jsx @@ -44,6 +44,10 @@ const StudentView = () => { } }; + const handlePreferenceChange = (newPreferences) => { + setPreferenceResult(newPreferences); + }; + return ( @@ -57,7 +61,7 @@ const StudentView = () => { - + From 78a383330418b3eb121529ef50bc925349b42a64 Mon Sep 17 00:00:00 2001 From: Eric Date: Sun, 10 Dec 2023 14:08:24 -0500 Subject: [PATCH 091/112] Deleted commented code --- .../studentView/PreferenceBox/index.jsx | 23 ------------------- 1 file changed, 23 deletions(-) diff --git a/src/views/HousingLottery/studentView/PreferenceBox/index.jsx b/src/views/HousingLottery/studentView/PreferenceBox/index.jsx index dad9a2eabb..413f749f0b 100644 --- a/src/views/HousingLottery/studentView/PreferenceBox/index.jsx +++ b/src/views/HousingLottery/studentView/PreferenceBox/index.jsx @@ -46,29 +46,6 @@ const Preference = ({onPreferenceChange}) => { onPreferenceChange({ morningOrNight, loudOrQuiet: newLoudOrQuiet }); }; - // const updatePreferences = (type, value) => { - // setPreferences((prevPreferences) => { - // // Check if the preference type is already in the list - // const existingPrefIndex = prevPreferences.findIndex((pref) => Object.keys(pref)[0] === type); - - // // If it exists, update the value, otherwise add it - // if (existingPrefIndex !== -1) { - // prevPreferences[existingPrefIndex][type] = value; - // return [...prevPreferences]; - // } else { - // return [...prevPreferences, { [type]: value }]; - // } - // }); - // }; - - // const handleClick = async () => { - // // You can access the list of preferences and selected values - // console.log('Preferences:', preferences); - // console.log('Morning or Night:', morningOrNight); - // console.log('Loud or Quiet:', loudOrQuiet); - // await housingService.addRoommate({ morningOrNight, loudOrQuiet }); - // }; - useEffect(() => { // Save preferences to local storage const storedPreferences = JSON.stringify({ morningOrNight, loudOrQuiet }); From 2fdd765c2ebcbd4ca00cb850a4bc36b786c32812 Mon Sep 17 00:00:00 2001 From: Eric Date: Sun, 10 Dec 2023 15:42:09 -0500 Subject: [PATCH 092/112] Fixed Agreements checkbox error and added feature --- .../HousingLottery/HousingLottery.module.scss | 45 ------------------- .../studentView/Instructions/index.jsx | 2 +- .../HousingLottery/studentView/index.jsx | 16 ++++++- 3 files changed, 15 insertions(+), 48 deletions(-) diff --git a/src/views/HousingLottery/HousingLottery.module.scss b/src/views/HousingLottery/HousingLottery.module.scss index 1a0ac2c13a..b69d924e54 100644 --- a/src/views/HousingLottery/HousingLottery.module.scss +++ b/src/views/HousingLottery/HousingLottery.module.scss @@ -177,51 +177,6 @@ strong.over_emphasized { } } -.apartment_card_header { - background-color: var(--mui-palette-primary-main); - color: var(--mui-palette-primary-contrastText); - :global { - .MuiTypography-colorTextSecondary { - color: var(--mui-palette-primary-contrastText); - font-size: 1.25rem; - } - - .MuiCardHeader-subheader { - color: var(--mui-palette-primary-contrastText); - } - } -} - -.apartment_instructions { - & :global(.MuiTypography-root) { - padding: 0.25rem 0.75rem; - } - - & :global(.MuiTypography-paragraph) { - text-align: left; - } - - & :global(.MuiTableContainer-root) { - border: 1px solid var(--mui-palette-neutral-700); - border-radius: 4px; - } -} - -.apartment_agreements_form_control { - text-align: left; - - &_label { - color: var(--mui-palette-neutral-700); - } - - // (CSSMODULES - fix mui overrides - disable no-descending-specificity) - /* stylelint-disable-next-line */ - & :global(.MuiDivider-root) { - margin-top: 0.5em; - margin-bottom: 0.5em; - } -} - .flexContainer { display: flex; flex-direction: column; diff --git a/src/views/HousingLottery/studentView/Instructions/index.jsx b/src/views/HousingLottery/studentView/Instructions/index.jsx index 08d80e5b9c..5c1a2cd694 100644 --- a/src/views/HousingLottery/studentView/Instructions/index.jsx +++ b/src/views/HousingLottery/studentView/Instructions/index.jsx @@ -50,7 +50,7 @@ const Instructions = () => { return ( } aria-controls="instructions-panel-content" id="instructions-panel-header" diff --git a/src/views/HousingLottery/studentView/index.jsx b/src/views/HousingLottery/studentView/index.jsx index e0c1e57d97..81f3fad80f 100644 --- a/src/views/HousingLottery/studentView/index.jsx +++ b/src/views/HousingLottery/studentView/index.jsx @@ -20,6 +20,13 @@ const StudentView = () => { console.log('Student Applicant Result:', studentApplicantResult); console.log('Preference Result:', preferenceResult); + const handleAgreementsChange = (allChecked) => { + setPreferenceResult((prevResult) => ({ + ...prevResult, + allAgreementsChecked: allChecked, + })); + }; + const handleClick = async () => { if (preferredHallResult.includes('')) { setSnackbar({ @@ -65,10 +72,15 @@ const StudentView = () => {
- + - From b8d9a4940f228b16e601f71c8b0fec2ef268b17d Mon Sep 17 00:00:00 2001 From: Eric Date: Sun, 10 Dec 2023 22:55:35 -0500 Subject: [PATCH 093/112] Fixed data to save in array --- .../HousingLottery/studentView/index.jsx | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/views/HousingLottery/studentView/index.jsx b/src/views/HousingLottery/studentView/index.jsx index 81f3fad80f..a40ddcedde 100644 --- a/src/views/HousingLottery/studentView/index.jsx +++ b/src/views/HousingLottery/studentView/index.jsx @@ -16,15 +16,20 @@ const StudentView = () => { const [preferenceResult, setPreferenceResult] = useState([]); const application_id = nanoid(8); const [snackbar, setSnackbar] = useState({ message: '', severity: null, open: false }); + const [areAllAgreementsChecked, setAreAllAgreementsChecked] = useState(false); console.log('Preferred Hall Result:', preferredHallResult); console.log('Student Applicant Result:', studentApplicantResult); - console.log('Preference Result:', preferenceResult); + console.log('Preference Result:', preferenceResult); const handleAgreementsChange = (allChecked) => { - setPreferenceResult((prevResult) => ({ - ...prevResult, - allAgreementsChecked: allChecked, - })); + const agreementData = [allChecked]; + console.log('Agreement Data:', agreementData); + setAreAllAgreementsChecked(allChecked); + }; + + const handlePreferenceChange = (newPreferences) => { + const preferenceData = [newPreferences.morningOrNight, newPreferences.loudOrQuiet]; + console.log('Preference Data:', preferenceData); }; const handleClick = async () => { @@ -51,9 +56,6 @@ const StudentView = () => { } }; - const handlePreferenceChange = (newPreferences) => { - setPreferenceResult(newPreferences); - }; return ( @@ -79,7 +81,7 @@ const StudentView = () => { className={styles.submit_button} variant="contained" onClick={handleClick} - disabled={!preferenceResult.allAgreementsChecked} + disabled={!areAllAgreementsChecked} > Submit From a3e4cdbc3678f2ac60349f4fa4e78c02646ee2a8 Mon Sep 17 00:00:00 2001 From: Wenlan Ji Date: Mon, 11 Dec 2023 00:28:48 -0500 Subject: [PATCH 094/112] fix preference list --- .../studentView/PreferenceBox/index.jsx | 14 ++++++++++---- src/views/HousingLottery/studentView/index.jsx | 18 ++++-------------- 2 files changed, 14 insertions(+), 18 deletions(-) diff --git a/src/views/HousingLottery/studentView/PreferenceBox/index.jsx b/src/views/HousingLottery/studentView/PreferenceBox/index.jsx index 413f749f0b..93bd1fe9ea 100644 --- a/src/views/HousingLottery/studentView/PreferenceBox/index.jsx +++ b/src/views/HousingLottery/studentView/PreferenceBox/index.jsx @@ -19,8 +19,8 @@ import housingService from 'services/housing'; import housing from 'services/housing'; import styles from '../../HousingLottery.module.css'; -const Preference = ({onPreferenceChange}) => { - const [preferences, setPreferences] = useState([]); // Store preferences as an array +const Preference = ({ onPreferenceChange }) => { + const [preferences, setPreferences] = useState(['', '']); // Store preferences as an array const [morningOrNight, setMorningOrNight] = useState(''); // Store the selected morning or night const [loudOrQuiet, setLoudOrQuiet] = useState(''); // Store the selected loud or quiet @@ -36,14 +36,20 @@ const Preference = ({onPreferenceChange}) => { const handleMorningOrNightChange = (event) => { const newMorningOrNight = event.target.value; + let newList = [...preferences]; + newList[0] = newMorningOrNight; setMorningOrNight(newMorningOrNight); - onPreferenceChange({ morningOrNight: newMorningOrNight, loudOrQuiet }); + setPreferences(newList); + onPreferenceChange(newList); }; const handleLoudOrQuietChange = (event) => { const newLoudOrQuiet = event.target.value; + let newList = [...preferences]; + newList[1] = newLoudOrQuiet; setLoudOrQuiet(newLoudOrQuiet); - onPreferenceChange({ morningOrNight, loudOrQuiet: newLoudOrQuiet }); + setPreferences(newList); + onPreferenceChange(newList); }; useEffect(() => { diff --git a/src/views/HousingLottery/studentView/index.jsx b/src/views/HousingLottery/studentView/index.jsx index a40ddcedde..0db7d0b354 100644 --- a/src/views/HousingLottery/studentView/index.jsx +++ b/src/views/HousingLottery/studentView/index.jsx @@ -19,7 +19,7 @@ const StudentView = () => { const [areAllAgreementsChecked, setAreAllAgreementsChecked] = useState(false); console.log('Preferred Hall Result:', preferredHallResult); console.log('Student Applicant Result:', studentApplicantResult); - console.log('Preference Result:', preferenceResult); + console.log('Preference Result:', preferenceResult); const handleAgreementsChange = (allChecked) => { const agreementData = [allChecked]; @@ -28,20 +28,11 @@ const StudentView = () => { }; const handlePreferenceChange = (newPreferences) => { - const preferenceData = [newPreferences.morningOrNight, newPreferences.loudOrQuiet]; - console.log('Preference Data:', preferenceData); + setPreferenceResult(newPreferences); + console.log('Preference Data:', newPreferences); }; const handleClick = async () => { - if (preferredHallResult.includes('')) { - setSnackbar({ - message: 'Please complete all hall preferences before submitting.', - severity: 'warning', - open: true, - }); - return; - } - try { console.log(application_id); await housingService.addApplicant(application_id, studentApplicantResult); @@ -56,7 +47,6 @@ const StudentView = () => { } }; - return ( @@ -77,7 +67,7 @@ const StudentView = () => { - - - - - Lottery Number - {Array.from({ length: 4 }, (_, i) => ( - - Applicant {i + 1}'s Email - - ))} - {Array.from({ length: 6 }, (_, i) => ( - Preferred Hall {i + 1} - ))} - {Array.from({ length: 2 }, (_, i) => ( - Preference {i + 1} - ))} - Class Standing - - - {/* - - {applicant.ApplicationID} - {Array.from({ length: 4 }, (_, i) => ( - {row[`Applicant ${i + 1}'s Email`]} - ))} - {Array.from({ length: 6 }, (_, i) => ( - {row[`Preferred Hall ${i + 1}`]} - ))} - {row.preference} - {row.standing} - - */} -
-
+ + + + Lottery Number + {Array.from({ length: 4 }, (_, i) => ( + + Applicant {i + 1}'s Email + + ))} + {Array.from({ length: 6 }, (_, i) => ( + Preferred Hall {i + 1} + ))} + {Array.from({ length: 2 }, (_, i) => ( + Preference {i + 1} + ))} + Class Standing + + + + {Object.keys(combinedData).map((applicationId, index) => { + const appData = combinedData[applicationId]; + return ( + + {index + 1} + {Array.from({ length: 4 }, (_, i) => ( + + {appData.applicants && appData.applicants.length > i ? appData.applicants[i] : ''} + + ))} + {Array.from({ length: 6 }, (_, i) => ( + + {appData.preferredHalls && appData.preferredHalls.length > i ? appData.preferredHalls[i] : ''} + + ))} + {Array.from({ length: 2 }, (_, i) => ( + + {appData.preferences && appData.preferences.length > i ? appData.preferences[i] : ''} + + ))} + {appData.year || ''} + + ); + })} + +
+ + + From 1f5824a577869bf576ae746222ccfc2321863d3d Mon Sep 17 00:00:00 2001 From: Wenlan Ji Date: Mon, 29 Jan 2024 06:56:00 -0500 Subject: [PATCH 105/112] add email for initail user --- src/views/HousingLottery/studentView/index.jsx | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/views/HousingLottery/studentView/index.jsx b/src/views/HousingLottery/studentView/index.jsx index 0db7d0b354..904ca89df1 100644 --- a/src/views/HousingLottery/studentView/index.jsx +++ b/src/views/HousingLottery/studentView/index.jsx @@ -1,4 +1,4 @@ -import { useState } from 'react'; +import { useEffect, useState } from 'react'; import { Button, Grid } from '@mui/material'; import PreferredHall from './PreferredHall'; import StudentApplicants from './StudentApplicants/index.jsx'; @@ -9,10 +9,17 @@ import housingService from 'services/housing'; import styles from '../HousingLottery.module.css'; import { nanoid } from 'nanoid'; import GordonSnackbar from 'components/Snackbar'; +import user from '../../../services/user'; const StudentView = () => { - const [preferredHallResult, setPreferredHallResult] = useState([]); + const [email, setEmail] = useState(''); const [studentApplicantResult, setStudentApplicantResult] = useState([]); + useEffect(async () => { + const profile = await user.getProfileInfo(); + setEmail(profile.Email); + setStudentApplicantResult([email]); + }, [email]); + const [preferredHallResult, setPreferredHallResult] = useState([]); const [preferenceResult, setPreferenceResult] = useState([]); const application_id = nanoid(8); const [snackbar, setSnackbar] = useState({ message: '', severity: null, open: false }); From a948554e494ec0f2e68e900c0fa6acfc746814ef Mon Sep 17 00:00:00 2001 From: Wenlan Ji Date: Sat, 3 Feb 2024 23:36:07 -0500 Subject: [PATCH 106/112] set and get due date --- src/services/housing.ts | 5 +++++ src/views/HousingLottery/adminView/index.jsx | 20 +++++++++++++++++++ .../HousingLottery/studentView/index.jsx | 15 ++++++++++++-- 3 files changed, 38 insertions(+), 2 deletions(-) diff --git a/src/services/housing.ts b/src/services/housing.ts index 5f9d7da7e4..daa1d40fbf 100644 --- a/src/services/housing.ts +++ b/src/services/housing.ts @@ -70,6 +70,7 @@ const getAllApplicant = (): Promise => http.get('housing/housing_lottery/all_applicant'); const getAllSchoolYear = (): Promise => http.get('housing/housing_lottery/all_school_year'); +const getDueDate = (): Promise => http.get('housing/housing_lottery/get_due_date'); const getCurrentApplicationID = (username: string = ''): Promise => http.get(username ? `housing/apartment/${username}/` : 'housing/apartment/'); @@ -182,6 +183,8 @@ const addHall = (applicantion_id: string, hallList: string[]) => const addPreference = (applicantion_id: string, preferenceList: string[]) => http.put(`housing/housing_lottery/preference/${applicantion_id}`, preferenceList); +const addDueDate = (dueDate: string) => http.put(`housing/housing_lottery/due_date/`, dueDate); + const housingService = { getApartmentSelectionDate, getApartmentHalls, @@ -190,6 +193,7 @@ const housingService = { getAllPreferredHall, getAllApplicant, getAllSchoolYear, + getDueDate, getCurrentApplicationID, saveApartmentApplication, deleteApartmentApplication, @@ -200,6 +204,7 @@ const housingService = { addApplicant, addHall, addPreference, + addDueDate, }; export default housingService; diff --git a/src/views/HousingLottery/adminView/index.jsx b/src/views/HousingLottery/adminView/index.jsx index 91c0b8da90..322f02e609 100644 --- a/src/views/HousingLottery/adminView/index.jsx +++ b/src/views/HousingLottery/adminView/index.jsx @@ -13,6 +13,7 @@ import { Card, CardHeader, CardContent, + TextField, Link, } from '@mui/material'; import housingService from 'services/housing'; @@ -26,12 +27,14 @@ const AdminView = () => { const [preferredHall, setPreferredHall] = useState([]); const [applicant, setApplicant] = useState([]); const [schoolYear, setSchoolYear] = useState([]); + const [dueDate, setDueDate] = useState(''); useEffect(() => { housingService.getAllPreference().then(setPreference); housingService.getAllPreferredHall().then(setPreferredHall); housingService.getAllApplicant().then(setApplicant); housingService.getAllSchoolYear().then(setSchoolYear); + housingService.getDueDate().then(setDueDate); }, []); const csvData = data.map((row) => ({ @@ -75,9 +78,26 @@ const AdminView = () => { console.log(schoolYear); }; + const submitDueDate = async () => { + await housingService.addDueDate(dueDate); + }; + return ( + + setDueDate(event.target.value)} + /> + + diff --git a/src/views/HousingLottery/studentView/index.jsx b/src/views/HousingLottery/studentView/index.jsx index 904ca89df1..c3280035b9 100644 --- a/src/views/HousingLottery/studentView/index.jsx +++ b/src/views/HousingLottery/studentView/index.jsx @@ -19,15 +19,20 @@ const StudentView = () => { setEmail(profile.Email); setStudentApplicantResult([email]); }, [email]); + const [preferredHallResult, setPreferredHallResult] = useState([]); const [preferenceResult, setPreferenceResult] = useState([]); - const application_id = nanoid(8); const [snackbar, setSnackbar] = useState({ message: '', severity: null, open: false }); const [areAllAgreementsChecked, setAreAllAgreementsChecked] = useState(false); console.log('Preferred Hall Result:', preferredHallResult); console.log('Student Applicant Result:', studentApplicantResult); console.log('Preference Result:', preferenceResult); + const [dueDate, setDueDate] = useState(''); + useEffect(() => { + housingService.getDueDate().then(setDueDate); + }, []); + const handleAgreementsChange = (allChecked) => { const agreementData = [allChecked]; console.log('Agreement Data:', agreementData); @@ -41,7 +46,13 @@ const StudentView = () => { const handleClick = async () => { try { - console.log(application_id); + let application_id = nanoid(8), + timeTarget = new Date(dueDate + ' 11:24:00 PM').getTime(), + timeNow = new Date().getTime(); + if (timeNow > timeTarget) { + application_id = 'zzz' + timeNow; + } + console.log('application_id ' + application_id); await housingService.addApplicant(application_id, studentApplicantResult); await housingService.addHall(application_id, preferredHallResult); await housingService.addPreference(application_id, preferenceResult); From a4faf0bf3fd94ee31b267a93201ccbd8679680d5 Mon Sep 17 00:00:00 2001 From: Eric Date: Mon, 5 Feb 2024 01:56:19 -0500 Subject: [PATCH 107/112] Fixed date input formatting --- src/views/HousingLottery/adminView/index.jsx | 25 ++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/src/views/HousingLottery/adminView/index.jsx b/src/views/HousingLottery/adminView/index.jsx index 322f02e609..8ce21de3b6 100644 --- a/src/views/HousingLottery/adminView/index.jsx +++ b/src/views/HousingLottery/adminView/index.jsx @@ -19,6 +19,7 @@ import { import housingService from 'services/housing'; import styles from '../HousingLottery.module.css'; import { CSVLink } from 'react-csv'; +import { setDate } from 'date-fns'; const AdminView = () => { const [data, setData] = useState([]); @@ -77,6 +78,20 @@ const AdminView = () => { console.log(applicant); console.log(schoolYear); }; + + const handleDateChange = (event) => { + let input = event.target.value.replace(/\D/g, ''); + + if (/^\d+$/.test(input)) { + if (input.length <= 2) { + setDueDate(input); + } else if (input.length <= 4) { + setDueDate(`${input.slice(0, 2)}/${input.slice(2)}`); + } else { + setDueDate(`${input.slice(0, 2)}/${input.slice(2, 4)}/${input.slice(4, 8)}`); + } + } + }; const submitDueDate = async () => { await housingService.addDueDate(dueDate); @@ -92,9 +107,15 @@ const AdminView = () => { color="secondary" label="Due Date" value={dueDate} - onChange={(event) => setDueDate(event.target.value)} + onChange={handleDateChange} + margin="normal" + helperText="* MM/DD/YYYY" /> - From 573a4549ef71d85d8b84639ec03661363fc609e3 Mon Sep 17 00:00:00 2001 From: Wenlan Ji Date: Thu, 8 Feb 2024 20:10:39 -0500 Subject: [PATCH 108/112] update time for due date --- src/views/HousingLottery/studentView/index.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/views/HousingLottery/studentView/index.jsx b/src/views/HousingLottery/studentView/index.jsx index c3280035b9..59622c4bf1 100644 --- a/src/views/HousingLottery/studentView/index.jsx +++ b/src/views/HousingLottery/studentView/index.jsx @@ -47,7 +47,7 @@ const StudentView = () => { const handleClick = async () => { try { let application_id = nanoid(8), - timeTarget = new Date(dueDate + ' 11:24:00 PM').getTime(), + timeTarget = new Date(dueDate + ' 11:59:59 PM').getTime(), timeNow = new Date().getTime(); if (timeNow > timeTarget) { application_id = 'zzz' + timeNow; From 0d0c8969f711c3de416fd2d9141f31f946015140 Mon Sep 17 00:00:00 2001 From: Zhijie Wang Date: Sat, 10 Feb 2024 18:52:43 -0500 Subject: [PATCH 109/112] fix the redundant row in the csv file and improve the code quaility --- src/views/HousingLottery/adminView/index.jsx | 46 +++++++++----------- 1 file changed, 21 insertions(+), 25 deletions(-) diff --git a/src/views/HousingLottery/adminView/index.jsx b/src/views/HousingLottery/adminView/index.jsx index 51a67ccb37..175de66ada 100644 --- a/src/views/HousingLottery/adminView/index.jsx +++ b/src/views/HousingLottery/adminView/index.jsx @@ -18,7 +18,6 @@ import { CSVLink } from 'react-csv'; const AdminView = () => { const [data, setData] = useState([]); - const [preference, setPreference] = useState([]); const [preferredHall, setPreferredHall] = useState([]); const [applicant, setApplicant] = useState([]); @@ -83,10 +82,10 @@ const AdminView = () => { return { 'Lottery Number': applicationId, //Jan 28: Now we still treat ApplicationID is used as Lottery Number - 'Applicant 1’s Email': appData.applicants[0] || '', - 'Applicant 2’s Email': appData.applicants[1] || '', - 'Applicant 3’s Email': appData.applicants[2] || '', - 'Applicant 4’s Email': appData.applicants[3] || '', + 'Applicant 1`s Email': appData.applicants[0] || '', + 'Applicant 2`s Email': appData.applicants[1] || '', + 'Applicant 3`s Email': appData.applicants[2] || '', + 'Applicant 4`s Email': appData.applicants[3] || '', 'Preferred Hall 1': appData.preferredHalls[0] || '', 'Preferred Hall 2': appData.preferredHalls[1] || '', 'Preferred Hall 3': appData.preferredHalls[2] || '', @@ -100,28 +99,23 @@ const AdminView = () => { }); const csvHeaders = [ - 'Lottery Number', - 'Applicant 1’s Email', - 'Applicant 2’s Email', - 'Applicant 3’s Email', - 'Applicant 4’s Email', - 'Preferred Hall 1', - 'Preferred Hall 2', - 'Preferred Hall 3', - 'Preferred Hall 4', - 'Preferred Hall 5', - 'Preferred Hall 6', - 'Preference 1', - 'Preference 2', - 'Class Standing', // Add class standing header + {label:'Lottery Number',key:'Lottery Number'}, + {label:'Applicant 1`s Email',key:'Applicant 1`s Email'}, + {label:'Applicant 2`s Email',key:'Applicant 2`s Email'}, + {label:'Applicant 3`s Email',key:'Applicant 3`s Email'}, + {label:'Applicant 4`s Email',key:'Applicant 4`s Email'}, + {label:'Preferred Hall 1',key:'Preferred Hall 1'}, + {label:'Preferred Hall 2',key:'Preferred Hall 2'}, + {label:'Preferred Hall 3',key:'Preferred Hall 3'}, + {label:'Preferred Hall 4',key:'Preferred Hall 4'}, + {label:'Preferred Hall 5',key:'Preferred Hall 5'}, + {label:'Preferred Hall 6',key:'Preferred Hall 6'}, + {label:'Preference 1',key:'Preference 1'}, + {label:'Preference 2',key:'Preference 2'}, + {label:'Class Standing',key:'Class Standing'}, ]; -const csvHeadersObject = csvHeaders.reduce((obj, header) => { - obj[header] = header; - return obj; -}, {}); -const csvDataForExport = [csvHeadersObject, ...csvData]; return ( @@ -130,9 +124,11 @@ const csvDataForExport = [csvHeadersObject, ...csvData];
- - {rows.map((row) => ( - - {row.description} - {row.points} - - ))} - -
-
-
-
-
- - If You Are Approved... - - - You will be notified of your placement in an apartment/Village{' '} - - building - {' '} - no later than Apr. 13. Further information about specific apartment/room selection will be - communicated in that email. - - - +
+ + Instructions (As easy as 1, 2, 3!) + + + 1. Review FAQs + + + 2. Access questionnaire + + + 3. Complete questionnaire by providing name(s), email(s), and housing preferences by Friday, Apr. 21 at noon. + + + + } + aria-controls="housing-lottery-faq-content" + id="housing-lottery-faq-header" + > + Housing Lottery FAQ + + + + 1. Who should complete the questionnaire?
+ Anyone who has not yet secured housing for the Fall 2022 semester should participate in the lottery by completing the questionnaire. +
+ {/* Repeat for other questions */} + + 3. How can I learn more about my housing options?
+ Please visit our residence halls for information about our residence halls. Room cost information can be obtained by visiting room costs. +
+ {/* Include all other FAQ items in a similar manner */} +
+
+
); }; From f86de1155422e9e5702fa9ae0ee15f557110ab0a Mon Sep 17 00:00:00 2001 From: Zhijie Wang Date: Sun, 11 Feb 2024 00:26:52 -0500 Subject: [PATCH 111/112] update the content of instructions based on the housing director's feedback --- .../studentView/Instructions/index.jsx | 85 +++++++++++++++++-- 1 file changed, 79 insertions(+), 6 deletions(-) diff --git a/src/views/HousingLottery/studentView/Instructions/index.jsx b/src/views/HousingLottery/studentView/Instructions/index.jsx index d256de2558..b9b96d17d1 100644 --- a/src/views/HousingLottery/studentView/Instructions/index.jsx +++ b/src/views/HousingLottery/studentView/Instructions/index.jsx @@ -11,9 +11,10 @@ import styles from '../../HousingLottery.module.css'; const Instructions = () => { return ( +
- - Instructions (As easy as 1, 2, 3!) + + Instructions (As easy as 1, 2, 3!) 1. Review FAQs @@ -27,7 +28,8 @@ const Instructions = () => { } + className={styles.housing_card_header} + expandIcon={} aria-controls="housing-lottery-faq-content" id="housing-lottery-faq-header" > @@ -38,12 +40,83 @@ const Instructions = () => { 1. Who should complete the questionnaire?
Anyone who has not yet secured housing for the Fall 2022 semester should participate in the lottery by completing the questionnaire.
- {/* Repeat for other questions */} + + 2. What happens if I do not complete the questionnaire by the deadline?
+ The questionnaire will remain open and can be completed after the deadline. + All late submissions will be placed on a housing waitlist and given a placement in July, as fall semester availability is much clearer by that time. +
3. How can I learn more about my housing options?
- Please visit our residence halls for information about our residence halls. Room cost information can be obtained by visiting room costs. + Please visit our residence halls + for information about our residence halls. Room cost information can be obtained by visiting + room costs . +
+ + 4. How will I learn my room assignment?
+ You will receive your room assignment via email no later than Friday, Apr.28. +
+ + 5. Do I need to be registered for classes to complete the questionnaire?
+ No, you should complete the questionnaire even if you are not yet registered for classes. + However, registration will be taken into consideration during the assigning process. See question #13. +
+ + 6.What if I complete the questionnaire, and then want to change my preferences?
+ Simply complete the questionnaire again. You can complete the questionnaire as many times as needed prior to the deadline. + Only your most recent submission will be taken into consideration. +
+ + 7. Do I need a roommate to complete the questionnaire?
+ No, you do not need a roommate to complete the questionnaire and receive a housing assignment. If you participate in the housing lottery without a roommate, you will be assigned a roommate. That assignment will be communicated via email. +
+ + 8. I have a roommate (or two or three). Should we all complete separate questionnaires?
+ No. If you are applying as a group of two, three, or four, you should only complete one questionnaire. Each group will receive one lottery number, regardless of group size. The person listed first on the questionnaire will serve as the contact person for your group. +
+ + 9. Can I request to room with an incoming student?
+ Yes, just include “(incoming)” after listing their name on the questionnaire. +
+ + 10. What about suite mates?
+ There is a space to indicate suite mate requests on the questionnaire. +
+ + 11. Are single rooms available during the lottery?
+ No, single rooms were assigned during the Special Accommodations process. +
+ + 12. Can I request a specific room during the lottery?
+ Yes, there is a space on the form to indicate a specific room request. We will do our best to accommodate requests, but there is no guarantee. +
+ + 13. How will lottery order be determined?
+ Lottery order will be determined class-by-class (based on current academic standing), using a randomizer. + For example, if 40 current seniors register for the lottery, the names of those 40 seniors will be inputted, and assigning will begin with the lowest number. + Current juniors, current sophomores, and current freshman will follow, in that order. + Important note: the aforementioned process assumes that a student is registered for Fall 2023 classes and is not on chapel probation. + All students, regardless of class, who are not registered for classes by the beginning of the assignment process will be grouped together, given lottery numbers, and assigned after the current freshman class. + If one member of a group is not registered for classes, the entire group will be considered as unregistered. Students on chapel probation will be included with the unregistered group. +
+ + 14. I am a sophomore, and my roommate is a senior. With which class will our questionnaire be reviewed?
+ In situations where group members have different academic standings, the group will be considered to have the standing of the member with the highest standing. + To use the example from the question, a sophomore + senior group would be considered to have senior standing. +
+ + 15. Where can I learn my class standing?
+ You can visit 360.gordon.edu to learn your class standing. +
+ + 16. What if I want housing other than what I receive?
+ It is our goal to accommodate every preference, but we are unfortunately unable to do so. + If you want to request a different location after receiving your assignment, you can email Housing on or after July 1 to request that. +
+ + 17. How can I receive confirmation that my questionnaire has been received?
+ If you would like confirmation that your questionnaire has been received, you will need to select the “Send me an email receipt of my responses” box at the bottom of the questionnaire. + No other confirmation will be provided.
- {/* Include all other FAQ items in a similar manner */}
From c909c09cc18030276e355a67bf379df8f4129e82 Mon Sep 17 00:00:00 2001 From: Zhijie Wang Date: Mon, 19 Feb 2024 14:10:03 -0500 Subject: [PATCH 112/112] Applicants'emails now has combined in one dropdown button for each application --- src/views/HousingLottery/adminView/index.jsx | 33 +++++++++++++++----- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/src/views/HousingLottery/adminView/index.jsx b/src/views/HousingLottery/adminView/index.jsx index 6a09a2f0e3..adeb094600 100644 --- a/src/views/HousingLottery/adminView/index.jsx +++ b/src/views/HousingLottery/adminView/index.jsx @@ -12,11 +12,16 @@ import { CardHeader, CardContent, TextField, + Accordion, + AccordionSummary, + AccordionDetails, + Typography, Link, } from '@mui/material'; import housingService from 'services/housing'; import styles from '../HousingLottery.module.css'; import { CSVLink } from 'react-csv'; +import ExpandMoreIcon from '@mui/icons-material/ExpandMore'; import { setDate } from 'date-fns'; const AdminView = () => { @@ -200,16 +205,29 @@ const AdminView = () => { return ( {ApplicationID} - {Array.from({ length: 4 }, (_, i) => ( - - {appData.applicants && appData.applicants.length > i ? appData.applicants[i] : ''} - - ))} + + + } + aria-controls={`panel1a-content-${index}`} + id={`panel1a-header-${index}`} + > + View Applicants + + + {appData.applicants.map((email, idx) => ( + + {email} + + ))} + + + {Array.from({ length: 6 }, (_, i) => ( - + {appData.preferredHalls && appData.preferredHalls.length > i ? appData.preferredHalls[i] : ''} - ))} + ))} {Array.from({ length: 2 }, (_, i) => ( {appData.preferences && appData.preferences.length > i ? appData.preferences[i] : ''} @@ -220,6 +238,7 @@ const AdminView = () => { ); })} +