-
Notifications
You must be signed in to change notification settings - Fork 0
Training Form
In order to provide a consistent design between different training modes, there are several components defined in src/components/TrainingForm.tsx. These components should be used to present the training questions.
The underlying, outmost component is BasicTrainingForm, which creates a form and draws the card around it.
It receives a parameter, onSubmit, which will be called once the form is submitted.
Children of this component will be displayed within the card.
To fill the card, there are the TrainingFormHeader, TrainingFormContent and TrainingFormFooter components.
TrainingFormHeader displays the title and some additional buttons (they should not be used to capture user input), typically buttons to open a hint and info text modal. The title is a string passed to the component, it can be a react state, such that it changes depending on the stage of your algorithm. It can also be used to display feedback, like "Your soluton is correct". Children of this component are displayed on the right of the title.
TrainingFormContent should contain the user-interaction part of the training mode, like entering values, sorting edges etc... It receives no additional parameters and it's children should be the content.
TrainingFormFooter should be used to display "control" buttons, like the submit button. It receives no additonal parameters and it's children should be the buttons.
To simplify the buttons, severaly common buttons are defined in src/components/TrainingFormButtons.tsx.
All buttons defined there can be used with an optional disabled state, which determines whether they are clickable. All buttons except the submit button need an onClick function.
An example implementation for a training mode using the components could look like this:
import { useForm } from "react-hook-form";
import { BasicTrainingForm, TrainingFormHeader, TrainingFormContent, TrainingFormFooter } from "../../components/TrainingForm";
import { TrainingFormSubmitButton } from "../../components/TrainingFormButtons";
...
interface IMyTrainingPageProbs {
graphState: Graph<GraphNode, GraphLink>;
setGraphState: (state: Graph<GraphNode, GraphLink>) => void;
}
export const MyTrainingPage: React.FC<IMyTrainingPageProbs> = ({ graphState, setGraphState }) => {
const { handleSubmit, reset } = useForm();
const onSubmit = (): void => {
...
};
...
return (
<BasicTrainingForm onSubmit={handleSubmit(onSubmit)}>
<TrainingFormHeader title="My new training mode!">
Additional buttons!
</TrainingFormHeader>
<TrainingFormContent>
Your Questions here!
</TrainingFormContent>
<TrainingFormFooter>
Your bottom text and buttons here!
<TrainingFormSubmitButton />
</TrainingFormFooter>
</BasicTrainingForm>
);
};
Since many training modes use a hint modal which shows the pseudocode of the algorithm, there is another component: TrainingFormWithHeader which combines the other training form components.
It takes the title and onSubmit parameters, similarly to the ones in BasicTrainingForm and TrainingFormHeader. Additionally, it receives useAlgorithmStore which should be the store of your algorithm. It will then be used to get the pseudocode of the algorithm. The info attribute can be a string state which includes some description about the task. Children of this component will be wrapped with TrainingFormContent and you are expected to fill the controls attribute with buttons which will be shown at the bottom and automatically wrapped within TrainingFormFooter.
Additionally, it is possible to pass a feedback argument, which will be shown above the controls. This is typically used in combination with the FeedbackAlert component to show feedback messages in a box with highlighting.
This component allows to simplify the return value of the example above:
...
import { TrainingFormWithHeader } from "../../components/TrainingForm";
import { useMyAlgorithmStore } from "../../algorithms/myAlgorithm/store";
...
return (
<TrainingFormWithHeader
title="My new training mode!"
info="This additional text will be shown when the user presses on the i at the top right!"
onSubmit={handleSubmit(onSubmit)}
useAlgorithmStore={useMyAlgorithmStore}
controls={
<>
// Your bottom buttons here!
<TrainingFormSubmitButton />
</>
}
feedback={
<FeedbackAlert
// feedback is expected to be a state of type `Feedback` which changes according to the user inputs
feedback={feedback}
// isShowingResults is expected to be a bool state which controls whether the feedback is visible
isFeedbackVisible={isShowingResults}
/>
}
>
Your Questions here!
</TrainingFormWithHeader>
);
};