overleaf/services/web/frontend/js/features/settings/context/user-email-context.tsx
ilkin-overleaf 5b0c122f5d Merge pull request #7290 from overleaf/ii-7154-list-user-emails
List of user emails

GitOrigin-RevId: 28a8e405812932ba7ebd8043a4dc9d3c573a68b2
2022-04-11 08:03:38 +00:00

105 lines
2.3 KiB
TypeScript

import { createContext, useContext, useReducer, useCallback } from 'react'
import getMeta from '../../../utils/meta'
import useSafeDispatch from '../../../shared/hooks/use-safe-dispatch'
import { UserEmailData } from '../../../../../types/user-email'
import { normalize, NormalizedObject } from '../../../utils/normalize'
// eslint-disable-next-line no-unused-vars
enum Actions {
SET_LOADING_STATE = 'SET_LOADING_STATE', // eslint-disable-line no-unused-vars
}
type ActionSetLoading = {
type: Actions.SET_LOADING_STATE
payload: boolean
}
type State = {
isLoading: boolean
data: {
byId: NormalizedObject<UserEmailData>
}
}
type Action = ActionSetLoading
const setLoadingAction = (state: State, action: ActionSetLoading) => ({
...state,
isLoading: action.payload,
})
const initialState: State = {
isLoading: false,
data: {
byId: {},
},
}
const reducer = (state: State, action: Action) => {
switch (action.type) {
case Actions.SET_LOADING_STATE:
return setLoadingAction(state, action)
}
}
const initializer = (initialState: State) => {
const normalized = normalize<UserEmailData>(getMeta('ol-userEmails'), {
idAttribute: 'email',
})
const byId = normalized || {}
return {
...initialState,
data: {
...initialState.data,
byId,
},
}
}
function useUserEmails() {
const [state, dispatch] = useReducer(reducer, initialState, initializer)
const safeDispatch = useSafeDispatch(dispatch)
const setLoading = useCallback(
(flag: boolean) => {
safeDispatch({
type: Actions.SET_LOADING_STATE,
payload: flag,
})
},
[safeDispatch]
)
return {
state,
setLoading,
}
}
const UserEmailsContext = createContext<
ReturnType<typeof useUserEmails> | undefined
>(undefined)
UserEmailsContext.displayName = 'UserEmailsContext'
type UserEmailsProviderProps = {
children: React.ReactNode
} & Record<string, unknown>
function UserEmailsProvider(props: UserEmailsProviderProps) {
const value = useUserEmails()
return <UserEmailsContext.Provider value={value} {...props} />
}
const useUserEmailsContext = () => {
const context = useContext(UserEmailsContext)
if (context === undefined) {
throw new Error('useUserEmailsContext must be used in a UserEmailsProvider')
}
return context
}
export { UserEmailsProvider, useUserEmailsContext }