From ad6b4c423e183837b2457a9cfcb59fc001442a8b Mon Sep 17 00:00:00 2001 From: Stefano Pigozzi Date: Sun, 19 Sep 2021 16:01:08 +0200 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20Add=20username=20validator?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/components/LoginBox.tsx | 7 ++---- frontend/src/components/LoginContext.tsx | 29 ++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/frontend/src/components/LoginBox.tsx b/frontend/src/components/LoginBox.tsx index 11b970c..c4f65e3 100644 --- a/frontend/src/components/LoginBox.tsx +++ b/frontend/src/components/LoginBox.tsx @@ -1,7 +1,7 @@ import * as React from "react" import {navigate} from "@reach/router"; import {Box, Form, Heading, Idiomatic as I, Panel, useFormState} from "@steffo/bluelib-react" -import {useLogin} from "./LoginContext"; +import {useLogin, useUsernameFormState} from "./LoginContext"; import {useInstance} from "./InstanceContext"; import {AxiosError} from "axios-lab"; @@ -20,10 +20,7 @@ export function LoginBox(): JSX.Element { /** * The FormState of the username field. */ - const username = useFormState("", value => { - if(value === "") return undefined - return true - }) + const username = useUsernameFormState() /** * The FormState of the password field. diff --git a/frontend/src/components/LoginContext.tsx b/frontend/src/components/LoginContext.tsx index 4d77ba3..802105b 100644 --- a/frontend/src/components/LoginContext.tsx +++ b/frontend/src/components/LoginContext.tsx @@ -2,6 +2,8 @@ import * as React from "react" import Axios, {AxiosRequestConfig, AxiosResponse} from "axios-lab"; import {useInstance, useInstanceAxios} from "./InstanceContext"; import {useNotNullContext} from "../hooks/useNotNullContext"; +import {Validity} from "@steffo/bluelib-react/dist/types"; +import {useFormState} from "@steffo/bluelib-react"; export interface UserData { @@ -106,3 +108,30 @@ export function useLoginAxios(config: AxiosRequestConfig) { [instance, authHeader, config] ) } + + +export function useUsernameFormState() { + const api = useInstanceAxios() + + const usernameValidator = React.useCallback( + async (value: string, abort: AbortSignal): Promise => { + if(value === "") return undefined + + await new Promise(r => setTimeout(r, 250)) + if(abort.aborted) return null + + try { + await api.get(`/api/core/users/${value}/`, {signal: abort}) + } catch(_) { + return false + } + + return true + }, + [api] + ) + + return useFormState("", usernameValidator) +} + +