From 996c14afb9d81e962ef66b99bd869bce4f3688f0 Mon Sep 17 00:00:00 2001
From: Hassan Abouelela <47495861+HassanAbouelela@users.noreply.github.com>
Date: Wed, 6 Jan 2021 08:00:31 +0300
Subject: Breaks Up CSS Into Components

Moves the styles from the CSS file, into emotion CSS in each component's
file to make navigation easier, and keep CSS and JSX together.Drops
raw-loader dependency.

Signed-off-by: Hassan Abouelela <47495861+HassanAbouelela@users.noreply.github.com>
---
 src/pages/FormPage.tsx | 168 +++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 141 insertions(+), 27 deletions(-)

(limited to 'src/pages/FormPage.tsx')

diff --git a/src/pages/FormPage.tsx b/src/pages/FormPage.tsx
index b966e84..647003f 100644
--- a/src/pages/FormPage.tsx
+++ b/src/pages/FormPage.tsx
@@ -11,12 +11,143 @@ 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};
+`;
+
 function FormPage(): JSX.Element {
     const { id } = useParams<PathParams>();
 
@@ -33,7 +164,7 @@ function FormPage(): JSX.Element {
     }
 
     const questions = form.questions.map((question, index) => {
-        return <RenderedQuestion question={question} public_state={new Map()} key={index}/>;
+        return <RenderedQuestion question={question} public_state={new Map()} key={index + Date.now()}/>;
     });
 
     function handleSubmit(event: SyntheticEvent) {
@@ -53,39 +184,22 @@ function FormPage(): JSX.Element {
     const open: boolean = form.features.includes(FormFeatures.Open);
 
     let closed_header = null;
-    let submit = null;
-
-    if (open) {
-        submit = (
-            <div className="submit_form">
-                <button form="form" type="submit">Submit</button>
-            </div>
-        );
-    } else {
-        closed_header = (
-            <div className="closed_header">
-                <div>This form is now closed. You will not be able to submit your response.</div>
-            </div>
-        );
+    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} key={2}/>
-            <div css={css`${require("./css/FormPage.css")};`}>
-                <form id="form" onSubmit={handleSubmit} className="unselectable">
+            <HeaderBar title={form.name} description={form.description}/>
+
+            <div>
+                <form id="form" onSubmit={handleSubmit} css={[formStyles, unselectable]}>
                     { closed_header }
-                    {questions}
+                    { questions }
                 </form>
-                <div className="nav unselectable">
-                    <div className={ "nav_buttons" + (open ? "" : " closed") }>
-                        <Link to="/" className="return_home">Return Home</Link>
-                    </div>
-                    <br className="nav_separator"/>
-                    { submit }
-                </div>
+                <Navigation form_state={open}/>
             </div>
+
             <div css={css`margin-bottom: 10rem`}/>
             <ScrollToTop/>
         </div>
-- 
cgit v1.2.3

