-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'main' into feature/simple-settings-page
- Loading branch information
Showing
8 changed files
with
520 additions
and
202 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
import { Modal } from 'antd'; | ||
import 'survey-core/defaultV2.min.css'; | ||
import { Model } from 'survey-core'; | ||
import { Survey } from 'survey-react-ui'; | ||
import { useState, useEffect } from 'react'; | ||
import { | ||
ApplicationQuestionData, | ||
ApplicationAnswer, | ||
QueriedVolunteerEventDTO, | ||
} from 'bookem-shared/src/types/database'; | ||
|
||
// choices can type string[] or null | ||
const processChoices = (choices: String[] | undefined) => { | ||
if (choices == null) { | ||
return null; | ||
} | ||
|
||
return choices.map(choice => { | ||
return { | ||
value: choice, | ||
text: choice, | ||
}; | ||
}); | ||
}; | ||
|
||
// process answes to fit the answer type. return the answer casted into application answer | ||
const processAnswers = (answerObj: any) => { | ||
// the key of the answer object is the question id | ||
// the value is the answer. The value can be a string or an array of strings | ||
// we need to convert this into an array of application answers | ||
const answers = Object.keys(answerObj).map(key => { | ||
const answer = answerObj[key]; | ||
return { | ||
questionId: key, | ||
// check if the answer is an array, if not convert it into an array | ||
text: Array.isArray(answer) ? answer : [answer], | ||
}; | ||
}); | ||
|
||
return answers; | ||
}; | ||
|
||
const makeSurveyModel = (questions: ApplicationQuestionData[]) => { | ||
const elements = questions.map(question => { | ||
return { | ||
name: question._id, | ||
title: question.title, | ||
type: question.type, | ||
isRequired: question.isRequired, | ||
choices: processChoices(question.choices), | ||
}; | ||
}); | ||
|
||
return { | ||
elements: elements, | ||
}; | ||
}; | ||
|
||
export default function ApplicationPopup({ | ||
visible, | ||
onClose, | ||
event, | ||
onSubmit, | ||
}: { | ||
visible: boolean; | ||
onClose: () => void; | ||
event: QueriedVolunteerEventDTO; | ||
onSubmit: () => void; | ||
}) { | ||
const { name } = event; | ||
const [questions, setQuestions] = useState<ApplicationQuestionData[]>([]); | ||
|
||
let survey = new Model(makeSurveyModel(questions)); | ||
|
||
survey.onComplete.add(result => { | ||
const answers = processAnswers(result.data); | ||
console.log('Survey results: ', answers); | ||
// send the answers to the server | ||
fetch('/api/event/' + event._id + '/apply', { | ||
method: 'POST', | ||
headers: { | ||
'Content-Type': 'application/json', | ||
}, | ||
body: JSON.stringify({ | ||
answers: answers, | ||
}), | ||
}); | ||
|
||
onClose(); | ||
onSubmit(); | ||
}); | ||
|
||
useEffect(() => { | ||
const fetchQuestions = async () => { | ||
const res = await fetch('/api/event/' + event._id + '/apply', { | ||
method: 'GET', | ||
headers: { | ||
'Content-Type': 'application/json', | ||
}, | ||
}); | ||
|
||
// no application questions found | ||
if (res.status === 404) { | ||
return; | ||
} | ||
|
||
const data = await res.json(); | ||
const questions = data.message; | ||
setQuestions(questions); | ||
}; | ||
// fetch the questions from the database | ||
// set the survey model | ||
fetchQuestions(); | ||
}, [event._id]); | ||
|
||
return ( | ||
<Modal | ||
width={800} | ||
// title="Application" | ||
open={visible} | ||
onCancel={onClose} | ||
footer={null}> | ||
<h2> | ||
Application for event: <br /> | ||
<span style={{ color: 'gray', fontSize: '1rem' }}>{name}</span> | ||
</h2> | ||
<Survey model={survey} /> | ||
</Modal> | ||
); | ||
} |
78 changes: 78 additions & 0 deletions
78
components/Event/EventApplication/ApplicationStatusDisplay.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
import { StatusDisplayText } from '@/styles/components/Event/eventName.styles'; | ||
import { | ||
CheckCircleOutlined, | ||
ReadOutlined, | ||
ExclamationCircleOutlined, | ||
} from '@ant-design/icons'; | ||
import { useState, useEffect } from 'react'; | ||
import { | ||
ApplicationStatus, | ||
ApplicationResponseData, | ||
QueriedVolunteerEventDTO, | ||
} from 'bookem-shared/src/types/database'; | ||
|
||
const ApprovedText = () => ( | ||
<span> | ||
<CheckCircleOutlined | ||
style={{ | ||
color: 'green', | ||
margin: '0 10px', | ||
}} | ||
/> | ||
Approved | ||
</span> | ||
); | ||
|
||
const PendingText = () => ( | ||
<span> | ||
<ReadOutlined | ||
style={{ | ||
color: 'orange', | ||
margin: '0 10px', | ||
}} | ||
/> | ||
Under Review | ||
</span> | ||
); | ||
|
||
const RejectedText = () => ( | ||
<span> | ||
<ExclamationCircleOutlined | ||
style={{ | ||
color: 'red', | ||
margin: '0 10px', | ||
}} | ||
/> | ||
Rejected | ||
</span> | ||
); | ||
|
||
const statusDisplayText = { | ||
[ApplicationStatus.Pending]: <PendingText />, | ||
[ApplicationStatus.Approved]: <ApprovedText />, | ||
[ApplicationStatus.Rejected]: <RejectedText />, | ||
}; | ||
|
||
// Display the status of the volunteer application | ||
// TODO: add logic for fetching application responses and display its status | ||
const ApplicationStatusDisplay = ({ | ||
event, | ||
applicationResponses, | ||
}: { | ||
event: QueriedVolunteerEventDTO; | ||
applicationResponses: ApplicationResponseData | null; | ||
}) => { | ||
if (applicationResponses?.status == null) { | ||
return <StatusDisplayText>Application Required</StatusDisplayText>; | ||
} | ||
|
||
return ( | ||
<StatusDisplayText> | ||
Application Status: | ||
<br /> | ||
{statusDisplayText[applicationResponses.status]} | ||
</StatusDisplayText> | ||
); | ||
}; | ||
|
||
export default ApplicationStatusDisplay; |
Oops, something went wrong.