Skip to content

Commit

Permalink
Merge pull request #444 from ubc-biztech/workshop-max-attendees
Browse files Browse the repository at this point in the history
Workshop max attendees
  • Loading branch information
ddennis924 authored Aug 27, 2023
2 parents 2361bb0 + 61f9463 commit ba0438a
Show file tree
Hide file tree
Showing 4 changed files with 237 additions and 29 deletions.
12 changes: 8 additions & 4 deletions src/pages/admin/DynamicForm/FormCreate.js
Original file line number Diff line number Diff line change
Expand Up @@ -711,6 +711,8 @@ const FormCreateForm = (props) => {
- TEXT
- SELECT
- CHECKBOX
- UPLOAD
- WORKSHOP SELECTION
Below is the data struct for registrationQuestions
Expand Down Expand Up @@ -738,14 +740,16 @@ const dummyData = [
questionImageUrl: "",
},
{
type: "SELECT",
label: "How interested are you in this event?",
choices: "1,2,3,4,5",
type: "WORKSHOP SELECTION",
label: "Select your workshop for this event",
choices: "Workshop 1,Workshop 2,Workshop 3,Workshop 4",
participantCap: "50,30,30,30",
required: true,
questionImageUrl: "",
}
];


const partnerDummyData = [
{
type: "CHECKBOX",
Expand Down Expand Up @@ -817,7 +821,7 @@ const FormCreate = (props) => {
};

const regQuestionSchema = Yup.object({
type: Yup.mixed().oneOf(["TEXT", "SELECT", "CHECKBOX", "UPLOAD"]).required(),
type: Yup.mixed().oneOf(["TEXT", "SELECT", "CHECKBOX", "UPLOAD", "WORKSHOP SELECTION"]).required(),
label: Yup.string().required("Question is a required field"),
choices: Yup.string(),
required: Yup.boolean().required(),
Expand Down
112 changes: 109 additions & 3 deletions src/pages/admin/DynamicForm/FormRegister.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,10 @@ const styles = {
},
submitSection: {
padding: "2rem"
},
disabled: {
pointerEvents: "none",
color: "grey",
}
};

Expand Down Expand Up @@ -173,6 +177,8 @@ const FormRegister = (props) => {
const [questionDomain, setQuestionDomain] = useState("");
const [isNonMemberModalOpen, setisNonMemberModalOpen] = useState(false);
const [isSubmitting, setIsSubmitting] = useState(false);
const [workshopChoicesArr, setWorkshopChoicesArr] = useState([]);
// const [workshopCounts, setWorkShopCounts] = useState([]);

const parsedRegistrationQuestions = currEvent.registrationQuestions?.map(
({
Expand Down Expand Up @@ -257,10 +263,24 @@ const FormRegister = (props) => {
);
eventData.counts = regData;
setCurrEvent(eventData);

// Populate the dynamicCounts array with data
eventData.counts.dynamicCounts.forEach((dynamicCount) => {
dynamicCount.counts.forEach((workshop) => {
if (workshop.count >= workshop.cap) {
workshop.isDisabled = true;
} else {
workshop.isDisabled = false;
}
});

// Push the modified dynamicCount into the dynamicCounts array
setWorkshopChoicesArr(eventData.counts.dynamicCounts);
});
}
};
fetchEvent();
}, []); // eslint-disable-line react-hooks/exhaustive-deps
}, [user, eventId, eventYear, registeredEvents, currEvent]);

useEffect(() => {
if (user) {
Expand Down Expand Up @@ -311,6 +331,41 @@ const FormRegister = (props) => {
}
}, [currEvent]); // eslint-disable-line react-hooks/exhaustive-deps

// disable workshops which are full from selection and mark them as such
useEffect(() => {
if (currEvent) {
const remaining =
currEvent.capac -
(currEvent.counts.registeredCount + currEvent.counts.checkedInCount);
if (remaining > 0 && remaining <= 20) {
setRegAlert(
<Alert severity="error" className={classes.regAlert}>
Warning: {currEvent.ename || "this event"} only has {remaining} spot
{remaining > 1 ? "s" : ""} left!
</Alert>
);
} else if (remaining <= 0 && !user) {
setRegAlert(
<Alert severity="error" className={classes.regAlert}>
Warning: {currEvent.ename || "this event"} is full!
</Alert>
);
} else {
setRegAlert(null);
}
if (
!(
user?.isMember ||
user?.admin ||
currEvent.pricing?.nonMembers === undefined ||
samePricing()
)
) {
setisNonMemberModalOpen(true);
}
}
}, [currEvent]); // eslint-disable-line react-hooks/exhaustive-deps

const updateField = useCallback(
(index, value) => {
const responses = responseData;
Expand Down Expand Up @@ -388,6 +443,7 @@ const FormRegister = (props) => {
);

const loadQuestions = () => {
let workshopQuestionCount = 0;
const returnArr = [];
for (let i = 0; i < formData.questions.length; i++) {
const {
Expand Down Expand Up @@ -643,6 +699,54 @@ const FormRegister = (props) => {
</FormControl>
</div>
);
} else if (questionType === "WORKSHOP SELECTION") {
returnArr.push(
<div style={{
paddingBottom: "1.5rem"
}}>
<p style={{
opacity: "0.7",
fontSize: "1rem",
margin: "0.5rem 0"
}}>
{question}
{question && required && "*"}
</p>
{questionImageUrl && (
<div style={styles.imageContainer}>
<img
style={styles.image}
src={questionImageUrl || ImagePlaceholder}
alt="Registration Form"
/>
</div>
)}
<FormControl
error={!!responseError[i]}
helperText={!!responseError[i] && responseError[i]}
>
<Select
className={classes.select}
labelId="q-type"
variant="outlined"
margin="dense"
value={responseData[i] || ""}
onChange={(e) => updateField(i, e.target.value)}
>
{workshopChoicesArr.length && workshopChoicesArr[workshopQuestionCount].counts.map((countItem, index) => (
<MenuItem key={index} value={countItem.label} disabled={countItem.isDisabled}>
{countItem.label}
{countItem.isDisabled ? " (Workshop is full)" : ""}
</MenuItem>
))}
</Select>
{!!responseError[i] && (
<FormHelperText>{responseError[i]}</FormHelperText>
)}
</FormControl>
</div>
);
workshopQuestionCount += 1;
}
}
return returnArr;
Expand Down Expand Up @@ -703,7 +807,7 @@ const FormRegister = (props) => {
const dynamicResponses = {
};
for (let i = BASIC_QUESTIONS.length; i < formData.questions.length; i++) {
if (formData.questions[i].questionType === "CHECKBOX") {
if (formData.questions[i].questionType === "CHECKBOX" || formData.questions[i].questionType === "WORKSHOP SELECTION") {
dynamicResponses[formData.questions[i].questionId] = responseData[
i
]?.join(", ");
Expand Down Expand Up @@ -797,6 +901,8 @@ const FormRegister = (props) => {
dynamicResponses[formData.questions[i].questionId] = responseData[
i
]?.join(", ");
} else if (formData.questions[i].questionType === "WORKSHOP SELECTION") {
dynamicResponses[formData.questions[i].questionId] = responseData[i];
} else {
dynamicResponses[formData.questions[i].questionId] = responseData[i];
}
Expand Down Expand Up @@ -830,7 +936,7 @@ const FormRegister = (props) => {
})
.catch((err) => {
alert(
`An error has occured: ${err} Please contact an exec for support.`
`An error has occured: ${err} Please contact an exec for support. 4`
);
setIsSubmitting(false);
});
Expand Down
86 changes: 65 additions & 21 deletions src/pages/admin/DynamicForm/components/CustomQuestion.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,15 @@ const CustomQuestion = (props) => {
handleBlur,
errors,
touched,
submitCount
submitCount,
} = useFormikContext();

const {
id, name, index, length
} = props;

const {
type, label, choices, questionImageUrl, charLimit, required, isSkillsQuestion
type, label, choices, questionImageUrl, charLimit, required, participantCap, isSkillsQuestion
} = props.data;
const questionStyles = {
// -------- QUESTION COMPONENT STYLES ----------
Expand Down Expand Up @@ -143,6 +143,7 @@ const CustomQuestion = (props) => {
<MenuItem value="CHECKBOX">Checkbox</MenuItem>
<MenuItem value="SELECT">Selection</MenuItem>
<MenuItem value="UPLOAD">Upload</MenuItem>
<MenuItem value="WORKSHOP SELECTION">Workshop Selection</MenuItem>
</Select>
<div style={questionStyles.iconsContainer}>
<div style={questionStyles.move}>
Expand Down Expand Up @@ -245,30 +246,73 @@ const CustomQuestion = (props) => {
value={choices}
/>
)}
<div style={questionStyles.checkboxWrapper}>
<div style={questionStyles.checkboxContainer}>
Skills Question?
<Checkbox
id={`${id}.isSkillsQuestion`}
name={`${name}.isSkillsQuestion`}
color="primary"
aria-label="Skills question?"
checked={isSkillsQuestion}

{type === "WORKSHOP SELECTION" && (
<div>
<TextField
id={`${id}.choices`}
name={`${name}.choices`}
label="Workshop Choices"
fullWidth
required
margin="normal"
variant="filled"
onChange={handleChange}
onBlur={handleBlur}
error={showError("choices)")}
helperText={
showError("choices")
}
value={choices}
/>
<Tooltip title="Items must match number of workshops." arrow>
<TextField
id={`${id}.participantCap`}
name={`${name}.participantCap`}
label="Maximum Participants for each Workshop"
fullWidth
required
margin="normal"
variant="filled"
onChange={handleChange}
onBlur={handleBlur}
error={showError("participantCap")}
helperText={
showError("participantCap") &&
errors.registrationQuestions[index].participantCap
}
value={participantCap}
/>
</Tooltip>
</div>
<div style={questionStyles.checkboxContainer}>
)}

<div style={questionStyles.requiredContainer}>
<div style={questionStyles.checkboxWrapper}>
<div style={questionStyles.checkboxContainer}>
Skills Question?
<Checkbox
id={`${id}.isSkillsQuestion`}
name={`${name}.isSkillsQuestion`}
color="primary"
aria-label="Skills question?"
checked={isSkillsQuestion}
onChange={handleChange}
onBlur={handleBlur}
/>
</div>
<div style={questionStyles.checkboxContainer}>
Required?
<Checkbox
id={`${id}.required`}
name={`${name}.required`}
color="primary"
aria-label="Required question?"
checked={required}
onChange={handleChange}
onBlur={handleBlur}
/>
<Checkbox
id={`${id}.required`}
name={`${name}.required`}
color="primary"
aria-label="Required question?"
checked={required}
onChange={handleChange}
onBlur={handleBlur}
/>
</div>
</div>
</div>
</div>
Expand Down
Loading

0 comments on commit ba0438a

Please sign in to comment.