Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix/O3-3983: Allow Same-Day Program Enrollment and Completion #2039

Draft
wants to merge 13 commits into
base: main
Choose a base branch
from
5 changes: 5 additions & 0 deletions packages/esm-patient-programs-app/src/config-schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,14 @@ export const configSchema = {
'Whether to show the Program status field in the Record program enrollment and Edit program enrollment forms. If set to true, the `Program status` field is displayed in the Programs datatable',
_default: false,
},
allowCompletionTime: {
_type: Type.Boolean,
_default: false,
},
};

export interface ConfigObject {
hideAddProgramButton: boolean;
showProgramStatusField: boolean;
allowCompletionTime: boolean;
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useCallback, useEffect, useMemo } from 'react';
import React, { useCallback, useEffect, useMemo, useState } from 'react';
import classNames from 'classnames';
import { type TFunction, useTranslation } from 'react-i18next';
import dayjs from 'dayjs';
Expand Down Expand Up @@ -92,6 +92,7 @@ const ProgramsForm: React.FC<ProgramsFormProps> = ({
const {
control,
handleSubmit,
setValue,
watch,
formState: { errors, isDirty, isSubmitting },
} = useForm<ProgramsFormData>({
Expand Down Expand Up @@ -192,46 +193,85 @@ const ProgramsForm: React.FC<ProgramsFormProps> = ({
/>
);

const [selectedDate, setSelectedDate] = useState<Date | null>(
currentEnrollment?.dateEnrolled ? parseDate(currentEnrollment.dateEnrolled) : new Date(),
);
const [selectedTime, setSelectedTime] = useState<string>(
new Date().toLocaleTimeString('en-GB', { hour: '2-digit', minute: '2-digit' }),
);

const handleDateChange = ([date]: Date[]) => {
setSelectedDate(date);
updateDateTime(date, selectedTime);
};

const handleTimeChange = (event: React.ChangeEvent<HTMLInputElement>) => {
const time = event.target.value;
setSelectedTime(time);
updateDateTime(selectedDate, time);
};

const updateDateTime = (date: Date | null, time: string) => {
if (date) {
const [hours, minutes] = time.split(':').map(Number);
const updatedDateTime = new Date(date);
updatedDateTime.setHours(hours);
updatedDateTime.setMinutes(minutes);
setValue('enrollmentDate', updatedDateTime);
}
};

const enrollmentDate = (
<Controller
name="enrollmentDate"
control={control}
render={({ field: { onChange, value } }) => (
<DatePicker
aria-label="enrollment date"
id="enrollmentDate"
datePickerType="single"
dateFormat="d/m/Y"
maxDate={new Date().toISOString()}
placeholder="dd/mm/yyyy"
onChange={([date]) => onChange(date)}
value={value}
>
<DatePickerInput id="enrollmentDateInput" labelText={t('dateEnrolled', 'Date enrolled')} />
</DatePicker>
)}
/>
<DatePicker
aria-label="enrollment date"
id="enrollmentDate"
datePickerType="single"
dateFormat="d/m/Y"
maxDate={new Date().toISOString()}
placeholder="dd/mm/yyyy"
onChange={handleDateChange}
value={selectedDate}
>
<DatePickerInput id="enrollmentDateInput" labelText={t('dateEnrolled', 'Date enrolled')} />
</DatePicker>
);

const completionDate = (
<Controller
name="completionDate"
control={control}
render={({ field: { onChange, value } }) => (
<DatePicker
aria-label="completion date"
id="completionDate"
datePickerType="single"
dateFormat="d/m/Y"
minDate={new Date(watch('enrollmentDate')).toISOString()}
maxDate={new Date().toISOString()}
placeholder="dd/mm/yyyy"
onChange={([date]) => onChange(date)}
value={value}
>
<DatePickerInput id="completionDateInput" labelText={t('dateCompleted', 'Date completed')} />
</DatePicker>
)}
render={({ field: { onChange, value } }) => {
const handleChange = ([date]) => {
if (!date) return;

const selectedDate = new Date(date);
const today = new Date();
today.setHours(0, 0, 0, 0);

if (selectedDate.toDateString() === today.toDateString()) {
onChange(new Date());
} else {
selectedDate.setUTCHours(23, 59, 59, 999);
onChange(selectedDate);
Copy link
Contributor

@Muppasanipraneeth Muppasanipraneeth Feb 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

selectedDate.setHours(23, 59, 59, 999);

Copy link
Contributor

@Muppasanipraneeth Muppasanipraneeth Feb 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Screenshot 2025-02-07 at 8 35 58 AM @denniskigen correct me if I am wrong when we use selectedDate.setUTCHours(23, 59, 59, 999); we can observe its new day for us

Comment on lines +243 to +254
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

handleChange should be moved outside of render to prevent it from being recreated on every render.

}
};

return (
<DatePicker
aria-label="completion date"
id="completionDate"
datePickerType="single"
dateFormat="d/m/Y"
minDate={new Date(watch('enrollmentDate')).toISOString()}
maxDate={new Date().toISOString()}
placeholder="dd/mm/yyyy"
onChange={handleChange}
value={value}
>
<DatePickerInput id="completionDateInput" labelText={t('dateCompleted', 'Date completed')} />
</DatePicker>
);
}}
/>
);

Expand Down
Loading