1
0
mirror of https://github.com/spacebarchat/client.git synced 2024-11-22 10:22:30 +01:00

auth layout changes

This commit is contained in:
Puyodead1 2023-08-08 18:20:36 -04:00
parent d2a4b4f3cf
commit be4595ddce
No known key found for this signature in database
GPG Key ID: A4FA4FEC0DD353FC
4 changed files with 262 additions and 308 deletions

View File

@ -0,0 +1,156 @@
import styled from "styled-components";
import Button from "./Button";
import Container from "./Container";
export const Wrapper = styled(Container)`
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
background-color: var(--background-tertiary);
`;
export const AuthContainer = styled(Container)`
background-color: var(--background-primary-alt);
padding: 32px;
font-size: 18px;
color: var(--text-muted);
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
@media (max-width: 480px) {
width: 100%;
height: 100%;
}
@media (min-width: 480px) {
width: 480px;
border-radius: 18px;
}
`;
export const HeaderContainer = styled.div`
width: 100%;
`;
export const Header = styled.h1`
margin-bottom: 3px;
color: var(--text);
font-weight: 600;
font-size: 24px;
`;
export const SubHeader = styled.h2<{ noBranding?: boolean }>`
margin-top: 3px;
color: var(--text-muted);
font-weight: 400;
font-size: ${(props) => (props.noBranding ? "20px" : "16px")};
`;
export const FormContainer = styled.form`
width: 100%;
`;
export const InputContainer = styled.h1<{ marginBottom: boolean }>`
margin-bottom: ${(props) => (props.marginBottom ? "20px" : "0")};
display: flex;
flex-direction: column;
align-items: flex-start;
`;
export const LabelWrapper = styled.div<{ error?: boolean }>`
display: flex;
flex-direction: row;
margin-bottom: 8px;
color: ${(props) => (props.error ? "var(--error)" : "var(--text)")};
`;
export const InputErrorText = styled.label`
font-size: 14px;
font-weight: 400;
font-style: italic;
`;
export const InputLabel = styled.label`
font-size: 14px;
font-weight: 700;
`;
export const InputWrapper = styled.div`
width: 100%;
display: flex;
`;
// TODO: Fix border hover causing small layout shift
export const Input = styled.input<{ error?: boolean }>`
outline: none;
background: var(--background-secondary);
padding: 10px;
font-size: 16px;
flex: 1;
border-radius: 12px;
color: var(--text);
margin: 0;
border: none;
aria-invalid: ${(props) => (props.error ? "true" : "false")};
border: ${(props) => (props.error ? "1px solid var(--error)" : "none")};
&:focus {
border: 1px solid var(--primary);
}
`;
export const PasswordResetLink = styled.button`
margin-bottom: 20px;
margin-top: 4px;
padding: 2px 0;
font-size: 14px;
display: flex;
color: var(--text-link);
background: none;
border: none;
&:hover {
text-decoration: underline;
cursor: pointer;
}
`;
export const SubmitButton = styled(Button)`
margin-bottom: 8px;
width: 100%;
min-width: 130px;
min-height: 44px;
font-size: 14px;
`;
export const AuthSwitchPageContainer = styled.div`
margin-top: 4px;
text-align: initial;
`;
export const AuthSwitchPageLabel = styled.label`
font-size: 14px;
`;
export const AuthSwitchPageLink = styled.button`
font-size: 14px;
background: none;
border: none;
color: var(--text-link);
@media (max-width: 480px) {
display: inline-block;
}
&:hover {
text-decoration: underline;
cursor: pointer;
}
`;
export const Divider = styled.span`
padding: 0 4px;
`;

View File

