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

Add login context and instancebox

This commit is contained in:
Steffo 2021-09-16 17:43:57 +02:00
parent 6fbcff2256
commit 8f463fa701
4 changed files with 130 additions and 17 deletions

View file

@ -1,19 +1,22 @@
import * as React from 'react'; import * as React from 'react';
import {Bluelib, Heading, LayoutThreeCol} from "@steffo/bluelib-react"; import {Bluelib, Heading, LayoutThreeCol} from "@steffo/bluelib-react";
import {Router} from "./routes/Router"; import {Router} from "./routes/Router";
import {InstanceContextProvider} from "./components/InstanceContext";
import {LoginContextProvider} from "./components/LoginContext";
function App() { function App() {
return ( return (
<Bluelib theme={"sophon"}> <InstanceContextProvider>
<LayoutThreeCol> <LoginContextProvider>
<LayoutThreeCol.Center> <Bluelib theme={"sophon"}>
<Heading level={1}> <LayoutThreeCol>
Sophon <LayoutThreeCol.Center>
</Heading> <Router/>
<Router/> </LayoutThreeCol.Center>
</LayoutThreeCol.Center> </LayoutThreeCol>
</LayoutThreeCol> </Bluelib>
</Bluelib> </LoginContextProvider>
</InstanceContextProvider>
); );
} }

View file

@ -0,0 +1,30 @@
import * as React from "react"
import * as ReactDOM from "react-dom"
import {Box, Heading, Form} from "@steffo/bluelib-react";
import {useInstance} from "./InstanceContext";
import {useLogin} from "./LoginContext";
interface InstanceBoxProps {
}
export function InstanceBox({}: InstanceBoxProps): JSX.Element {
const instance = useInstance()
const login = useLogin()
return (
<Box>
<Heading level={3}>
Instance select
</Heading>
<p>
Select the Sophon instance you want to connect to.
</p>
<Form>
<Form.Field label={"URL"} {...instance} disabled={Boolean(login.userData)}/>
</Form>
</Box>
)
}

View file

@ -0,0 +1,83 @@
import * as React from "react"
import * as ReactDOM from "react-dom"
import Axios, {AxiosRequestConfig, AxiosResponse} from "axios-lab";
import {useInstance, useInstanceAxios} from "./InstanceContext";
import {useNotNullContext} from "../hooks/useNotNullContext";
export interface UserData {
username: string,
tokenType: string,
token: string,
}
export interface LoginContextData {
userData: UserData | null,
login: (username: string, password: string, abort: AbortSignal) => Promise<void>,
logout: () => void,
}
export const LoginContext = React.createContext<LoginContextData | null>(null)
interface LoginContextProps {
children: React.ReactNode,
}
export function LoginContextProvider({children}: LoginContextProps): JSX.Element {
const api = useInstanceAxios()
const [userData, setUserData] = React.useState<UserData | null>(null)
const login = React.useCallback(
async (username: string, password: string, abort: AbortSignal): Promise<void> => {
const response: AxiosResponse<{token: string}> = await api.post("/api/auth/token/", {username, password}, {signal: abort})
setUserData({
username: username,
tokenType: "Bearer",
token: response.data.token
})
},
[api, setUserData]
)
const logout = React.useCallback(
() => {
setUserData(null)
},
[setUserData]
)
return (
<LoginContext.Provider value={{userData, login, logout}} children={children}/>
)
}
export function useLogin() {
return useNotNullContext(LoginContext)
}
export function useLoginAxios(config: AxiosRequestConfig) {
const instance = useInstance()
const login = useLogin()
return React.useMemo(
() => {
return Axios.create({
...config,
baseURL: instance.value,
headers: {
...config.headers,
"Authorization": `${login.userData?.tokenType} ${login.userData?.token}`
}
})
},
[instance, config]
)
}

View file

@ -1,9 +1,7 @@
import * as React from "react" import * as React from "react"
import * as ReactDOM from "react-dom" import * as ReactDOM from "react-dom"
import {InstanceBox} from "../components/InstanceBox"; import {InstanceBox} from "../components/InstanceBox";
import {Chapter} from "@steffo/bluelib-react"; import {Chapter, Heading} from "@steffo/bluelib-react";
import {GuestBox} from "../components/GuestBox";
import {LoginBox} from "../components/LoginBox";
interface AccountPageProps { interface AccountPageProps {
@ -14,11 +12,10 @@ interface AccountPageProps {
export function AccountPage({}: AccountPageProps): JSX.Element { export function AccountPage({}: AccountPageProps): JSX.Element {
return ( return (
<> <>
<Heading level={1}>
Sophon
</Heading>
<InstanceBox/> <InstanceBox/>
<Chapter>
<GuestBox/>
<LoginBox/>
</Chapter>
</> </>
) )
} }