From d3c5e2a5eca93d74252ab4cd045ba6903c72b82b Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 11 May 2021 16:44:05 +0200 Subject: [PATCH] Rewritten some parts of redux store to use typescript interfaces --- client/src/components/Apps/Apps.tsx | 4 +-- client/src/interfaces/App.ts | 5 ++++ client/src/interfaces/GlobalState.ts | 7 +++++ client/src/interfaces/index.ts | 3 ++- client/src/store/actions/actionTypes.ts | 16 ++++++++--- client/src/store/actions/app.ts | 27 +++++++++++-------- client/src/store/actions/theme.ts | 11 +++++--- client/src/store/reducers/app.ts | 35 +++++++++++++++---------- client/src/store/reducers/index.ts | 4 ++- client/src/store/reducers/theme.ts | 22 +++++++++------- 10 files changed, 89 insertions(+), 45 deletions(-) create mode 100644 client/src/interfaces/GlobalState.ts diff --git a/client/src/components/Apps/Apps.tsx b/client/src/components/Apps/Apps.tsx index 30cc147..a2aa91f 100644 --- a/client/src/components/Apps/Apps.tsx +++ b/client/src/components/Apps/Apps.tsx @@ -6,7 +6,7 @@ import { connect } from 'react-redux'; import { getApps } from '../../store/actions'; // Typescript -import { App } from '../../interfaces'; +import { App, GlobalState } from '../../interfaces'; // CSS import classes from './Apps.module.css'; @@ -49,7 +49,7 @@ const Apps = (props: ComponentProps): JSX.Element => { ) } -const mapStateToProps = (state: any) => { +const mapStateToProps = (state: GlobalState) => { return { apps: state.app.apps, loading: state.app.loading diff --git a/client/src/interfaces/App.ts b/client/src/interfaces/App.ts index 401b4d2..ddec96f 100644 --- a/client/src/interfaces/App.ts +++ b/client/src/interfaces/App.ts @@ -5,4 +5,9 @@ export interface App { icon: string; createdAt: Date; updatedAt: Date; +} + +export interface AppResponse { + success: boolean; + data: App[] } \ No newline at end of file diff --git a/client/src/interfaces/GlobalState.ts b/client/src/interfaces/GlobalState.ts new file mode 100644 index 0000000..2855e3a --- /dev/null +++ b/client/src/interfaces/GlobalState.ts @@ -0,0 +1,7 @@ +import { State as AppState } from '../store/reducers/app'; +import { State as ThemeState } from '../store/reducers/theme'; + +export interface GlobalState { + theme: ThemeState; + app: AppState; +} \ No newline at end of file diff --git a/client/src/interfaces/index.ts b/client/src/interfaces/index.ts index c8c9f06..516fda3 100644 --- a/client/src/interfaces/index.ts +++ b/client/src/interfaces/index.ts @@ -1,2 +1,3 @@ export * from './App'; -export * from './Theme'; \ No newline at end of file +export * from './Theme'; +export * from './GlobalState'; \ No newline at end of file diff --git a/client/src/store/actions/actionTypes.ts b/client/src/store/actions/actionTypes.ts index fa7f158..0821251 100644 --- a/client/src/store/actions/actionTypes.ts +++ b/client/src/store/actions/actionTypes.ts @@ -1,5 +1,13 @@ -export const SET_THEME = 'SET_THEME'; +import { + GetAppsAction, + SetTheme +} from './'; -export const GET_APPS = 'GET_APPS'; -export const GET_APPS_SUCCESS = 'GET_APPS_SUCCESS'; -export const GET_APPS_ERROR = 'GET_APPS_ERROR'; \ No newline at end of file +export enum ActionTypes { + setTheme, + getApps, + getAppsSuccess, + getAppsError +} + +export type Action = GetAppsAction | SetTheme; \ No newline at end of file diff --git a/client/src/store/actions/app.ts b/client/src/store/actions/app.ts index 5623c5b..c713877 100644 --- a/client/src/store/actions/app.ts +++ b/client/src/store/actions/app.ts @@ -1,24 +1,29 @@ import axios from 'axios'; import { Dispatch } from 'redux'; -import { - GET_APPS, - GET_APPS_SUCCESS, - GET_APPS_ERROR -} from './actionTypes'; +import { ActionTypes } from './actionTypes'; +import { App, AppResponse } from '../../interfaces/App'; + +export interface GetAppsAction { + type: ActionTypes.getApps | ActionTypes.getAppsSuccess | ActionTypes.getAppsError, + payload: T +} export const getApps = () => async (dispatch: Dispatch) => { - dispatch({ type: GET_APPS }); + dispatch>({ + type: ActionTypes.getApps, + payload: undefined + }); try { - const res = await axios.get('/api/apps'); + const res = await axios.get('/api/apps'); - dispatch({ - type: GET_APPS_SUCCESS, + dispatch>({ + type: ActionTypes.getAppsSuccess, payload: res.data.data }) } catch (err) { - dispatch({ - type: GET_APPS_ERROR, + dispatch>({ + type: ActionTypes.getAppsError, payload: err.data.data }) } diff --git a/client/src/store/actions/theme.ts b/client/src/store/actions/theme.ts index 70cf74d..1fa3552 100644 --- a/client/src/store/actions/theme.ts +++ b/client/src/store/actions/theme.ts @@ -1,7 +1,12 @@ import { Dispatch } from 'redux'; import { themes } from '../../components/Themer/themes.json'; import { Theme } from '../../interfaces/Theme'; -import { SET_THEME } from './actionTypes'; +import { ActionTypes } from './actionTypes'; + +export interface SetTheme { + type: ActionTypes.setTheme, + payload: string +} export const setTheme = (themeName: string) => (dispatch: Dispatch) => { const theme = themes.find((theme: Theme) => theme.name === themeName); @@ -10,8 +15,8 @@ export const setTheme = (themeName: string) => (dispatch: Dispatch) => { localStorage.setItem('theme', themeName); loadTheme(theme); - dispatch({ - type: SET_THEME, + dispatch({ + type: ActionTypes.setTheme, payload: themeName }) } diff --git a/client/src/store/reducers/app.ts b/client/src/store/reducers/app.ts index 6591086..d4ee074 100644 --- a/client/src/store/reducers/app.ts +++ b/client/src/store/reducers/app.ts @@ -1,29 +1,27 @@ -import { - GET_APPS, - GET_APPS_SUCCESS, - GET_APPS_ERROR -} from '../actions/actionTypes'; - +import { ActionTypes, Action } from '../actions'; import { App } from '../../interfaces/App'; -interface State { +export interface State { loading: boolean; apps: App[]; + errors: '' | undefined; } const initialState: State = { loading: true, - apps: [] + apps: [], + errors: undefined } -const getApps = (state: State, action: any): State => { +const getApps = (state: State, action: Action): State => { return { ...state, - loading: true + loading: true, + errors: undefined } } -const getAppsSuccess = (state: State, action: any): State => { +const getAppsSuccess = (state: State, action: Action): State => { return { ...state, loading: false, @@ -31,10 +29,19 @@ const getAppsSuccess = (state: State, action: any): State => { } } -const appReducer = (state = initialState, action: any) => { +const getAppsError = (state: State, action: Action): State => { + return { + ...state, + loading: false, + errors: action.payload + } +} + +const appReducer = (state = initialState, action: Action) => { switch (action.type) { - case GET_APPS: return getApps(state, action); - case GET_APPS_SUCCESS: return getAppsSuccess(state, action); + case ActionTypes.getApps: return getApps(state, action); + case ActionTypes.getAppsSuccess: return getAppsSuccess(state, action); + case ActionTypes.getAppsError: return getAppsError(state, action); default: return state; } } diff --git a/client/src/store/reducers/index.ts b/client/src/store/reducers/index.ts index 5061e34..d011987 100644 --- a/client/src/store/reducers/index.ts +++ b/client/src/store/reducers/index.ts @@ -1,9 +1,11 @@ import { combineReducers } from 'redux'; +import { GlobalState } from '../../interfaces/GlobalState'; + import themeReducer from './theme'; import appReducer from './app'; -const rootReducer = combineReducers({ +const rootReducer = combineReducers({ theme: themeReducer, app: appReducer }) diff --git a/client/src/store/reducers/theme.ts b/client/src/store/reducers/theme.ts index 084168b..63767d2 100644 --- a/client/src/store/reducers/theme.ts +++ b/client/src/store/reducers/theme.ts @@ -1,17 +1,21 @@ -import { SET_THEME } from '../actions/actionTypes'; +import { ActionTypes, Action } from '../actions'; -const initialState = { +export interface State { + theme: string; +} + +const initialState: State = { theme: 'blues' } -const themeReducer = (state = initialState, action: any) => { +const setTheme = (state: State, action: Action): State => { + return { theme: action.payload }; +} + +const themeReducer = (state = initialState, action: Action) => { switch (action.type) { - case SET_THEME: - return { - theme: action.payload - }; - default: - return state; + case ActionTypes.setTheme: return setTheme(state, action); + default: return state; } }