import { IMPRESSION_BAD, IMPRESSION_GOOD, IMPRESSION_NEUTRAL, NOTES_MAX_LENGTH, WorkoutSession } from "@/components/Routines/models/WorkoutSession"; import { useAddSessionQuery, useEditSessionQuery, useFindSessionQuery } from "@/components/Routines/queries"; import { WgerTextField } from "@/core/forms/WgerTextField"; import { dateTimeToHHMM, dateToYYYYMMDD } from "@/core/lib/date"; import { SentimentNeutral, SentimentSatisfiedAlt, SentimentVeryDissatisfied } from "@mui/icons-material"; import { Button, ButtonGroup, Typography } from "@mui/material"; import Grid from '@mui/material/Grid'; import { DatePicker, LocalizationProvider, TimePicker } from "@mui/x-date-pickers"; import { AdapterLuxon } from "@mui/x-date-pickers/AdapterLuxon"; import { Form, Formik, FormikProps } from "formik"; import { DateTime } from "luxon"; import React, { useEffect, useRef } from 'react'; import { useTranslation } from "react-i18next"; import * as yup from 'yup'; interface SessionFormProps { initialSession?: WorkoutSession; dayId: number, routineId: number, selectedDate: DateTime, setSelectedDate: React.Dispatch> } type SessionFormValues = { notes: string | null; date: Date; start: DateTime | DateTime | null; end: DateTime | DateTime | null; impression: string; }; export const SessionForm = ({ initialSession, dayId, routineId, selectedDate, setSelectedDate }: SessionFormProps) => { const formikRef = useRef | null>(null); const [t, i18n] = useTranslation(); const [session, setSession] = React.useState(initialSession); const addSessionQuery = useAddSessionQuery(); const editSessionQuery = useEditSessionQuery(session?.id || ''); const findSessionQuery = useFindSessionQuery( routineId, { routine: routineId, date: dateToYYYYMMDD(selectedDate.toJSDate()), day: dayId } ); const isLoading = addSessionQuery.isPending || editSessionQuery.isPending || findSessionQuery.isLoading; const validationSchema = yup.object({ notes: yup .string() .max(NOTES_MAX_LENGTH, t('forms.maxLength', { chars: NOTES_MAX_LENGTH })), date: yup .date() .required(), start: yup .date() .nullable(), end: yup .date() .nullable() .min( yup.ref('start'), t('forms.endBeforeStart') ), fitInWeek: yup.boolean() }); useEffect(() => { if (!formikRef.current) { return; } if (findSessionQuery.data) { formikRef.current.setValues({ notes: findSessionQuery.data.notes || '', impression: findSessionQuery.data.impression || IMPRESSION_NEUTRAL, date: findSessionQuery.data.date, start: findSessionQuery.data.timeStart ? DateTime.fromJSDate(findSessionQuery.data.timeStart) : null, end: findSessionQuery.data.timeEnd ? DateTime.fromJSDate(findSessionQuery.data.timeEnd) : null, }); setSession(findSessionQuery.data); } else if (findSessionQuery.isSuccess && !findSessionQuery.data) { formikRef.current.setValues({ notes: '', impression: IMPRESSION_NEUTRAL, date: initialSession?.date || DateTime.now().toJSDate(), //JS Date, not DateTime start: initialSession?.timeStart ? DateTime.fromJSDate(initialSession.timeStart) : null, end: initialSession?.timeEnd ? DateTime.fromJSDate(initialSession.timeEnd) : null, }); setSession(undefined); } }, [findSessionQuery.data, findSessionQuery.isSuccess, initialSession, selectedDate]); return ( { const data = { day: dayId, routine: routineId, date: dateToYYYYMMDD(selectedDate.toJSDate()), notes: values.notes!, impression: values.impression, // eslint-disable-next-line camelcase time_start: values.start ? dateTimeToHHMM(values.start.toJSDate()) : null, // eslint-disable-next-line camelcase time_end: values.end ? dateTimeToHHMM(values.end.toJSDate()) : null }; if (session !== undefined) { // @ts-ignore String vs string await editSessionQuery.mutateAsync({ ...data, id: session.id }); } else { // @ts-ignore String vs string await addSessionQuery.mutateAsync(data); // navigate(makeLink(WgerLink.ROUTINE_EDIT, i18n.language, { id: routineId })); } }} > {formik => (
{ if (!newValue) { return; } formik.setFieldValue('date', newValue); setSelectedDate(newValue); }} disableFuture={true} slotProps={{ textField: { variant: "standard", fullWidth: true, error: formik.touched.date && Boolean(formik.errors.date), // helperText: formik.touched.date && formik.errors.date } }} /> { if (newValue) { formik.setFieldValue('start', newValue); } }} slotProps={{ textField: { variant: "standard", fullWidth: true, error: formik.touched.start && Boolean(formik.errors.start), helperText: formik.touched.start && formik.errors.start } }} /> { if (newValue) { formik.setFieldValue('end', newValue); } }} slotProps={{ textField: { variant: "standard", fullWidth: true, error: formik.touched.end && Boolean(formik.errors.end), helperText: formik.touched.end && formik.errors.end } }} /> {t('routines.impression')}
)}
); };