aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-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`}/>