Skip to content

Instantly share code, notes, and snippets.

@Raja0sama
Created May 18, 2021 21:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Raja0sama/4935d8d888f38ebaa1a8d6e8992598d5 to your computer and use it in GitHub Desktop.
Save Raja0sama/4935d8d888f38ebaa1a8d6e8992598d5 to your computer and use it in GitHub Desktop.
DVA Redux
import Auth from '@/services/auth';
import { queryCurrent, query as queryUsers } from '@/services/user';
import Firestore from '@/services/firestore';
import { refs, functions, auth, db } from '@/services/utils/firebase_config';
import { getAuthority, removeAuthority, setAuthority } from '@/utils/authority';
import { dispatch, RANDOMWORDS, redirectWhenLoggedIn, replacerFunc } from '@/utils/utils';
import { message } from 'antd';
import axios from 'axios';
import { loadAlerts } from '@/.umi/plugin-dva/connect';
import { history } from 'umi';
import { take } from 'lodash-es';
const namespace = 'user';
export const LoginAs = (payload) => ({ type: `${namespace}/loginAs`, payload });
export const logoutAs = (payload) => ({ type: `${namespace}/logoutAs` });
export const Login = (payload) => ({ type: `${namespace}/login`, payload });
export const Register = (payload) => ({ type: `${namespace}/register`, payload });
export const RegisterModerator = (payload) => ({ type: `${namespace}/registerModerator`, payload });
const startLoading = (loadingType) => ({ type: 'startLoading', loadingType });
const stopLoading = (loadingType) => ({ type: 'stopLoading', loadingType });
const UserModel = {
namespace,
state: {
currentUser: {},
user: undefined,
loginAs: undefined,
loading: {
user: false,
login: false,
register: false,
layout: false,
},
},
effects: {
*loginAs({ payload }, { call, put, select }) {
const { currentUser, user } = yield select(({ user }) => ({
currentUser: user.currentUser,
user: user.user,
}));
const userTo = payload;
delete userTo._original;
const getAccess = yield Firestore.get(
refs.organizations.doc(userTo.organizations[0]).collection('accessControl').doc(userTo.id),
);
let authority = [];
if (Array.isArray(getAccess?.authority)) authority = [...authority, ...getAccess.authority];
else authority.push(getAccess.authority);
setAuthority(authority);
yield put({ type: 'login_In', user: userTo, auth: true });
yield localStorage.setItem('@preview', JSON.stringify({ ...user, new: userTo }));
location.href = '/';
},
*logoutAs({ payload }, { call, put, select }) {
let user = yield localStorage.getItem('@preview');
user = JSON.parse(user);
delete user.new;
yield put({ type: 'login_In', user, auth: true });
yield localStorage.removeItem('@preview');
history.go('/');
},
*registerModerator({ payload }, { call, put, select }) {
const user = yield select(({ user }) => {
return user.user;
});
yield put(startLoading('registerModerator'));
try {
const createUser = functions.httpsCallable('createUser');
const password = RANDOMWORDS(7);
const user = yield call(createUser, { email: payload.email, password });
const userId = user.data.uid;
const currUserId = auth().currentUser.uid;
var orgID = '';
const doc = yield refs.users.doc(currUserId).get();
if (!doc.exists) {
return false;
} else {
orgID = doc.data().organizations[0];
}
// TODO : Change update operations to a batch. See user registration for the example.
const batch = db().batch();
batch.set(refs.users.doc(userId), {
firstName: payload.firstName,
lastName: payload.lastName,
email: payload.email,
created_at: new Date(),
phone: payload.phone,
organizations: [orgID],
password,
role: 'moderator',
status: 'active',
});
batch.set(refs.organizations.doc(`${orgID}/accessControl/${userId}`), {
authority: 'moderator',
});
yield batch.commit();
message.success('Moderator created successfully');
yield axios
.post('https://webinar-wave.vercel.app/email', {
to: [payload.email],
message: `<pre>Hi, Your account has been created , You have been assigned as a moderator<br/> Your password is ${password}.`,
subject: 'Welcome to Webinar wave',
})
.then((e) => console.log({ SUCCESS: e }))
.catch((e) => console.log({ failed: e }));
payload.cb({ type: 'success' });
} catch (err) {
message.error('error: ', err);
payload.cb({ type: 'unsuccessful' });
}
yield put(stopLoading('register'));
},
*register({ payload }, { call, put }) {
yield put(startLoading('register'));
try {
// create an organization
const orgID = yield refs.organizations.doc().id;
const batch = db().batch();
batch.set(refs.organizations.doc(orgID), {
name: payload.organization,
});
const auth = yield call(Auth.register_with_email, payload.email, payload.password);
batch.set(refs.users.doc(auth.user.uid), {
first_name: payload.firstName,
last_name: payload.lastName,
email: payload.email,
created_at: new Date(),
phone: payload.phone,
organizations: [orgID],
role: 'owner',
status: 'active',
});
batch.set(refs.organizations.doc(`${orgID}/accessControl/${auth.user.uid}`), {
authority: 'admin',
});
// TODO : remove commenting
yield batch.commit();
yield axios.post('https://webinar-wave.vercel.app/email', {
to: [payload.email],
message: `<pre>Hi, Your account has been created successfully.`,
subject: 'Welcome to Webinar wave',
});
} catch (error) {
var errorCode = error.code;
var errorMessage = error.message;
if (errorCode == 'auth/weak-password') {
message.error('The password is too weak.');
} else {
message.error(errorMessage);
}
}
yield put(stopLoading('register'));
},
*login({ payload }, { call, put }) {
yield put(startLoading('login'));
try {
yield call(Auth.login_with_email, payload.username, payload.password);
yield put(stopLoading('login'));
} catch (e) {
yield put(stopLoading('login'));
message.error('Error occured, make sure to input correct credientials.');
}
},
*fetch(_, { call, put }) {
const response = yield call(queryUsers);
yield put({
type: 'save',
payload: response,
});
},
*fetchCurrent(_, { call, put }) {
const user = yield call(Auth.curr_user);
yield put({
type: 'saveCurrentUser',
payload: user,
});
},
*login_In({ user, auth }, { call, take }) {
let unSub;
try {
unSub = yield Firestore.listen(
refs.users.doc(user.uid || user.id),
async (User) => {
const put = dispatch;
if (User) {
User.uid = user.uid;
const org = User.organizations;
const getAccess = await Firestore.get(
refs.organizations.doc(org[0]).collection('accessControl').doc(User.id),
);
let authority = [];
if (Array.isArray(getAccess.authority))
authority = [...authority, ...getAccess.authority];
else authority.push(getAccess.authority);
setAuthority(authority);
put({
type: 'user/setState',
user: { ...User, authority },
});
console.log({ user });
put(loadAlerts(user.uid));
put({
type: 'buildings/init',
});
if (!auth) redirectWhenLoggedIn();
put(stopLoading('layout'));
} else {
put(stopLoading('layout'));
put({ type: 'notification/unSub' });
// log the person out
}
},
(error) => console.log('user listener', { error }),
);
} catch (error) {}
yield take(`${namespace}/userUnsub`);
unSub && unSub();
},
},
subscriptions: {
async authSubscriber({ dispatch }) {
dispatch(startLoading('layout'));
return Auth.subscribe(async (user) => {
if (user) {
// loginAs;
const data = await localStorage.getItem('@preview');
if (data) return dispatch({ type: 'login_In', user: JSON.parse(data).new });
dispatch({ type: 'login_In', user });
} else {
dispatch(stopLoading('layout'));
dispatch({ type: 'notification/unSub' });
dispatch({ type: 'setState', user: undefined });
}
});
},
},
reducers: {
setState(state, newState) {
return { ...state, ...newState };
},
startLoading(state, { loadingType }) {
return { ...state, loading: { ...state.loading, [loadingType]: true } };
},
stopLoading(state, { loadingType }) {
return { ...state, loading: { ...state.loading, [loadingType]: false } };
},
saveCurrentUser(state, action) {
return { ...state, currentUser: action.payload || {} };
},
changeNotifyCount(
state = {
currentUser: {},
},
action,
) {
return {
...state,
currentUser: {
...state.currentUser,
notifyCount: action.payload.totalCount,
unreadCount: action.payload.unreadCount,
},
};
},
},
};
export default UserModel;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment