aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorGravatar Hassan Abouelela <[email protected]>2022-07-19 13:58:34 +0200
committerGravatar Hassan Abouelela <[email protected]>2022-07-19 13:58:34 +0200
commit191581e287f78ba325fdd7681c83586309b59df2 (patch)
tree72331f121c3d5baa6f449e6c1ad362a98d35b5c8 /src
parentClear Authorization On Error (diff)
Simplify Navigation Component
Extract the styles from the navigation component to common styles, and convert it to a function component. Signed-off-by: Hassan Abouelela <[email protected]>
Diffstat (limited to 'src')
-rw-r--r--src/commonStyles.tsx61
-rw-r--r--src/components/OAuth2Button.tsx6
-rw-r--r--src/pages/FormPage/ErrorPage.tsx29
-rw-r--r--src/pages/FormPage/Navigation.tsx111
-rw-r--r--src/pages/FormPage/SuccessPage.tsx10
-rw-r--r--src/tests/components/OAuth2Button.test.tsx4
6 files changed, 101 insertions, 120 deletions
diff --git a/src/commonStyles.tsx b/src/commonStyles.tsx
index bfae17e..b4989da 100644
--- a/src/commonStyles.tsx
+++ b/src/commonStyles.tsx
@@ -51,8 +51,7 @@ const textInputs = css`
border-radius: 8px;
`;
-const submitStyles = css`
- text-align: right;
+const actionButtonStyles = css`
white-space: nowrap;
button:disabled {
@@ -61,6 +60,7 @@ const submitStyles = css`
}
button {
+ width: 100%;
cursor: pointer;
border: none;
@@ -91,12 +91,65 @@ const invalidStyles = css`
}
`;
+const mainTextStyles = css`
+ margin: auto;
+ width: 50%;
+
+ text-align: center;
+ font-size: 1.5rem;
+
+ > div {
+ margin: 2rem auto;
+ }
+
+ @media (max-width: 800px) {
+ width: 80%;
+ }
+`;
+
+const navigationStyles = css`
+ display: flex;
+ flex-direction: row;
+ justify-content: space-around;
+ align-items: center;
+ flex-wrap: wrap;
+
+ column-gap: 20px;
+ row-gap: 20px;
+
+ > * {
+ // Make all elements the same size
+ flex: 0 1 16rem;
+ }
+`;
+
+const returnButtonStyles = css`
+ font-size: 1.5rem;
+ text-align: center;
+
+ color: white;
+ text-decoration: none;
+ background-color: ${colors.greyple};
+
+ padding: 0.5rem 0;
+ border-radius: 8px;
+
+ transition: background-color 300ms;
+
+ :hover {
+ background-color: ${colors.darkerGreyple};
+ }
+`;
+
export {
selectable,
unselectable,
hiddenInput,
multiSelectInput,
textInputs,
- submitStyles,
- invalidStyles
+ actionButtonStyles,
+ invalidStyles,
+ mainTextStyles,
+ returnButtonStyles,
+ navigationStyles,
};
diff --git a/src/components/OAuth2Button.tsx b/src/components/OAuth2Button.tsx
index 885c080..be8d160 100644
--- a/src/components/OAuth2Button.tsx
+++ b/src/components/OAuth2Button.tsx
@@ -11,7 +11,7 @@ import { selectable } from "../commonStyles";
interface OAuth2ButtonProps {
scopes?: OAuthScopes[],
- rerender: () => void
+ rerender?: () => void
}
const iconStyles = css`
@@ -59,7 +59,7 @@ async function login(props: OAuth2ButtonProps, errorDialog: React.RefObject<HTML
throw reason.Error;
});
- if (checkScopes(props.scopes)) {
+ if (checkScopes(props.scopes) && props.rerender) {
props.rerender();
}
}
@@ -71,7 +71,7 @@ function OAuth2Button(props: OAuth2ButtonProps): JSX.Element {
return <span>
<button disabled={disabled} onClick={() => login(props, errorDialog, setDisabled)}>
<FontAwesomeIcon icon={faDiscord} css={iconStyles}/>
- <span css={textStyles}>Discord Login</span>
+ <span css={textStyles}>Login To Submit</span>
</button>
<div css={[errorStyles, selectable]} ref={errorDialog}/>
</span>;
diff --git a/src/pages/FormPage/ErrorPage.tsx b/src/pages/FormPage/ErrorPage.tsx
index da336cf..351170b 100644
--- a/src/pages/FormPage/ErrorPage.tsx
+++ b/src/pages/FormPage/ErrorPage.tsx
@@ -7,9 +7,7 @@ import HeaderBar from "../../components/HeaderBar";
import {Form} from "../../api/forms";
import {clearAuth} from "../../api/auth";
-import {selectable, submitStyles, unselectable} from "../../commonStyles";
-
-import Navigation from "./Navigation";
+import * as styles from "../../commonStyles";
interface ErrorProps {
@@ -28,19 +26,18 @@ export default function ErrorPage(props: ErrorProps): JSX.Element {
return (
<div>
<HeaderBar title={props.form.name} description={props.form.description}/>
- <div css={[unselectable, Navigation.containerStyles]}>
- <h3 css={selectable}>{props.message}</h3>
- <div className={ "return_button" }>
- <Link to="/" css={Navigation.returnStyles}>Return Home</Link>
- </div>
- <br css={Navigation.separatorStyles}/>
- <div css={submitStyles}>
- <button
- type="button" css={refreshStyles}
- onClick={location.reload.bind(window.location)} // TODO: State should probably be saved here
- >
- Refresh
- </button>
+ <div css={[styles.unselectable, styles.mainTextStyles]}>
+ <h3 css={styles.selectable}>{props.message}</h3>
+ <div css={styles.navigationStyles}>
+ <Link css={styles.returnButtonStyles} to="/">Return Home</Link>
+ <div css={styles.actionButtonStyles}>
+ <button
+ type="button" css={refreshStyles}
+ onClick={location.reload.bind(window.location)} // TODO: State should probably be saved here
+ >
+ Refresh
+ </button>
+ </div>
</div>
</div>
</div>
diff --git a/src/pages/FormPage/Navigation.tsx b/src/pages/FormPage/Navigation.tsx
index 52cd47e..20c7dce 100644
--- a/src/pages/FormPage/Navigation.tsx
+++ b/src/pages/FormPage/Navigation.tsx
@@ -1,12 +1,9 @@
/** @jsx jsx */
-import {jsx, css} from "@emotion/react";
-
-import React from "react";
+import {jsx} from "@emotion/react";
+import React, {useState} from "react";
import {Link} from "react-router-dom";
-import colors from "../../colors";
-import {submitStyles, unselectable} from "../../commonStyles";
-
+import * as styles from "../../commonStyles";
import {checkScopes, OAuthScopes} from "../../api/auth";
import OAuth2Button from "../../components/OAuth2Button";
@@ -16,92 +13,28 @@ interface NavigationProps {
scopes: OAuthScopes[]
}
-export default class Navigation extends React.Component<NavigationProps> {
- static containerStyles = css`
- margin: auto;
- width: 50%;
-
- text-align: center;
- font-size: 1.5rem;
-
- > div {
- display: inline-block;
- margin: 2rem auto;
- width: 50%;
- }
-
- @media (max-width: 870px) {
- width: 100%;
-
- > div {
- display: flex;
- justify-content: center;
-
- margin: 0 auto;
+export default function Navigation(props: NavigationProps): JSX.Element {
+ const [authorized, setAuth] = useState<boolean>(!(
+ props.scopes.includes(OAuthScopes.Identify) && !checkScopes(props.scopes)
+ ));
+
+ let submit = null;
+ if (props.form_state) {
+ let innerElement;
+ if (!authorized) {
+ innerElement = <OAuth2Button rerender={() => setAuth(true)} scopes={props.scopes}/>;
+ } else {
+ innerElement = <button form="form" type="submit">Submit</button>;
}
- }
-
- .return_button {
- text-align: left;
- }
-
- .return_button.closed {
- text-align: center;
- }
- `;
-
- static separatorStyles = css`
- height: 0;
- display: none;
-
- @media (max-width: 870px) {
- display: block;
- }
- `;
-
- static returnStyles = css`
- padding: 0.5rem 2.2rem;
- border-radius: 8px;
-
- color: white;
- text-decoration: none;
- white-space: nowrap;
-
- background-color: ${colors.greyple};
- transition: background-color 300ms;
-
- :hover {
- background-color: ${colors.darkerGreyple};
- }
- `;
-
- constructor(props: NavigationProps) {
- super(props);
- this.state = {"logged_in": false};
+ submit = <div css={styles.actionButtonStyles}>{innerElement}</div>;
}
- render(): JSX.Element {
- let submit = null;
-
- if (this.props.form_state) {
- let inner_submit;
- if (this.props.scopes.includes(OAuthScopes.Identify) && !checkScopes(this.props.scopes)) {
- // Render OAuth button if login is required, and the scopes needed are not available
- inner_submit = <OAuth2Button scopes={this.props.scopes} rerender={() => this.setState({"logged_in": true})}/>;
- } else {
- inner_submit = <button form="form" type="submit">Submit</button>;
- }
- submit = <div css={submitStyles}>{ inner_submit }</div>;
- }
-
- return (
- <div css={[unselectable, Navigation.containerStyles]}>
- <div className={ "return_button" + (this.props.form_state ? "" : " closed") }>
- <Link to="/" css={Navigation.returnStyles}>Return Home</Link>
- </div>
- <br css={Navigation.separatorStyles}/>
+ return (
+ <div css={[styles.unselectable, styles.mainTextStyles]}>
+ <div css={styles.navigationStyles}>
+ <Link to="/" css={styles.returnButtonStyles}>Return Home</Link>
{ submit }
</div>
- );
- }
+ </div>
+ );
}
diff --git a/src/pages/FormPage/SuccessPage.tsx b/src/pages/FormPage/SuccessPage.tsx
index e35bd4d..e83ca0d 100644
--- a/src/pages/FormPage/SuccessPage.tsx
+++ b/src/pages/FormPage/SuccessPage.tsx
@@ -4,9 +4,7 @@ import {Link} from "react-router-dom";
import {Form} from "../../api/forms";
import HeaderBar from "../../components/HeaderBar";
-import {unselectable} from "../../commonStyles";
-
-import Navigation from "./Navigation";
+import {returnButtonStyles, navigationStyles, unselectable, mainTextStyles} from "../../commonStyles";
interface SuccessProps {
@@ -34,10 +32,10 @@ export default function Success(props: SuccessProps): JSX.Element {
return (
<div>
<HeaderBar title={props.form.name} description={props.form.description}/>
- <div css={[unselectable, Navigation.containerStyles, divStyle]}>
+ <div css={[unselectable, mainTextStyles, divStyle]}>
<h3 css={thanksStyle}>{submitted_text}</h3>
- <div className={"return_button closed"}>
- <Link to="/" css={Navigation.returnStyles}>Return Home</Link>
+ <div css={navigationStyles}>
+ <Link to="/" css={returnButtonStyles}>Return Home</Link>
</div>
</div>
</div>
diff --git a/src/tests/components/OAuth2Button.test.tsx b/src/tests/components/OAuth2Button.test.tsx
index a773686..2a67f98 100644
--- a/src/tests/components/OAuth2Button.test.tsx
+++ b/src/tests/components/OAuth2Button.test.tsx
@@ -3,8 +3,8 @@ import { render } from "@testing-library/react";
import OAuth2Button from "../../components/OAuth2Button";
test("renders oauth2 sign in button text", () => {
- const { getByText } = render(<OAuth2Button />);
- const button = getByText(/Discord Login/i);
+ const { getByText } = render(<OAuth2Button/>);
+ const button = getByText(/Login To Submit/i);
expect(button).toBeInTheDocument();
});