diff options
author | 2022-07-19 13:58:34 +0200 | |
---|---|---|
committer | 2022-07-19 13:58:34 +0200 | |
commit | 191581e287f78ba325fdd7681c83586309b59df2 (patch) | |
tree | 72331f121c3d5baa6f449e6c1ad362a98d35b5c8 /src | |
parent | Clear 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.tsx | 61 | ||||
-rw-r--r-- | src/components/OAuth2Button.tsx | 6 | ||||
-rw-r--r-- | src/pages/FormPage/ErrorPage.tsx | 29 | ||||
-rw-r--r-- | src/pages/FormPage/Navigation.tsx | 111 | ||||
-rw-r--r-- | src/pages/FormPage/SuccessPage.tsx | 10 | ||||
-rw-r--r-- | src/tests/components/OAuth2Button.test.tsx | 4 |
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(); }); |