Created
February 22, 2023 21:41
-
-
Save MichaelrMentele/ffabe9a9af014ddbde7d8885a03ceab0 to your computer and use it in GitHub Desktop.
This file contains hidden or 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 { useMutation } from '@apollo/client' | |
import lodash from 'lodash' | |
import { | |
CreateLienholderInput, | |
CreateLienholderMutation, | |
CreateLienholderMutationVariables, | |
DeleteLienholderMutation, | |
DeleteLienholderMutationVariables, | |
FindLienholdersQuery, | |
Lienholder, | |
UpdateLienholderInput, | |
UpdateLienholderMutation, | |
UpdateLienholderMutationVariables, | |
} from 'types/graphql' | |
import { | |
ADDRESS_FIELDS, | |
CUSTOMER_DEAL_FIELDS, | |
DEAL_TRADE_IN_FIELDS, | |
GET_LIENHOLDERS, | |
LIENHOLDER_FIELDS, | |
} from 'src/gql' | |
export const CREATE_LIENHOLDER = gql` | |
${LIENHOLDER_FIELDS} | |
${ADDRESS_FIELDS} | |
${CUSTOMER_DEAL_FIELDS} | |
${DEAL_TRADE_IN_FIELDS} | |
mutation CreateLienholderMutation($input: CreateLienholderInput!) { | |
createLienholder(input: $input) { | |
...LienholderFields | |
address { | |
...CoreAddressFields | |
} | |
customerDeals { | |
...CustomerDealFields | |
} | |
tradeIns { | |
...DealTradeInFields | |
} | |
} | |
} | |
` | |
export const UPDATE_LIENHOLDER = gql` | |
${LIENHOLDER_FIELDS} | |
${ADDRESS_FIELDS} | |
mutation UpdateLienholderMutation($id: Int!, $input: UpdateLienholderInput!) { | |
updateLienholder(id: $id, input: $input) { | |
...LienholderFields | |
address { | |
...CoreAddressFields | |
} | |
} | |
} | |
` | |
export const DELETE_LIENHOLDER = gql` | |
mutation DeleteLienholderMutation($id: Int!) { | |
deleteLienholder(id: $id) { | |
id | |
} | |
} | |
` | |
interface LienholderAlreadyExists { | |
id?: number | |
externalId: string | |
name: string | |
} | |
interface UseLienholdersHook { | |
lienholders: [Lienholder] | |
} | |
/** | |
* Hook to create update and delete Lienholders with validations and cache updates for gql | |
* | |
* @param {string} lienholders - lienholders from the query or cache | |
*/ | |
export function useLienholders(args: UseLienholdersHook) { | |
const { lienholders } = args | |
// ********* MUTATIONS ********* | |
const [createLienholderMutation] = useMutation< | |
CreateLienholderMutation, | |
CreateLienholderMutationVariables | |
>(CREATE_LIENHOLDER, { | |
update: (cache, mutationResult) => { | |
const lienholdersFromCache = cache.readQuery<FindLienholdersQuery>({ | |
query: GET_LIENHOLDERS, | |
}) | |
const newLienholder = mutationResult.data.createLienholder | |
const newLienholders = lodash.cloneDeep(lienholdersFromCache.lienholders) | |
newLienholders.push(newLienholder) | |
cache.writeQuery({ | |
query: GET_LIENHOLDERS, | |
data: { lienholders: newLienholders }, | |
}) | |
}, | |
}) | |
const [updateLienholderMutation] = useMutation< | |
UpdateLienholderMutation, | |
UpdateLienholderMutationVariables | |
>(UPDATE_LIENHOLDER, { | |
update: (cache, mutationResult) => { | |
const { address, ...newLienholder } = mutationResult.data.updateLienholder | |
cache.writeFragment({ | |
id: `Lienholder:${mutationResult.data.updateLienholder.id}`, | |
fragment: LIENHOLDER_FIELDS, | |
data: newLienholder, | |
}) | |
cache.writeFragment({ | |
id: `Address:${mutationResult.data.updateLienholder?.address?.id}`, | |
fragment: ADDRESS_FIELDS, | |
data: address, | |
}) | |
return mutationResult | |
}, | |
}) | |
const [deleteLienholderMutation] = useMutation< | |
DeleteLienholderMutation, | |
DeleteLienholderMutationVariables | |
>(DELETE_LIENHOLDER, { | |
update: (cache, mutationResult) => { | |
// UPSTACK: Will add proper cache update here | |
console.log('deleted lienholder: ', mutationResult.data) | |
return mutationResult | |
}, | |
}) | |
// ********* VALIDATIONS ********* | |
const lienholderAlreadyExists = (args: LienholderAlreadyExists) => { | |
const { id, externalId, name } = args | |
const alreadyExists = lienholders | |
? lienholders.find((lienholder) => { | |
if ( | |
lienholder.externalId === externalId || | |
lienholder.name === name || | |
lienholder.id === id | |
) { | |
return true | |
} | |
}) | |
: false | |
return alreadyExists | |
} | |
/** | |
* If the address object has any properties, clean the address object, otherwise delete the address | |
* object | |
* @param newLienholderData - The data that the user entered into the form. | |
*/ | |
const cleanCreateLienholderInput = (newLienholderData) => { | |
let addressIsValid = false | |
Object.keys(newLienholderData.address).every((field) => { | |
if (newLienholderData.address[field]) { | |
addressIsValid = true | |
return false | |
} | |
return true | |
}) | |
let result = cleanExternalIdInput(newLienholderData) | |
if (addressIsValid) { | |
result = cleanAddressInput(result) | |
} else { | |
delete result.address | |
} | |
return result | |
} | |
/** | |
* - Sets address.state to null if it's empty | |
* - if the type is empty, pass 'primary' instead. | |
* @param newLienholderData - The data that will be sent to the API. | |
*/ | |
const cleanAddressInput = (newLienholderData) => { | |
const result = lodash.cloneDeep(newLienholderData) | |
for (const key in result.address) { | |
if (result.address[key] === '') { | |
// Don't pass empty strings to backend | |
result.address[key] = null | |
} | |
} | |
delete result.address.id | |
result['address'] = { | |
...result.address, | |
// Don't pass empty string for type | |
type: result.address.type || 'primary', | |
} | |
return result | |
} | |
const cleanExternalIdInput = (newLienholderData) => { | |
const result = lodash.cloneDeep(newLienholderData) | |
if (!result.externalId) { | |
// Don't pass empty string for state | |
result.externalId = null | |
} | |
return result | |
} | |
// ********* COMMANDS ********* | |
const updateLienholder = async (id: number, input: UpdateLienholderInput) => { | |
const { externalId, name } = input | |
const alreadyExists = lienholderAlreadyExists({ id, externalId, name }) | |
if (!alreadyExists) { | |
throw new Error('Lienholder does not exist') | |
} | |
const cleanedInput = cleanExternalIdInput(cleanAddressInput(input)) | |
return await updateLienholderMutation({ | |
variables: { | |
id, | |
input: cleanedInput, | |
}, | |
}) | |
} | |
const createLienholder = async (input: CreateLienholderInput) => { | |
const { externalId, name } = input | |
const alreadyExists = lienholderAlreadyExists({ externalId, name }) | |
if (alreadyExists) { | |
throw new Error('Lienholder already exists') | |
} | |
const cleanedInput = cleanCreateLienholderInput(input) | |
return await createLienholderMutation({ | |
variables: { | |
input: cleanedInput, | |
}, | |
}) | |
} | |
// ********* COMMANDS *********` | |
const deleteLienholder = (id: number) => { | |
deleteLienholderMutation({ | |
variables: { | |
id, | |
}, | |
}) | |
} | |
return { | |
createLienholder, | |
deleteLienholder, | |
updateLienholder, | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment