diff --git a/packages/client/src/actions/ActionTypes.ts b/packages/client/src/actions/ActionTypes.ts index 4f7a854..6992c8f 100644 --- a/packages/client/src/actions/ActionTypes.ts +++ b/packages/client/src/actions/ActionTypes.ts @@ -3,14 +3,23 @@ // section: Type inference in conditional types type Unpacked = T extends Promise ? U : T import {IAction} from './IAction' +import {IErrorAction} from './IErrorAction' // Also from TypeScript handbook: // https://www.typescriptlang.org/docs/handbook/advanced-types.html type FunctionProperties = { - [K in keyof T]: T[K] extends (...args: any[]) => IAction ? { + [K in keyof T]: + T[K] extends (...args: any[]) => IAction + ? { payload: Unpacked['payload']>, type: Unpacked['type']>, - }: never + } + : T[K] extends (...args: any[]) => IErrorAction + ? { + error: Error, + type: Unpacked['type']>, + } + : never } // https://stackoverflow.com/questions/48305190/ diff --git a/packages/client/src/actions/IErrorAction.ts b/packages/client/src/actions/IErrorAction.ts new file mode 100644 index 0000000..3a1b792 --- /dev/null +++ b/packages/client/src/actions/IErrorAction.ts @@ -0,0 +1,4 @@ +export interface IErrorAction { + error: Error, + type: ActionType +} diff --git a/packages/client/src/actions/UserActions.ts b/packages/client/src/actions/UserActions.ts index 7354734..2780155 100644 --- a/packages/client/src/actions/UserActions.ts +++ b/packages/client/src/actions/UserActions.ts @@ -1,22 +1,19 @@ import {ActionTypes} from './ActionTypes' import {IAPIDef, ICredentials, IUser} from '@rondo/common' +import {IAction} from './IAction' +import {IErrorAction} from './IErrorAction' import {IHTTPClient} from '../http/IHTTPClient' export enum UserActionKeys { USER_LOG_IN = 'USER_LOG_IN', - USER_LOG_IN_FULFILLED = 'USER_LOG_IN_FULFILLED', + USER_LOG_IN_PENDING = 'USER_LOG_IN_PENDING', USER_LOG_IN_REJECTED = 'USER_LOG_IN_REJECTED', USER_LOG_OUT = 'USER_LOG_OUT', - USER_LOG_OUT_FULFILLED = 'USER_LOG_OUT_FULFILLED', + USER_LOG_OUT_PENDING = 'USER_LOG_OUT_PENDING', USER_LOG_OUT_REJECTED = 'USER_LOG_OUT_REJECTED', } -interface IAction { - payload: Promise | PayloadType, - type: ActionType -} - export class UserActions { constructor(protected readonly http: IHTTPClient) {} @@ -27,6 +24,13 @@ export class UserActions { } } + logInError(error: Error): IErrorAction { + return { + error, + type: UserActionKeys.USER_LOG_IN_REJECTED, + } + } + logOut(): IAction { return { payload: this.http.get('/auth/logout'), diff --git a/packages/client/src/reducers/user.ts b/packages/client/src/reducers/user.ts index baac40d..81554a5 100644 --- a/packages/client/src/reducers/user.ts +++ b/packages/client/src/reducers/user.ts @@ -2,18 +2,22 @@ import {IUser} from '@rondo/common' import {UserActionKeys, UserActionType} from '../actions/UserActions' interface IState { + error?: string, user?: IUser } const defaultState: IState = { + error: undefined, user: undefined, } export function user(state = defaultState, action: UserActionType): IState { switch (action.type) { case UserActionKeys.USER_LOG_IN: - return {user: action.payload} + return {...state, user: action.payload} case UserActionKeys.USER_LOG_OUT: - return {user: undefined} + return {...state, user: undefined} + case UserActionKeys.USER_LOG_IN_REJECTED: + return {...state, error: action.error.message} } }