@ -3,12 +3,28 @@ import { Routes } from "@spacebarchat/spacebar-api-types/v9";
import React from "react";
import { useForm } from "react-hook-form";
import { useNavigate } from "react-router-dom";
import styled from "styled-components";
import Button from "../components/Button";
import Container from "../components/Container";
import HCaptcha from "../components/HCaptcha";
import {
AuthContainer,
AuthSwitchPageContainer,
AuthSwitchPageLabel,
AuthSwitchPageLink,
Divider,
FormContainer,
Header,
Input,
InputContainer,
InputErrorText,
InputLabel,
InputWrapper,
LabelWrapper,
PasswordResetLink,
SubHeader,
SubmitButton,
Wrapper,
} from "../components/AuthComponents";
import HCaptcha, { HeaderContainer } from "../components/HCaptcha";
import MFA from "../components/MFA";
import { useAppStore } from "../stores/AppStore";
import { AUTH_NO_BRANDING, useAppStore } from "../stores/AppStore";
import {
IAPILoginRequest,
IAPILoginResponse,
@ -17,151 +33,6 @@ import {
} from "../utils/interfaces/api";
import { messageFromFieldError } from "../utils/messageFromFieldError";
export const Wrapper = styled(Container)`
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
background-color: var(--background-tertiary);
`;
export const AuthBox = styled(Container)`
background-color: var(--background-primary-alt);
padding: 32px;
font-size: 18px;
color: var(--text-muted);
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
@media (max-width: 480px) {
width: 100%;
height: 100%;
}
@media (min-width: 480px) {
width: 480px;
border-radius: 18px;
}
`;
export const HeaderContainer = styled.div`
width: 100%;
`;
export const Header = styled.h1`
font-weight: 600;
margin-bottom: 8px;
font-size: 24px;
color: var(--text);
`;
export const SubHeader = styled.h2`
color: var(--text-muted);
font-weight: 400;
font-size: 16px;
`;
export const FormContainer = styled.form`
width: 100%;
`;
export const InputContainer = styled.h1<{ marginBottom: boolean }>`
margin-bottom: ${(props) => (props.marginBottom ? "20px" : "0")};
display: flex;
flex-direction: column;
align-items: flex-start;
`;
export const LabelWrapper = styled.div<{ error?: boolean }>`
display: flex;
flex-direction: row;
margin-bottom: 8px;
color: ${(props) => (props.error ? "var(--error)" : "#b1b5bc")};
`;
export const InputErrorText = styled.label`
font-size: 14px;
font-weight: 400;
font-style: italic;
`;
export const InputLabel = styled.label`
font-size: 14px;
font-weight: 700;
`;
export const InputWrapper = styled.div`
width: 100%;
display: flex;
`;
export const Input = styled.input<{ error?: boolean }>`
outline: none;
background: var(--background-secondary);
padding: 10px;
font-size: 16px;
flex: 1;
border-radius: 12px;
color: var(--text);
margin: 0;
border: none;
aria-invalid: ${(props) => (props.error ? "true" : "false")};
`;
export const PasswordResetLink = styled.button`
margin-bottom: 20px;
margin-top: 4px;
padding: 2px 0;
font-size: 14px;
display: flex;
color: var(--text-link);
background: none;
border: none;
&:hover {
text-decoration: underline;
cursor: pointer;
}
`;
export const LoginButton = styled(Button)`
margin-bottom: 8px;
width: 100%;
min-width: 130px;
min-height: 44px;
`;
export const RegisterContainer = styled.div`
margin-top: 4px;
text-align: initial;
`;
export const RegisterLabel = styled.label`
font-size: 14px;
`;
export const RegisterLink = styled.button`
font-size: 14px;
background: none;
border: none;
color: var(--text-link);
@media (max-width: 480px) {
display: inline-block;
}
&:hover {
text-decoration: underline;
cursor: pointer;
}
`;
export const Divider = styled.span`
padding: 0 4px;
`;
type FormValues = {
login: string;
password: string;
@ -299,10 +170,22 @@ function LoginPage() {
return (
<Wrapper>
<AuthBox>
<AuthContainer>
<HeaderContainer>
<Header>Welcome Back!</Header>
<SubHeader>We're so excited to see you again!</SubHeader>
{AUTH_NO_BRANDING ? (
<>
<Header>Login to Spacebar</Header>
</>
) : (
<>
{/* Note: This would need to change depending on the theme */}
<img
src="https://github.com/spacebarchat/spacebarchat/blob/master/branding/png/Spacebar__Logo-White.png?raw=true"
height={48}
/>
<SubHeader noBranding>Log into Spacebar</SubHeader>
</>
)}
</HeaderContainer>
<FormContainer onSubmit={onSubmit}>
@ -324,6 +207,7 @@ function LoginPage() {
<InputWrapper>
<Input
type="email"
placeholder="Email"
autoFocus
{...register("login", { required: true })}
error={!!errors.login}
@ -347,6 +231,7 @@ function LoginPage() {
<InputWrapper>
<Input
type="password"
placeholder="Password"
{...register("password", { required: true })}
error={!!errors.password}
disabled={loading}
@ -366,29 +251,29 @@ function LoginPage() {
Forgot your password?
</PasswordResetLink>
<LoginButton
<SubmitButton
variant="primary"
type="submit"
disabled={loading}
>
Log In
</LoginButton>
Login
</SubmitButton>
<RegisterContainer>
<RegisterLabel>
Don't have an account?&nbsp;
</RegisterLabel>
<RegisterLink
<AuthSwitchPageContainer>
<AuthSwitchPageLabel>
New to Spacebar?&nbsp;
</AuthSwitchPageLabel>
<AuthSwitchPageLink
onClick={() => {
navigate("/register");
}}
type="button"
>
Sign Up
</RegisterLink>
</RegisterContainer>
Register
</AuthSwitchPageLink>
</AuthSwitchPageContainer>
</FormContainer>
</AuthBox>
</AuthContainer>
</Wrapper>
);
}

View File

@ -3,12 +3,27 @@ import { Routes } from "@spacebarchat/spacebar-api-types/v9";
import React from "react";
import { useForm } from "react-hook-form";
import { useNavigate } from "react-router-dom";
import styled from "styled-components";
import Button from "../components/Button";
import Container from "../components/Container";
import {
AuthContainer,
AuthSwitchPageContainer,
AuthSwitchPageLabel,
AuthSwitchPageLink,
Divider,
FormContainer,
Header,
Input,
InputContainer,
InputErrorText,
InputLabel,
InputWrapper,
LabelWrapper,
SubHeader,
SubmitButton,
Wrapper,
} from "../components/AuthComponents";
import DOBInput from "../components/DOBInput";
import HCaptcha from "../components/HCaptcha";
import { useAppStore } from "../stores/AppStore";
import { AUTH_NO_BRANDING, useAppStore } from "../stores/AppStore";
import {
IAPILoginResponseSuccess,
IAPIRegisterRequest,
@ -16,129 +31,6 @@ import {
} from "../utils/interfaces/api";
import { messageFromFieldError } from "../utils/messageFromFieldError";
const Wrapper = styled(Container)`
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
background-color: var(--background-tertiary);
`;
const AuthBox = styled(Container)`
background-color: var(--background-primary-alt);
padding: 32px;
font-size: 18px;
color: var(--text-muted);
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
@media (max-width: 480px) {
width: 100%;
height: 100%;
}
@media (min-width: 480px) {
width: 480px;
border-radius: 18px;
}
`;
const HeaderContainer = styled.div`
width: 100%;
`;
const Header = styled.h1`
font-weight: 600;
margin-bottom: 8px;
font-size: 24px;
color: var(--text);
`;
// const SubHeader = styled.h2`
// color: var(--text-muted);
// font-weight: 400;
// font-size: 16px;
// `;
const FormContainer = styled.form`
width: 100%;
`;
const InputContainer = styled.h1<{ marginBottom: boolean }>`
margin-bottom: ${(props) => (props.marginBottom ? "20px" : "0")};
display: flex;
flex-direction: column;
align-items: flex-start;
`;
const LabelWrapper = styled.div<{ error?: boolean }>`
display: flex;
flex-direction: row;
margin-bottom: 8px;
color: ${(props) => (props.error ? "var(--error)" : "#b1b5bc")};
`;
const InputErrorText = styled.label`
font-size: 14px;
font-weight: 400;
font-style: italic;
`;
const InputLabel = styled.label`
font-size: 14px;
font-weight: 700;
`;
const InputWrapper = styled.div`
width: 100%;
display: flex;
`;
const Input = styled.input<{ error?: boolean }>`
outline: none;
background: var(--background-secondary);
padding: 10px;
font-size: 16px;
border-radius: 12px;
color: var(--text);
margin: 0;
border: none;
aria-invalid: ${(props) => (props.error ? "true" : "false")};
box-sizing: border-box;
width: 100%;
`;
const LoginButton = styled(Button)`
margin-bottom: 8px;
width: 100%;
min-width: 130px;
min-height: 44px;
`;
const LoginLink = styled.button`
margin-top: 4px;
float: left;
font-size: 14px;
background: none;
border: none;
color: var(--text-link);
@media (max-width: 480px) {
display: inline-block;
}
&:hover {
text-decoration: underline;
cursor: pointer;
}
`;
const Divider = styled.span`
padding: 0 4px;
`;
type FormValues = {
email: string;
username: string;
@ -279,11 +171,21 @@ function RegistrationPage() {
return (
<Wrapper>
<AuthBox>
<HeaderContainer>
<Header>Create an account</Header>
{/* <SubHeader>We're so excited to see you again!</SubHeader> */}
</HeaderContainer>
<AuthContainer>
{AUTH_NO_BRANDING ? (
<>
<Header>Create an account</Header>
</>
) : (
<>
{/* Note: This would need to change depending on the theme */}
<img
src="https://github.com/spacebarchat/spacebarchat/blob/master/branding/png/Spacebar__Logo-White.png?raw=true"
height={48}
/>
<SubHeader noBranding>Create an account</SubHeader>
</>
)}
<FormContainer onSubmit={onSubmit}>
<InputContainer
@ -304,6 +206,7 @@ function RegistrationPage() {
<InputWrapper>
<Input
type="email"
placeholder="Email"
autoFocus
{...register("email", { required: true })}
error={!!errors.email}
@ -330,6 +233,7 @@ function RegistrationPage() {
<InputWrapper>
<Input
{...register("username", { required: true })}
placeholder="Username"
error={!!errors.username}
disabled={loading}
/>
@ -351,6 +255,7 @@ function RegistrationPage() {
<InputWrapper>
<Input
type="password"
placeholder="Password"
{...register("password", { required: true })}
error={!!errors.password}
disabled={loading}
@ -396,24 +301,29 @@ function RegistrationPage() {
</InputWrapper>
</InputContainer>
<LoginButton
<SubmitButton
variant="primary"
type="submit"
disabled={loading}
>
Create Account
</LoginButton>
</SubmitButton>
<LoginLink
onClick={() => {
navigate("/login", { replace: true });
}}
type="button"
>
Already have an account?
</LoginLink>
<AuthSwitchPageContainer>
<AuthSwitchPageLabel>
Already have an account?&nbsp;
</AuthSwitchPageLabel>
<AuthSwitchPageLink
onClick={() => {
navigate("/login");
}}
type="button"
>
Login
</AuthSwitchPageLink>
</AuthSwitchPageContainer>
</FormContainer>
</AuthBox>
</AuthContainer>
</Wrapper>
);
}

View File

@ -12,6 +12,9 @@ import PrivateChannelStore from "./PrivateChannelStore";
import ThemeStore from "./ThemeStore";
import UserStore from "./UserStore";
// dev thing to force toggle branding on auth pages for testing.
export const AUTH_NO_BRANDING = false;
export default class AppStore {
// whether the gateway is ready
@observable isGatewayReady = false;