Created
June 23, 2020 09:53
-
-
Save adnaan/76ce62701da0f8318e61589ebecfb145 to your computer and use it in GitHub Desktop.
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 {createSlice} from "@reduxjs/toolkit"; | |
import {asyncThunk, rx, asyncAction} from "./thunks"; | |
import {identity} from "./identity"; | |
export const fetchAccount = asyncThunk( | |
"account", | |
"fetchAccount", | |
async (id, state) => { | |
return identity.currentUser().attributes(); | |
}); | |
export const resetAPIKey = asyncThunk( | |
"account", | |
"resetAPIKey", | |
async (id, state) => { | |
return identity.currentUser().resetAPIKey(); | |
}); | |
export const updateName = asyncThunk( | |
"account", | |
"updateName", | |
async (name, state) => { | |
return identity.currentUser().update({data: {name: name}}); | |
}); | |
export const updateEmail = asyncThunk( | |
"account", | |
"updateEmail", | |
async (email, state) => { | |
return identity.currentUser().update({email: email}); | |
}); | |
export const requestPasswordRecovery = asyncThunk( | |
"account", | |
"requestPasswordRecovery", | |
async (email, state) => { | |
return identity.requestPasswordRecovery(email); | |
}); | |
export const confirm = asyncThunk( | |
"account", | |
"confirm", | |
async (data, state) => { | |
return identity.confirm(data, true); | |
}); | |
export const confirmPasswordReset = asyncThunk( | |
"account", | |
"confirmPasswordReset", | |
async (data, state) => { | |
return identity | |
.recover(data.token) | |
.then(response => { | |
const user = identity.currentUser(); | |
user.update({password: data.password}) | |
.then() | |
.catch(error => { | |
throw error; | |
}); | |
}) | |
}); | |
export const login = asyncThunk( | |
"account", | |
"login", | |
async (data, state) => { | |
return identity.login(data.email, data.pass, true); | |
}); | |
export const signup = asyncThunk( | |
"account", | |
"signup", | |
async (data, state) => { | |
console.log("signup") | |
return identity.signup(data.email, data.pass, data.data); | |
}); | |
export const logout = asyncThunk( | |
"account", | |
"logout", | |
async (data, state) => { | |
return identity.currentUser().logout(); | |
}); | |
export const subscribePlan = asyncThunk( | |
"account", | |
"subscribePlan", | |
async (data, state) => { | |
console.log(data, identity.currentUser()) | |
return identity.currentUser().subscribePlan(data); | |
}); | |
export const unsubscribePlan = asyncThunk( | |
"account", | |
"unsubscribePlan", | |
async (data, state) => { | |
return identity.currentUser().unsubscribePlan(data); | |
}) | |
export const listPaymentMethods = asyncThunk( | |
"account", | |
"listPaymentMethods", | |
async (data, state) => { | |
return identity.currentUser().listPaymentMethods(); | |
}); | |
export const addPaymentMethod = asyncThunk( | |
"account", | |
"addPaymentMethod", | |
async (id, state) => { | |
return identity.currentUser().addPaymentMethod(id); | |
}); | |
export const removePaymentMethod = asyncThunk( | |
"account", | |
"removePaymentMethod", | |
async (id, state) => { | |
return identity.currentUser().removePaymentMethod(id); | |
}); | |
export const setDefaultPaymentMethod = asyncThunk( | |
"account", | |
"setDefaultPaymentMethod", | |
async (id, state) => { | |
return identity.currentUser().setDefaultPaymentMethod(id); | |
}); | |
export const paymentMethodsUpdate = (state, action) => { | |
state.paymentMethods = action.payload.data; | |
state.default_payment_method_id = action.payload.default_payment_method_id; | |
}; | |
export const listInvoices = asyncThunk( | |
"account", | |
"listInvoices", | |
async (data, state) => { | |
return identity.currentUser().listInvoices(); | |
}); | |
export const listUsage = asyncThunk( | |
"account", | |
"listUsage", | |
async (data, state) => { | |
return identity.currentUser().listUsage(); | |
}); | |
const fetchUserAccountAction = asyncAction( | |
"app", | |
"fetchUserAccount", | |
async data => identity.currentUser().getAccount(), | |
(state, action) => { | |
state.userAccount = action.payload | |
} | |
); | |
export const fetchUserAccount = fetchUserAccountAction.thunk; | |
const createOrgAction = asyncAction( | |
"app", | |
"createOrg", | |
async data => identity.currentUser().createOrg(data), | |
(state, action) => { | |
state.userAccount = action.payload | |
} | |
); | |
export const createOrg = createOrgAction.thunk; | |
export const userUpdate = (state, action) => { | |
state.user = action.payload | |
} | |
export const initialAccountState = { | |
loading: {}, | |
user: identity.currentUser(), | |
userAccount: null, | |
subscription: null, | |
paymentMethods: [], | |
default_payment_method_id: null, | |
invoices: null, | |
usage: null, | |
error: {}, | |
currentRequestId: {}, | |
}; | |
export const accountSlice = createSlice({ | |
name: "account", | |
initialState: initialAccountState, | |
reducers: { | |
setUser: (state, action) => { | |
state.user = action.payload | |
} | |
}, | |
extraReducers: { | |
...rx(login, userUpdate), | |
...rx(logout, (state, action) => { | |
state.user = null | |
}), | |
...rx(signup), | |
...rx(fetchAccount, (state, action) => { | |
state.user = action.payload | |
}), | |
...rx(resetAPIKey, userUpdate), | |
...rx(updateName, userUpdate), | |
...rx(updateEmail, userUpdate), | |
...rx(requestPasswordRecovery), | |
...rx(confirm), | |
...rx(confirmPasswordReset), | |
...rx(subscribePlan, (state, action) => { | |
state.subscription = action.payload | |
}), | |
...rx(unsubscribePlan, (state, action) => { | |
state.subscription = action.payload | |
}), | |
...rx(listPaymentMethods, paymentMethodsUpdate), | |
...rx(addPaymentMethod, paymentMethodsUpdate), | |
...rx(removePaymentMethod, paymentMethodsUpdate), | |
...rx(setDefaultPaymentMethod, paymentMethodsUpdate), | |
...rx(listInvoices, (state, action) => { | |
state.invoices = action.payload | |
}), | |
...rx(listUsage, (state, action) => { | |
state.usage = action.payload | |
}), | |
...fetchUserAccountAction.reducers, | |
...createOrgAction.reducers | |
} | |
}); | |
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 {createAsyncThunk} from "@reduxjs/toolkit"; | |
const pending = (state, action) => { | |
const key = action.type.split('/')[1]; | |
if (state.loading[key] === 'idle' || state.loading[key] === undefined) { | |
state.loading[key] = 'pending'; | |
state.error[key] = undefined; | |
state.currentRequestId[key] = action.meta.requestId | |
} | |
}; | |
const fulfilled = (update) => { | |
return (state, action) => { | |
const {requestId} = action.meta; | |
const key = action.type.split('/')[1]; | |
// console.log("fulfilled => ", state.loading[key], key, state.currentRequestId[key], requestId); | |
if (state.loading[key] === 'pending' && state.currentRequestId[key] === requestId) { | |
state.loading[key] = 'idle'; | |
state.currentRequestId[key] = undefined; | |
state.error[key] = undefined | |
if (update) { | |
update(state, action); | |
} | |
} | |
} | |
}; | |
const rejected = (state, action) => { | |
const {requestId} = action.meta; | |
const key = action.type.split('/')[1]; | |
// console.log("rejected => ", state.loading[key], key, state.currentRequestId[key], requestId); | |
if (state.loading[key] === 'pending' && state.currentRequestId[key] === requestId) { | |
console.log("rejected", key, action.error) | |
state.loading[key] = 'idle'; | |
state.error[key] = action.error; | |
state.currentRequestId[key] = undefined | |
} | |
}; | |
const rx = (thunk, update) => { | |
return { | |
[thunk.pending]: pending, | |
[thunk.fulfilled]: fulfilled(update), | |
[thunk.rejected]: rejected | |
} | |
}; | |
const asyncThunk = (stateName, actionName, fetchFn) => { | |
return createAsyncThunk( | |
`${stateName}/${actionName}`, | |
(id, {getState}) => { | |
return fetchFn(id, getState()) | |
} | |
) | |
}; | |
const asyncAction = (stateName, actionName, fetchFn, update) => { | |
const thunk = createAsyncThunk( | |
`${stateName}/${actionName}`, | |
(payload, {getState}) => { | |
return fetchFn(payload) | |
} | |
); | |
const reducers = { | |
[thunk.pending]: pending, | |
[thunk.fulfilled]: fulfilled(update), | |
[thunk.rejected]: rejected | |
} | |
return {thunk, reducers} | |
}; | |
export { | |
asyncAction, | |
asyncThunk, | |
rx, | |
rejected, | |
fulfilled, | |
pending, | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment