mirror of
https://github.com/Steffo99/sophon.git
synced 2024-12-22 14:54:22 +00:00
🔧 Split LoginBox
from LoginButton
This commit is contained in:
parent
66f21d9d1d
commit
d915673ef7
3 changed files with 80 additions and 66 deletions
|
@ -2,85 +2,27 @@ import {faUser} from "@fortawesome/free-solid-svg-icons"
|
|||
import {Box, Form, Heading, useFormState} from "@steffo/bluelib-react"
|
||||
import * as React from "react"
|
||||
import {useAuthorizationContext} from "../../contexts/authorization"
|
||||
import {SophonToken, SophonUser} from "../../types/SophonTypes"
|
||||
import {Validators} from "../../utils/Validators"
|
||||
import {IconText} from "../elements/IconText"
|
||||
import {useInstanceAxios} from "../instance/useInstanceAxios"
|
||||
import {AuthorizationLoginButton} from "./AuthorizationLoginButton"
|
||||
|
||||
|
||||
export function AuthorizationLoginBox(): JSX.Element {
|
||||
const axios = useInstanceAxios()
|
||||
const authorization = useAuthorizationContext()
|
||||
|
||||
const [error, setError] = React.useState<Error | undefined>(undefined)
|
||||
|
||||
const username = useFormState<string>("", Validators.doNotValidate)
|
||||
const password = useFormState<string>("", Validators.doNotValidate)
|
||||
|
||||
const canLogin =
|
||||
React.useMemo<boolean>(
|
||||
() => (
|
||||
axios !== undefined && authorization !== undefined && authorization.state.token === undefined
|
||||
authorization !== undefined && authorization.state.token === undefined
|
||||
),
|
||||
[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 (
|
||||
<Box disabled={!canLogin}>
|
||||
<Heading level={3}>
|
||||
|
@ -111,11 +53,11 @@ export function AuthorizationLoginBox(): JSX.Element {
|
|||
{...password}
|
||||
/>
|
||||
<Form.Row>
|
||||
<Form.Button type={"submit"} bluelibClassNames={buttonColor} disabled={!canClickLogin} onClick={doLogin}>
|
||||
<IconText icon={faUser} spin={authorization?.state.running}>
|
||||
Login
|
||||
</IconText>
|
||||
</Form.Button>
|
||||
<AuthorizationLoginButton
|
||||
disabled={!canLogin}
|
||||
username={username.value}
|
||||
password={password.value}
|
||||
/>
|
||||
</Form.Row>
|
||||
</Form>
|
||||
</Box>
|
||||
|
|
|
@ -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>
|
||||
)
|
||||
}
|
|
@ -33,7 +33,7 @@ export function NotebookDescriptionBox(): JSX.Element | null {
|
|||
}
|
||||
|
||||
return (
|
||||
<Box>
|
||||
<Box builtinColor={locked_by ? "blue" : undefined}>
|
||||
<Heading level={3}>
|
||||
<FontAwesomeIcon icon={faBook}/> About <I>{notebook.value.name}</I>
|
||||
</Heading>
|
||||
|
|
Loading…
Reference in a new issue