aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Hassan Abouelela <[email protected]>2021-02-13 01:21:36 +0300
committerGravatar Hassan Abouelela <[email protected]>2021-02-13 01:21:36 +0300
commit451c825c77cd68eafeb262eb1ea5cbfc21dce550 (patch)
treed6d7ed63dab13fd111f23265048cdfec00bdea08
parentMakes 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]>
-rw-r--r--src/commonStyles.tsx32
-rw-r--r--src/components/OAuth2Button.tsx14
-rw-r--r--src/pages/FormPage.tsx65
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`}/>