/** @jsx jsx */ import { jsx, css } from "@emotion/react"; import { Link } from "react-router-dom"; import React, { SyntheticEvent, useEffect, useState, createRef, RefObject } from "react"; import { useParams } from "react-router"; import HeaderBar from "../components/HeaderBar"; import RenderedQuestion from "../components/Question"; import Loading from "../components/Loading"; import ScrollToTop from "../components/ScrollToTop"; import { Form, FormFeatures, getForm } from "../api/forms"; import colors from "../colors"; import { unselectable } from "../commonStyles"; import { Question } from "../api/question"; interface PathParams { id: string } interface NavigationProps { form_state: boolean // Whether the form is open or not } class Navigation extends React.Component { containerStyles = css` margin: auto; width: 50%; text-align: center; font-size: 1.5rem; white-space: nowrap; > div { display: inline-block; margin: 2rem auto; width: 50%; } @media (max-width: 850px) { width: 100%; > div { display: flex; justify-content: center; margin: 0 auto; } } .return_button { text-align: left; } .return_button.closed { text-align: center; } `; separatorStyles = css` height: 0; display: none; @media (max-width: 850px) { display: block; } `; returnStyles = css` padding: 0.5rem 2rem; border-radius: 8px; color: white; text-decoration: none; background-color: ${colors.greyple}; transition: background-color 300ms; :hover { background-color: ${colors.darkerGreyple}; } } `; submitStyles = css` text-align: right; button { padding: 0.5rem 4rem; cursor: pointer; border: none; border-radius: 8px; color: white; font: inherit; background-color: ${colors.blurple}; transition: background-color 300ms; } button:hover { background-color: ${colors.darkerBlurple}; } `; render(): JSX.Element { let submit = null; if (this.props.form_state) { submit = (
); } return (
Return Home

{ submit }
); } } const formStyles = css` margin: auto; width: 50%; @media (max-width: 800px) { /* Make form larger on mobile and tablet screens */ width: 80%; } `; const closedHeaderStyles = css` margin-bottom: 2rem; padding: 1rem 4rem; border-radius: 8px; text-align: center; font-size: 1.5rem; background-color: ${colors.error}; @media (max-width: 500px) { padding: 1rem 1.5rem; } `; function FormPage(): JSX.Element { const { id } = useParams(); const [form, setForm] = useState
(); useEffect(() => { getForm(id).then(form => { setForm(form); }); }, []); if (!form) { return ; } const questionsMap: Map = new Map(); form.questions.map((question, index) => { questionsMap.set(question.id, ()} scroll_ref={createRef()} question={question} public_state={new Map()} key={index + Date.now()}/>); }); function handleSubmit(event: SyntheticEvent) { event.preventDefault(); // Client-side required validation const invalidFieldIds: string[] = []; questionsMap.forEach((prop, id) => { const question: Question = prop.props.question; if (!question.required) { return; } prop.ref.current.validateField(); // In case when field is invalid, add this to invalid fields list. if (prop.props.public_state.get("valid") === false) { invalidFieldIds.push(id); } }); if (invalidFieldIds.length) { const firstErrored = questionsMap.get(invalidFieldIds[0]); if (firstErrored !== undefined) { firstErrored.props.scroll_ref.current.scrollIntoView({ behavior: "smooth", block: "center" }); } return; } questionsMap.forEach(prop => { const question = prop.props.question; // TODO: Parse input from each question, and submit switch (question.type) { default: console.log(question.id, prop.props.public_state); } }); event.preventDefault(); } const open: boolean = form.features.includes(FormFeatures.Open); let closed_header = null; if (!open) { closed_header =
This form is now closed. You will not be able to submit your response.
; } const questions: JSX.Element[] = []; questionsMap.forEach(val => questions.push(val)); return (
{ closed_header } { questions }
); } export default FormPage;