diff options
author | 2021-02-13 01:21:36 +0300 | |
---|---|---|
committer | 2021-02-13 01:21:36 +0300 | |
commit | 451c825c77cd68eafeb262eb1ea5cbfc21dce550 (patch) | |
tree | d6d7ed63dab13fd111f23265048cdfec00bdea08 /src | |
parent | Makes Authorize Helper Async (diff) |
Dynamically Show Discord OAuth Button
Dynamically displays an auth button in place of the submit button if
needed, and adds full authorization flow.
Signed-off-by: Hassan Abouelela <[email protected]>
Diffstat (limited to 'src')
-rw-r--r-- | src/commonStyles.tsx | 32 | ||||
-rw-r--r-- | src/components/OAuth2Button.tsx | 14 | ||||
-rw-r--r-- | src/pages/FormPage.tsx | 65 |
3 files changed, 74 insertions, 37 deletions
diff --git a/src/commonStyles.tsx b/src/commonStyles.tsx index 89a2746..eb3e319 100644 --- a/src/commonStyles.tsx +++ b/src/commonStyles.tsx @@ -1,4 +1,5 @@ import { css } from "@emotion/react"; +import colors from "./colors"; const selectable = css` -moz-user-select: text; @@ -50,6 +51,36 @@ const textInputs = css` border-radius: 8px; `; +const submitStyles = css` + text-align: right; + + button:disabled { + background-color: ${colors.greyple}; + cursor: default; + } + + button { + cursor: pointer; + + border: none; + border-radius: 8px; + + color: white; + font: inherit; + + background-color: ${colors.blurple}; + transition: background-color 300ms; + } + + button[type="submit"] { + padding: 0.55rem 4.25rem; + } + + button:enabled:hover { + background-color: ${colors.darkerBlurple}; + } +`; + export { selectable, @@ -57,4 +88,5 @@ export { hiddenInput, multiSelectInput, textInputs, + submitStyles }; diff --git a/src/components/OAuth2Button.tsx b/src/components/OAuth2Button.tsx index 231e560..90a25fa 100644 --- a/src/components/OAuth2Button.tsx +++ b/src/components/OAuth2Button.tsx @@ -5,12 +5,13 @@ import { useState } from "react"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { faDiscord } from "@fortawesome/free-brands-svg-icons"; -import authenticate, { OAuthScopes } from "../api/auth"; +import authenticate, {checkScopes, OAuthScopes} from "../api/auth"; interface OAuth2ButtonProps { scopes?: OAuthScopes[], - path?: string + path?: string, + rerender: () => void } const iconStyles = css` @@ -27,9 +28,16 @@ const textStyles = css` function OAuth2Button(props: OAuth2ButtonProps): JSX.Element { const [disabled, setDisabled] = useState<boolean>(false); + async function login() { + await authenticate(props.scopes, setDisabled, props.path); + + if (checkScopes(props.scopes, props.path)) { + props.rerender(); + } + } return ( - <button disabled={disabled} onClick={() => authenticate(props.scopes, setDisabled, props.path)}> + <button disabled={disabled} onClick={() => login()}> <FontAwesomeIcon icon={faDiscord} css={iconStyles}/> <span css={textStyles}>Discord Login</span> </button> diff --git a/src/pages/FormPage.tsx b/src/pages/FormPage.tsx index c49b9fd..4237e86 100644 --- a/src/pages/FormPage.tsx +++ b/src/pages/FormPage.tsx @@ -9,10 +9,12 @@ import HeaderBar from "../components/HeaderBar"; import RenderedQuestion from "../components/Question"; import Loading from "../components/Loading"; import ScrollToTop from "../components/ScrollToTop"; +import OAuth2Button from "../components/OAuth2Button"; import { Form, FormFeatures, getForm } from "../api/forms"; +import { OAuthScopes, checkScopes } from "../api/auth"; import colors from "../colors"; -import { unselectable } from "../commonStyles"; +import { submitStyles, unselectable } from "../commonStyles"; interface PathParams { @@ -20,10 +22,13 @@ interface PathParams { } interface NavigationProps { - form_state: boolean // Whether the form is open or not + form_state: boolean, // Whether the form is open or not + scopes: OAuthScopes[] } class Navigation extends React.Component<NavigationProps> { + PAGE_PATH = "/form" + containerStyles = css` margin: auto; width: 50%; @@ -38,7 +43,7 @@ class Navigation extends React.Component<NavigationProps> { width: 50%; } - @media (max-width: 850px) { + @media (max-width: 870px) { width: 100%; > div { @@ -62,13 +67,13 @@ class Navigation extends React.Component<NavigationProps> { height: 0; display: none; - @media (max-width: 850px) { + @media (max-width: 870px) { display: block; } `; returnStyles = css` - padding: 0.5rem 2rem; + padding: 0.55rem 2.2rem; border-radius: 8px; color: white; @@ -83,36 +88,21 @@ class Navigation extends React.Component<NavigationProps> { } `; - 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}; - } - `; + constructor(props: NavigationProps) { + super(props); + this.setState({"logged_in": false}); + } render(): JSX.Element { let submit = null; + if (this.props.form_state) { - submit = ( - <div css={this.submitStyles}> - <button form="form" type="submit">Submit</button> - </div> - ); + if (this.props.scopes.includes(OAuthScopes.Identify) && !checkScopes(this.props.scopes, this.PAGE_PATH)) { + // Render OAuth button if login is required, and the scopes needed are not available + submit = <OAuth2Button path={this.PAGE_PATH} scopes={this.props.scopes} rerender={() => this.setState({"logged_in": true})}/>; + } else { + submit = <button form="form" type="submit">Submit</button>; + } } return ( @@ -121,7 +111,7 @@ class Navigation extends React.Component<NavigationProps> { <Link to="/" css={this.returnStyles}>Return Home</Link> </div> <br css={this.separatorStyles}/> - { submit } + <div css={submitStyles}>{ submit }</div> </div> ); } @@ -146,7 +136,7 @@ const closedHeaderStyles = css` font-size: 1.5rem; background-color: ${colors.error}; - + @media (max-width: 500px) { padding: 1rem 1.5rem; } @@ -186,6 +176,13 @@ function FormPage(): JSX.Element { } const open: boolean = form.features.includes(FormFeatures.Open); + const require_auth: boolean = form.features.includes(FormFeatures.RequiresLogin); + + const scopes = []; + if (require_auth) { + scopes.push(OAuthScopes.Identify); + if (form.features.includes(FormFeatures.CollectEmail)) { scopes.push(OAuthScopes.Email); } + } let closed_header = null; if (!open) { @@ -201,7 +198,7 @@ function FormPage(): JSX.Element { { closed_header } { questions } </form> - <Navigation form_state={open}/> + <Navigation form_state={open} scopes={scopes}/> </div> <div css={css`margin-bottom: 10rem`}/> |