/* @aztlan/generator-front 1.1.4 */ import * as React from 'react' import { useMemo, useEffect, useCallback, } from 'react' import * as PropTypes from 'prop-types' import { InferProps } from 'prop-types' import { useFormContext, useWatch, } from 'react-hook-form' import styleNames from '@aztlan/bem' import { Field, useFieldsValidity, } from '@aztlan/ui' import { WEEKDAYS } from '../constants.js' import { useTupleFormatOpeningHours } from '../hooks/index.js' const baseClassName = styleNames.base const componentClassName = 'add-item-form' const fieldNameMap = { openDay :'openDay', openHour :'openHour', closesOnSameDay:'closesOnSameDay', closeDay :'closeDay', closeHour :'closeHour', } /** * description * @param {InferProps} props - * @returns {React.ReactElement} - Rendered AddItemForm */ function AddItemForm({ id, className: userClassName, style, name, close, addOpeningHours, spanContentDesktop, spanLabelDesktop, }: // ...otherProps InferProps): React.ReactElement { const { setValue } = useFormContext() const sharedFieldProps = useMemo( () => ({ spanContentDesktop, spanLabelDesktop, }), [ spanContentDesktop, spanLabelDesktop, ], ) const fields = useMemo( () => [ { name :`${name}.${fieldNameMap.openDay}`, label :'Opens on', type :'select', options:Object.values(WEEKDAYS).map((e) => ({ value:e, label:e, })), }, { name :`${name}.${fieldNameMap.openHour}`, label:'At', type :'time', }, { name :`${name}.${fieldNameMap.closesOnSameDay}`, label :'Closes on the same day', type :'checkbox', optional:true, }, { name :`${name}.${fieldNameMap.closeDay}`, label :'Closes on', type :'select', options:Object.values(WEEKDAYS).map((e) => ({ value:e, label:e, })), condition:[ [`${name}.${fieldNameMap.closesOnSameDay}`], ([closesOnSameDay]) => closesOnSameDay === false, ], }, { name :`${name}.${fieldNameMap.closeHour}`, label:'At', type :'time', step :60, }, ], [], ) const fieldNames = [ fieldNameMap.openDay, fieldNameMap.openHour, fieldNameMap.closeDay, fieldNameMap.closeHour, fieldNameMap.closesOnSameDay, ].map((e) => `${name}.${e}`) const fieldValues = useWatch({ name: fieldNames }) /** Always set the closesOnSameDay to true on form open */ useEffect( () => { setValue( `${name}.${fieldNameMap.closesOnSameDay}`, true, ) }, [], ) /** Always set the closeDay to the same as the openDay on closesOnSameDay changes */ useEffect( () => { if (fieldValues[4]) { setValue( `${name}.${fieldNameMap.closeDay}`, fieldValues[0], ) } }, [ fieldValues[4], fieldValues[0], ], ) const preparedData = useTupleFormatOpeningHours({ openDay :fieldValues[0], openTime :fieldValues[1], closeDay :fieldValues[4] ? fieldValues[0] : fieldValues[2], closeTime:fieldValues[3], }) const { validateFields } = useFieldsValidity(fields) const submitSubformAndClose = useCallback( async () => { const valid = await validateFields() if (valid) { addOpeningHours(preparedData) close() } }, [ addOpeningHours, close, preparedData, validateFields, ], ) return (
e) .join(' ')} style={style} // {...otherProps} > {fields.map(({ name: fieldName, ...fieldProps }) => ( ))}
) } AddItemForm.propTypes = { /** The HTML id for this element */ id:PropTypes.string, /** The HTML class names for this element */ className:PropTypes.string, /** The React-written, css properties for this element. */ style:PropTypes.objectOf(PropTypes.string), /** The name of the form */ name:PropTypes.string.isRequired, /** The close function */ close:PropTypes.func.isRequired, /** The addOpeningHours function */ addOpeningHours:PropTypes.func.isRequired, /** The spanContentDesktop */ spanContentDesktop:PropTypes.number.isRequired, /** The spanLabelDesktop */ spanLabelDesktop:PropTypes.number.isRequired, } export default AddItemForm