Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor user reducers and actions using redux toolkit #3127

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 0 additions & 20 deletions client/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,6 @@ export const CLOSE_PREFERENCES = 'CLOSE_PREFERENCES';
export const SET_FONT_SIZE = 'SET_FONT_SIZE';
export const SET_LINE_NUMBERS = 'SET_LINE_NUMBERS';

export const AUTH_USER = 'AUTH_USER';
export const UNAUTH_USER = 'UNAUTH_USER';
export const AUTH_ERROR = 'AUTH_ERROR';

export const SETTINGS_UPDATED = 'SETTINGS_UPDATED';

export const API_KEY_CREATED = 'API_KEY_CREATED';
export const API_KEY_REMOVED = 'API_KEY_REMOVED';

export const SET_PROJECT_NAME = 'SET_PROJECT_NAME';
export const RENAME_PROJECT = 'RENAME_PROJECT';

Expand Down Expand Up @@ -104,15 +95,6 @@ export const END_SKETCH_REFRESH = 'END_SKETCH_REFRESH';
export const DETECT_INFINITE_LOOPS = 'DETECT_INFINITE_LOOPS';
export const RESET_INFINITE_LOOPS = 'RESET_INFINITE_LOOPS';

export const RESET_PASSWORD_INITIATE = 'RESET_PASSWORD_INITIATE';
export const RESET_PASSWORD_RESET = 'RESET_PASSWORD_RESET';
export const INVALID_RESET_PASSWORD_TOKEN = 'INVALID_RESET_PASSWORD_TOKEN';

export const EMAIL_VERIFICATION_INITIATE = 'EMAIL_VERIFICATION_INITIATE';
export const EMAIL_VERIFICATION_VERIFY = 'EMAIL_VERIFICATION_VERIFY';
export const EMAIL_VERIFICATION_VERIFIED = 'EMAIL_VERIFICATION_VERIFIED';
export const EMAIL_VERIFICATION_INVALID = 'EMAIL_VERIFICATION_INVALID';

// eventually, handle errors more specifically and better
export const ERROR = 'ERROR';

Expand All @@ -139,5 +121,3 @@ export const CLOSE_SKETCHLIST_MODAL = 'CLOSE_SKETCHLIST_MODAL';

export const START_SAVING_PROJECT = 'START_SAVING_PROJECT';
export const END_SAVING_PROJECT = 'END_SAVING_PROJECT';

export const SET_COOKIE_CONSENT = 'SET_COOKIE_CONSENT';
97 changes: 36 additions & 61 deletions client/modules/User/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,27 @@ import { showErrorModal, justOpenedProject } from '../IDE/actions/ide';
import { setLanguage } from '../IDE/actions/preferences';
import { showToast, setToastText } from '../IDE/actions/toast';

export function authError(error) {
return {
type: ActionTypes.AUTH_ERROR,
payload: error
};
}
import { userActions } from './reducers';

const {
authUser,
unauthUser,
resetPasswordInitiate,
emailVerificationInitiate,
emailVerificationVerify,
emailVerificationVerified,
emailVerificationInvalid,
invalidResetPasswordToken,
apiKeyRemoved,
setCookieConsent
} = userActions;

export const {
authError,
resetPasswordReset,
settingsUpdated,
apiKeyCreated
} = userActions;

