Up to date CRA Started by Patrick Fic
This commit is contained in:
30
src/redux/application/application.actions.js
Normal file
30
src/redux/application/application.actions.js
Normal file
@@ -0,0 +1,30 @@
|
||||
import ApplicationActionTypes from "./application.types";
|
||||
|
||||
export const setRooms = (rooms) => ({
|
||||
type: ApplicationActionTypes.SET_ROOMS,
|
||||
payload: rooms,
|
||||
});
|
||||
|
||||
export const addRoom = (room) => ({
|
||||
type: ApplicationActionTypes.ADD_ROOM,
|
||||
payload: room,
|
||||
});
|
||||
|
||||
export const addImages = ({ roomId, images }) => ({
|
||||
type: ApplicationActionTypes.ADD_IMAGES_TO_ROOM,
|
||||
payload: { roomId, images },
|
||||
});
|
||||
|
||||
export const removeRoom = (roomId) => ({
|
||||
type: ApplicationActionTypes.REMOVE_ROOM,
|
||||
payload: roomId,
|
||||
});
|
||||
|
||||
export const markNa = (roomId) => ({
|
||||
type: ApplicationActionTypes.MARK_ROOM_NA,
|
||||
payload: roomId,
|
||||
});
|
||||
export const joinRoom = (roomId) => ({
|
||||
type: ApplicationActionTypes.JOIN_ROOM,
|
||||
payload: roomId,
|
||||
});
|
||||
53
src/redux/application/application.reducer.js
Normal file
53
src/redux/application/application.reducer.js
Normal file
@@ -0,0 +1,53 @@
|
||||
import ApplicationActionTypes from "./application.types";
|
||||
import _ from "lodash";
|
||||
const INITIAL_STATE = {
|
||||
rooms: [],
|
||||
images: {
|
||||
id: [],
|
||||
},
|
||||
};
|
||||
|
||||
const applicationReducer = (state = INITIAL_STATE, action) => {
|
||||
switch (action.type) {
|
||||
case ApplicationActionTypes.SET_ROOMS:
|
||||
return {
|
||||
...state,
|
||||
rooms: _.unionBy(state.rooms, action.payload, "id"),
|
||||
};
|
||||
case ApplicationActionTypes.ADD_ROOM:
|
||||
return {
|
||||
...state,
|
||||
rooms: _.unionBy(state.rooms, [action.payload], "id"),
|
||||
};
|
||||
case ApplicationActionTypes.ADD_IMAGES_TO_ROOM:
|
||||
return {
|
||||
...state,
|
||||
images: {
|
||||
...state.images,
|
||||
[action.payload.roomId]: _.unionBy(
|
||||
state.images[action.payload.roomId] || [],
|
||||
action.payload.images,
|
||||
|
||||
"filename"
|
||||
),
|
||||
},
|
||||
};
|
||||
case ApplicationActionTypes.REMOVE_ROOM:
|
||||
return {
|
||||
...state,
|
||||
rooms: state.rooms.filter((r) => r.id !== action.payload),
|
||||
};
|
||||
|
||||
case ApplicationActionTypes.MARK_ROOM_NA:
|
||||
return {
|
||||
...state,
|
||||
rooms: state.rooms.map((room) =>
|
||||
room.id === action.payload ? { ...room, na: true } : room
|
||||
),
|
||||
};
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
};
|
||||
|
||||
export default applicationReducer;
|
||||
40
src/redux/application/application.sagas.js
Normal file
40
src/redux/application/application.sagas.js
Normal file
@@ -0,0 +1,40 @@
|
||||
import { all, call, takeLatest } from "redux-saga/effects";
|
||||
import ApplicationActionTypes from "./application.types";
|
||||
export function* onJoinRoom() {
|
||||
yield takeLatest(ApplicationActionTypes.JOIN_ROOM, joinRoom);
|
||||
}
|
||||
export function* joinRoom({ payload: roomId }) {
|
||||
// console.log("function*joinRoom -> roomId", roomId);
|
||||
// //TH eactual function
|
||||
// const state = yield select();
|
||||
// const room = state.application.rooms.filter((r) => r.id === roomId)[0];
|
||||
// yield put(addImages({ roomId: null, images: [] }));
|
||||
// if (room) {
|
||||
// socket.emit(
|
||||
// "join",
|
||||
// {
|
||||
// roomName: room.name,
|
||||
// parentRoomName: room.parentName,
|
||||
// password: Math.round(Math.random() * 1000).toString(),
|
||||
// },
|
||||
// co.wrap(function* (payload) {
|
||||
// console.log("Checking Room", payload);
|
||||
// if (payload.room && payload.room.id) {
|
||||
// console.log("about to put");
|
||||
// yield put(
|
||||
// addImages({
|
||||
// roomId: payload.room.id,
|
||||
// images: payload.room.medias,
|
||||
// })
|
||||
// );
|
||||
// } else {
|
||||
// yield put(markNa(room.id));
|
||||
// }
|
||||
// })
|
||||
// );
|
||||
// }
|
||||
}
|
||||
|
||||
export function* applicationSagas() {
|
||||
yield all([call(onJoinRoom)]);
|
||||
}
|
||||
13
src/redux/application/application.selectors.js
Normal file
13
src/redux/application/application.selectors.js
Normal file
@@ -0,0 +1,13 @@
|
||||
import { createSelector } from "reselect";
|
||||
|
||||
const selectApplication = (state) => state.application;
|
||||
|
||||
export const selectRooms = createSelector(
|
||||
[selectApplication],
|
||||
(application) => application.rooms
|
||||
);
|
||||
|
||||
export const selectImages = createSelector(
|
||||
[selectApplication],
|
||||
(application) => application.images
|
||||
);
|
||||
9
src/redux/application/application.types.js
Normal file
9
src/redux/application/application.types.js
Normal file
@@ -0,0 +1,9 @@
|
||||
const ApplicationActionTypes = {
|
||||
SET_ROOMS: "SET_ROOMS",
|
||||
ADD_ROOM: "ADD_ROOM",
|
||||
ADD_IMAGES_TO_ROOM: "ADD_IMAGES_TO_ROOM",
|
||||
REMOVE_ROOM: "REMOVE_ROOM",
|
||||
MARK_ROOM_NA: "MARK_ROOM_NA",
|
||||
JOIN_ROOM: "JOIN_ROOM",
|
||||
};
|
||||
export default ApplicationActionTypes;
|
||||
18
src/redux/root.reducer.js
Normal file
18
src/redux/root.reducer.js
Normal file
@@ -0,0 +1,18 @@
|
||||
import { combineReducers } from "redux";
|
||||
import { persistReducer } from "redux-persist";
|
||||
import storage from "redux-persist/lib/storage";
|
||||
import applicationReducer from "./application/application.reducer";
|
||||
import userReducer from "./user/user.reducer";
|
||||
|
||||
const persistConfig = {
|
||||
key: "root",
|
||||
storage,
|
||||
// blacklist: ["application"],
|
||||
};
|
||||
|
||||
const rootReducer = combineReducers({
|
||||
application: applicationReducer,
|
||||
user: userReducer,
|
||||
});
|
||||
|
||||
export default persistReducer(persistConfig, rootReducer);
|
||||
6
src/redux/root.saga.js
Normal file
6
src/redux/root.saga.js
Normal file
@@ -0,0 +1,6 @@
|
||||
import { all, call } from "redux-saga/effects";
|
||||
import { applicationSagas } from "./application/application.sagas";
|
||||
|
||||
export default function* rootSaga() {
|
||||
yield all([call(applicationSagas)]);
|
||||
}
|
||||
33
src/redux/store.js
Normal file
33
src/redux/store.js
Normal file
@@ -0,0 +1,33 @@
|
||||
import { createStore, applyMiddleware, compose } from "redux";
|
||||
import { persistStore } from "redux-persist";
|
||||
import { createLogger } from "redux-logger";
|
||||
import createSagaMiddleware from "redux-saga";
|
||||
|
||||
import rootReducer from "./root.reducer";
|
||||
import rootSaga from "./root.saga";
|
||||
|
||||
const sagaMiddleWare = createSagaMiddleware();
|
||||
|
||||
const middlewares = [sagaMiddleWare];
|
||||
//if (process.env.NODE_ENV === "development") {
|
||||
middlewares.push(createLogger({ collapsed: true, diff: true }));
|
||||
//}
|
||||
|
||||
const composeEnhancers =
|
||||
typeof window === "object" && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__
|
||||
? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({
|
||||
// Specify extension’s options like name, actionsBlacklist, actionsCreators, serialize...
|
||||
})
|
||||
: compose;
|
||||
|
||||
const enhancer = composeEnhancers(
|
||||
applyMiddleware(...middlewares)
|
||||
// other store enhancers if any
|
||||
);
|
||||
|
||||
export const store = createStore(rootReducer, enhancer);
|
||||
sagaMiddleWare.run(rootSaga);
|
||||
|
||||
export const persistor = persistStore(store);
|
||||
|
||||
export default { store, persistStore };
|
||||
84
src/redux/user/user.actions.js
Normal file
84
src/redux/user/user.actions.js
Normal file
@@ -0,0 +1,84 @@
|
||||
import UserActionTypes from "./user.types";
|
||||
|
||||
export const signInSuccess = (user) => ({
|
||||
type: UserActionTypes.SIGN_IN_SUCCESS,
|
||||
payload: user,
|
||||
});
|
||||
export const signInFailure = (errorMsg) => ({
|
||||
type: UserActionTypes.SIGN_IN_FAILURE,
|
||||
payload: errorMsg,
|
||||
});
|
||||
|
||||
export const emailSignInStart = (emailAndPassword) => ({
|
||||
type: UserActionTypes.EMAIL_SIGN_IN_START,
|
||||
payload: emailAndPassword,
|
||||
});
|
||||
|
||||
export const checkUserSession = () => ({
|
||||
type: UserActionTypes.CHECK_USER_SESSION,
|
||||
});
|
||||
|
||||
export const signOutStart = () => ({
|
||||
type: UserActionTypes.SIGN_OUT_START,
|
||||
});
|
||||
export const signOutSuccess = () => ({
|
||||
type: UserActionTypes.SIGN_OUT_SUCCESS,
|
||||
});
|
||||
|
||||
export const signOutFailure = (error) => ({
|
||||
type: UserActionTypes.SIGN_OUT_FAILURE,
|
||||
payload: error,
|
||||
});
|
||||
|
||||
export const unauthorizedUser = () => ({
|
||||
type: UserActionTypes.UNAUTHORIZED_USER,
|
||||
});
|
||||
|
||||
export const setUserLanguage = (language) => ({
|
||||
type: UserActionTypes.SET_USER_LANGUAGE,
|
||||
payload: language,
|
||||
});
|
||||
|
||||
export const updateUserDetails = (userDetails) => ({
|
||||
type: UserActionTypes.UPDATE_USER_DETAILS,
|
||||
payload: userDetails,
|
||||
});
|
||||
|
||||
export const updateUserDetailsSuccess = (userDetails) => ({
|
||||
type: UserActionTypes.UPDATE_USER_DETAILS_SUCCESS,
|
||||
payload: userDetails,
|
||||
});
|
||||
|
||||
|
||||
|
||||
export const setLocalFingerprint = (fingerprint) => ({
|
||||
type: UserActionTypes.SET_LOCAL_FINGERPRINT,
|
||||
payload: fingerprint,
|
||||
});
|
||||
|
||||
export const sendPasswordReset = (email) => ({
|
||||
type: UserActionTypes.SEND_PASSWORD_RESET_EMAIL_START,
|
||||
payload: email,
|
||||
});
|
||||
export const sendPasswordResetFailure = (error) => ({
|
||||
type: UserActionTypes.SEND_PASSWORD_RESET_EMAIL_FAILURE,
|
||||
payload: error,
|
||||
});
|
||||
export const sendPasswordResetSuccess = () => ({
|
||||
type: UserActionTypes.SEND_PASSWORD_RESET_EMAIL_SUCCESS,
|
||||
});
|
||||
|
||||
export const validatePasswordResetStart = (emailAndPin) => ({
|
||||
type: UserActionTypes.VALIDATE_PASSWORD_RESET_START,
|
||||
payload: emailAndPin,
|
||||
});
|
||||
|
||||
export const validatePasswordResetSuccess = () => ({
|
||||
type: UserActionTypes.VALIDATE_PASSWORD_RESET_SUCCESS,
|
||||
});
|
||||
|
||||
export const validatePasswordResetFailure = (error) => ({
|
||||
type: UserActionTypes.VALIDATE_PASSWORD_RESET_FAILURE,
|
||||
payload: error,
|
||||
});
|
||||
|
||||
90
src/redux/user/user.reducer.js
Normal file
90
src/redux/user/user.reducer.js
Normal file
@@ -0,0 +1,90 @@
|
||||
import UserActionTypes from "./user.types";
|
||||
|
||||
const INITIAL_STATE = {
|
||||
currentUser: {
|
||||
authorized: null,
|
||||
//language: "en-US"
|
||||
},
|
||||
bodyshop: null,
|
||||
fingerprint: null,
|
||||
error: null,
|
||||
conflict: false,
|
||||
passwordreset: {
|
||||
email: null,
|
||||
error: null,
|
||||
success: false,
|
||||
},
|
||||
authLevel: 0,
|
||||
};
|
||||
|
||||
const userReducer = (state = INITIAL_STATE, action) => {
|
||||
switch (action.type) {
|
||||
case UserActionTypes.SET_LOCAL_FINGERPRINT:
|
||||
return { ...state, fingerprint: action.payload };
|
||||
|
||||
case UserActionTypes.VALIDATE_PASSWORD_RESET_START:
|
||||
case UserActionTypes.SEND_PASSWORD_RESET_EMAIL_START:
|
||||
return {
|
||||
...state,
|
||||
passwordreset: {
|
||||
email: action.payload,
|
||||
error: null,
|
||||
success: false,
|
||||
},
|
||||
};
|
||||
case UserActionTypes.VALIDATE_PASSWORD_RESET_FAILURE:
|
||||
case UserActionTypes.SEND_PASSWORD_RESET_EMAIL_FAILURE:
|
||||
return { ...state, passwordreset: { error: action.payload } };
|
||||
case UserActionTypes.VALIDATE_PASSWORD_RESET_SUCCESS:
|
||||
case UserActionTypes.SEND_PASSWORD_RESET_EMAIL_SUCCESS:
|
||||
return {
|
||||
...state,
|
||||
passwordreset: { ...state.passwordreset, success: true },
|
||||
};
|
||||
case UserActionTypes.SIGN_IN_SUCCESS:
|
||||
return {
|
||||
...state,
|
||||
currentUser: action.payload,
|
||||
error: null,
|
||||
};
|
||||
case UserActionTypes.SIGN_OUT_SUCCESS:
|
||||
return {
|
||||
...state,
|
||||
currentUser: { authorized: false },
|
||||
error: null,
|
||||
};
|
||||
case UserActionTypes.UNAUTHORIZED_USER:
|
||||
return {
|
||||
...state,
|
||||
error: null,
|
||||
currentUser: { authorized: false },
|
||||
};
|
||||
case UserActionTypes.SET_USER_LANGUAGE:
|
||||
return {
|
||||
...state,
|
||||
language: action.payload,
|
||||
};
|
||||
case UserActionTypes.UPDATE_USER_DETAILS_SUCCESS:
|
||||
return {
|
||||
...state,
|
||||
currentUser: {
|
||||
...state.currentUser,
|
||||
...action.payload, //Spread current user details in.
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
case UserActionTypes.SIGN_IN_FAILURE:
|
||||
case UserActionTypes.SIGN_OUT_FAILURE:
|
||||
case UserActionTypes.EMAIL_SIGN_UP_FAILURE:
|
||||
return {
|
||||
...state,
|
||||
error: action.payload,
|
||||
};
|
||||
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
};
|
||||
|
||||
export default userReducer;
|
||||
237
src/redux/user/user.sagas.js
Normal file
237
src/redux/user/user.sagas.js
Normal file
@@ -0,0 +1,237 @@
|
||||
import Fingerprint2 from "fingerprintjs2";
|
||||
import LogRocket from "logrocket";
|
||||
import { all, call, delay, put, select, takeLatest } from "redux-saga/effects";
|
||||
import {
|
||||
auth,
|
||||
firestore,
|
||||
getCurrentUser,
|
||||
logImEXEvent,
|
||||
updateCurrentUser,
|
||||
} from "../../firebase/firebase.utils";
|
||||
import {
|
||||
checkInstanceId,
|
||||
setInstanceConflict,
|
||||
setInstanceId,
|
||||
setLocalFingerprint,
|
||||
signInFailure,
|
||||
signInSuccess,
|
||||
signOutFailure,
|
||||
signOutSuccess,
|
||||
unauthorizedUser,
|
||||
updateUserDetailsSuccess,
|
||||
sendPasswordResetFailure,
|
||||
sendPasswordResetSuccess,
|
||||
validatePasswordResetSuccess,
|
||||
validatePasswordResetFailure,
|
||||
setAuthlevel,
|
||||
} from "./user.actions";
|
||||
import UserActionTypes from "./user.types";
|
||||
|
||||
export function* onEmailSignInStart() {
|
||||
yield takeLatest(UserActionTypes.EMAIL_SIGN_IN_START, signInWithEmail);
|
||||
}
|
||||
export function* signInWithEmail({ payload: { email, password } }) {
|
||||
try {
|
||||
logImEXEvent("redux_sign_in_attempt", { user: email });
|
||||
|
||||
const { user } = yield auth.signInWithEmailAndPassword(email, password);
|
||||
|
||||
yield put(
|
||||
signInSuccess({
|
||||
uid: user.uid,
|
||||
email: user.email,
|
||||
displayName: user.displayName,
|
||||
photoURL: user.photoURL,
|
||||
authorized: true,
|
||||
})
|
||||
);
|
||||
} catch (error) {
|
||||
yield put(signInFailure(error));
|
||||
logImEXEvent("redux_sign_in_failure", { user: email, error });
|
||||
}
|
||||
}
|
||||
|
||||
export function* onCheckUserSession() {
|
||||
yield takeLatest(UserActionTypes.CHECK_USER_SESSION, isUserAuthenticated);
|
||||
}
|
||||
export function* isUserAuthenticated() {
|
||||
try {
|
||||
logImEXEvent("redux_auth_check");
|
||||
|
||||
const user = yield getCurrentUser();
|
||||
if (!user) {
|
||||
yield put(unauthorizedUser());
|
||||
return;
|
||||
}
|
||||
|
||||
LogRocket.identify(user.email);
|
||||
yield put(
|
||||
signInSuccess({
|
||||
uid: user.uid,
|
||||
email: user.email,
|
||||
displayName: user.displayName,
|
||||
photoURL: user.photoURL,
|
||||
authorized: true,
|
||||
})
|
||||
);
|
||||
} catch (error) {
|
||||
yield put(signInFailure(error));
|
||||
}
|
||||
}
|
||||
export function* onSignOutStart() {
|
||||
yield takeLatest(UserActionTypes.SIGN_OUT_START, signOutStart);
|
||||
}
|
||||
export function* signOutStart() {
|
||||
try {
|
||||
logImEXEvent("redux_sign_out");
|
||||
|
||||
yield auth.signOut();
|
||||
yield put(signOutSuccess());
|
||||
localStorage.removeItem("token");
|
||||
} catch (error) {
|
||||
yield put(signOutFailure(error.message));
|
||||
}
|
||||
}
|
||||
|
||||
export function* onUpdateUserDetails() {
|
||||
yield takeLatest(UserActionTypes.UPDATE_USER_DETAILS, updateUserDetails);
|
||||
}
|
||||
export function* updateUserDetails(userDetails) {
|
||||
try {
|
||||
yield updateCurrentUser(userDetails.payload);
|
||||
yield put(updateUserDetailsSuccess(userDetails.payload));
|
||||
} catch (error) {
|
||||
//yield put(signOutFailure(error.message));
|
||||
//TODO error handling
|
||||
}
|
||||
}
|
||||
export function* onSetInstanceId() {
|
||||
yield takeLatest(UserActionTypes.SET_INSTANCE_ID, setInstanceIdSaga);
|
||||
}
|
||||
export function* setInstanceIdSaga({ payload: uid }) {
|
||||
try {
|
||||
const userInstanceRef = firestore.doc(`userInstance/${uid}`);
|
||||
|
||||
const fingerprint = Fingerprint2.x64hash128(
|
||||
(yield Fingerprint2.getPromise({})).map((c) => c.value).join(""),
|
||||
31
|
||||
);
|
||||
|
||||
yield userInstanceRef.set({
|
||||
timestamp: new Date(),
|
||||
fingerprint,
|
||||
});
|
||||
|
||||
yield put(setLocalFingerprint(fingerprint));
|
||||
yield delay(5 * 60 * 1000);
|
||||
if (process.env.NODE_ENV === "production") yield put(checkInstanceId(uid));
|
||||
} catch (error) {
|
||||
console.log("error", error);
|
||||
//yield put(signOutFailure(error.message));
|
||||
//TODO error handling
|
||||
}
|
||||
}
|
||||
|
||||
export function* onCheckInstanceId() {
|
||||
yield takeLatest(UserActionTypes.CHECK_INSTANCE_ID, checkInstanceIdSaga);
|
||||
}
|
||||
export function* checkInstanceIdSaga({ payload: uid }) {
|
||||
try {
|
||||
const userInstanceRef = firestore.doc(`userInstance/${uid}`);
|
||||
|
||||
const snapshot = yield userInstanceRef.get();
|
||||
let fingerprint = yield select((state) => state.user.fingerprint);
|
||||
|
||||
if (snapshot.data().fingerprint === fingerprint) {
|
||||
yield delay(5 * 60 * 1000);
|
||||
yield put(checkInstanceId(uid));
|
||||
} else {
|
||||
console.log("ERROR: Fingerprints do not match. Conflict detected.");
|
||||
logImEXEvent("instance_confict");
|
||||
yield put(setInstanceConflict());
|
||||
}
|
||||
} catch (error) {
|
||||
console.log("error", error);
|
||||
//TODO error handling
|
||||
}
|
||||
}
|
||||
|
||||
export function* onSignInSuccess() {
|
||||
yield takeLatest(UserActionTypes.SIGN_IN_SUCCESS, signInSuccessSaga);
|
||||
}
|
||||
|
||||
export function* signInSuccessSaga({ payload }) {
|
||||
LogRocket.identify(payload.email);
|
||||
|
||||
if (!payload.email.includes("@imex.")) yield put(setInstanceId(payload.uid));
|
||||
yield logImEXEvent("redux_sign_in_success");
|
||||
}
|
||||
|
||||
export function* onSendPasswordResetStart() {
|
||||
yield takeLatest(
|
||||
UserActionTypes.SEND_PASSWORD_RESET_EMAIL_START,
|
||||
sendPasswordResetEmail
|
||||
);
|
||||
}
|
||||
export function* sendPasswordResetEmail({ payload }) {
|
||||
try {
|
||||
yield auth.sendPasswordResetEmail(payload, {
|
||||
url: "https://imex.online/passwordreset",
|
||||
});
|
||||
console.log("Good should send.");
|
||||
yield put(sendPasswordResetSuccess());
|
||||
} catch (error) {
|
||||
yield put(sendPasswordResetFailure(error.message));
|
||||
}
|
||||
}
|
||||
|
||||
export function* onValidatePasswordResetStart() {
|
||||
yield takeLatest(
|
||||
UserActionTypes.VALIDATE_PASSWORD_RESET_START,
|
||||
validatePasswordResetStart
|
||||
);
|
||||
}
|
||||
export function* validatePasswordResetStart({ payload: { password, code } }) {
|
||||
try {
|
||||
yield auth.confirmPasswordReset(code, password);
|
||||
yield put(validatePasswordResetSuccess());
|
||||
} catch (error) {
|
||||
console.log("function*validatePasswordResetStart -> error", error);
|
||||
yield put(validatePasswordResetFailure(error.message));
|
||||
}
|
||||
}
|
||||
|
||||
export function* onSetShopDetails() {
|
||||
yield takeLatest(
|
||||
UserActionTypes.SET_SHOP_DETAILS,
|
||||
SetAuthLevelFromShopDetails
|
||||
);
|
||||
}
|
||||
export function* SetAuthLevelFromShopDetails({ payload }) {
|
||||
try {
|
||||
const userEmail = yield select((state) => state.user.currentUser.email);
|
||||
|
||||
const authRecord = payload.associations.filter(
|
||||
(a) => a.useremail === userEmail
|
||||
);
|
||||
|
||||
yield put(setAuthlevel(authRecord[0] ? authRecord[0].authlevel : 0));
|
||||
} catch (error) {
|
||||
yield put(signInFailure(error.message));
|
||||
}
|
||||
}
|
||||
|
||||
export function* userSagas() {
|
||||
yield all([
|
||||
call(onEmailSignInStart),
|
||||
call(onCheckUserSession),
|
||||
call(onSignOutStart),
|
||||
call(onUpdateUserDetails),
|
||||
call(onSetInstanceId),
|
||||
call(onCheckInstanceId),
|
||||
call(onSignInSuccess),
|
||||
call(onSendPasswordResetStart),
|
||||
call(onValidatePasswordResetStart),
|
||||
call(onSetShopDetails),
|
||||
]);
|
||||
}
|
||||
18
src/redux/user/user.selectors.js
Normal file
18
src/redux/user/user.selectors.js
Normal file
@@ -0,0 +1,18 @@
|
||||
import { createSelector } from "reselect";
|
||||
|
||||
const selectUser = (state) => state.user;
|
||||
|
||||
export const selectCurrentUser = createSelector(
|
||||
[selectUser],
|
||||
(user) => user.currentUser
|
||||
);
|
||||
|
||||
export const selectSignInError = createSelector(
|
||||
[selectUser],
|
||||
(user) => user.error
|
||||
);
|
||||
|
||||
export const selectPasswordReset = createSelector(
|
||||
[selectUser],
|
||||
(user) => user.passwordreset
|
||||
);
|
||||
31
src/redux/user/user.types.js
Normal file
31
src/redux/user/user.types.js
Normal file
@@ -0,0 +1,31 @@
|
||||
const UserActionTypes = {
|
||||
SET_CURRENT_USER: "SET_CURRENT_USER",
|
||||
GOOGLE_SIGN_IN_START: "GOOGLE_SIGN_IN_START",
|
||||
SIGN_IN_SUCCESS: "SIGN_IN_SUCCESS",
|
||||
SIGN_IN_FAILURE: "SIGN_IN_FAILURE",
|
||||
EMAIL_SIGN_IN_START: "EMAIL_SIGN_IN_START",
|
||||
CHECK_USER_SESSION: "CHECK_USER_SESSION",
|
||||
SIGN_OUT_START: "SIGN_OUT_START",
|
||||
SIGN_OUT_SUCCESS: "SIGN_OUT_SUCCESS",
|
||||
SIGN_OUT_FAILURE: "SIGN_OUT_FAILURE",
|
||||
EMAIL_SIGN_UP_START: "EMAIL_SIGN_UP_START",
|
||||
EMAIL_SIGN_UP_SUCCESS: "EMAIL_SIGN_UP_SUCCESS",
|
||||
EMAIL_SIGN_UP_FAILURE: "EMAIL_SIGN_UP_FAILURE",
|
||||
UNAUTHORIZED_USER: "UNAUTHORIZED_USER",
|
||||
SET_USER_LANGUAGE: "SET_USER_LANGUAGE",
|
||||
UPDATE_USER_DETAILS: "UPDATE_USER_DETAILS",
|
||||
UPDATE_USER_DETAILS_SUCCESS: "UPDATE_USER_DETAILS_SUCCESS",
|
||||
SET_SHOP_DETAILS: "SET_SHOP_DETAILS",
|
||||
SET_INSTANCE_ID: "SET_INSTANCE_ID",
|
||||
CHECK_INSTANCE_ID: "CHECK_INSTANCE_ID",
|
||||
SET_INSTANCE_CONFLICT: "SET_INSTANCE_CONFLICT",
|
||||
SET_LOCAL_FINGERPRINT: "SET_LOCAL_FINGERPRINT",
|
||||
SEND_PASSWORD_RESET_EMAIL_START: "SEND_PASSWORD_RESET_EMAIL_START",
|
||||
SEND_PASSWORD_RESET_EMAIL_FAILURE: "SEND_PASSWORD_RESET_EMAIL_FAILURE",
|
||||
SEND_PASSWORD_RESET_EMAIL_SUCCESS: "SEND_PASSWORD_RESET_EMAIL_SUCCESS",
|
||||
VALIDATE_PASSWORD_RESET_START: "VALIDATE_PASSWORD_RESET_START",
|
||||
VALIDATE_PASSWORD_RESET_SUCCESS: "VALIDATE_PASSWORD_RESET_SUCCESS",
|
||||
VALIDATE_PASSWORD_RESET_FAILURE: "VALIDATE_PASSWORD_RESET_FAILURE",
|
||||
SET_AUTH_LEVEL: "SET_AUTH_LEVEL",
|
||||
};
|
||||
export default UserActionTypes;
|
||||
Reference in New Issue
Block a user