aboutsummaryrefslogtreecommitdiffstats
path: root/src/pages
diff options
context:
space:
mode:
authorGravatar Joe Banks <[email protected]>2021-01-17 16:19:18 +0000
committerGravatar GitHub <[email protected]>2021-01-17 16:19:18 +0000
commitc1bee9cb0efba823740095380cfcca9bf47eb196 (patch)
tree18ed06bca3d17341e9eeabc5364023b9f3ee250b /src/pages
parentMerge pull request #82 from python-discord/renovate/typescript-eslint-monorepo (diff)
parentCenters Title With No Description (diff)
Merge pull request #74 from python-discord/form-rendering
Diffstat (limited to 'src/pages')
-rw-r--r--src/pages/FormPage.tsx194
-rw-r--r--src/pages/LandingPage.tsx7
2 files changed, 188 insertions, 13 deletions
diff --git a/src/pages/FormPage.tsx b/src/pages/FormPage.tsx
index 1805897..c49b9fd 100644
--- a/src/pages/FormPage.tsx
+++ b/src/pages/FormPage.tsx
@@ -1,17 +1,157 @@
/** @jsx jsx */
-import { jsx } from "@emotion/react";
+import { jsx, css } from "@emotion/react";
import { Link } from "react-router-dom";
+import React, { SyntheticEvent, useEffect, useState } from "react";
import { useParams } from "react-router";
+
import HeaderBar from "../components/HeaderBar";
-import { useEffect, useState } from "react";
-import { Form, getForm } from "../api/forms";
+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";
+
interface PathParams {
id: string
}
+interface NavigationProps {
+ form_state: boolean // Whether the form is open or not
+}
+
+class Navigation extends React.Component<NavigationProps> {
+ 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 = (
+ <div css={this.submitStyles}>
+ <button form="form" type="submit">Submit</button>
+ </div>
+ );
+ }
+
+ return (
+ <div css={[unselectable, this.containerStyles]}>
+ <div className={ "return_button" + (this.props.form_state ? "" : " closed") }>
+ <Link to="/" css={this.returnStyles}>Return Home</Link>
+ </div>
+ <br css={this.separatorStyles}/>
+ { submit }
+ </div>
+ );
+ }
+}
+
+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<PathParams>();
@@ -21,19 +161,53 @@ function FormPage(): JSX.Element {
getForm(id).then(form => {
setForm(form);
});
- });
+ }, []);
if (!form) {
return <Loading/>;
}
- return <div>
- <HeaderBar title={form.name}/>
- <div css={{marginLeft: "20px"}}>
- <h1>{form.description}</h1>
- <Link to="/" css={{color: "white"}}>Return home</Link>
+ const questions = form.questions.map((question, index) => {
+ return <RenderedQuestion question={question} public_state={new Map()} key={index + Date.now()}/>;
+ });
+
+ function handleSubmit(event: SyntheticEvent) {
+ questions.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 = <div css={closedHeaderStyles}>This form is now closed. You will not be able to submit your response.</div>;
+ }
+
+ return (
+ <div>
+ <HeaderBar title={form.name} description={form.description}/>
+
+ <div>
+ <form id="form" onSubmit={handleSubmit} css={[formStyles, unselectable]}>
+ { closed_header }
+ { questions }
+ </form>
+ <Navigation form_state={open}/>
+ </div>
+
+ <div css={css`margin-bottom: 10rem`}/>
+ <ScrollToTop/>
</div>
- </div>;
+ );
}
export default FormPage;
diff --git a/src/pages/LandingPage.tsx b/src/pages/LandingPage.tsx
index 124bbcf..af968ad 100644
--- a/src/pages/LandingPage.tsx
+++ b/src/pages/LandingPage.tsx
@@ -4,10 +4,11 @@ import { useEffect, useState } from "react";
import HeaderBar from "../components/HeaderBar";
import FormListing from "../components/FormListing";
-
-import { getForms, Form } from "../api/forms";
import OAuth2Button from "../components/OAuth2Button";
import Loading from "../components/Loading";
+import ScrollToTop from "../components/ScrollToTop";
+
+import { getForms, Form } from "../api/forms";
function LandingPage(): JSX.Element {
const [forms, setForms] = useState<Form[]>();
@@ -25,8 +26,8 @@ function LandingPage(): JSX.Element {
return <div>
<HeaderBar/>
+ <ScrollToTop/>
<div>
-
<div css={css`
display: flex;
align-items: center;