export function signUpUser(formValues) {
return apiClient.post('/signup', formValues);
Expand All @@ -21,13 +36,6 @@ export function loginUser(formValues) {
return apiClient.post('/login', formValues);
}

export function authenticateUser(user) {
return {
type: ActionTypes.AUTH_USER,
user
};
}

export function loginUserFailure(error) {
return {
type: ActionTypes.AUTH_ERROR,
Expand All @@ -49,7 +57,7 @@ export function validateAndLoginUser(formProps) {
return new Promise((resolve) => {
loginUser(formProps)
.then((response) => {
dispatch(authenticateUser(response.data));
dispatch(authUser(response.data));
dispatch(setPreferences(response.data.preferences));
dispatch(
setLanguage(response.data.preferences.language, {
Expand All @@ -76,7 +84,7 @@ export function validateAndSignUpUser(formValues) {
return new Promise((resolve) => {
signUpUser(formValues)
.then((response) => {
dispatch(authenticateUser(response.data));
dispatch(authUser(response.data));
dispatch(justOpenedProject());
browserHistory.push(previousPath);
resolve();
Expand All @@ -100,7 +108,7 @@ export function getUser() {
return;
}

dispatch(authenticateUser(data));
dispatch(authUser(data));
dispatch({
type: ActionTypes.SET_PREFERENCES,
preferences: data.preferences
Expand Down Expand Up @@ -147,9 +155,7 @@ export function logoutUser() {
apiClient
.get('/logout')
.then(() => {
dispatch({
type: ActionTypes.UNAUTH_USER
});
dispatch(unauthUser());
resetProject(dispatch);
})
.catch((error) => {
Expand All @@ -162,9 +168,7 @@ export function logoutUser() {
export function initiateResetPassword(formValues) {
return (dispatch) =>
new Promise((resolve) => {
dispatch({
type: ActionTypes.RESET_PASSWORD_INITIATE
});
dispatch(resetPasswordInitiate());
return apiClient
.post('/reset-password', formValues)
.then(() => resolve())
Expand All @@ -181,9 +185,7 @@ export function initiateResetPassword(formValues) {

export function initiateVerification() {
return (dispatch) => {
dispatch({
type: ActionTypes.EMAIL_VERIFICATION_INITIATE
});
dispatch(emailVerificationInitiate());
apiClient
.post('/verify/send', {})
.then(() => {
Expand All @@ -201,46 +203,27 @@ export function initiateVerification() {

export function verifyEmailConfirmation(token) {
return (dispatch) => {
dispatch({
type: ActionTypes.EMAIL_VERIFICATION_VERIFY,
state: 'checking'
});
dispatch(emailVerificationVerify({ state: 'checking' }));
return apiClient
.get(`/verify?t=${token}`, {})
.then((response) =>
dispatch({
type: ActionTypes.EMAIL_VERIFICATION_VERIFIED,
message: response.data
})
dispatch(emailVerificationVerified({ message: response.data }))
)
.catch((error) => {
const { response } = error;
dispatch({
type: ActionTypes.EMAIL_VERIFICATION_INVALID,
message: response.data
});
dispatch(emailVerificationInvalid({ message: response.data }));
});
};
}

export function resetPasswordReset() {
return {
type: ActionTypes.RESET_PASSWORD_RESET
};
}

export function validateResetPasswordToken(token) {
return (dispatch) => {
apiClient
.get(`/reset-password/${token}`)
.then(() => {
// do nothing if the token is valid
})
.catch(() =>
dispatch({
type: ActionTypes.INVALID_RESET_PASSWORD_TOKEN
})
);
.catch(() => dispatch(invalidResetPasswordToken()));
};
}

Expand All @@ -250,14 +233,12 @@ export function updatePassword(formValues, token) {
apiClient
.post(`/reset-password/${token}`, formValues)
.then((response) => {
dispatch(authenticateUser(response.data));
dispatch(authUser(response.data));
browserHistory.push('/');
resolve();
})
.catch((error) => {
dispatch({
type: ActionTypes.INVALID_RESET_PASSWORD_TOKEN
});
dispatch(invalidResetPasswordToken());
resolve({ error });
})
);
Expand Down Expand Up @@ -313,10 +294,7 @@ export function removeApiKey(keyId) {
apiClient
.delete(`/account/api-keys/${keyId}`)
.then((response) => {
dispatch({
type: ActionTypes.API_KEY_REMOVED,
user: response.data
});
dispatch(apiKeyRemoved(response.data));
})
.catch((error) => {
const { response } = error;
Expand All @@ -330,7 +308,7 @@ export function unlinkService(service) {
apiClient
.delete(`/auth/${service}`)
.then((response) => {
dispatch(authenticateUser(response.data));
dispatch(authUser(response.data));
})
.catch((error) => {
const { response } = error;
Expand All @@ -346,10 +324,7 @@ export function setUserCookieConsent(cookieConsent) {
apiClient
.put('/cookie-consent', { cookieConsent })
.then(() => {
dispatch({
type: ActionTypes.SET_COOKIE_CONSENT,
cookieConsent
});
dispatch(setCookieConsent(cookieConsent));
})
.catch((error) => {
const { response } = error;
Expand Down
117 changes: 72 additions & 45 deletions client/modules/User/reducers.js
Original file line number Diff line number Diff line change
@@ -1,51 +1,78 @@
import * as ActionTypes from '../../constants';
import { createSlice } from '@reduxjs/toolkit';

const user = (state = { authenticated: false }, action) => {
switch (action.type) {
case ActionTypes.AUTH_USER:
const initialState = {
authenticated: false,
resetPasswordInitiate: false,
resetPasswordInvalid: false,
emailVerificationInitiate: false,
emailVerificationTokenState: null,
cookieConsent: false
};

const userSlice = createSlice({
name: 'user',
initialState,
reducers: {
authUser: (state, action) => {
const { user } = action.payload;
return {
...action.user,
...user,
authenticated: true
};
case ActionTypes.UNAUTH_USER:
return {
authenticated: false
};
case ActionTypes.AUTH_ERROR:
return {
authenticated: false
};
case ActionTypes.RESET_PASSWORD_INITIATE:
return Object.assign({}, state, { resetPasswordInitiate: true });
case ActionTypes.RESET_PASSWORD_RESET:
return Object.assign({}, state, { resetPasswordInitiate: false });
case ActionTypes.INVALID_RESET_PASSWORD_TOKEN:
return Object.assign({}, state, { resetPasswordInvalid: true });
case ActionTypes.EMAIL_VERIFICATION_INITIATE:
return Object.assign({}, state, { emailVerificationInitiate: true });
case ActionTypes.EMAIL_VERIFICATION_VERIFY:
return Object.assign({}, state, {
emailVerificationTokenState: 'checking'
});
case ActionTypes.EMAIL_VERIFICATION_VERIFIED:
return Object.assign({}, state, {
emailVerificationTokenState: 'verified'
});
case ActionTypes.EMAIL_VERIFICATION_INVALID:
return Object.assign({}, state, {
emailVerificationTokenState: 'invalid'
});
case ActionTypes.SETTINGS_UPDATED:
return { ...state, ...action.user };
case ActionTypes.API_KEY_REMOVED:
return { ...state, ...action.user };
case ActionTypes.API_KEY_CREATED:
return { ...state, ...action.user };
case ActionTypes.SET_COOKIE_CONSENT:
return { ...state, cookieConsent: action.cookieConsent };
default:
return state;
},
unauthUser: (state, action) => ({
authenticated: false
}),
authError: (state, action) => ({
authenticated: false
}),
resetPasswordInitiate: (state, action) => ({
...state,
resetPasswordInitiate: true
}),
resetPasswordReset: (state, action) => ({
...state,
resetPasswordInitiate: false
}),
invalidResetPasswordToken: (state, action) => ({
...state,
resetPasswordInvalid: true
}),
emailVerificationInitiate: (state, action) => ({
...state,
emailVerificationInitiate: true
}),
emailVerificationVerify: (state, action) => ({
...state,
emailVerificationTokenState: 'checking'
}),
emailVerificationVerified: (state, action) => ({
...state,
emailVerificationTokenState: 'verified'
}),
emailVerificationInvalid: (state, action) => ({
...state,
emailVerificationTokenState: 'invalid'
}),
settingsUpdated: (state, action) => ({
...state,
...action.payload.user
}),
apiKeyRemoved: (state, action) => ({
...state,
...action.payload.user
}),
apiKeyCreated: (state, action) => ({
...state,
...action.payload.user
}),
setCookieConsent: (state, action) => ({
...state,
cookieConsent: action.payload.cookieConsent
})
}
};
});

export const userActions = userSlice.actions;

export default user;
export default userSlice.reducer;
Loading