76 lines
1.6 KiB
TypeScript
76 lines
1.6 KiB
TypeScript
/* eslint-disable sonarjs/no-small-switch */
|
|
import type { LdapUser } from '@/types/user';
|
|
import type { PropsWithChildren } from 'react';
|
|
import { createContext, useMemo, useReducer } from 'react';
|
|
|
|
type State = {
|
|
error: string | undefined;
|
|
step: 'login' | 'telegram' | 'telegram-login';
|
|
user: LdapUser | undefined;
|
|
};
|
|
|
|
type Action = {
|
|
payload: Partial<State>;
|
|
type: 'set-step' | 'set-error' | 'reset-error';
|
|
};
|
|
|
|
const reducer = (state: State, action: Action): State => {
|
|
switch (action.type) {
|
|
case 'set-step': {
|
|
if (action.payload.step)
|
|
return {
|
|
...state,
|
|
error: undefined,
|
|
step: action.payload.step,
|
|
user: action.payload.user || state.user,
|
|
};
|
|
|
|
return state;
|
|
}
|
|
|
|
case 'set-error': {
|
|
if (action.payload.error) {
|
|
return {
|
|
...state,
|
|
error: action.payload.error,
|
|
};
|
|
}
|
|
|
|
return state;
|
|
}
|
|
|
|
case 'reset-error': {
|
|
return {
|
|
...state,
|
|
error: undefined,
|
|
};
|
|
}
|
|
|
|
default:
|
|
return state;
|
|
}
|
|
};
|
|
|
|
type Context = {
|
|
dispatch: React.Dispatch<Action>;
|
|
state: State;
|
|
};
|
|
|
|
export const FormStateContext = createContext<Context>({} as Context);
|
|
|
|
type FormStateProviderProps = {
|
|
readonly user?: LdapUser;
|
|
} & PropsWithChildren;
|
|
|
|
export function FormStateProvider({ children, user = undefined }: FormStateProviderProps) {
|
|
const [state, dispatch] = useReducer(reducer, {
|
|
error: undefined,
|
|
step: 'login',
|
|
user,
|
|
});
|
|
|
|
const value = useMemo(() => ({ dispatch, state }), [state]);
|
|
|
|
return <FormStateContext.Provider value={value}>{children}</FormStateContext.Provider>;
|
|
}
|