Created
May 18, 2021 21:26
-
-
Save Raja0sama/4935d8d888f38ebaa1a8d6e8992598d5 to your computer and use it in GitHub Desktop.
DVA Redux
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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