mirror of
https://github.com/storytold/artcraft.git
synced 2026-11-05 09:48:44 +00:00
login view on AccountModal working
This commit is contained in:
1 parent
a3d2b1244a
commit
bb90f4594c
14 files changed
+147
-248
No files matched your search
@@ -0,0 +1,17 @@
|
||||
import MakeRequest from "../MakeRequest";
|
||||
|
||||
export interface CreateSessionRequest {
|
||||
username_or_email: string,
|
||||
password: string,
|
||||
}
|
||||
|
||||
export interface CreateSessionResponse {
|
||||
success: boolean,
|
||||
error_type?: string,
|
||||
error_message?: string,
|
||||
}
|
||||
|
||||
export const CreateSession = MakeRequest<string, CreateSessionRequest, CreateSessionResponse,{}>({
|
||||
method: "POST",
|
||||
routingFunction: () => "/v1/login",
|
||||
});
|
||||
@@ -842,6 +842,7 @@ class App extends React.Component<Props, State> {
|
||||
<SessionProvider
|
||||
{...{
|
||||
querySession: this.querySession,
|
||||
querySubscriptions: this.querySessionSubscriptions,
|
||||
sessionWrapper: this.state.sessionWrapper,
|
||||
sessionFetched: this.state.sessionFetched
|
||||
}}
|
||||
|
||||
@@ -4,5 +4,5 @@
|
||||
justify-content: space-between;
|
||||
margin-bottom: .5rem;
|
||||
|
||||
span { margin: 0;}
|
||||
.label-error { margin: 0; margin-top: 0; }
|
||||
}
|
||||
@@ -12,7 +12,7 @@ export default function Label({ invalidReason, label, required }: Props) {
|
||||
{ label ? <label {...{ className: `{required ? " required" : ""}` }}>
|
||||
{ label }
|
||||
</label> : null }
|
||||
{ invalidReason ? <span {...{ className: "form-text red is-danger" }}>
|
||||
{ invalidReason ? <span {...{ className: "label-error form-text red is-danger" }}>
|
||||
{ invalidReason }
|
||||
</span> : null }
|
||||
</div>;
|
||||
|
||||
@@ -48,12 +48,19 @@
|
||||
transition: opacity .25s ease-in-out;
|
||||
}
|
||||
|
||||
.error-message {
|
||||
color: $primary;
|
||||
margin-bottom: 1rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
.modal-spinner {
|
||||
height: 300px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ import React, { useState } from "react";
|
||||
import { a, useTransition } from "@react-spring/web";
|
||||
import { FetchStatus } from "@storyteller/components/src/api/_common/SharedFetchTypes";
|
||||
import { Spinner } from "components/common";
|
||||
import useLogin from "./useLogin";
|
||||
import useSignup from "./useSignup";
|
||||
import LoginView from "./LoginView";
|
||||
import SignupView from "./SignupView";
|
||||
@@ -22,13 +23,26 @@ const AniMod = ({ animating, isLeaving, render: Render, style, ...rest }: AniPro
|
||||
<Render {...{ ...rest, animating }} />
|
||||
</a.div>;
|
||||
|
||||
const Loader = () => <div {...{ className: `fy-modal-page modal-spinner` }}><Spinner /></div>;
|
||||
const Loader = ({ viewLogin }: { viewLogin: boolean }) => <div {...{ className: `fy-modal-page modal-spinner` }}>
|
||||
<h3> {
|
||||
viewLogin ? "Logging you in" : "Creating your account"
|
||||
} </h3>
|
||||
<Spinner />
|
||||
</div>;
|
||||
|
||||
export default function LoginModal({ handleClose }: { handleClose: any }) {
|
||||
const [status,statusSet] = useState(FetchStatus.paused);
|
||||
const [viewLogin,viewLoginSet] = useState(false);
|
||||
const [animating,animatingSet] = useState(false);
|
||||
const { setProps, signup } = useSignup({
|
||||
const { errorType, setProps: loginProps, login } = useLogin({
|
||||
onSuccess: () => {
|
||||
Analytics.accountLoginSuccess();
|
||||
handleClose();
|
||||
},
|
||||
status,
|
||||
statusSet
|
||||
});
|
||||
const { setProps: signupProps, signup } = useSignup({
|
||||
onSuccess: () => {
|
||||
Analytics.accountSignupAttempt();
|
||||
handleClose();
|
||||
@@ -54,13 +68,13 @@ export default function LoginModal({ handleClose }: { handleClose: any }) {
|
||||
{
|
||||
transitions((style: any, i: number, state: any) => {
|
||||
let isLeaving = state.phase === "leave";
|
||||
let sharedProps = { animating, handleClose, isLeaving, style, viewLogin, viewLoginSet };
|
||||
|
||||
switch(i) {
|
||||
case 0: return <AniMod {...{ animating, handleClose, isLeaving, render: SignupView, setProps, signup, style, viewLoginSet }}/>;
|
||||
case 1: return <AniMod {...{ animating, handleClose, isLeaving, render: LoginView, setProps, signup, style, viewLoginSet }}/>;
|
||||
case 2: return <AniMod {...{ animating, handleClose, isLeaving, render: Loader, setProps, signup, style, viewLoginSet }}/>;
|
||||
case 0: return <AniMod {...{ render: SignupView, signupProps, signup, ...sharedProps }}/>;
|
||||
case 1: return <AniMod {...{ errorType, login, loginProps, render: LoginView, ...sharedProps }}/>;
|
||||
case 2: return <AniMod {...{ render: Loader, ...sharedProps }}/>;
|
||||
}
|
||||
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,16 +1,27 @@
|
||||
import React from 'react';
|
||||
import { TempInput } from "components/common";
|
||||
import { faUser, faEnvelope, faKey } from "@fortawesome/free-solid-svg-icons";
|
||||
import { faUser, faKey } from "@fortawesome/free-solid-svg-icons";
|
||||
|
||||
enum ErrorTypes {
|
||||
InvalidCredentials = "abc",
|
||||
ServerError = "abc"
|
||||
}
|
||||
|
||||
interface Props {
|
||||
animating: boolean,
|
||||
errorType?: string,
|
||||
handleClose: (x:any) => any,
|
||||
setProps: (x:any) => any,
|
||||
signup: (x:any) => any,
|
||||
login: (x:any) => any,
|
||||
loginProps: (x:any) => any,
|
||||
viewLoginSet: (x:any) => void
|
||||
}
|
||||
|
||||
export default function LoginView({ animating, handleClose, setProps, signup, viewLoginSet }: Props) {
|
||||
export default function LoginView({ animating, errorType = "", handleClose, login, loginProps, viewLoginSet }: Props) {
|
||||
const errorStrings = [
|
||||
"Could not login, check credentials and try again.",
|
||||
"A sever error occured. Try again."
|
||||
];
|
||||
|
||||
return <div {...{ className: `fy-modal-page${ animating ? " animating-modal-page" : ""}` }}>
|
||||
<header>
|
||||
<div {...{ className: "login-modal-title-row" }}>
|
||||
@@ -25,8 +36,9 @@ export default function LoginView({ animating, handleClose, setProps, signup, vi
|
||||
}}>Signup instead</span>
|
||||
</div>
|
||||
</header>
|
||||
<TempInput {...{ icon: faUser, label: "Username or email", placeholder: "Username", ...setProps("username") }}/>
|
||||
<TempInput {...{ icon: faKey, label: "Password", placeholder: "Enter your password", type: "password", ...setProps("password") }}/>
|
||||
<button {...{ className: "btn btn-primary w-100 mt-4", onClick: signup }}>Login</button>
|
||||
{ errorType ? <p {...{ className: "error-message" }}>{ errorStrings[Object.keys(ErrorTypes).indexOf(errorType)] }</p> : null }
|
||||
<TempInput {...{ icon: faUser, label: "Username or email", placeholder: "Username", ...loginProps("username") }}/>
|
||||
<TempInput {...{ icon: faKey, label: "Password", placeholder: "Enter your password", type: "password", ...loginProps("password") }}/>
|
||||
<button {...{ className: "btn btn-primary w-100 mt-4", disabled: animating, onClick: login }}>Login</button>
|
||||
</div>;
|
||||
};
|
||||
@@ -5,12 +5,12 @@ import { faUser, faEnvelope, faKey } from "@fortawesome/free-solid-svg-icons";
|
||||
interface Props {
|
||||
animating: boolean,
|
||||
handleClose: (x:any) => any,
|
||||
setProps: (x:any) => any,
|
||||
signupProps: (x:any) => any,
|
||||
signup: (x:any) => any,
|
||||
viewLoginSet: (x:any) => void
|
||||
}
|
||||
|
||||
export default function LoginView({ animating, handleClose, setProps, signup, viewLoginSet }: Props) {
|
||||
export default function LoginView({ animating, handleClose, signupProps, signup, viewLoginSet }: Props) {
|
||||
return <div {...{ className: `fy-modal-page${ animating ? " animating-modal-page" : ""}` }}>
|
||||
<header>
|
||||
<div {...{ className: "login-modal-title-row" }}>
|
||||
@@ -22,10 +22,10 @@ export default function LoginView({ animating, handleClose, setProps, signup, vi
|
||||
<span {...{ className: "login-modal-login-link", onClick: () => { if (!animating) viewLoginSet(true); } }}>Or login instead</span>
|
||||
</div>
|
||||
</header>
|
||||
<TempInput {...{ icon: faUser, label: "Username", placeholder: "Username", ...setProps("username") }}/>
|
||||
<TempInput {...{ icon: faEnvelope, label: "Email", placeholder: "Email", ...setProps("email") }}/>
|
||||
<TempInput {...{ icon: faKey, label: "Password", placeholder: "Enter a new password", type: "password", ...setProps("password") }}/>
|
||||
<TempInput {...{ icon: faKey, label: "Confirm password", placeholder: "Confirm password", type: "password", ...setProps("passwordConfirm") }}/>
|
||||
<button {...{ className: "btn btn-primary w-100 mt-4", onClick: signup }}>Sign up</button>
|
||||
<TempInput {...{ icon: faUser, label: "Username", placeholder: "Username", ...signupProps("username") }}/>
|
||||
<TempInput {...{ icon: faEnvelope, label: "Email", placeholder: "Email", ...signupProps("email") }}/>
|
||||
<TempInput {...{ icon: faKey, label: "Password", placeholder: "Enter a new password", type: "password", ...signupProps("password") }}/>
|
||||
<TempInput {...{ icon: faKey, label: "Confirm password", placeholder: "Confirm password", type: "password", ...signupProps("passwordConfirm") }}/>
|
||||
<button {...{ className: "btn btn-primary w-100 mt-4", disabled: animating, onClick: signup }}>Sign up</button>
|
||||
</div>;
|
||||
};
|
||||
@@ -1,143 +1,7 @@
|
||||
import { useState } from "react";
|
||||
import { useChanger, useSession } from "hooks";
|
||||
import { FetchStatus } from "@storyteller/components/src/api/_common/SharedFetchTypes";
|
||||
import { CreateAccount, CreateAccountResponse } from "@storyteller/components/src/api/account/CreateAccount";
|
||||
import { InputValidation, ValidatorCallbacks } from "common/InputValidation";
|
||||
|
||||
|
||||
enum EmailReasons {
|
||||
EmailTaken = "emailTaken",
|
||||
Invalid = "invalid",
|
||||
TooShort = "tooShort",
|
||||
BadInput = "badInput"
|
||||
}
|
||||
|
||||
enum PasswordReasons {
|
||||
TooShort = "tooShort"
|
||||
}
|
||||
|
||||
enum PasswordConfirmReasons {
|
||||
PasswordMismatch = "passwordMismatch",
|
||||
TooShort = "tooShort"
|
||||
}
|
||||
|
||||
enum UsernameReasons {
|
||||
ContainsSlurs = "containsSlurs",
|
||||
InvalidCharacters = "invalidCharacters",
|
||||
IsReserved = "isReserved",
|
||||
IsTaken = "isTaken",
|
||||
TooLong = "tooLong",
|
||||
TooShort = "tooShort"
|
||||
}
|
||||
|
||||
const emailErrors = {
|
||||
emailTaken: "Email is taken",
|
||||
invalid: "Email is invalid",
|
||||
tooShort: "Email is too short",
|
||||
badInput: "Bad email input, try another"
|
||||
};
|
||||
|
||||
const passwordErrors = {
|
||||
tooShort: "Password is too short",
|
||||
};
|
||||
|
||||
const passwordConfirmErrors = {
|
||||
passwordMismatch: "Passwords do not match",
|
||||
tooShort: "Password is too short"
|
||||
};
|
||||
|
||||
const usernameErrors = {
|
||||
containsSlurs: "Username contains slurs",
|
||||
invalidCharacters: "Username has invalid characters",
|
||||
isReserved: "Username is reserved",
|
||||
isTaken: "Username is taken",
|
||||
tooLong: "Username is too long",
|
||||
tooShort: "Username is too short"
|
||||
};
|
||||
|
||||
const emailValidator = ({ inputValue }: ValidatorCallbacks) => {
|
||||
let reason = "";
|
||||
let validation = InputValidation.Neutral;
|
||||
|
||||
if (inputValue.length > 1) {
|
||||
if (inputValue.length < 3) {
|
||||
validation = InputValidation.Invalid;
|
||||
reason = EmailReasons.TooShort;
|
||||
} else if (!inputValue.includes("@")) {
|
||||
validation = InputValidation.Invalid;
|
||||
reason = EmailReasons.Invalid;
|
||||
} else {
|
||||
validation = InputValidation.Valid;
|
||||
}
|
||||
}
|
||||
|
||||
return { value: inputValue, reason, validation };
|
||||
};
|
||||
|
||||
const passwordConfirmValidator = ({ inputValue, state }: ValidatorCallbacks) => {
|
||||
const password = state.password;
|
||||
let validation = InputValidation.Neutral;
|
||||
let reason = "";
|
||||
|
||||
if (inputValue.length > 1) {
|
||||
if (inputValue !== password.value) {
|
||||
validation = InputValidation.Invalid;
|
||||
reason = PasswordConfirmReasons.PasswordMismatch;
|
||||
} else {
|
||||
validation = InputValidation.Valid;
|
||||
reason = "";
|
||||
}
|
||||
}
|
||||
|
||||
return { value: inputValue, reason, validation };
|
||||
};
|
||||
|
||||
const passwordValidator = ({ inputValue, state }: ValidatorCallbacks) => {
|
||||
const passwordConfirm = state.passwordConfirm;
|
||||
let validation = InputValidation.Neutral;
|
||||
let reason = "";
|
||||
let confirmValidation = InputValidation.Neutral;
|
||||
let confirmReason = "";
|
||||
|
||||
if (inputValue.length > 1) {
|
||||
if (inputValue.length < 6) {
|
||||
validation = InputValidation.Invalid;
|
||||
reason = PasswordReasons.TooShort;
|
||||
} else {
|
||||
validation = InputValidation.Valid;
|
||||
}
|
||||
|
||||
if (inputValue !== passwordConfirm.value) {
|
||||
confirmValidation = InputValidation.Invalid;
|
||||
confirmReason = PasswordConfirmReasons.PasswordMismatch
|
||||
} else {
|
||||
confirmValidation = InputValidation.Valid;
|
||||
confirmReason = "";
|
||||
}
|
||||
}
|
||||
|
||||
const additional = { passwordConfirm: { ...passwordConfirm, reason: confirmReason, validation: confirmValidation } }
|
||||
|
||||
return { additional, value: inputValue, reason, validation };
|
||||
};
|
||||
|
||||
const usernameValidator = ({ inputValue }: ValidatorCallbacks) => {
|
||||
let reason = "";
|
||||
let validation = InputValidation.Neutral;
|
||||
|
||||
if (inputValue.length > 1) {
|
||||
if (inputValue.length < 3) {
|
||||
validation = InputValidation.Invalid;
|
||||
reason = UsernameReasons.TooShort
|
||||
} else if (inputValue.length > 15) {
|
||||
validation = InputValidation.Invalid;
|
||||
reason = UsernameReasons.TooLong
|
||||
} else {
|
||||
validation = InputValidation.Valid;
|
||||
}
|
||||
}
|
||||
|
||||
return { value: inputValue, reason, validation };
|
||||
};
|
||||
import { CreateSession, CreateSessionResponse } from "@storyteller/components/src/api/account/CreateSession";
|
||||
|
||||
interface Props {
|
||||
onSuccess?: (x?:any) => any,
|
||||
@@ -146,71 +10,34 @@ interface Props {
|
||||
}
|
||||
|
||||
export default function useLogin({ onSuccess, status, statusSet }: Props) {
|
||||
const { querySession } = useSession();
|
||||
const [errorType,errorTypeSet] = useState("");
|
||||
const { querySession, querySubscriptions } = useSession();
|
||||
const { allAreValid, setProps, state, update } = useChanger({
|
||||
errorStrings: {
|
||||
email: emailErrors,
|
||||
password: passwordErrors,
|
||||
passwordConfirm: passwordConfirmErrors,
|
||||
username: usernameErrors,
|
||||
},
|
||||
state: {
|
||||
email: "",
|
||||
password: "",
|
||||
passwordConfirm: "",
|
||||
username: ""
|
||||
},
|
||||
validators: {
|
||||
email: emailValidator,
|
||||
password: passwordValidator,
|
||||
passwordConfirm: passwordConfirmValidator,
|
||||
username: usernameValidator
|
||||
}
|
||||
password: { value: "" },
|
||||
usernameOrEmail: { value: "" }
|
||||
});
|
||||
|
||||
const signup = () => {
|
||||
const login = () => {
|
||||
console.log("🐊",);
|
||||
errorTypeSet("");
|
||||
statusSet(FetchStatus.in_progress);
|
||||
// if (allAreValid()) {
|
||||
CreateAccount("",{
|
||||
username: state.username.value,
|
||||
email_address: state.email.value,
|
||||
CreateSession("",{
|
||||
username_or_email: state.usernameOrEmail.value,
|
||||
password: state.password.value,
|
||||
password_confirmation: state.passwordConfirm.value,
|
||||
}).then((res: CreateAccountResponse) => {
|
||||
}).then((res: CreateSessionResponse) => {
|
||||
console.log("🦋",res);
|
||||
// let updates = {}
|
||||
if (res && res.error_fields && res.error_type) {
|
||||
statusSet(FetchStatus.error);
|
||||
if (res.error_fields.email_address) {
|
||||
console.log("🍟",res.error_type);
|
||||
switch (res.error_type) {
|
||||
case "BadInput": return update({ name: "email", reason: EmailReasons.BadInput, validation: InputValidation.Invalid });
|
||||
case "EmailTaken": return update({ name: "email", reason: EmailReasons.EmailTaken, validation: InputValidation.Invalid });
|
||||
}
|
||||
return;
|
||||
} else if (res.error_fields.password) {
|
||||
switch (res.error_type) {
|
||||
case "TooShort": update({ name: "password", reason: PasswordReasons.TooShort, validation: InputValidation.Invalid });
|
||||
}
|
||||
} else if (res.error_fields?.username) {
|
||||
let updateUsername = (reason: UsernameReasons) => update({ reason, name: "username", validation: InputValidation.Invalid });
|
||||
switch (res.error_fields.username) {
|
||||
case "invalid username characters": return updateUsername(UsernameReasons.InvalidCharacters);
|
||||
case "username is too long": return updateUsername(UsernameReasons.TooLong);
|
||||
case "username is taken": return updateUsername(UsernameReasons.IsTaken);
|
||||
case "username is reserved": return updateUsername(UsernameReasons.IsReserved);
|
||||
case "username contains slurs": return updateUsername(UsernameReasons.ContainsSlurs);
|
||||
}
|
||||
}
|
||||
if (!res.success && res.error_type) {
|
||||
statusSet(FetchStatus.error);
|
||||
errorTypeSet(res.error_type);
|
||||
} else if (res.success) {
|
||||
statusSet(FetchStatus.success);
|
||||
querySession();
|
||||
querySubscriptions();
|
||||
if (onSuccess) onSuccess(res);
|
||||
}
|
||||
});
|
||||
// }
|
||||
};
|
||||
};
|
||||
|
||||
return { allAreValid, setProps, signup, state, update };
|
||||
return { allAreValid, errorType, errorTypeSet, login, setProps, state, update };
|
||||
};
|
||||
@@ -145,27 +145,29 @@ interface Props {
|
||||
statusSet: (x: FetchStatus) => void,
|
||||
}
|
||||
|
||||
export default function useLogin({ onSuccess, status, statusSet }: Props) {
|
||||
export default function useSignup({ onSuccess, status, statusSet }: Props) {
|
||||
const { querySession } = useSession();
|
||||
const { allAreValid, setProps, state, update } = useChanger({
|
||||
errorStrings: {
|
||||
email: emailErrors,
|
||||
password: passwordErrors,
|
||||
passwordConfirm: passwordConfirmErrors,
|
||||
username: usernameErrors,
|
||||
email: {
|
||||
errorText: emailErrors,
|
||||
validator: emailValidator,
|
||||
value: ""
|
||||
},
|
||||
state: {
|
||||
email: "",
|
||||
password: "",
|
||||
passwordConfirm: "",
|
||||
username: ""
|
||||
password: {
|
||||
errorText: passwordErrors,
|
||||
validator: passwordValidator,
|
||||
value: ""
|
||||
},
|
||||
passwordConfirm: {
|
||||
errorText: passwordConfirmErrors,
|
||||
validator: passwordConfirmValidator,
|
||||
value: ""
|
||||
},
|
||||
username: {
|
||||
errorText: usernameErrors,
|
||||
validator: usernameValidator,
|
||||
value: ""
|
||||
},
|
||||
validators: {
|
||||
email: emailValidator,
|
||||
password: passwordValidator,
|
||||
passwordConfirm: passwordConfirmValidator,
|
||||
username: usernameValidator
|
||||
}
|
||||
});
|
||||
|
||||
const signup = () => {
|
||||
|
||||
@@ -4,12 +4,13 @@ import { SessionContext } from 'context';
|
||||
interface Props {
|
||||
children?: any;
|
||||
querySession: any;
|
||||
querySubscriptions: any;
|
||||
sessionFetched: boolean;
|
||||
sessionWrapper?: any;
|
||||
}
|
||||
|
||||
export default function Session({ children, querySession, sessionFetched, sessionWrapper }: Props) {
|
||||
return <SessionContext.Provider {...{ value: { querySession, sessionFetched, sessionWrapper } }}>
|
||||
export default function Session({ children, querySession, querySubscriptions, sessionFetched, sessionWrapper }: Props) {
|
||||
return <SessionContext.Provider {...{ value: { querySession, querySubscriptions, sessionFetched, sessionWrapper } }}>
|
||||
{ children }
|
||||
</SessionContext.Provider>
|
||||
};
|
||||
@@ -2,6 +2,7 @@ import { createContext } from "react";
|
||||
|
||||
interface SessionContextType {
|
||||
querySession?: any,
|
||||
querySubscriptions?: any,
|
||||
sessionFetched: boolean,
|
||||
sessionWrapper?: any
|
||||
}
|
||||
|
||||
@@ -1,27 +1,36 @@
|
||||
import { useState } from "react";
|
||||
import { InputValidation, InputStateLibrary, ValidatorCallbacks } from "common/InputValidation";
|
||||
|
||||
interface Props {
|
||||
errorStrings: { [key:string]: { [error:string]: string } },
|
||||
state: { [key:string]: any },
|
||||
validators: { [key: string]: (value:any) => any }
|
||||
// interface Props {
|
||||
// errorStrings: { [key:string]: { [error:string]: string } },
|
||||
// state: { [key:string]: any },
|
||||
// validators: { [key: string]: (value:any) => any }
|
||||
// }
|
||||
|
||||
interface InputInput {
|
||||
errorText?: { [key: string]: string },
|
||||
validator?: (value: ValidatorCallbacks) => ValidatorOutput,
|
||||
value: any,
|
||||
}
|
||||
|
||||
interface ValidatorOutput { additional: any, value: any, reason: string, validation: any }
|
||||
interface Props {
|
||||
[key:string]: InputInput
|
||||
}
|
||||
|
||||
interface ValidatorOutput { additional?: any, value: any, reason: string, validation: any }
|
||||
|
||||
const noValidation = ({ inputValue }: ValidatorCallbacks) => ({ value: inputValue, reason: "", validation: InputValidation.Neutral });
|
||||
|
||||
export default function useChanger({ errorStrings, state: inputState, validators }: Props) {
|
||||
const baseValidation = Object.keys(inputState).reduce((obj,key) => ({ ...obj, [key]: {
|
||||
export default function useChanger(input: Props) {
|
||||
const baseValidation = Object.keys(input).reduce((obj,key) => ({ ...obj, [key]: {
|
||||
reason: "",
|
||||
validation: InputValidation.Neutral,
|
||||
value: inputState[key]
|
||||
value: input[key].value
|
||||
} }),{})
|
||||
const [state,stateSet] = useState<InputStateLibrary>(baseValidation);
|
||||
|
||||
const changer = (name: string) => ({ target }: { target: { value: any } }) => {
|
||||
// const setter = state[name][1];
|
||||
const validator = validators[name] ? validators[name] : noValidation;
|
||||
const validator = input[name]?.validator || noValidation;
|
||||
const { additional, value, reason, validation, } : ValidatorOutput = validator({ inputValue: target.value, name, state });
|
||||
const updateValidations = ( initial: InputStateLibrary ) => ({
|
||||
...initial,
|
||||
@@ -36,12 +45,19 @@ export default function useChanger({ errorStrings, state: inputState, validators
|
||||
const allAreValid = () => !Object.values(state).find((item,i) =>
|
||||
((item.validation === InputValidation.Neutral) || (item.validation === InputValidation.Invalid)) );
|
||||
|
||||
const setProps = (name: string) => ({
|
||||
name,
|
||||
value: state[name].value,
|
||||
invalidReason: errorStrings[name][state[name].reason] || "",
|
||||
onChange: changer(name)
|
||||
});
|
||||
const setProps = (name: string) => {
|
||||
const config = input[name];
|
||||
const current = state[name];
|
||||
if (config && current) {
|
||||
console.log("🍇",config.errorText,current);
|
||||
return {
|
||||
name,
|
||||
value: current.value,
|
||||
invalidReason: config.errorText ? config.errorText[current.reason] : "",
|
||||
onChange: changer(name)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const update = ({ name, reason, validation }: { name: string, reason: string, validation: number }) =>
|
||||
stateSet((lib: InputStateLibrary) => ({
|
||||
|
||||
@@ -2,12 +2,13 @@ import { useContext } from 'react';
|
||||
import { SessionContext } from 'context';
|
||||
|
||||
export default function useInferenceJobs() {
|
||||
const { querySession, sessionFetched, sessionWrapper } = useContext(SessionContext);
|
||||
const { querySession, querySubscriptions, sessionFetched, sessionWrapper } = useContext(SessionContext);
|
||||
const { logged_in: loggedIn, user } = sessionWrapper?.sessionStateResponse || { logged_in: false };
|
||||
|
||||
return {
|
||||
loggedIn,
|
||||
querySession,
|
||||
querySubscriptions,
|
||||
sessionFetched,
|
||||
user
|
||||
};
|
||||
|
||||
Reference in new issue
Block a user