@material-ui/icons#Info JavaScript Examples

The following examples show how to use @material-ui/icons#Info. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: team-member-dialog-display.js    From turinghut-website with BSD Zero Clause License 6 votes vote down vote up
DialogDisplay = ({ person: { name, designation, phoneNumber, emailId, githubProfile, linkedinProfile } }) => {
    const classes = teamMemberStyles();
    const [open, setOpen] = useState(false);
    return (
        <div className={`${classes.tilebar} ${classes.tilebarRootTitle} ${classes.tilebarBottom}`}>
            <div className={`${classes.titlePosRight} ${classes.titleWrap}`}>
                <div className={classes.title}>{name}</div>
                <div><span>{designation}</span></div>
            </div>
            <CardActions onClick={() => setOpen(true)} className={classes.actionItem}><Info /></CardActions>
            <Dialog
                aria-labelledby="simple-dialog-title"
                aria-describedby="simple-dialog-description"
                open={open}
                onClose={() => { setOpen(false) }}
            >
                <DialogContent style={{minWidth:'38vh',minHeight:'25vh'}}>
                    {name ? <DialogContentText className={classes.dialogHeading}>{name}</DialogContentText> : null}
                    {phoneNumber ? <DialogContentText className={classes.dialogContent}><LocalPhone className={classes.icon}/> {phoneNumber}</DialogContentText> : null}
                    {emailId ? <DialogContentText className={classes.dialogContent}><Mail className={classes.icon}/> {emailId}</DialogContentText> : null}
                    {githubProfile ? <a href={githubProfile} alt={"githubProfile"} ><GitHub className={classes.githubIcon} /></a> : null}
                    {linkedinProfile ? <a href={linkedinProfile} alt={"linkedinProfile"}><LinkedIn className={classes.linkedinIcon} /></a> : null}
                </DialogContent>
            </Dialog>
        </div>
    )
}
Example #2
Source File: QuizzesSection.js    From Quizzie with MIT License 4 votes vote down vote up
function QuizzesSection(props) {
	const [loading, setLoading] = useState(true);
	const [userType, setUserType] = useState(props.type);
	const [profile, setProfile] = useState(props.profile);
	const [quizzes, setQuizzes] = useState([]);
	const [quizzesEnrolled, setQuizzesEnrolled] = useState([]);

	const [joinModal, setJoinModal] = useState(false);
	const [quizCode, setQuizCode] = useState("");
	const [quizCodeError, setQuizCodeError] = useState(false);

	const [enrollModal, setEnrollModal] = useState(false);
	const [enrollQuizName, setEnrollQuiz] = useState("");
	const [enrollQuizId, setEnrollQuizId] = useState("");

	const [enrollSnack, setEnrollSnack] = useState(false);
	const [snackbar, setSnackBar] = useState(false);
	const [errorSnack, setErrorSnack] = useState(false);

	const [infoModal, setInfoModal] = useState(false);
	const [infoLoading, setInfoLoading] = useState(false);
	const [currQuiz, setCurrQuiz] = useState({});
	const [timeRemain, setTimeRemain] = useState("");

	const [startModal, setStartModal] = useState(false);
	const [quizStarted, setQuizStarted] = useState(false);
	const [redirectId, setRedirectId] = useState("");
	const [quizDetails, setQuizDetails] = useState({});

	const [earlyError, setEarlyError] = useState(false);
	const [lateError, setLateError] = useState(false);
	const [givenSnack, setGivenSnack] = useState(false);
	const [privateWrongCode, setPrivateWrongCode] = useState(false);
	const [alreadyEnrolled, setAlreadyEnrolled] = useState(false);

	const setRefresh = props.refresh;

	const { executeRecaptcha } = useGoogleReCaptcha();

	const getCols = () => {
		if (isWidthUp("md", props.width)) {
			return 3;
		}

		return 2;
	};

	const getInfoWidth = () => {
		if (isWidthUp("sm", props.width)) {
			return "45%";
		}

		return "80%";
	};

	const onCloseHandle = () => {
		setJoinModal(false);
		setInfoModal(false);
		setStartModal(false);

		setQuizCode("");
		setQuizCodeError(false);
		setEnrollModal(false);
		setEnrollQuiz("");
		setEnrollQuizId("");
		setTimeRemain("");
		setCurrQuiz({});
	};

	const onJoinClick = () => {
		setJoinModal(true);
	};

	const handleJoinChange = (event) => {
		setQuizCode(event.target.value);
	};

	const handleEnrollButton = (quiz) => {
		setEnrollQuiz(quiz.quizName);
		setEnrollQuizId(quiz._id);
		setEnrollModal(true);
	};

	const handleInfoButton = (quiz) => {
		setInfoModal(true);
		getQuizInfo(quiz.quizId._id);
	};

	const handleStartButton = (quiz) => {
		setEnrollQuiz(quiz.quizId.quizName);
		setEnrollQuizId(quiz.quizId._id);
		setStartModal(true);
	};

	const getQuizInfo = async (id) => {
		setInfoLoading(true);

		let token = localStorage.getItem("authToken");
		let url = `https://quizzie-api.herokuapp.com/quiz/${id}`;

		try {
			await axios
				.get(url, {
					headers: {
						"auth-token": token,
					},
				})
				.then((res) => {
					setCurrQuiz(res.data.result);
					setInfoLoading(false);
				});
		} catch (error) {
			console.log(error);
			onCloseHandle();
			setInfoLoading(false);
		}
	};

	const handleJoinSubmit = async () => {
		if (quizCode.trim().length === 0) {
			setQuizCodeError(true);
			return;
		}
		setQuizCodeError(false);
		setEnrollSnack(true);
		let url = "https://quizzie-api.herokuapp.com/quiz/enrollPrivate";
		let token = localStorage.getItem("authToken");

		let captcha = await executeRecaptcha("join_private");

		let data = {
			quizCode: quizCode,
			captcha: captcha,
		};

		try {
			await axios
				.patch(url, data, {
					headers: {
						"auth-token": token,
					},
				})
				.then((res) => {
					setRefresh(true);
					onCloseHandle();
					setSnackBar(true);
				});
		} catch (error) {
			setEnrollSnack(false);
			if (error.response.status === 404) {
				setPrivateWrongCode(true);
			} else if (error.response.status === 409) {
				setAlreadyEnrolled(true);
			} else {
				setErrorSnack(true);
			}
		}
	};

	const handleEnroll = async () => {
		setEnrollSnack(true);
		let token = localStorage.getItem("authToken");
		let url = "https://quizzie-api.herokuapp.com/quiz/enroll";

		let captcha = await executeRecaptcha("quiz_enroll");

		let data = {
			quizId: enrollQuizId,
			captcha: captcha,
		};

		try {
			await axios
				.patch(url, data, {
					headers: {
						"auth-token": token,
					},
				})
				.then((res) => {
					setRefresh(true);
					onCloseHandle();
					setSnackBar(true);
				});
		} catch (error) {
			console.log(error);
			setErrorSnack(true);
		}
	};

	const handleUnenroll = async () => {
		setEnrollSnack(true);
		let token = localStorage.getItem("authToken");
		let url = "https://quizzie-api.herokuapp.com/quiz/unenroll";

		let captcha = await executeRecaptcha("quiz_unenroll");

		let data = {
			quizId: currQuiz._id,
			captcha: captcha,
		};

		try {
			await axios
				.patch(url, data, {
					headers: {
						"auth-token": token,
					},
				})
				.then((res) => {
					setRefresh(true);
				});
		} catch (error) {
			console.log(error);
			setErrorSnack(true);
		}
	};

	const handleQuizStart = async () => {
		setEnrollSnack(true);
		let token = localStorage.getItem("authToken");
		let url = `https://quizzie-api.herokuapp.com/quiz/start`;

		let captcha = await executeRecaptcha("quiz_start");

		let data = {
			quizId: enrollQuizId,
			captcha: captcha,
		};

		try {
			await axios
				.patch(url, data, {
					headers: {
						"auth-token": token,
					},
				})
				.then((res) => {
					setRedirectId(data.quizId);
					setQuizDetails(res.data);
					setQuizStarted(true);
				});
		} catch (error) {
			setEnrollSnack(false);
			if (error.response.status === 401) {
				setEarlyError(true);
			} else if (error.response.status === 402) {
				setLateError(true);
			} else if (error.response.status === 405) {
				setGivenSnack(true);
			}
		}
	};

	const setupEnrolled = () => {
		let quizzes = [];

		profile.quizzesEnrolled.map((quiz) => {
			if (
				!profile.quizzesGiven.find((o) => o.quizId === quiz.quizId._id)
			) {
				quizzes.push(quiz);
			}
		});

		setQuizzesEnrolled(quizzes);
	};

	const getQuizzes = async () => {
		setLoading(true);
		let token = localStorage.getItem("authToken");
		let url = "https://quizzie-api.herokuapp.com/quiz/all";

		let quizList = [];

		try {
			await axios
				.get(url, {
					headers: {
						"auth-token": token,
					},
				})
				.then((res) => {
					res.data.result.map((quiz) => {
						if (quiz.quizType === "public") {
							if (userType === "user") {
								if (
									!profile.quizzesEnrolled.find(
										(o) => o.quizId._id === quiz._id
									)
								)
									quizList.push(quiz);
							} else quizList.push(quiz);
						}
					});

					quizList.sort(function (a, b) {
						return a.scheduledFor - b.scheduledFor;
					});

					setQuizzes(quizList);
					setLoading(false);
				});
		} catch (error) {
			console.log(error);
		}
	};

	useEffect(() => {
		if (infoModal) {
			if (currQuiz.scheduledFor <= Date.now()) {
				setTimeRemain("Already Started!");
			} else {
				setTimeout(() => {
					setTimeRemain(
						countdown(
							new Date(),
							new Date(Number(currQuiz.scheduledFor))
						).toString()
					);
				}, 1000);
			}
		}
	});

	useEffect(() => {
		if (userType === "user") setupEnrolled();
		getQuizzes();
	}, []);

	if (loading) {
		return <QuizLoading />;
	} else if (quizStarted) {
		return (
			<Redirect
				to={{
					pathname: `/quiz`,
					state: {
						questions: quizDetails.data,
						duration: quizDetails.duration,
						start: quizDetails.scheduledFor,
						id: enrollQuizId,
						timeStarted: Date.now(),
						restartStatus: quizDetails.quizRestart,
					},
				}}
			/>
		);
	} else {
		return (
			<div className="quizzes-section">
				<div className="quiz-btn-section">
					{userType === "user" ? (
						<Button className="join-quiz-btn" onClick={onJoinClick}>
							<Check />
							Join a Quiz
						</Button>
					) : null}
					{userType === "admin" ? (
						<Button
							className="create-quiz-btn"
							component={Link}
							to="/createQuiz"
						>
							<Add />
							Create a quiz
						</Button>
					) : null}
				</div>
				{userType === "user" ? (
					<div className="enrolled-list">
						<Typography variant="h5" className="up-quizzes">
							Enrolled Quizzes
						</Typography>
						{quizzesEnrolled.length === 0 ? (
							<p style={{ textAlign: "center" }}>
								Sorry! No quizzes available at the moment!
							</p>
						) : (
							<div className="quiz-list root1">
								<GridList
									cols={getCols()}
									className="grid-list btn-set"
								>
									{quizzesEnrolled.map((quiz) => (
										<GridListTile
											key={quiz._id}
											className="quiz-tile"
										>
											<img src="../CC LOGO-01.svg" />
											<GridListTileBar
												title={quiz.quizId.quizName}
												actionIcon={
													<div className="inline">
														<Tooltip title="Start Quiz">
															<IconButton
																aria-label={`start ${quiz.quizId.quizName}`}
																onClick={() =>
																	handleStartButton(
																		quiz
																	)
																}
															>
																<PlayCircleFilled className="enroll-icon" />
															</IconButton>
														</Tooltip>
														<Tooltip title="Info">
															<IconButton
																aria-label={`info ${quiz.quizId.quizName}`}
																onClick={() =>
																	handleInfoButton(
																		quiz
																	)
																}
															>
																<Info className="enroll-icon" />
															</IconButton>
														</Tooltip>
													</div>
												}
											/>
										</GridListTile>
									))}
								</GridList>
							</div>
						)}
					</div>
				) : null}
				<Typography variant="h5" className="up-quizzes">
					Upcoming Quizzes
				</Typography>
				{quizzes.length === 0 ? (
					<p style={{ textAlign: "center" }}>
						Sorry! No quizzes available at the moment!
					</p>
				) : (
					<div className="quiz-list root1">
						<GridList cols={getCols()} className="grid-list">
							{quizzes.map((quiz) => (
								<GridListTile
									key={quiz._id}
									className="quiz-tile"
								>
									<img src="../CC LOGO-01.svg" />
									<GridListTileBar
										title={quiz.quizName}
										subtitle={`By: ${quiz.adminId.name}`}
										actionIcon={
											userType === "user" ? (
												<Tooltip title="Enroll">
													<IconButton
														aria-label={`enroll ${quiz.quizName}`}
														onClick={() =>
															handleEnrollButton(
																quiz
															)
														}
													>
														<Check className="enroll-icon" />
													</IconButton>
												</Tooltip>
											) : null
										}
									/>
								</GridListTile>
							))}
						</GridList>
					</div>
				)}
				<Dialog
					open={joinModal}
					onClose={onCloseHandle}
					aria-labelledby="join-quiz-modal"
					PaperProps={{
						style: {
							backgroundColor: "white",
							color: "#333",
							minWidth: "30%",
						},
					}}
					style={{ width: "100%" }}
				>
					<div className="modal-info">
						{userType === "admin" ? (
							<Typography
								variant="h6"
								className="type-head join-sub"
							>
								Organizers cannot enroll in quizzes.
							</Typography>
						) : (
							<div
								style={{
									display: "flex",
									flexDirection: "column",
								}}
							>
								<Typography variant="h5" className="type-head">
									JOIN A PRIVATE QUIZ
								</Typography>
								<Typography
									variant="h6"
									className="type-head join-sub"
								>
									Enter the code of the quiz you want to join
								</Typography>
								<TextInput
									error={quizCodeError}
									helperText={
										quizCodeError ? "Required" : null
									}
									label="Quiz Code"
									variant="outlined"
									value={quizCode}
									onChange={handleJoinChange}
									className="quiz-code-field"
								/>
								<Button
									className="join-quiz-btn join-modal-btn"
									onClick={handleJoinSubmit}
								>
									Join!
								</Button>
							</div>
						)}
					</div>
				</Dialog>
				<Dialog
					open={enrollModal}
					onClose={onCloseHandle}
					aria-labelledby="enroll-quiz-modal"
					PaperProps={{
						style: {
							backgroundColor: "white",
							color: "#333",
							minWidth: "30%",
						},
					}}
					style={{ width: "100%" }}
				>
					<div className="modal-info">
						{userType === "admin" ? (
							<Typography
								variant="h6"
								className="type-head join-sub"
							>
								Organizers cannot enroll in quizzes.
							</Typography>
						) : (
							<div>
								<Typography
									variant="h6"
									className="type-head join-sub"
								>{`Are you sure you want to join ${enrollQuizName}?`}</Typography>
								<div className="btn-div m-top">
									{/* classes in Navbar.css */}
									<Button
										className="logout-btn m-right"
										onClick={handleEnroll}
									>
										Yes
									</Button>
									<Button
										className="cancel-btn m-left"
										onClick={onCloseHandle}
									>
										No
									</Button>
								</div>
							</div>
						)}
					</div>
				</Dialog>
				<Dialog
					open={startModal}
					onClose={onCloseHandle}
					aria-labelledby="start-quiz-modal"
					PaperProps={{
						style: {
							backgroundColor: "white",
							color: "#333",
							minWidth: "30%",
						},
					}}
					style={{ width: "100%" }}
				>
					<div className="modal-info">
						<div>
							<Typography
								variant="h6"
								className="type-head join-sub"
							>{`Are you sure you want to start ${enrollQuizName}?`}</Typography>
							<div className="btn-div m-top2 start-div">
								{/* classes in Navbar.css */}
								<Button
									className="logout-btn m-right"
									onClick={handleQuizStart}
								>
									Yes
								</Button>
								<Button
									className="cancel-btn m-left"
									onClick={onCloseHandle}
								>
									No
								</Button>
							</div>
						</div>
					</div>
				</Dialog>
				<Dialog
					open={infoModal}
					onClose={onCloseHandle}
					aria-labelledby="info-quiz-modal"
					PaperProps={{
						style: {
							backgroundColor: "white",
							color: "#333",
							minWidth: getInfoWidth(),
							maxHeight: "45%",
						},
					}}
					style={{ width: "100%" }}
				>
					<DialogTitle
						style={{ textAlign: "center", fontWeight: "bold" }}
					>
						Quiz Info
					</DialogTitle>

					{/* From the profile section */}
					{infoLoading ? (
						<Loading />
					) : (
						<div
							className="modal-info no-p-top"
							style={{ textAlign: "center" }}
						>
							<Typography
								variant="h6"
								className="profile-param info-param"
							>
								Name:{" "}
								<span className="profile-data">
									{currQuiz.quizName}
								</span>
							</Typography>
							<Typography
								variant="h6"
								className="profile-param info-param"
							>
								Date:{" "}
								<span className="profile-data">
									{new Date(
										Number(currQuiz.scheduledFor)
									).toDateString()}
								</span>
							</Typography>
							<Typography
								variant="h6"
								className="profile-param info-param"
							>
								Time:{" "}
								<span className="profile-data">
									{new Date(
										Number(currQuiz.scheduledFor)
									).toLocaleTimeString()}
								</span>
							</Typography>
							<div className="time-sec">
								<Typography
									variant="h6"
									className="profile-param info-param"
								>
									<span className="profile-data time-rem">
										{timeRemain}
									</span>
								</Typography>
							</div>
							<Button
								className="unenroll-btn"
								onClick={handleUnenroll}
							>
								<Block style={{ color: "white" }} />
								Unenroll
							</Button>
						</div>
					)}
				</Dialog>
				<Snackbar
					open={snackbar}
					autoHideDuration={2000}
					onClose={() => setSnackBar(false)}
				>
					<Alert
						variant="filled"
						severity="success"
						onClose={() => setSnackBar(false)}
					>
						Successfully Enrolled!
					</Alert>
				</Snackbar>
				<Snackbar
					open={errorSnack}
					autoHideDuration={2000}
					onClose={() => setErrorSnack(false)}
				>
					<Alert
						variant="filled"
						severity="error"
						onClose={() => setErrorSnack(false)}
					>
						There was some error. Please try again!
					</Alert>
				</Snackbar>
				<Snackbar
					open={enrollSnack}
					autoHideDuration={5000}
					onClose={() => setEnrollSnack(false)}
				>
					<Alert
						variant="filled"
						severity="info"
						onClose={() => setErrorSnack(false)}
					>
						Processing... Please Wait!
					</Alert>
				</Snackbar>
				<Snackbar
					open={earlyError}
					autoHideDuration={5000}
					onClose={() => setEarlyError(false)}
				>
					<Alert
						variant="filled"
						severity="error"
						onClose={() => setEarlyError(false)}
					>
						The quiz has not yet started!
					</Alert>
				</Snackbar>
				<Snackbar
					open={lateError}
					autoHideDuration={5000}
					onClose={() => setLateError(false)}
				>
					<Alert
						variant="filled"
						severity="error"
						onClose={() => setLateError(false)}
					>
						This quiz has ended!
					</Alert>
				</Snackbar>
				<Snackbar
					open={givenSnack}
					autoHideDuration={5000}
					onClose={() => setGivenSnack(false)}
				>
					<Alert
						variant="filled"
						severity="error"
						onClose={() => setGivenSnack(false)}
					>
						Already given this quiz!
					</Alert>
				</Snackbar>
				<Snackbar
					open={privateWrongCode}
					autoHideDuration={5000}
					onClose={() => setPrivateWrongCode(false)}
				>
					<Alert
						variant="filled"
						severity="error"
						onClose={() => setPrivateWrongCode(false)}
					>
						This quiz code does not exists!
					</Alert>
				</Snackbar>
				<Snackbar
					open={alreadyEnrolled}
					autoHideDuration={5000}
					onClose={() => setAlreadyEnrolled(false)}
				>
					<Alert
						variant="filled"
						severity="error"
						onClose={() => setAlreadyEnrolled(false)}
					>
						Already enrolled in this quiz!
					</Alert>
				</Snackbar>
			</div>
		);
	}
}
Example #3
Source File: EditQuiz.js    From Quizzie with MIT License 4 votes vote down vote up
function EditQuiz(props) {
	const quizId = props.match.params.id;

	const [loading, setLoading] = useState(true);
	const [redirect, setRedirect] = useState(false);

	const [quizDetails, setQuizDetails] = useState({});
	const [quizQuestions, setQuizQuestions] = useState([]);

	const [fileError, setFileError] = useState(false);
	const [serverError, setServerError] = useState(false);
	const [popoverAnchor, setPopoverAnchor] = useState(null);
	const popoverOpen = Boolean(popoverAnchor);

	const [questionModal, setQuestionModal] = useState(false);
	const [newQuestion, setNewQuestion] = useState("");
	const [newQuestionError, setNewQuestionError] = useState(false);

	const [option1, setOption1] = useState("");
	const [option1Error, setOption1Error] = useState(false);
	const [option2, setOption2] = useState("");
	const [option2Error, setOption2Error] = useState(false);
	const [option3, setOption3] = useState("");
	const [option3Error, setOption3Error] = useState(false);
	const [option4, setOption4] = useState("");
	const [option4Error, setOption4Error] = useState(false);
	const [correctOption, setCorrectOption] = useState(-1);
	const [correctOptionError, setCorrectOptionError] = useState(false);

	const [update, setUpdate] = useState(false);
	const [updateId, setUpdateId] = useState(null);

	const [deleteModal, setDeleteModal] = useState(false);
	const [deleteQuestionModal, setDeleteQuestionModal] = useState(false);

	const [quizRestartModal, setQuizRestartModal] = useState(false);
	const [closeQuizModal, setCloseQuizModal] = useState(false);

	const [responses, setResponses] = useState([]);

	const [searchData, setSearchData] = useState(responses);
	const [searchText, setSearchText] = useState("");
	const [sortBy, setSortBy] = useState(-1);

	const { executeRecaptcha } = useGoogleReCaptcha();

	const onCloseHandle = () => {
		setQuestionModal(false);
		if (update) {
			setUpdate(false);
			setUpdateId(null);
			clearModal();
		}
	};

	const handlePopover = (event) => {
		setPopoverAnchor(event.currentTarget);
	};

	const handlePopoverClose = () => {
		setPopoverAnchor(null);
	};

	const onQuestionChange = (event) => {
		setNewQuestion(event.target.value);
	};

	const handleOptionChange1 = (event) => {
		setOption1(event.target.value);
	};
	const handleOptionChange2 = (event) => {
		setOption2(event.target.value);
	};
	const handleOptionChange3 = (event) => {
		setOption3(event.target.value);
	};
	const handleOptionChange4 = (event) => {
		setOption4(event.target.value);
	};

	const handleCorrectOption = (event) => {
		setCorrectOption(event.target.value);
	};

	const clearModal = () => {
		setNewQuestion("");
		setNewQuestionError(false);
		setOption1("");
		setOption1Error(false);
		setOption2("");
		setOption2Error(false);
		setOption3("");
		setOption3Error(false);
		setOption4("");
		setOption4Error(false);
		setCorrectOption(-1);
		setCorrectOptionError(false);
	};

	const handleFileDrop = (files) => {
		const reader = new FileReader();

		let questions = [];

		reader.onabort = () => {
			setFileError(true);
			return;
		};
		reader.onerror = () => {
			setFileError(true);
			return;
		};

		reader.onload = () => {
			csv.parse(reader.result, (err, data) => {
				if (data === undefined) {
					setFileError(true);
					return;
				}
				data.map((question) => {
					if (question[0].trim() === "") {
						return null;
					}
					let obj = {
						quizId: quizId,
						description: question[0],
						options: [
							{ text: question[1] },
							{ text: question[2] },
							{ text: question[3] },
							{ text: question[4] },
						],
						correctAnswer: question[5],
					};

					questions.push(obj);
				});
				submitCSV(questions);
			});
		};

		reader.readAsBinaryString(files[0]);
	};

	const submitCSV = async (questions) => {
		setLoading(true);
		let token = localStorage.getItem("authToken");
		let url = "https://quizzie-api.herokuapp.com/question/csv";

		let captcha = await executeRecaptcha("submit_csv");

		let data = {
			questions: questions,
			captcha: captcha,
		};

		try {
			await axios
				.post(url, data, {
					headers: {
						"auth-token": token,
					},
				})
				.then((res) => {
					console.log(res);
					setLoading(false);
					clearModal();
					onCloseHandle();
					getQuizDetails();
				});
		} catch (error) {
			setServerError(true);
			console.log(error);
		}
	};

	const handleSearchChange = (event) => {
		setSearchText(event.target.value);

		let newRes = responses.filter(
			(response) =>
				response.userId.name
					.toLowerCase()
					.search(event.target.value.trim().toLowerCase()) !== -1 ||
				String(response.marks) ===
					event.target.value.trim().toLowerCase()
		);
		let sorted = sortByFunc(sortBy, newRes);

		setSearchData(sorted);
	};

	const handleSortChange = (event) => {
		setSortBy(event.target.value);

		let newRes = sortByFunc(event.target.value, searchData);

		setSearchData(newRes);
	};

	const sortByFunc = (by, array) => {
		if (by === "score") {
			return array.sort(function (a, b) {
				return b.marks - a.marks;
			});
		} else if (by === "name") {
			return array.sort(function (a, b) {
				return a.userId.name - b.userId.name;
			});
		} else if (by === "recent") {
			return array.sort(function (a, b) {
				return b.timeEnded - a.timeEnded;
			});
		} else {
			return array;
		}
	};

	const handleRestart = async () => {
		let token = localStorage.getItem("authToken");
		let url = `https://quizzie-api.herokuapp.com/quiz/restart`;

		let captcha = await executeRecaptcha("restart_quiz");

		let data = {
			quizId: quizId,
			captcha: captcha,
		};

		try {
			await axios
				.patch(url, data, {
					headers: {
						"auth-token": token,
					},
				})
				.then((res) => {
					setQuizRestartModal(false);
					getQuizDetails();
				});
		} catch (error) {
			console.log(error);
		}
	};

	const handleQuizClose = async () => {
		let token = localStorage.getItem("authToken");
		let url = `https://quizzie-api.herokuapp.com/quiz/close`;

		let captcha = await executeRecaptcha("quiz_close");

		let data = {
			quizId: quizId,
			captcha: captcha,
		};

		try {
			await axios
				.patch(url, data, {
					headers: {
						"auth-token": token,
					},
				})
				.then((res) => {
					setCloseQuizModal(false);
					getQuizDetails();
				});
		} catch (error) {
			console.log(error);
		}
	};

	const handleQuestionEditBtn = (question) => {
		setUpdate(true);
		setUpdateId(question._id);
		setNewQuestion(question.description);
		setOption1(question.options[0].text);
		setOption2(question.options[1].text);
		setOption3(question.options[2].text);
		setOption4(question.options[3].text);
		setCorrectOption(question.correctAnswer);
		setQuestionModal(true);
	};

	const handleQuestionDeleteBtn = (question) => {
		setUpdateId(question._id);
		setDeleteQuestionModal(true);
	};

	const handleQuestionModalClose = () => {
		setUpdateId(null);
		setDeleteQuestionModal(false);
	};

	const handleDeleteBtn = () => {
		setDeleteModal(true);
	};

	const handleDeleteQuestion = async () => {
		let token = localStorage.getItem("authToken");
		let url = `https://quizzie-api.herokuapp.com/question/${updateId}`;

		// let captcha = executeRecaptcha("delete_quiz");

		try {
			await axios
				.delete(url, {
					headers: {
						"auth-token": token,
					},
				})
				.then((res) => {
					setUpdateId(null);
					setDeleteQuestionModal(false);
					getQuizDetails();
				});
		} catch (error) {
			console.log(error);
		}
	};

	const handleDelete = async () => {
		let token = localStorage.getItem("authToken");
		let url = `https://quizzie-api.herokuapp.com/quiz/delete`;

		let data = {
			quizId: quizId,
		};

		try {
			await axios
				.delete(url, {
					headers: {
						"auth-token": token,
					},
					data: data,
				})
				.then((res) => {
					setRedirect(true);
				});
		} catch (error) {
			console.log(error);
		}
	};

	const handleQuestionUpdate = async () => {
		if (!validate()) return;

		let token = localStorage.getItem("authToken");
		let url = `https://quizzie-api.herokuapp.com/question/update/${updateId}`;

		let captcha = await executeRecaptcha("question_update");

		let updateOps = [
			{ propName: "description", value: newQuestion },
			{
				propName: "options",
				value: [
					{
						text: option1,
					},
					{
						text: option2,
					},
					{
						text: option3,
					},
					{
						text: option4,
					},
				],
			},
			{ propName: "correctAnswer", value: correctOption },
		];

		let data = {
			updateOps: updateOps,
			captcha: captcha,
		};

		try {
			await axios
				.patch(url, data, {
					headers: {
						"auth-token": token,
					},
				})
				.then((res) => {
					onCloseHandle();
					getQuizDetails();
				});
		} catch (error) {
			console.log(error);
		}
	};

	const validate = () => {
		if (newQuestion.trim().length === 0) {
			setNewQuestionError(true);
			return false;
		}

		if (option1.trim().length === 0) {
			setOption1Error(true);
			return false;
		}
		if (option2.trim().length === 0) {
			setOption2Error(true);
			return false;
		}
		if (option3.trim().length === 0) {
			setOption3Error(true);
			return false;
		}
		if (option4.trim().length === 0) {
			setOption4Error(true);
			return false;
		}

		if (correctOption === -1) {
			setCorrectOptionError(true);
			return false;
		}

		return true;
	};

	const handleQuestionSubmit = async () => {
		//TODO: Handle Validation

		if (!validate()) return;

		let token = localStorage.getItem("authToken");
		let url = `https://quizzie-api.herokuapp.com/question/add`;

		let captcha = await executeRecaptcha("submit_question");

		let options = [
			{ text: option1 },
			{ text: option2 },
			{ text: option3 },
			{ text: option4 },
		];

		let data = {
			quizId: quizId,
			description: newQuestion,
			options: options,
			correctAnswer: correctOption,
			captcha: captcha,
		};

		try {
			await axios
				.post(url, data, {
					headers: {
						"auth-token": token,
					},
				})
				.then((res) => {
					clearModal();
					getQuizDetails();
					setQuestionModal(false);
				});
		} catch (error) {
			console.log(error);
		}
	};

	const isOwnerOfQuiz = async () => {
		let token = localStorage.getItem("authToken");
		let url = `https://quizzie-api.herokuapp.com/quiz/checkAdmin/${quizId}`;

		try {
			await axios
				.get(url, {
					headers: {
						"auth-token": token,
					},
				})
				.then((res) => {
					return true;
				});
		} catch (error) {
			setRedirect(true);
			return;
		}
	};

	const getQuizDetails = async () => {
		setLoading(true);
		let token = localStorage.getItem("authToken");
		let url = `https://quizzie-api.herokuapp.com/quiz/${quizId}`;

		try {
			await axios
				.get(url, {
					headers: {
						"auth-token": token,
					},
				})
				.then((res) => {
					setQuizDetails(res.data.result);
				});
		} catch (error) {
			console.log(error);
		}

		url = `https://quizzie-api.herokuapp.com/question/all/${quizId}`;

		try {
			await axios
				.get(url, {
					headers: {
						"auth-token": token,
					},
				})
				.then((res) => {
					setQuizQuestions(res.data.result);
				});
		} catch (error) {
			console.log(error);
		}

		url = `https://quizzie-api.herokuapp.com/admin/allStudentsQuizResult/${quizId}`;

		try {
			await axios
				.get(url, {
					headers: {
						"auth-token": token,
					},
				})
				.then((res) => {
					setResponses(res.data.userResults);
					setSearchData(res.data.userResults);
					setLoading(false);
				});
		} catch (error) {
			console.log(error);
		}
	};

	useEffect(() => {
		let token = localStorage.getItem("authToken");
		if (token === null) {
			setLoading(false);
			setRedirect(true);
			return;
		}

		isOwnerOfQuiz();
		getQuizDetails();
	}, []);

	if (loading) {
		return <Loading />;
	} else if (redirect) {
		return <Redirect to="/dashboard" />;
	} else {
		return (
			<Container className="edit-quiz-page">
				<Typography
					variant="h3"
					className="dash-head p-top edit-quiz-head"
				>
					Edit Quiz
				</Typography>
				<div className="edit-btn-bar">
					<Button
						className="edit-details-btn"
						component={Link}
						to={`/updateQuizDetails/${quizId}`}
					>
						<Create className="edit-icon" />
						Edit Details
					</Button>
					<Button
						className="edit-details-btn delete-btn"
						onClick={handleDeleteBtn}
					>
						<Delete className="edit-icon" />
						Delete Quiz
					</Button>
					{quizDetails.quizStatus === 1 ? (
						<Button
							className="edit-details-btn"
							style={{ marginLeft: "3%" }}
							onClick={() => setCloseQuizModal(true)}
						>
							<Replay className="edit-quiz" />
							Close Quiz
						</Button>
					) : quizDetails.quizStatus === 2 ? (
						<Button
							className="edit-details-btn"
							style={{ marginLeft: "3%" }}
							onClick={() => setQuizRestartModal(true)}
						>
							<Replay className="edit-quiz" />
							Restart Quiz
						</Button>
					) : null}
				</div>
				<div className="quiz-details-sec">
					<Typography variant="h6" className="quiz-detail-param">
						Name:{" "}
						<span className="quiz-detail-text">
							{quizDetails.quizName}
						</span>
					</Typography>
					<Typography variant="h6" className="quiz-detail-param">
						Date:{" "}
						<span className="quiz-detail-text">
							{new Date(
								Number(quizDetails.scheduledFor)
							).toDateString()}
						</span>
					</Typography>
					<Typography variant="h6" className="quiz-detail-param">
						Time:{" "}
						<span className="quiz-detail-text">
							{new Date(
								Number(quizDetails.scheduledFor)
							).toLocaleTimeString()}
						</span>
					</Typography>
					<Typography variant="h6" className="quiz-detail-param">
						Duration:{" "}
						<span className="quiz-detail-text">
							{quizDetails.quizDuration} minutes
						</span>
					</Typography>
					<Typography variant="h6" className="quiz-detail-param">
						Type:{" "}
						<span className="quiz-detail-text">
							{quizDetails.quizType}
						</span>
					</Typography>
					{quizDetails.quizType === "private" ? (
						<Typography variant="h6" className="quiz-detail-param">
							Quiz Code:{" "}
							<span className="quiz-detail-text">
								{quizDetails.quizCode}
							</span>
						</Typography>
					) : null}
				</div>
				<div className="quiz-questions-sec">
					<Typography variant="h4" className="quiz-questions-head">
						Questions
					</Typography>
					<div className="quiz-questions-display">
						<div className="add-question-bar">
							<Button
								className="add-question-btn"
								onClick={() => setQuestionModal(true)}
							>
								Add a question
							</Button>
						</div>
						{quizQuestions.length === 0 ? (
							<p style={{ textAlign: "center" }}>
								No questions added yet!
							</p>
						) : (
							<div className="questions-list-display">
								{quizQuestions.map((question) => (
									<ExpansionPanel
										elevation={3}
										className="expansion"
										key={question._id}
									>
										<ExpansionPanelSummary
											className="question-summary"
											expandIcon={<ExpandMore />}
											aria-controls="question-content"
											aria-label="Expand"
										>
											<FormControlLabel
												style={{ marginRight: "0" }}
												aria-label="Edit"
												control={
													<IconButton>
														<Create />
													</IconButton>
												}
												// label={question.description}
												onClick={() =>
													handleQuestionEditBtn(
														question
													)
												}
											/>
											<FormControlLabel
												aria-label="Edit"
												control={
													<IconButton>
														<Delete />
													</IconButton>
												}
												// label={question.description}
												onClick={() =>
													handleQuestionDeleteBtn(
														question
													)
												}
											/>
											<Typography className="question-label">
												{question.description}
											</Typography>
										</ExpansionPanelSummary>
										<ExpansionPanelDetails>
											<List
												component="nav"
												className="options-display"
											>
												{question.options.map(
													(option) => (
														<ListItem
															button
															key={option._id}
														>
															<ListItemIcon>
																<Adjust
																	style={{
																		color:
																			question.correctAnswer ===
																			option.text
																				? "green"
																				: "black",
																	}}
																/>
															</ListItemIcon>
															<ListItemText
																style={{
																	color:
																		question.correctAnswer ===
																		option.text
																			? "green"
																			: "black",
																}}
																primary={
																	option.text
																}
															/>
														</ListItem>
													)
												)}
											</List>
										</ExpansionPanelDetails>
									</ExpansionPanel>
								))}
							</div>
						)}
					</div>
					<Typography
						variant="h4"
						className="quiz-questions-head m-top"
					>
						Submissions
					</Typography>
					<div className="quiz-students-list">
						<div className="add-question-bar">
							<Button
								className="add-question-btn stats-btn"
								component={
									responses.length !== 0 ? Link : Button
								}
								to={{
									pathname: "/quizStats",
									state: { responses: responses },
								}}
							>
								<BarChart />
								View Stats
							</Button>
						</div>
						{responses.length === 0 ? (
							<p
								style={{
									textAlign: "center",
									margin: "0",
									paddingTop: "3%",
									paddingBottom: "3%",
								}}
							>
								No responses yet!
							</p>
						) : (
							<>
								<div className="search-bar">
									<TextField
										placeholder="Search by name or score"
										type="text"
										onChange={handleSearchChange}
										className="search-input"
										value={searchText}
									/>
									<div style={{ marginLeft: "3%" }}>
										<InputLabel id="sort-by">
											Sort by
										</InputLabel>
										<Select
											labelId="sort-by"
											id="sort-select"
											value={sortBy}
											onChange={handleSortChange}
										>
											<MenuItem value={-1}>
												<em>None</em>
											</MenuItem>
											<MenuItem value="recent">
												Recent
											</MenuItem>
											<MenuItem value="score">
												Score
											</MenuItem>
											<MenuItem value="name">
												Name
											</MenuItem>
										</Select>
									</div>
								</div>
								<List aria-label="responses list">
									{searchData.map((response) => (
										<ListItem
											button
											key={response._id}
											component={Link}
											to={{
												pathname: `/studentResponse`,
												state: { response: response },
											}}
										>
											<ListItemText
												primary={response.userId.name}
												secondary={`Scored: ${response.marks}`}
											/>
										</ListItem>
									))}
								</List>
							</>
						)}
					</div>
				</div>
				<Dialog
					open={questionModal}
					onClose={onCloseHandle}
					aria-labelledby="add-question-modal"
					PaperProps={{
						style: {
							backgroundColor: "white",
							color: "#333",
							minWidth: "50%",
						},
					}}
					style={{ width: "100%" }}
				>
					<div className="add-ques-heading">
						<Typography
							variant="h6"
							style={{ textAlign: "center", margin: "2% 5%" }}
						>
							New Question{" "}
						</Typography>
						{!update ? (
							<IconButton onClick={handlePopover}>
								<Info className="add-info-icon" />
							</IconButton>
						) : null}
						<Popover
							id="file-upload-popover"
							open={popoverOpen}
							anchorEl={popoverAnchor}
							onClose={handlePopoverClose}
							anchorOrigin={{
								vertical: "bottom",
								horizontal: "left",
							}}
							disableRestoreFocus
							useLayerForClickAway={false}
							PaperProps={{ style: { maxWidth: "400px" } }}
						>
							<p className="popover-text">
								You can upload a <strong>.csv</strong> file with
								questions. The format should be: the{" "}
								<strong>
									first column should contain the question
									text.
								</strong>{" "}
								The next 4 columns must contain the{" "}
								<strong>four options.</strong> And the sixth
								column should contain{" "}
								<strong>
									the correct answer (it should match one of
									the four options)
								</strong>
								. <br />
								<br />
								<strong>
									NOTE: THE FILE SHOULD EXACTLY MATCH THE
									GIVEN FORMAT.
								</strong>{" "}
								You will be able to see and edit all the
								question though.
							</p>
						</Popover>
					</div>
					{!update ? (
						<>
							<div className="dropzone">
								<Dropzone
									onDrop={(acceptedFiles) =>
										handleFileDrop(acceptedFiles)
									}
								>
									{({ getRootProps, getInputProps }) => (
										<section>
											<div {...getRootProps()}>
												<input {...getInputProps()} />
												<AddCircle className="drop-icon" />
												<p
													style={{
														color:
															"rgb(110, 110, 110)",
													}}
												>
													Drag 'n' drop or click to
													select files
												</p>
											</div>
										</section>
									)}
								</Dropzone>
							</div>
							<p className="manual-head">
								<span>Or manually add the question</span>
							</p>
						</>
					) : null}
					<div className="new-question-form">
						<TextInput
							error={newQuestionError}
							helperText={
								newQuestionError ? "This cannot be empty" : null
							}
							className="new-ques-input"
							variant="outlined"
							label="Question Text"
							value={newQuestion}
							onChange={onQuestionChange}
						/>
						<hr style={{ width: "100%", marginBottom: "3%" }} />
						<Grid container spacing={1}>
							<Grid item xs={12} sm={6}>
								<TextInput
									error={option1Error}
									helperText={
										option1Error
											? "This cannot be empty"
											: null
									}
									className="new-ques-input"
									variant="outlined"
									label="Option 1"
									value={option1}
									onChange={handleOptionChange1}
								/>
							</Grid>
							<Grid item xs={12} sm={6}>
								<TextInput
									error={option2Error}
									helperText={
										option2Error
											? "This cannot be empty"
											: null
									}
									className="new-ques-input"
									variant="outlined"
									label="Option 2"
									value={option2}
									onChange={handleOptionChange2}
								/>
							</Grid>
						</Grid>
						<Grid container spacing={1}>
							<Grid item xs={12} sm={6}>
								<TextInput
									error={option3Error}
									helperText={
										option3Error
											? "This cannot be empty"
											: null
									}
									className="new-ques-input"
									variant="outlined"
									label="Option 3"
									value={option3}
									onChange={handleOptionChange3}
								/>
							</Grid>
							<Grid item xs={12} sm={6}>
								<TextInput
									error={option4Error}
									helperText={
										option4Error
											? "This cannot be empty"
											: null
									}
									className="new-ques-input"
									variant="outlined"
									label="Option 4"
									value={option4}
									onChange={handleOptionChange4}
								/>
							</Grid>
						</Grid>
						<hr style={{ width: "100%", marginBottom: "3%" }} />
						<InputLabel id="correct-option">
							Correct Option
						</InputLabel>
						<Select
							error={correctOptionError}
							className="correct-answer-select"
							style={{ width: "50%" }}
							labelId="correct-option"
							value={correctOption}
							onChange={handleCorrectOption}
						>
							<MenuItem value={-1}>None</MenuItem>
							{option1.trim().length !== 0 ? (
								<MenuItem value={option1}>{option1}</MenuItem>
							) : null}
							{option2.trim().length !== 0 ? (
								<MenuItem value={option2}>{option2}</MenuItem>
							) : null}
							{option3.trim().length !== 0 ? (
								<MenuItem value={option3}>{option3}</MenuItem>
							) : null}
							{option4.trim().length !== 0 ? (
								<MenuItem value={option4}>{option4}</MenuItem>
							) : null}
						</Select>
						{!update ? (
							<Button
								className="add-question-submit"
								onClick={handleQuestionSubmit}
							>
								Add Question
							</Button>
						) : (
							<Button
								className="add-question-submit"
								onClick={handleQuestionUpdate}
							>
								Update Question
							</Button>
						)}
					</div>
				</Dialog>
				<Dialog
					open={deleteModal}
					onClose={() => setDeleteModal(false)}
					aria-labelledby="delete-quiz-modal"
					PaperProps={{
						style: {
							backgroundColor: "white",
							color: "black",
							minWidth: "10%",
						},
					}}
				>
					<DialogTitle>
						Are you sure you want to delete this quiz?
					</DialogTitle>
					<div className="btn-div">
						<Button
							className="logout-btn m-right bg-red-btn"
							onClick={handleDelete}
						>
							Yes
						</Button>
						<Button
							className="cancel-btn m-left"
							onClick={() => setDeleteModal(false)}
						>
							No
						</Button>
					</div>
				</Dialog>
				<Dialog
					open={deleteQuestionModal}
					onClose={handleQuestionModalClose}
					aria-labelledby="delete-quiz-modal"
					PaperProps={{
						style: {
							backgroundColor: "white",
							color: "black",
							minWidth: "10%",
						},
					}}
				>
					<DialogTitle>
						Are you sure you want to delete this question?
					</DialogTitle>
					<div className="btn-div">
						<Button
							className="logout-btn m-right bg-red-btn"
							onClick={handleDeleteQuestion}
						>
							Yes
						</Button>
						<Button
							className="cancel-btn m-left"
							onClick={handleQuestionModalClose}
						>
							No
						</Button>
					</div>
				</Dialog>
				<Dialog
					open={quizRestartModal}
					onClose={() => setQuizRestartModal(false)}
					aria-labelledby="restart-quiz-modal"
					PaperProps={{
						style: {
							backgroundColor: "white",
							color: "black",
							minWidth: "10%",
						},
					}}
				>
					<DialogTitle>
						Are you sure you want to restart this quiz?
					</DialogTitle>
					<div className="btn-div">
						<Button
							className="logout-btn m-right bg-green-btn"
							onClick={handleRestart}
						>
							Yes
						</Button>
						<Button
							className="cancel-btn m-left bg-red-btn"
							onClick={() => setQuizRestartModal(false)}
						>
							No
						</Button>
					</div>
				</Dialog>
				<Dialog
					open={closeQuizModal}
					onClose={() => setCloseQuizModal(false)}
					aria-labelledby="restart-quiz-modal"
					PaperProps={{
						style: {
							backgroundColor: "white",
							color: "black",
							minWidth: "10%",
						},
					}}
				>
					<DialogTitle>
						Are you sure you want to close this quiz?
					</DialogTitle>
					<div className="btn-div">
						<Button
							className="logout-btn m-right bg-green-btn"
							onClick={handleQuizClose}
						>
							Yes
						</Button>
						<Button
							className="cancel-btn m-left bg-red-btn"
							onClick={() => setCloseQuizModal(false)}
						>
							No
						</Button>
					</div>
				</Dialog>
				<Snackbar
					open={fileError}
					autoHideDuration={3000}
					onClose={() => setFileError(false)}
					anchorOrigin={{ vertical: "bottom", horizontal: "left" }}
				>
					<Alert
						variant="filled"
						severity="error"
						onClose={() => setFileError(false)}
					>
						There was some problem with the file. Try again...
					</Alert>
				</Snackbar>
				<Snackbar
					open={serverError}
					autoHideDuration={3000}
					onClose={() => setServerError(false)}
					anchorOrigin={{ vertical: "bottom", horizontal: "left" }}
				>
					<Alert
						variant="filled"
						severity="error"
						onClose={() => setServerError(false)}
					>
						There was some problem with the server. Try again...
					</Alert>
				</Snackbar>
			</Container>
		);
	}
}
Example #4
Source File: MainAppBar.js    From landlord with MIT License 4 votes vote down vote up
export default function MainAppBar(props) {
  const classes = useStyles();
  const [mobileOpen, setMobileOpen] = React.useState(false);

  const handleDrawerToggle = (variant) => {
    setMobileOpen(variant === "temporary" && !mobileOpen);
  };

  const drawer = (variant) => (
      <div>
        <div className={classes.toolbar}/>
        <Divider/>
        <List component="nav">
          <ListItem button component={Link} to="/" onClick={() => handleDrawerToggle(variant)} key={"/"}>
            <ListItemIcon><Home/></ListItemIcon>
            <ListItemText primary="Home"/>
          </ListItem>

          <ListItem button component={Link} to="/out-of-omaha" onClick={() => handleDrawerToggle(variant)} key={"/out-of-omaha"}>
            <ListItemIcon><LocationCity/></ListItemIcon>
            <ListItemText primary="Out of Omaha"/>
          </ListItem>
          <List component="div" disablePadding dense>
            <ListItem className={classes.nested} button component={Link} to="/out-of-omaha/map" onClick={() => handleDrawerToggle(variant)} key={"/out-of-omaha/map"}>
              <ListItemIcon><Place/></ListItemIcon>
              <ListItemText primary="Out of Omaha Map"/>
            </ListItem>
          </List>

          <ListItem button component={Link} to="/out-of-state" onClick={() => handleDrawerToggle(variant)} key={"/out-of-state"}>
            <ListItemIcon><Map/></ListItemIcon>
            <ListItemText primary="Out of State"/>
          </ListItem>
          <List component="div" disablePadding dense>
            <ListItem className={classes.nested} button component={Link} to="/out-of-state/map" onClick={() => handleDrawerToggle(variant)} key={"/out-of-state/map"}>
              <ListItemIcon><Place/></ListItemIcon>
              <ListItemText primary="Out of State Map"/>
            </ListItem>
          </List>

          <ListItem button component={Link} to="/low-condition" onClick={() => handleDrawerToggle(variant)} key={"/low-condition"}>
            <ListItemIcon><TrendingDown/></ListItemIcon>
            <ListItemText primary="Low Condition"/>
          </ListItem>
          <List component="div" disablePadding dense>
            <ListItem className={classes.nested} button component={Link} to="/low-condition/map" onClick={() => handleDrawerToggle(variant)} key={"/low-condition/map"}>
              <ListItemIcon><Place/></ListItemIcon>
              <ListItemText primary="Low Condition Map"/>
            </ListItem>
          </List>

          <ListItem button component={Link} to="/about" onClick={() => handleDrawerToggle(variant)} key={"/about"}>
            <ListItemIcon><Info/></ListItemIcon>
            <ListItemText primary="About"/>
          </ListItem>
        </List>
      </div>
  );

  return (
      <div className={classes.root}>
        <CssBaseline/>
        <AppBar position="fixed" className={classes.appBar}>
          <Toolbar>
            <IconButton
                color="inherit"
                aria-label="open drawer"
                edge="start"
                onClick={() => handleDrawerToggle("temporary")}
                className={classes.menuButton}
            >
              <MenuIcon/>
            </IconButton>
            <img src="/landlord/favicon.png" alt="logo" className={classes.logo} width={30} height={30}/>
            <Typography variant="h6" noWrap>
              Landlords of Omaha
            </Typography>
          </Toolbar>
        </AppBar>
        <nav className={classes.drawer}>
          <Hidden mdUp implementation="css">
            <Drawer
                variant="temporary"
                anchor="left"
                open={mobileOpen}
                onClose={() => handleDrawerToggle("temporary")}
                classes={{
                  paper: classes.drawerPaper,
                }}
                ModalProps={{
                  keepMounted: true, // Better open performance on mobile.
                }}
            >
              {drawer("temporary")}
            </Drawer>
          </Hidden>
          <Hidden smDown implementation="css">
            <Drawer
                classes={{
                  paper: classes.drawerPaper,
                }}
                variant="permanent"
                open
            >
              {drawer("permanent")}
            </Drawer>
          </Hidden>
        </nav>
        <div className={classes.contentWrapper}>
          <div className={classes.toolbar}/>
          <main className={classes.main}>
            {props.children}
          </main>

          <footer className={classes.footer}>
            <div className={classes.footerBody}>
              <Typography variant="body2" component="p">Learn more about this project:</Typography>
              <Box display="flex" justifyContent="center">
                <Box m={1} p={1}>
                  <a className={classes.footerLink} rel="noreferrer" target="_blank" href="https://codefornebraska.slack.com/messages/housing"><Icon icon={slackIcon} width="36" height="36"/></a>
                </Box>
                <Box m={1} p={1}>
                  <a className={classes.footerLink} rel="noreferrer" target="_blank" href="https://github.com/codefornebraska/landlord"><Icon icon={githubIcon} width="36" height="36"/></a>
                </Box>
              </Box>
            </div>
            <div className={classes.footerCopyright}>
              <Typography variant="body2">
                {`Copyright © `}
                <a className={classes.footerLink}  rel="noreferrer" target="_blank" href="https://www.codefornebraska.org/">Code for Nebraska</a>
                {` ${new Date().getFullYear()}`}
              </Typography>
            </div>
          </footer>
        </div>
      </div>
  );
}