Skip to content

Commit

Permalink
Merge pull request #3196 from LiteFarmOrg/LF-4208/Add_multi_step_form
Browse files Browse the repository at this point in the history
LF-4208: Add multi step form
  • Loading branch information
kathyavini authored Apr 26, 2024
2 parents 66e5d58 + 0015d20 commit 94dceed
Show file tree
Hide file tree
Showing 5 changed files with 122 additions and 12 deletions.
88 changes: 88 additions & 0 deletions packages/webapp/src/components/Form/MultiStepForm/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/*
* Copyright 2024 LiteFarm.org
* This file is part of LiteFarm.
*
* LiteFarm is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* LiteFarm is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details, see <https://www.gnu.org/licenses/>.
*/

import { useState, useMemo } from 'react';

import MultiStepPageTitle from '../../PageTitle/MultiStepPageTitle';
import Layout from '../../Layout';
import { ClickAwayListener } from '@mui/material';
import { FormProvider, useForm } from 'react-hook-form';

export const MultiStepForm = ({ history, getSteps, cancelModalTitle, defaultFormValues }) => {
const [activeStepIndex, setActiveStepIndex] = useState(0);
const [showConfirmCancelModal, setShowConfirmCancelModal] = useState(false);
const [formData, setFormData] = useState();

const form = useForm({
mode: 'onBlur',
defaultValues: defaultFormValues,
});

const steps = useMemo(() => getSteps(formData), [getSteps, formData]);
const progressBarValue = useMemo(
() => (100 / (steps.length + 1)) * (activeStepIndex + 1),
[steps],
);

const storeFormData = () => {
const values = form.getValues();
setFormData({ ...formData, ...values });
};

const onGoBack = () => {
if (activeStepIndex === 0) {
onCancel();
return;
}
storeFormData();
setActiveStepIndex(activeStepIndex - 1);
};

const onGoForward = () => {
storeFormData();
setActiveStepIndex(activeStepIndex + 1);
};

const onCancel = () => {
history.back();
};

const onClickAway = () => {
setShowConfirmCancelModal(true);
};

const activeStep = steps[activeStepIndex];

return (
<ClickAwayListener onClickAway={onClickAway} mouseEvent="onMouseDown" touchEvent="onTouchStart">
<div>
<Layout>
<MultiStepPageTitle
title={activeStep.title}
onGoBack={onGoBack}
onCancel={onCancel}
cancelModalTitle={cancelModalTitle}
value={progressBarValue}
showConfirmCancelModal={showConfirmCancelModal}
setShowConfirmCancelModal={setShowConfirmCancelModal}
/>
<FormProvider {...form}>
<activeStep.FormContent onGoForward={onGoForward} form={form} />
</FormProvider>
</Layout>
</div>
</ClickAwayListener>
);
};
10 changes: 7 additions & 3 deletions packages/webapp/src/components/PageTitle/CancelButton.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,13 @@ import { colors } from '../../assets/theme';
import CancelFlowModal from '../Modals/CancelFlowModal';
import PropTypes from 'prop-types';

export function CancelButton({ onCancel, cancelModalTitle }) {
export function CancelButton({
onCancel,
cancelModalTitle,
showConfirmCancelModal,
setShowConfirmCancelModal,
}) {
const { t } = useTranslation();
const [showConfirmCancelModal, setShowConfirmCancelModal] = useState(false);
return (
<>
{showConfirmCancelModal && (
Expand All @@ -21,7 +25,7 @@ export function CancelButton({ onCancel, cancelModalTitle }) {
data-cy="cancel-flow"
sm
style={{ color: colors.teal700 }}
onClick={() => (!!cancelModalTitle ? setShowConfirmCancelModal(true) : onCancel())}
onClick={() => (cancelModalTitle ? setShowConfirmCancelModal(true) : onCancel())}
>
{t('common:CANCEL')}
</Semibold>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Semibold } from '../../Typography';
import React from 'react';
import React, { useState } from 'react';
import styles from './styles.module.scss';
import { BsChevronLeft } from 'react-icons/bs';
import PropTypes from 'prop-types';
Expand All @@ -14,8 +14,11 @@ function MultiStepPageTitle({
style,
value,
cancelModalTitle,
showProgressBar,
showConfirmCancelModal,
setShowConfirmCancelModal,
}) {
const [localShowModal, setLocalShowModal] = useState(false); // original form flow

return (
<div style={style}>
<div className={styles.titleContainer}>
Expand All @@ -27,7 +30,14 @@ function MultiStepPageTitle({
)}
<Semibold style={{ marginBottom: 0, color: colors.grey600 }}>{title}</Semibold>
</div>
{onCancel && <CancelButton onCancel={onCancel} cancelModalTitle={cancelModalTitle} />}
{onCancel && (
<CancelButton
onCancel={onCancel}
cancelModalTitle={cancelModalTitle}
showConfirmCancelModal={showConfirmCancelModal || localShowModal}
setShowConfirmCancelModal={setShowConfirmCancelModal || setLocalShowModal}
/>
)}
</div>
<ProgressBar value={value} />
</div>
Expand All @@ -41,4 +51,7 @@ MultiStepPageTitle.prototype = {
onCancel: PropTypes.func,
style: PropTypes.object,
value: PropTypes.number,
cancelModalTitle: PropTypes.string,
showConfirmCancelModal: PropTypes.bool,
setShowConfirmCancelModal: PropTypes.func,
};
12 changes: 10 additions & 2 deletions packages/webapp/src/components/PageTitle/v2/index.jsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { Title } from '../../Typography';
import React from 'react';
import React, { useState } from 'react';
import styles from './styles.module.scss';
import { BsChevronLeft } from 'react-icons/bs';
import PropTypes from 'prop-types';
import { CancelButton } from '../CancelButton';

function PageTitle({ title, onGoBack, onCancel, style, cancelModalTitle, label }) {
const [showConfirmCancelModal, setShowConfirmCancelModal] = useState(false);
return (
<div className={styles.container} style={style}>
<div className={styles.leftContainer} style={{ overflow: 'hidden', wordBreak: 'break-word' }}>
Expand All @@ -18,7 +19,14 @@ function PageTitle({ title, onGoBack, onCancel, style, cancelModalTitle, label }
{title.length > 77 ? `${title.substring(0, 77).trim()}...` : title}
</Title>
</div>
{!!onCancel && <CancelButton onCancel={onCancel} cancelModalTitle={cancelModalTitle} />}
{!!onCancel && (
<CancelButton
onCancel={onCancel}
cancelModalTitle={cancelModalTitle}
showConfirmCancelModal={showConfirmCancelModal}
setShowConfirmCancelModal={setShowConfirmCancelModal}
/>
)}
{label}
</div>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
import React, { useEffect, useMemo, useState } from 'react';
import { useSelector } from 'react-redux';
import {
hookFormPersistHistoryStackSelector,
hookFormPersistSelector,
} from './hookFormPersistSlice';
import { hookFormPersistSelector } from './hookFormPersistSlice';
import Spinner from '../../../components/Spinner';
import useHookFormPersist from './index';

Expand Down

0 comments on commit 94dceed

Please sign in to comment.