1
Fork 0
mirror of https://github.com/Steffo99/sophon.git synced 2024-12-22 06:44:21 +00:00

🔧 Split LoginBox from LoginButton

This commit is contained in:
Steffo 2021-10-16 16:00:18 +02:00 committed by Stefano Pigozzi
parent 8b3e070a91
commit a2c24111ae
3 changed files with 80 additions and 66 deletions

View file

@ -2,85 +2,27 @@ import {faUser} from "@fortawesome/free-solid-svg-icons"
import {Box, Form, Heading, useFormState} from "@steffo/bluelib-react" import {Box, Form, Heading, useFormState} from "@steffo/bluelib-react"
import * as React from "react" import * as React from "react"
import {useAuthorizationContext} from "../../contexts/authorization" import {useAuthorizationContext} from "../../contexts/authorization"
import {SophonToken, SophonUser} from "../../types/SophonTypes"
import {Validators} from "../../utils/Validators" import {Validators} from "../../utils/Validators"
import {IconText} from "../elements/IconText" import {IconText} from "../elements/IconText"
import {useInstanceAxios} from "../instance/useInstanceAxios" import {useInstanceAxios} from "../instance/useInstanceAxios"
import {AuthorizationLoginButton} from "./AuthorizationLoginButton"
export function AuthorizationLoginBox(): JSX.Element { export function AuthorizationLoginBox(): JSX.Element {
const axios = useInstanceAxios() const axios = useInstanceAxios()
const authorization = useAuthorizationContext() const authorization = useAuthorizationContext()
const [error, setError] = React.useState<Error | undefined>(undefined)
const username = useFormState<string>("", Validators.doNotValidate) const username = useFormState<string>("", Validators.doNotValidate)
const password = useFormState<string>("", Validators.doNotValidate) const password = useFormState<string>("", Validators.doNotValidate)
const canLogin = const canLogin =
React.useMemo<boolean>( React.useMemo<boolean>(
() => ( () => (
axios !== undefined && authorization !== undefined && authorization.state.token === undefined authorization !== undefined && authorization.state.token === undefined
), ),
[axios, authorization], [axios, authorization],
) )
const canClickLogin =
React.useMemo<boolean>(
() => (
canLogin && !authorization!.state.running && username.value !== "" && password.value !== ""
),
[authorization, canLogin, username, password],
)
const doLogin =
React.useCallback(
async () => {
if(!axios) {
return
}
if(!authorization) {
return
}
authorization.dispatch({
type: "start:login",
})
setError(undefined)
try {
const loginRequest = await axios.post<SophonToken>("/api/auth/token/", {username: username.value, password: password.value})
const dataRequest = await axios.get<SophonUser>(`/api/core/users/${username.value}/`)
authorization.dispatch({
type: "success:login",
user: dataRequest.data,
token: loginRequest.data.token,
})
}
catch(e) {
setError(e as Error)
authorization.dispatch({
type: "failure:login",
})
return
}
},
[axios, authorization, username, password],
)
const buttonColor =
React.useMemo<string>(
() => {
if(!authorization) {
return ""
}
if(error) {
return "color-red"
}
return ""
},
[authorization, error],
)
return ( return (
<Box disabled={!canLogin}> <Box disabled={!canLogin}>
<Heading level={3}> <Heading level={3}>
@ -111,11 +53,11 @@ export function AuthorizationLoginBox(): JSX.Element {
{...password} {...password}
/> />
<Form.Row> <Form.Row>
<Form.Button type={"submit"} bluelibClassNames={buttonColor} disabled={!canClickLogin} onClick={doLogin}> <AuthorizationLoginButton
<IconText icon={faUser} spin={authorization?.state.running}> disabled={!canLogin}
Login username={username.value}
</IconText> password={password.value}
</Form.Button> />
</Form.Row> </Form.Row>
</Form> </Form>
</Box> </Box>

View file

@ -0,0 +1,72 @@
import {faUser} from "@fortawesome/free-solid-svg-icons"
import {Button} from "@steffo/bluelib-react"
import * as React from "react"
import {useAuthorizationContext} from "../../contexts/authorization"
import {CanBeDisabled} from "../../types/ExtraTypes"
import {SophonToken, SophonUser} from "../../types/SophonTypes"
import {IconText} from "../elements/IconText"
import {useInstanceAxios} from "../instance/useInstanceAxios"
export interface AuthorizationLoginButtonProps extends CanBeDisabled {
username: string,
password: string,
}
export function AuthorizationLoginButton({username, password, disabled = false}: AuthorizationLoginButtonProps): JSX.Element {
const authorization = useAuthorizationContext()
const axios = useInstanceAxios()
const [error, setError] = React.useState<Error | undefined>(undefined)
const canLogin =
React.useMemo<boolean>(
() => (
!disabled && authorization !== undefined && !authorization.state.running && username !== "" && password !== ""
),
[authorization, username, password],
)
const doLogin =
React.useCallback(
async () => {
if(!axios) {
return
}
if(!authorization) {
return
}
authorization.dispatch({
type: "start:login",
})
setError(undefined)
try {
const loginRequest = await axios.post<SophonToken>("/api/auth/token/", {username, password})
const dataRequest = await axios.get<SophonUser>(`/api/core/users/${username}/`)
authorization.dispatch({
type: "success:login",
user: dataRequest.data,
token: loginRequest.data.token,
})
}
catch(e) {
setError(e as Error)
authorization.dispatch({
type: "failure:login",
})
return
}
},
[axios, authorization, username, password],
)
return (
<Button type={"submit"} builtinColor={error ? "red" : undefined} disabled={!canLogin} onClick={doLogin}>
<IconText icon={faUser} spin={authorization?.state.running}>
Login
</IconText>
</Button>
)
}

View file

@ -33,7 +33,7 @@ export function NotebookDescriptionBox(): JSX.Element | null {
} }
return ( return (
<Box> <Box builtinColor={locked_by ? "blue" : undefined}>
<Heading level={3}> <Heading level={3}>
<FontAwesomeIcon icon={faBook}/>&nbsp;About <I>{notebook.value.name}</I> <FontAwesomeIcon icon={faBook}/>&nbsp;About <I>{notebook.value.name}</I>
</Heading> </Heading>