Last active
August 11, 2023 04:07
-
-
Save seandogg/bfa408ed707a50a55d8805a67ead1d52 to your computer and use it in GitHub Desktop.
translate-x-help
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 log from 'loglevel'; | |
import PropTypes from 'prop-types'; | |
import { useState, useEffect } from 'react'; | |
import useLocalStorage from 'use-local-storage'; | |
import SvgIcon from '@/components/SvgIcon'; | |
import useSettings from '@/hooks/useSettings'; | |
const CreditsButton = ({ | |
display_vertical = false, | |
product, | |
className, | |
spanClassName, | |
plusSvgClassName, | |
creditSvgWidth | |
}) => { | |
const { dispatch } = useSettings(); | |
const [creditLabel, setCreditLabel] = useState(''); | |
const [savedStates] = useLocalStorage('jurisdictionKeys', []); | |
// data is coming down from algolia different than shopify | |
// also we have series products that need a seperate graph here | |
// we can extract the credits and label for each of them below. | |
const extractCredits = (product) => { | |
if (!product) return []; | |
log.debug('product is: ', product); | |
if (product?.variants && product?.variants?.edges) { | |
if (!product?.variants?.edges?.length) return []; | |
// get the variant credits from the variant with any downcased title of "live registration" first, | |
// else fallback to liveRegistrationVariant | |
const liveRegistrationVariant = product.variants.edges.find((variant) => { | |
if (variant?.node?.title?.toLowerCase() === 'live registration') { | |
return ( | |
variant?.node?.metafields?.course?.credits || | |
JSON.parse(variant?.node?.credits?.value ?? '{}') | |
); | |
} | |
}); | |
log.debug('liveRegistrationVariant:', liveRegistrationVariant); | |
if (liveRegistrationVariant) { | |
return ( | |
liveRegistrationVariant?.node?.metafields?.course?.credits || | |
JSON.parse(liveRegistrationVariant?.node?.credits?.value ?? '{}') | |
); | |
} | |
// this can be the fallback | |
const availableVariantCredits = product.variants.edges.map((variant) => { | |
log.debug('availableVariantCredits is: ', variant); | |
return ( | |
variant?.node?.metafields?.course?.credits || | |
JSON.parse(variant?.node?.credits?.value ?? '{}') | |
); | |
}); | |
if (liveRegistrationVariant) { | |
log.debug('liveRegistrationVariant:', liveRegistrationVariant); | |
const uniqueLiveRegistrationCredits = new Set( | |
liveRegistrationVariant.flat().map((credit) => JSON.stringify(credit)) | |
); | |
// Return unique live registration credit options | |
return Array.from(uniqueLiveRegistrationCredits).map((credit) => | |
JSON.parse(credit) | |
); | |
} else if (availableVariantCredits) { | |
// Remove duplicate credit options from flattened array | |
const uniqueVariantCredits = new Set( | |
availableVariantCredits.flat().map((credit) => JSON.stringify(credit)) | |
); | |
// Return unique credit options | |
return Array.from(uniqueVariantCredits).map((credit) => | |
JSON.parse(credit) | |
); | |
} else if (product?.meta?.course?.credits) { | |
return product?.meta?.course?.credits ?? []; | |
} else if (product?.credits) { | |
return JSON.parse(product?.credits?.value) ?? []; | |
} else { | |
return []; | |
} | |
} else { | |
return []; | |
} | |
}; | |
const formatCreditLabel = (credits, savedStates) => { | |
if (!credits) return ''; | |
const builtLabels = credits | |
.filter((credit) => savedStates.includes(credit['credit-key'])) | |
.map((credit) => `${credit['credit-total']} ${credit['credit-title']}`) | |
// filter any duplicates out | |
.filter((credit, index, self) => self.indexOf(credit) === index); | |
const label = | |
builtLabels.length > 0 | |
? builtLabels.join(', ') | |
: `${credits.length} CLE Options Available`; | |
return label.length > 25 ? `${label.substring(0, 22)}...` : label; // truncate longer labels | |
}; | |
const setButtonLabels = () => { | |
if (!product) return; | |
const credits = extractCredits(product); | |
const label = formatCreditLabel(credits, savedStates); | |
setCreditLabel(label); | |
}; | |
useEffect(() => { | |
setButtonLabels(); | |
}, [savedStates, product]); | |
const btnClass = [ | |
'btn--secondary', | |
'btn--credit', | |
'cursor-pointer', | |
'select-none', | |
'whitespace-nowrap', | |
'relative', | |
'z-10', | |
'text-fine-print', | |
'font-medium' | |
]; | |
const buttonClasses = [ | |
...btnClass, | |
...(Array.isArray(className) ? className : [className]) | |
]; | |
const spanClass = ['select-none', 'align-middle']; | |
const spanClasses = [ | |
...spanClass, | |
...(Array.isArray(spanClassName) ? spanClassName : [spanClassName]) | |
]; | |
const plusSvgClass = ['align-middle', 'select-none', 'icon-plus']; | |
const plusSvgClasses = [ | |
...plusSvgClass, | |
...(Array.isArray(plusSvgClassName) ? plusSvgClassName : [plusSvgClassName]) | |
]; | |
if (!product || creditLabel === '') return <></>; | |
return ( | |
<button | |
type="button" | |
aria-label={creditLabel} | |
className={[ | |
...buttonClasses, | |
...(display_vertical | |
? ['border-0', 'transition-none'] | |
: ['transition-all', 'xl-max:border-0']) | |
].join(' ')} | |
onClick={() => { | |
dispatch({ | |
type: 'SET_MODAL', | |
data: { | |
name: 'credits', | |
state: true, | |
product: { | |
...product, | |
meta: { | |
course: { | |
credits: extractCredits(product) | |
} | |
} | |
} | |
} | |
}); | |
}} | |
> | |
<SvgIcon | |
height={creditSvgWidth ? creditSvgWidth : 15} | |
width={creditSvgWidth ? creditSvgWidth : 15} | |
className="icon-credits select-none " | |
name="credits" | |
/> | |
<span className={[...spanClasses].join(' ')}>{creditLabel}</span> | |
<SvgIcon | |
height={15} | |
width={15} | |
className={[...plusSvgClasses].join(' ')} | |
name="plus" | |
/> | |
</button> | |
); | |
}; | |
CreditsButton.propTypes = { | |
product: PropTypes.shape({ | |
variants: PropTypes.shape({ | |
edges: PropTypes.arrayOf( | |
PropTypes.shape({ | |
node: PropTypes.shape({ | |
credits: PropTypes.shape({ | |
value: PropTypes.string | |
}), | |
metafields: PropTypes.shape({ | |
course: PropTypes.shape({ | |
credits: PropTypes.arrayOf( | |
PropTypes.shape({ | |
'credit-key': PropTypes.string, | |
'credit-title': PropTypes.string, | |
'credit-total': PropTypes.string | |
}) | |
) | |
}) | |
}) | |
}) | |
}) | |
) | |
}), | |
meta: PropTypes.shape({ | |
course: PropTypes.shape({ | |
credits: PropTypes.arrayOf( | |
PropTypes.shape({ | |
'credit-key': PropTypes.string, | |
'credit-title': PropTypes.string, | |
'credit-total': PropTypes.string | |
}) | |
) | |
}) | |
}), | |
credits: PropTypes.shape({ | |
value: PropTypes.string | |
}) | |
}), | |
className: PropTypes.oneOfType([ | |
PropTypes.string, | |
PropTypes.arrayOf(PropTypes.string) | |
]), | |
spanClassName: PropTypes.oneOfType([ | |
PropTypes.string, | |
PropTypes.arrayOf(PropTypes.string) | |
]), | |
plusSvgClassName: PropTypes.oneOfType([ | |
PropTypes.string, | |
PropTypes.arrayOf(PropTypes.string) | |
]), | |
creditSvgWidth: PropTypes.number, | |
display_vertical: PropTypes.bool | |
}; | |
export default CreditsButton; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment