import React, { type ChangeEvent, useCallback } from 'react'; import { ContentSwitcher, Layer, Switch, TextInput } from '@carbon/react'; import { useTranslation } from 'react-i18next'; import { useField } from 'formik'; import { OpenmrsDatePicker, useConfig } from '@openmrs/esm-framework'; import { usePatientRegistrationContext } from '../../patient-registration-context'; import { type RegistrationConfig } from '../../../config-schema'; import styles from '../field.scss'; const calcBirthdate = (yearDelta, monthDelta, dateOfBirth) => { const { enabled, month, dayOfMonth } = dateOfBirth.useEstimatedDateOfBirth; const startDate = new Date(); const resultMonth = new Date(startDate.getFullYear() - yearDelta, startDate.getMonth() - monthDelta, 1); const daysInResultMonth = new Date(resultMonth.getFullYear(), resultMonth.getMonth() + 1, 0).getDate(); const resultDate = new Date( resultMonth.getFullYear(), resultMonth.getMonth(), Math.min(startDate.getDate(), daysInResultMonth), ); return enabled ? new Date(resultDate.getFullYear(), month, dayOfMonth) : resultDate; }; export const DobField: React.FC = () => { const { t } = useTranslation(); const { fieldConfigurations: { dateOfBirth }, } = useConfig(); const allowEstimatedBirthDate = dateOfBirth?.allowEstimatedDateOfBirth; const [{ value: dobUnknown }] = useField('birthdateEstimated'); const [birthdate, birthdateMeta] = useField('birthdate'); const [yearsEstimated, yearsEstimateMeta] = useField('yearsEstimated'); const [monthsEstimated, monthsEstimateMeta] = useField('monthsEstimated'); const { setFieldValue, setFieldTouched } = usePatientRegistrationContext(); const today = new Date(); const onToggle = useCallback( (e: { name?: string | number }) => { setFieldValue('birthdateEstimated', e.name === 'unknown'); setFieldValue('birthdate', ''); setFieldValue('yearsEstimated', 0); setFieldValue('monthsEstimated', ''); setFieldTouched('birthdateEstimated', true, false); }, [setFieldTouched, setFieldValue], ); const onDateChange = useCallback( (birthdate: Date) => { setFieldValue('birthdate', birthdate); setFieldTouched('birthdate', true, false); }, [setFieldValue, setFieldTouched], ); const onEstimatedYearsChange = useCallback( (ev: ChangeEvent) => { const years = +ev.target.value; if (!isNaN(years) && years < 140 && years >= 0) { setFieldValue('yearsEstimated', years); setFieldValue('birthdate', calcBirthdate(years, monthsEstimateMeta.value, dateOfBirth)); } }, [setFieldValue, dateOfBirth, monthsEstimateMeta.value], ); const onEstimatedMonthsChange = useCallback( (ev: ChangeEvent) => { const months = +ev.target.value; if (!isNaN(months)) { setFieldValue('monthsEstimated', months); setFieldValue('birthdate', calcBirthdate(yearsEstimateMeta.value, months, dateOfBirth)); } }, [setFieldValue, dateOfBirth, yearsEstimateMeta.value], ); const updateBirthdate = useCallback(() => { const months = +monthsEstimateMeta.value % 12; const years = +yearsEstimateMeta.value + Math.floor(monthsEstimateMeta.value / 12); setFieldValue('yearsEstimated', years); setFieldValue('monthsEstimated', months > 0 ? months : ''); setFieldValue('birthdate', calcBirthdate(years, months, dateOfBirth)); setFieldTouched('yearsEstimated', true, false); setFieldTouched('monthsEstimated', true, false); setFieldTouched('birthdate', true, false); }, [setFieldValue, setFieldTouched, monthsEstimateMeta, yearsEstimateMeta, dateOfBirth]); return (

{t('birthFieldLabelText', 'Birth')}

{(allowEstimatedBirthDate || dobUnknown) && (
{t('dobToggleLabelText', 'Date of birth known?')}
{t('yes', 'Yes')} {t('no', 'No')}
)} {!dobUnknown ? (
setFieldTouched('birthdate', true, false)} maxDate={today} labelText={t('dateOfBirthLabelText', 'Date of birth')} isInvalid={!!(birthdateMeta.touched && birthdateMeta.error)} invalidText={t(birthdateMeta.error)} value={birthdate.value} />
) : (
{ yearsEstimated.onBlur(e); setFieldTouched('yearsEstimated', true, false); updateBirthdate(); }} />
{ monthsEstimated.onBlur(e); setFieldTouched('monthsEstimated', true, false); updateBirthdate(); }} />
)}
); };